consolidate emby.server.core into emby.server.implementations

pull/1154/head
Luke Pulverenti 7 years ago
parent 52aeb3c40b
commit 40442f887b

@ -32,12 +32,10 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.4.11\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\NLog.4.4.12\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text, Version=4.5.8.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath>
<Private>True</Private>
<Reference Include="ServiceStack.Text, Version=4.5.12.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ServiceStack.Text.4.5.12\lib\net45\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="SharpCompress, Version=0.14.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath>

@ -152,13 +152,23 @@ namespace Emby.Common.Implementations.Logging
RemoveTarget("ApplicationLogFileWrapper");
var wrapper = new AsyncTargetWrapper();
// https://github.com/NLog/NLog/wiki/Performance
var wrapper = new AsyncTargetWrapper
{
OverflowAction = AsyncTargetWrapperOverflowAction.Block,
QueueLimit = 10000,
BatchSize = 500,
TimeToSleepBetweenBatches = 50
};
wrapper.Name = "ApplicationLogFileWrapper";
var logFile = new FileTarget
{
FileName = path,
Layout = "${longdate} ${level} ${logger}: ${message}"
Layout = "${longdate} ${level} ${logger}: ${message}",
KeepFileOpen = true,
ConcurrentWrites = false
};
logFile.Name = "ApplicationLogFile";

@ -506,7 +506,7 @@ namespace Emby.Common.Implementations.Networking
public async Task<IpAddressInfo[]> GetHostAddressesAsync(string host)
{
var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false);
return addresses.Select(ToIpAddressInfo).ToArray();
return addresses.Select(ToIpAddressInfo).ToArray(addresses.Length);
}
/// <summary>

@ -14,6 +14,7 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Extensions;
namespace Emby.Common.Implementations.ScheduledTasks
{
@ -274,7 +275,8 @@ namespace Emby.Common.Implementations.ScheduledTasks
{
get
{
return InternalTriggers.Select(i => i.Item1).ToArray();
var triggers = InternalTriggers;
return triggers.Select(i => i.Item1).ToArray(triggers.Length);
}
set
{
@ -288,7 +290,7 @@ namespace Emby.Common.Implementations.ScheduledTasks
SaveTriggers(triggerList);
InternalTriggers = triggerList.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
InternalTriggers = triggerList.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray(triggerList.Length);
}
}

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NLog" version="4.4.11" targetFramework="net46" />
<package id="ServiceStack.Text" version="4.5.8" targetFramework="net462" />
<package id="NLog" version="4.4.12" targetFramework="net46" />
<package id="ServiceStack.Text" version="4.5.12" targetFramework="net46" />
<package id="SharpCompress" version="0.14.0" targetFramework="net462" />
<package id="SimpleInjector" version="4.0.8" targetFramework="net46" />
</packages>

@ -30,6 +30,7 @@ using MediaBrowser.Controller.Playlists;
using MediaBrowser.Controller.TV;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Xml;
using MediaBrowser.Model.Extensions;
namespace Emby.Dlna.ContentDirectory
{
@ -457,14 +458,14 @@ namespace Emby.Dlna.ContentDirectory
{
Limit = limit,
StartIndex = startIndex,
SortBy = sortOrders.ToArray(),
SortBy = sortOrders.ToArray(sortOrders.Count),
SortOrder = sort.SortOrder,
User = user,
Recursive = true,
IsMissing = false,
ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name },
IsFolder = isFolder,
MediaTypes = mediaTypes.ToArray(),
MediaTypes = mediaTypes.ToArray(mediaTypes.Count),
DtoOptions = GetDtoOptions()
});
}
@ -508,12 +509,12 @@ namespace Emby.Dlna.ContentDirectory
{
ItemId = item.Id
}).ToArray();
});
var result = new QueryResult<ServerItem>
{
Items = items.Select(i => new ServerItem(i)).ToArray(),
TotalRecordCount = items.Length
Items = items.Select(i => new ServerItem(i)).ToArray(items.Count),
TotalRecordCount = items.Count
};
return ApplyPaging(result, startIndex, limit);
@ -662,7 +663,7 @@ namespace Emby.Dlna.ContentDirectory
return new QueryResult<ServerItem>
{
Items = list.ToArray(),
Items = list.ToArray(list.Count),
TotalRecordCount = list.Count
};
}
@ -740,7 +741,7 @@ namespace Emby.Dlna.ContentDirectory
return new QueryResult<ServerItem>
{
Items = list.ToArray(),
Items = list.ToArray(list.Count),
TotalRecordCount = list.Count
};
}
@ -828,7 +829,7 @@ namespace Emby.Dlna.ContentDirectory
return new QueryResult<ServerItem>
{
Items = list.ToArray(),
Items = list.ToArray(list.Count),
TotalRecordCount = list.Count
};
}
@ -995,7 +996,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = genresResult.TotalRecordCount,
Items = genresResult.Items.Select(i => i.Item1).ToArray()
Items = genresResult.Items.Select(i => i.Item1).ToArray(genresResult.Items.Length)
};
return ToResult(result);
@ -1013,7 +1014,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = genresResult.TotalRecordCount,
Items = genresResult.Items.Select(i => i.Item1).ToArray()
Items = genresResult.Items.Select(i => i.Item1).ToArray(genresResult.Items.Length)
};
return ToResult(result);
@ -1031,7 +1032,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = artists.TotalRecordCount,
Items = artists.Items.Select(i => i.Item1).ToArray()
Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length)
};
return ToResult(result);
@ -1049,7 +1050,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = artists.TotalRecordCount,
Items = artists.Items.Select(i => i.Item1).ToArray()
Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length)
};
return ToResult(result);
@ -1068,7 +1069,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = artists.TotalRecordCount,
Items = artists.Items.Select(i => i.Item1).ToArray()
Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length)
};
return ToResult(result);
@ -1196,7 +1197,7 @@ namespace Emby.Dlna.ContentDirectory
{
var serverItems = result
.Select(i => new ServerItem(i))
.ToArray();
.ToArray(result.Count);
return new QueryResult<ServerItem>
{
@ -1210,7 +1211,7 @@ namespace Emby.Dlna.ContentDirectory
var serverItems = result
.Items
.Select(i => new ServerItem(i))
.ToArray();
.ToArray(result.Items.Length);
return new QueryResult<ServerItem>
{
@ -1227,7 +1228,7 @@ namespace Emby.Dlna.ContentDirectory
sortOrders.Add(ItemSortBy.SortName);
}
query.SortBy = sortOrders.ToArray();
query.SortBy = sortOrders.ToArray(sortOrders.Count);
query.SortOrder = sort.SortOrder;
}
@ -1243,8 +1244,7 @@ namespace Emby.Dlna.ContentDirectory
DtoOptions = GetDtoOptions()
});
var serverItems = itemsResult.Items.Select(i => new ServerItem(i))
.ToArray();
var serverItems = itemsResult.Items.Select(i => new ServerItem(i)).ToArray(itemsResult.Items.Length);
return new QueryResult<ServerItem>
{

@ -18,6 +18,7 @@ using System.Text;
using System.Text.RegularExpressions;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Reflection;
using MediaBrowser.Model.Extensions;
namespace Emby.Dlna
{
@ -106,7 +107,6 @@ namespace Emby.Dlna
}
else
{
_logger.Debug("No matching device profile found. The default will need to be used.");
LogUnmatchedProfile(deviceInfo);
}
@ -220,12 +220,8 @@ namespace Emby.Dlna
}
else
{
var msg = new StringBuilder();
foreach (var header in headers)
{
msg.AppendLine(header.Key + ": " + header.Value);
}
_logger.LogMultiline("No matching device profile found. The default will need to be used.", LogSeverity.Info, msg);
var headerString = string.Join(", ", headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(headers.Count));
_logger.Debug("No matching device profile found. {0}", headerString);
}
return profile;

@ -15,6 +15,7 @@ using System.Threading.Tasks;
using System.Xml.Linq;
using Emby.Dlna.Server;
using MediaBrowser.Model.Threading;
using MediaBrowser.Model.Extensions;
namespace Emby.Dlna.PlayTo
{
@ -890,7 +891,7 @@ namespace Emby.Dlna.PlayTo
if (room != null && !string.IsNullOrWhiteSpace(room.Value))
friendlyNames.Add(room.Value);
deviceProperties.Name = string.Join(" ", friendlyNames.ToArray());
deviceProperties.Name = string.Join(" ", friendlyNames.ToArray(friendlyNames.Count));
var model = document.Descendants(uPnpNamespaces.ud.GetName("modelName")).FirstOrDefault();
if (model != null)

@ -1,6 +1,7 @@
using MediaBrowser.Model.Dlna;
using System.Linq;
using System.Xml.Serialization;
using MediaBrowser.Model.Extensions;
namespace Emby.Dlna.Profiles
{
@ -164,7 +165,7 @@ namespace Emby.Dlna.Profiles
public void AddXmlRootAttribute(string name, string value)
{
var atts = XmlRootAttributes ?? new XmlAttribute[] { };
var list = atts.ToList();
var list = atts.ToList(atts.Length);
list.Add(new XmlAttribute
{
@ -172,7 +173,7 @@ namespace Emby.Dlna.Profiles
Value = value
});
XmlRootAttributes = list.ToArray();
XmlRootAttributes = list.ToArray(list.Count);
}
}
}

@ -226,7 +226,7 @@ namespace Emby.Dlna.Server
}
}
var characters = characterList.ToArray();
var characters = characterList.ToArray(characterList.Count);
var serverName = new string(characters);

@ -11,6 +11,7 @@ using System.Xml;
using Emby.Dlna.Didl;
using MediaBrowser.Controller.Extensions;
using MediaBrowser.Model.Xml;
using MediaBrowser.Model.Extensions;
namespace Emby.Dlna.Service
{
@ -235,26 +236,29 @@ namespace Emby.Dlna.Service
private void LogRequest(ControlRequest request)
{
var builder = new StringBuilder();
if (!Config.GetDlnaConfiguration().EnableDebugLog)
{
return;
}
var headers = string.Join(", ", request.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
builder.AppendFormat("Headers: {0}", headers);
builder.AppendLine();
//builder.Append(request.InputXml);
var originalHeaders = request.Headers;
var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(originalHeaders.Count));
Logger.LogMultiline("Control request", LogSeverity.Debug, builder);
Logger.Debug("Control request. Headers: {0}", headers);
}
private void LogResponse(ControlResponse response)
{
var builder = new StringBuilder();
if (!Config.GetDlnaConfiguration().EnableDebugLog)
{
return;
}
var headers = string.Join(", ", response.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
builder.AppendFormat("Headers: {0}", headers);
builder.AppendLine();
builder.Append(response.Xml);
var originalHeaders = response.Headers;
var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(originalHeaders.Count));
//builder.Append(response.Xml);
Logger.LogMultiline("Control response", LogSeverity.Debug, builder);
Logger.Debug("Control response. Headers: {0}", headers);
}
}
}

@ -17,12 +17,10 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
using Emby.Drawing.Common;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Threading;
using TagLib;
using MediaBrowser.Model.Extensions;
namespace Emby.Drawing
{
@ -662,7 +660,7 @@ namespace Emby.Drawing
var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList();
cacheKeys.Add(originalImagePath + dateModified.Ticks);
return string.Join("|", cacheKeys.ToArray()).GetMD5().ToString("N");
return string.Join("|", cacheKeys.ToArray(cacheKeys.Count)).GetMD5().ToString("N");
}
/// <summary>

@ -111,7 +111,7 @@ namespace Emby.Photos
}
item.Genres = image.ImageTag.Genres.ToList();
item.Tags = image.ImageTag.Keywords.ToList();
item.Tags = image.ImageTag.Keywords;
item.Software = image.ImageTag.Software;
if (image.ImageTag.Orientation == TagLib.Image.ImageOrientation.None)

@ -1,176 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{776B9F0C-5195-45E3-9A36-1CC1F0D8E0B0}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Emby.Server.Core</RootNamespace>
<AssemblyName>Emby.Server.Core</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.2\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ServiceStack.Text, Version=4.5.8.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="ApplicationHost.cs" />
<Compile Include="ApplicationPathHelper.cs" />
<Compile Include="Cryptography\ASN1.cs" />
<Compile Include="Cryptography\ASN1Convert.cs" />
<Compile Include="Cryptography\BitConverterLE.cs" />
<Compile Include="Cryptography\CertificateGenerator.cs" />
<Compile Include="Cryptography\CryptoConvert.cs" />
<Compile Include="Cryptography\PfxGenerator.cs" />
<Compile Include="Cryptography\PKCS1.cs" />
<Compile Include="Cryptography\PKCS12.cs" />
<Compile Include="Cryptography\PKCS7.cs" />
<Compile Include="Cryptography\PKCS8.cs" />
<Compile Include="Cryptography\X501Name.cs" />
<Compile Include="Cryptography\X509Builder.cs" />
<Compile Include="Cryptography\X509Certificate.cs" />
<Compile Include="Cryptography\X509CertificateBuilder.cs" />
<Compile Include="Cryptography\X509CertificateCollection.cs" />
<Compile Include="Cryptography\X509Extension.cs" />
<Compile Include="Cryptography\X509Extensions.cs" />
<Compile Include="Cryptography\X520Attributes.cs" />
<Compile Include="EntryPoints\ExternalPortForwarding.cs" />
<Compile Include="HttpServerFactory.cs" />
<Compile Include="IO\LibraryMonitor.cs" />
<Compile Include="IO\MemoryStreamProvider.cs" />
<Compile Include="Localization\TextLocalizer.cs" />
<Compile Include="Logging\ConsoleLogger.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SystemEvents.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Emby.Common.Implementations\Emby.Common.Implementations.csproj">
<Project>{1e37a338-9f57-4b70-bd6d-bb9c591e319b}</Project>
<Name>Emby.Common.Implementations</Name>
</ProjectReference>
<ProjectReference Include="..\Emby.Dlna\Emby.Dlna.csproj">
<Project>{805844ab-e92f-45e6-9d99-4f6d48d129a5}</Project>
<Name>Emby.Dlna</Name>
</ProjectReference>
<ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj">
<Project>{08fff49b-f175-4807-a2b5-73b0ebd9f716}</Project>
<Name>Emby.Drawing</Name>
</ProjectReference>
<ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj">
<Project>{89ab4548-770d-41fd-a891-8daff44f452c}</Project>
<Name>Emby.Photos</Name>
</ProjectReference>
<ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj">
<Project>{e383961b-9356-4d5d-8233-9a1079d03055}</Project>
<Name>Emby.Server.Implementations</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj">
<Project>{4fd51ac5-2c16-4308-a993-c3a84f3b4582}</Project>
<Name>MediaBrowser.Api</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
<Name>MediaBrowser.Common</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
<Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
<Name>MediaBrowser.Controller</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj">
<Project>{7ef9f3e0-697d-42f3-a08f-19deb5f84392}</Project>
<Name>MediaBrowser.LocalMetadata</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj">
<Project>{0bd82fa6-eb8a-4452-8af5-74f9c3849451}</Project>
<Name>MediaBrowser.MediaEncoding</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Providers\MediaBrowser.Providers.csproj">
<Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project>
<Name>MediaBrowser.Providers</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj">
<Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project>
<Name>MediaBrowser.Server.Implementations</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj">
<Project>{5624b7b5-b5a7-41d8-9f10-cc5611109619}</Project>
<Name>MediaBrowser.WebDashboard</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj">
<Project>{23499896-b135-4527-8574-c26e926ea99e}</Project>
<Name>MediaBrowser.XbmcMetadata</Name>
</ProjectReference>
<ProjectReference Include="..\Mono.Nat\Mono.Nat.csproj">
<Project>{cb7f2326-6497-4a3d-ba03-48513b17a7be}</Project>
<Name>Mono.Nat</Name>
</ProjectReference>
<ProjectReference Include="..\OpenSubtitlesHandler\OpenSubtitlesHandler.csproj">
<Project>{4a4402d4-e910-443b-b8fc-2c18286a2ca0}</Project>
<Name>OpenSubtitlesHandler</Name>
</ProjectReference>
<ProjectReference Include="..\SocketHttpListener\SocketHttpListener.csproj">
<Project>{1d74413b-e7cf-455b-b021-f52bdf881542}</Project>
<Name>SocketHttpListener</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

@ -1,34 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Emby.Server.Core")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Emby.Server.Core")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("776b9f0c-5195-45e3-9a36-1cc1f0d8e0b0")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="SimpleInjector" publicKeyToken="984cb50dea722e99" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.7.0" newVersion="4.0.7.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/></startup></configuration>

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.2" targetFramework="net462" />
<package id="ServiceStack.Text" version="4.5.8" targetFramework="net462" />
<package id="SimpleInjector" version="4.0.8" targetFramework="net46" />
</packages>

@ -18,6 +18,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Activity
{
@ -436,7 +437,7 @@ namespace Emby.Server.Implementations.Activity
{
Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
Type = "ScheduledTaskFailed",
Overview = string.Join(Environment.NewLine, vals.ToArray()),
Overview = string.Join(Environment.NewLine, vals.ToArray(vals.Count)),
ShortOverview = runningTime,
Severity = LogSeverity.Error
});

@ -10,6 +10,7 @@ using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
using SQLitePCL.pretty;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Activity
{
@ -94,13 +95,13 @@ namespace Emby.Server.Implementations.Activity
var whereTextWithoutPaging = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
if (startIndex.HasValue && startIndex.Value > 0)
{
var pagingWhereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLogEntries {0} ORDER BY DateCreated DESC LIMIT {1})",
pagingWhereText,
@ -109,7 +110,7 @@ namespace Emby.Server.Implementations.Activity
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@ -154,7 +155,7 @@ namespace Emby.Server.Implementations.Activity
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
}
result.Items = list.ToArray();
result.Items = list.ToArray(list.Count);
return result;
}, ReadTransactionMode);

@ -1,11 +1,52 @@
using MediaBrowser.Api;
using Emby.Common.Implementations;
using Emby.Common.Implementations.Archiving;
using Emby.Common.Implementations.IO;
using Emby.Common.Implementations.Reflection;
using Emby.Common.Implementations.ScheduledTasks;
using Emby.Common.Implementations.Serialization;
using Emby.Common.Implementations.TextEncoding;
using Emby.Common.Implementations.Xml;
using Emby.Dlna;
using Emby.Dlna.ConnectionManager;
using Emby.Dlna.ContentDirectory;
using Emby.Dlna.Main;
using Emby.Dlna.MediaReceiverRegistrar;
using Emby.Dlna.Ssdp;
using Emby.Drawing;
using Emby.Photos;
using Emby.Server.Implementations.Activity;
using Emby.Server.Implementations.Channels;
using Emby.Server.Implementations.Collections;
using Emby.Server.Implementations.Configuration;
using Emby.Server.Implementations.Data;
using Emby.Server.Implementations.Devices;
using Emby.Server.Implementations.Dto;
using Emby.Server.Implementations.FFMpeg;
using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.HttpServer.Security;
using Emby.Server.Implementations.IO;
using Emby.Server.Implementations.Library;
using Emby.Server.Implementations.LiveTv;
using Emby.Server.Implementations.Localization;
using Emby.Server.Implementations.MediaEncoder;
using Emby.Server.Implementations.Migrations;
using Emby.Server.Implementations.Notifications;
using Emby.Server.Implementations.Playlists;
using Emby.Server.Implementations.Security;
using Emby.Server.Implementations.Session;
using Emby.Server.Implementations.Social;
using Emby.Server.Implementations.TV;
using Emby.Server.Implementations.Updates;
using MediaBrowser.Api;
using MediaBrowser.Common;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions;
using Emby.Common.Implementations.ScheduledTasks;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Progress;
using MediaBrowser.Common.Security;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Chapters;
@ -17,6 +58,9 @@ using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
@ -34,102 +78,47 @@ using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Controller.Sync;
using MediaBrowser.Controller.TV;
using MediaBrowser.LocalMetadata.Savers;
using MediaBrowser.MediaEncoding.BdInfo;
using MediaBrowser.MediaEncoding.Encoder;
using MediaBrowser.MediaEncoding.Subtitles;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.News;
using MediaBrowser.Model.Reflection;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Social;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Text;
using MediaBrowser.Model.Updates;
using MediaBrowser.Model.Xml;
using MediaBrowser.Providers.Chapters;
using MediaBrowser.Providers.Manager;
using MediaBrowser.Providers.Subtitles;
using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers;
using OpenSubtitlesHandler;
using ServiceStack;
using SocketHttpListener.Primitives;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Emby.Common.Implementations;
using Emby.Common.Implementations.Archiving;
using Emby.Common.Implementations.IO;
using Emby.Common.Implementations.Reflection;
using Emby.Common.Implementations.Serialization;
using Emby.Common.Implementations.TextEncoding;
using Emby.Common.Implementations.Xml;
using Emby.Photos;
using MediaBrowser.Model.IO;
using MediaBrowser.Api.Playback;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Security;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using Emby.Dlna;
using Emby.Dlna.ConnectionManager;
using Emby.Dlna.ContentDirectory;
using Emby.Dlna.Main;
using Emby.Dlna.MediaReceiverRegistrar;
using Emby.Dlna.Ssdp;
using Emby.Server.Core;
using Emby.Server.Implementations.Activity;
using Emby.Server.Implementations.Devices;
using Emby.Server.Implementations.FFMpeg;
using Emby.Server.Core.IO;
using Emby.Server.Core.Localization;
using Emby.Server.Implementations.Migrations;
using Emby.Server.Implementations.Security;
using Emby.Server.Implementations.Social;
using Emby.Server.Implementations.Channels;
using Emby.Server.Implementations.Collections;
using Emby.Server.Implementations.Dto;
using Emby.Server.Implementations.IO;
using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.HttpServer.Security;
using Emby.Server.Implementations.Library;
using Emby.Server.Implementations.LiveTv;
using Emby.Server.Implementations.Localization;
using Emby.Server.Implementations.MediaEncoder;
using Emby.Server.Implementations.Notifications;
using Emby.Server.Implementations.Data;
using Emby.Server.Implementations.Playlists;
using Emby.Server.Implementations;
using Emby.Server.Implementations.ServerManager;
using Emby.Server.Implementations.Session;
using Emby.Server.Implementations.TV;
using Emby.Server.Implementations.Updates;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.News;
using MediaBrowser.Model.Reflection;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Social;
using MediaBrowser.Model.Text;
using MediaBrowser.Model.Xml;
using OpenSubtitlesHandler;
using ServiceStack;
using SocketHttpListener.Primitives;
using Emby.Server.MediaEncoding.Subtitles;
using MediaBrowser.MediaEncoding.BdInfo;
using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions;
using Emby.Drawing;
using Emby.Server.Implementations.Migrations;
using MediaBrowser.Model.Diagnostics;
using Emby.Common.Implementations.Diagnostics;
using Emby.Server.Implementations.Configuration;
namespace Emby.Server.Core
namespace Emby.Server.Implementations
{
/// <summary>
/// Class CompositionRoot
@ -357,13 +346,6 @@ namespace Emby.Server.Core
{
var builder = GetBaseExceptionMessage(ApplicationPaths);
// Skip if plugins haven't been loaded yet
//if (Plugins != null)
//{
// var pluginString = string.Join("|", Plugins.Select(i => i.Name + "-" + i.Version.ToString()).ToArray());
// builder.Insert(0, string.Format("Plugins: {0}{1}", pluginString, Environment.NewLine));
//}
builder.Insert(0, string.Format("Version: {0}{1}", ApplicationVersion, Environment.NewLine));
builder.Insert(0, "*** Error Report ***" + Environment.NewLine);
@ -608,7 +590,7 @@ namespace Emby.Server.Core
RegisterSingleInstance(HttpServer, false);
progress.Report(10);
ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamFactory, textEncoding);
ServerManager = new ServerManager.ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamFactory, textEncoding);
RegisterSingleInstance(ServerManager);
var innerProgress = new ActionableProgress<double>();
@ -884,7 +866,7 @@ namespace Emby.Server.Core
probePath = info.ProbePath;
var hasExternalEncoder = string.Equals(info.Version, "external", StringComparison.OrdinalIgnoreCase);
var mediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"),
var mediaEncoder = new MediaEncoding.Encoder.MediaEncoder(LogManager.GetLogger("MediaEncoder"),
JsonSerializer,
encoderPath,
probePath,
@ -980,8 +962,6 @@ namespace Emby.Server.Core
BaseItem.CollectionManager = CollectionManager;
BaseItem.MediaSourceManager = MediaSourceManager;
CollectionFolder.XmlSerializer = XmlSerializer;
BaseStreamingService.AppHost = this;
BaseStreamingService.HttpClient = HttpClient;
Utilities.CryptographyProvider = CryptographyProvider;
AuthenticatedAttribute.AuthService = AuthService;
}
@ -1254,7 +1234,7 @@ namespace Emby.Server.Core
list.Add(GetAssembly(typeof(InstallationManager)));
// MediaEncoding
list.Add(GetAssembly(typeof(MediaEncoder)));
list.Add(GetAssembly(typeof(MediaEncoding.Encoder.MediaEncoder)));
// Dlna
list.Add(GetAssembly(typeof(DlnaEntryPoint)));
@ -1267,10 +1247,7 @@ namespace Emby.Server.Core
list.AddRange(GetAssembliesWithPartsInternal());
// Include composable parts in the running assembly
list.Add(GetAssembly(typeof(ApplicationHost)));
return list;
return list.ToList();
}
protected abstract List<Assembly> GetAssembliesWithPartsInternal();

@ -2,7 +2,7 @@
using System.Configuration;
using System.IO;
namespace Emby.Server.Core
namespace Emby.Server.Implementations
{
public static class ApplicationPathHelper
{

@ -159,7 +159,7 @@ namespace Emby.Server.Implementations.Channels
all = all.Take(query.Limit.Value).ToList();
}
var returnItems = all.ToArray();
var returnItems = all.ToArray(all.Count);
var result = new QueryResult<Channel>
{
@ -182,8 +182,10 @@ namespace Emby.Server.Implementations.Channels
{
};
var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false))
.ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ConfigureAwait(false));
var returnItems = returnList
.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@ -567,8 +569,9 @@ namespace Emby.Server.Implementations.Channels
Fields = query.Fields.ToList()
};
var returnItems = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false))
.ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false));
var returnItems = returnList
.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@ -676,12 +679,10 @@ namespace Emby.Server.Implementations.Channels
internalItems = internalItems.Take(query.Limit.Value).ToArray();
}
var returnItemArray = internalItems.ToArray();
return new QueryResult<BaseItem>
{
TotalRecordCount = totalCount,
Items = returnItemArray
Items = internalItems
};
}
@ -813,12 +814,10 @@ namespace Emby.Server.Implementations.Channels
var internalItems = await Task.WhenAll(itemTasks).ConfigureAwait(false);
var returnItemArray = internalItems.ToArray();
return new QueryResult<BaseItem>
{
TotalRecordCount = totalCount,
Items = returnItemArray
Items = internalItems
};
}
@ -837,8 +836,10 @@ namespace Emby.Server.Implementations.Channels
Fields = query.Fields.ToList()
};
var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false))
.ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ConfigureAwait(false));
var returnItems = returnList
.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@ -989,8 +990,10 @@ namespace Emby.Server.Implementations.Channels
Fields = query.Fields.ToList()
};
var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false))
.ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ConfigureAwait(false));
var returnItems = returnList
.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@ -1191,7 +1194,7 @@ namespace Emby.Server.Implementations.Channels
}
}
var returnItemArray = all.ToArray();
var returnItemArray = all.ToArray(all.Count);
RefreshIfNeeded(returnItemArray);
return new QueryResult<BaseItem>
@ -1309,7 +1312,7 @@ namespace Emby.Server.Implementations.Channels
{
item.Name = info.Name;
item.Genres = info.Genres;
item.Studios = info.Studios;
item.Studios = info.Studios.ToArray(info.Studios.Count);
item.CommunityRating = info.CommunityRating;
item.Overview = info.Overview;
item.IndexNumber = info.IndexNumber;
@ -1319,7 +1322,7 @@ namespace Emby.Server.Implementations.Channels
item.ProviderIds = info.ProviderIds;
item.OfficialRating = info.OfficialRating;
item.DateCreated = info.DateCreated ?? DateTime.UtcNow;
item.Tags = info.Tags;
item.Tags = info.Tags.ToArray(info.Tags.Count);
item.HomePageUrl = info.HomePageUrl;
}
else if (info.Type == ChannelItemType.Folder && info.FolderType == ChannelFolderType.Container)

@ -16,6 +16,7 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Configuration
{
@ -216,7 +217,7 @@ namespace Emby.Server.Implementations.Configuration
list.Add(service);
options.DisabledMetadataSavers = list.ToArray();
options.DisabledMetadataSavers = list.ToArray(list.Count);
}
}
@ -236,7 +237,7 @@ namespace Emby.Server.Implementations.Configuration
list.Add(options);
config.MetadataOptions = list.ToArray();
config.MetadataOptions = list.ToArray(list.Count);
}
return options;

@ -136,24 +136,6 @@ namespace Emby.Server.Implementations.Data
queries.Add("PRAGMA temp_store = file");
}
////foreach (var query in queries)
////{
//// db.Execute(query);
////}
//Logger.Info("synchronous: " + db.Query("PRAGMA synchronous").SelectScalarString().First());
//Logger.Info("temp_store: " + db.Query("PRAGMA temp_store").SelectScalarString().First());
/*if (!string.Equals(_defaultWal, "wal", StringComparison.OrdinalIgnoreCase))
{
queries.Add("PRAGMA journal_mode=WAL");
using (WriteLock.Write())
{
db.ExecuteAll(string.Join(";", queries.ToArray()));
}
}
else*/
foreach (var query in queries)
{
db.Execute(query);
@ -212,6 +194,13 @@ namespace Emby.Server.Implementations.Data
"pragma temp_store = memory"
});
}
else
{
queries.AddRange(new List<string>
{
"pragma temp_store = file"
});
}
db.ExecuteAll(string.Join(";", queries.ToArray()));
Logger.Info("PRAGMA synchronous=" + db.Query("PRAGMA synchronous").SelectScalarString().First());

@ -31,6 +31,7 @@ using MediaBrowser.Model.Reflection;
using SQLitePCL.pretty;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Threading;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Data
{
@ -836,7 +837,7 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@IsInMixedFolder", item.IsInMixedFolder);
if (item.LockedFields.Count > 0)
if (item.LockedFields.Length > 0)
{
saveItemStatement.TryBind("@LockedFields", string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()));
}
@ -845,7 +846,7 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBindNull("@LockedFields");
}
if (item.Studios.Count > 0)
if (item.Studios.Length > 0)
{
saveItemStatement.TryBind("@Studios", string.Join("|", item.Studios.ToArray()));
}
@ -865,9 +866,9 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@ExternalServiceId", item.ServiceName);
if (item.Tags.Count > 0)
if (item.Tags.Length > 0)
{
saveItemStatement.TryBind("@Tags", string.Join("|", item.Tags.ToArray()));
saveItemStatement.TryBind("@Tags", string.Join("|", item.Tags));
}
else
{
@ -984,16 +985,16 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@ProviderIds", SerializeProviderIds(item));
saveItemStatement.TryBind("@Images", SerializeImages(item));
if (item.ProductionLocations.Count > 0)
if (item.ProductionLocations.Length > 0)
{
saveItemStatement.TryBind("@ProductionLocations", string.Join("|", item.ProductionLocations.ToArray()));
saveItemStatement.TryBind("@ProductionLocations", string.Join("|", item.ProductionLocations));
}
else
{
saveItemStatement.TryBindNull("@ProductionLocations");
}
if (item.ThemeSongIds.Count > 0)
if (item.ThemeSongIds.Length > 0)
{
saveItemStatement.TryBind("@ThemeSongIds", string.Join("|", item.ThemeSongIds.ToArray()));
}
@ -1002,7 +1003,7 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBindNull("@ThemeSongIds");
}
if (item.ThemeVideoIds.Count > 0)
if (item.ThemeVideoIds.Length > 0)
{
saveItemStatement.TryBind("@ThemeVideoIds", string.Join("|", item.ThemeVideoIds.ToArray()));
}
@ -1089,9 +1090,9 @@ namespace Emby.Server.Implementations.Data
private string SerializeImages(BaseItem item)
{
var images = item.ImageInfos.ToList();
var images = item.ImageInfos;
if (images.Count == 0)
if (images.Length == 0)
{
return null;
}
@ -1108,22 +1109,24 @@ namespace Emby.Server.Implementations.Data
return;
}
if (item.ImageInfos.Count > 0)
if (item.ImageInfos.Length > 0)
{
return;
}
var parts = value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
var list = new List<ItemImageInfo>();
foreach (var part in parts)
{
var image = ItemImageInfoFromValueString(part);
if (image != null)
{
item.ImageInfos.Add(image);
list.Add(image);
}
}
item.ImageInfos = list.ToArray(list.Count);
}
public string ToValueString(ItemImageInfo image)
@ -1678,7 +1681,7 @@ namespace Emby.Server.Implementations.Data
return parsedValue;
}
return (MetadataFields?)null;
}).Where(i => i.HasValue).Select(i => i.Value).ToList();
}).Where(i => i.HasValue).Select(i => i.Value).ToArray();
}
index++;
}
@ -1687,7 +1690,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
item.Studios = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
item.Studios = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
index++;
}
@ -1696,7 +1699,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
item.Tags = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
item.Tags = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
index++;
}
@ -1873,7 +1876,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
item.ProductionLocations = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
item.ProductionLocations = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray();
}
index++;
}
@ -1882,7 +1885,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
item.ThemeSongIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList();
item.ThemeSongIds = SplitToGuids(reader.GetString(index));
}
index++;
}
@ -1891,7 +1894,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
item.ThemeVideoIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList();
item.ThemeVideoIds = SplitToGuids(reader.GetString(index));
}
index++;
}
@ -1950,12 +1953,26 @@ namespace Emby.Server.Implementations.Data
return item;
}
private Guid[] SplitToGuids(string value)
{
var ids = value.Split('|');
var result = new Guid[ids.Length];
for (var i = 0; i < result.Length; i++)
{
result[i] = new Guid(ids[i]);
}
return result;
}
/// <summary>
/// Gets the critic reviews.
/// </summary>
/// <param name="itemId">The item id.</param>
/// <returns>Task{IEnumerable{ItemReview}}.</returns>
public IEnumerable<ItemReview> GetCriticReviews(Guid itemId)
public List<ItemReview> GetCriticReviews(Guid itemId)
{
return new List<ItemReview>();
}
@ -2206,7 +2223,7 @@ namespace Emby.Server.Implementations.Data
return false;
}
private List<ItemFields> allFields = Enum.GetNames(typeof(ItemFields))
private readonly List<ItemFields> allFields = Enum.GetNames(typeof(ItemFields))
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
.ToList();
@ -2548,11 +2565,11 @@ namespace Emby.Server.Implementations.Data
}
}
query.ExcludeItemIds = excludeIds.ToArray();
query.ExcludeItemIds = excludeIds.ToArray(excludeIds.Count);
query.ExcludeProviderIds = item.ProviderIds;
}
return list.ToArray();
return list.ToArray(list.Count);
}
private void BindSimilarParams(InternalItemsQuery query, IStatement statement)
@ -2595,7 +2612,7 @@ namespace Emby.Server.Implementations.Data
if (groups.Count > 0)
{
return " Group by " + string.Join(",", groups.ToArray());
return " Group by " + string.Join(",", groups.ToArray(groups.Count));
}
return string.Empty;
@ -2632,7 +2649,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@ -2689,7 +2706,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@ -2842,7 +2859,7 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemList(query);
return new QueryResult<BaseItem>
{
Items = returnList.ToArray(),
Items = returnList.ToArray(returnList.Count),
TotalRecordCount = returnList.Count
};
}
@ -2865,7 +2882,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
var whereTextWithoutPaging = whereText;
@ -2926,8 +2943,7 @@ namespace Emby.Server.Implementations.Data
return connection.RunInTransaction(db =>
{
var result = new QueryResult<BaseItem>();
var statements = PrepareAllSafe(db, statementTexts)
.ToList();
var statements = PrepareAllSafe(db, statementTexts);
if (!isReturningZeroItems)
{
@ -2981,7 +2997,7 @@ namespace Emby.Server.Implementations.Data
LogQueryTime("GetItems", commandText, now);
result.Items = list.ToArray();
result.Items = list.ToArray(list.Count);
return result;
}, ReadTransactionMode);
@ -3133,7 +3149,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@ -3204,7 +3220,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@ -3277,7 +3293,7 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemIdsList(query);
return new QueryResult<Guid>
{
Items = returnList.ToArray(),
Items = returnList.ToArray(returnList.Count),
TotalRecordCount = returnList.Count
};
}
@ -3292,7 +3308,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
var whereTextWithoutPaging = whereText;
@ -3355,8 +3371,7 @@ namespace Emby.Server.Implementations.Data
{
var result = new QueryResult<Guid>();
var statements = PrepareAllSafe(db, statementTexts)
.ToList();
var statements = PrepareAllSafe(db, statementTexts);
if (!isReturningZeroItems)
{
@ -3399,7 +3414,7 @@ namespace Emby.Server.Implementations.Data
LogQueryTime("GetItemIds", commandText, now);
result.Items = list.ToArray();
result.Items = list.ToArray(list.Count);
return result;
}, ReadTransactionMode);
@ -3604,7 +3619,7 @@ namespace Emby.Server.Implementations.Data
}
if (programAttribtues.Count > 0)
{
whereClauses.Add("(" + string.Join(" OR ", programAttribtues.ToArray()) + ")");
whereClauses.Add("(" + string.Join(" OR ", programAttribtues.ToArray(programAttribtues.Count)) + ")");
}
}
@ -5129,9 +5144,9 @@ namespace Emby.Server.Implementations.Data
var itemCountColumns = new List<Tuple<string, string>>();
var typesToCount = query.IncludeItemTypes.ToList();
var typesToCount = query.IncludeItemTypes;
if (typesToCount.Count > 0)
if (typesToCount.Length > 0)
{
var itemCountColumnQuery = "select group_concat(type, '|')" + GetFromText("B");
@ -5191,7 +5206,7 @@ namespace Emby.Server.Implementations.Data
var whereText = " where Type=@SelectType";
if (typesToCount.Count == 0)
if (typesToCount.Length == 0)
{
whereText += " And CleanName In (Select CleanValue from ItemValues where " + typeClause + " AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))";
}
@ -5269,8 +5284,7 @@ namespace Emby.Server.Implementations.Data
var list = new List<Tuple<BaseItem, ItemCounts>>();
var result = new QueryResult<Tuple<BaseItem, ItemCounts>>();
var statements = PrepareAllSafe(db, statementTexts)
.ToList();
var statements = PrepareAllSafe(db, statementTexts);
if (!isReturningZeroItems)
{
@ -5345,7 +5359,7 @@ namespace Emby.Server.Implementations.Data
{
result.TotalRecordCount = list.Count;
}
result.Items = list.ToArray();
result.Items = list.ToArray(list.Count);
return result;
@ -5354,11 +5368,11 @@ namespace Emby.Server.Implementations.Data
}
}
private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, List<string> typesToCount)
private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, string[] typesToCount)
{
var counts = new ItemCounts();
if (typesToCount.Count == 0)
if (typesToCount.Length == 0)
{
return counts;
}

@ -649,12 +649,12 @@ namespace Emby.Server.Implementations.Dto
dto.GameSystem = item.GameSystemName;
}
private List<string> GetImageTags(BaseItem item, List<ItemImageInfo> images)
private string[] GetImageTags(BaseItem item, List<ItemImageInfo> images)
{
return images
.Select(p => GetImageCacheTag(item, p))
.Where(i => i != null)
.ToList();
.ToArray();
}
private string GetImageCacheTag(BaseItem item, ImageType type)
@ -766,7 +766,7 @@ namespace Emby.Server.Implementations.Dto
}
}
dto.People = list.ToArray();
dto.People = list.ToArray(list.Count);
}
/// <summary>
@ -1049,12 +1049,12 @@ namespace Emby.Server.Implementations.Dto
{
if (!string.IsNullOrWhiteSpace(item.Tagline))
{
dto.Taglines = new List<string> { item.Tagline };
dto.Taglines = new string[] { item.Tagline };
}
if (dto.Taglines == null)
{
dto.Taglines = new List<string>();
dto.Taglines = new string[]{};
}
}
@ -1430,9 +1430,9 @@ namespace Emby.Server.Implementations.Dto
if (fields.Contains(ItemFields.ProductionLocations))
{
if (item.ProductionLocations.Count > 0 || item is Movie)
if (item.ProductionLocations.Length > 0 || item is Movie)
{
dto.ProductionLocations = item.ProductionLocations.ToArray();
dto.ProductionLocations = item.ProductionLocations;
}
}

@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -40,6 +41,8 @@
<Compile Include="AppBase\BaseApplicationPaths.cs" />
<Compile Include="AppBase\BaseConfigurationManager.cs" />
<Compile Include="AppBase\ConfigurationHelper.cs" />
<Compile Include="ApplicationHost.cs" />
<Compile Include="ApplicationPathHelper.cs" />
<Compile Include="Branding\BrandingConfigurationFactory.cs" />
<Compile Include="Browser\BrowserLauncher.cs" />
<Compile Include="Channels\ChannelConfigurations.cs" />
@ -52,6 +55,24 @@
<Compile Include="Collections\CollectionManager.cs" />
<Compile Include="Collections\CollectionsDynamicFolder.cs" />
<Compile Include="Configuration\ServerConfigurationManager.cs" />
<Compile Include="Cryptography\ASN1.cs" />
<Compile Include="Cryptography\ASN1Convert.cs" />
<Compile Include="Cryptography\BitConverterLE.cs" />
<Compile Include="Cryptography\CertificateGenerator.cs" />
<Compile Include="Cryptography\CryptoConvert.cs" />
<Compile Include="Cryptography\PfxGenerator.cs" />
<Compile Include="Cryptography\PKCS1.cs" />
<Compile Include="Cryptography\PKCS12.cs" />
<Compile Include="Cryptography\PKCS7.cs" />
<Compile Include="Cryptography\PKCS8.cs" />
<Compile Include="Cryptography\X501Name.cs" />
<Compile Include="Cryptography\X509Builder.cs" />
<Compile Include="Cryptography\X509Certificate.cs" />
<Compile Include="Cryptography\X509CertificateBuilder.cs" />
<Compile Include="Cryptography\X509CertificateCollection.cs" />
<Compile Include="Cryptography\X509Extension.cs" />
<Compile Include="Cryptography\X509Extensions.cs" />
<Compile Include="Cryptography\X520Attributes.cs" />
<Compile Include="Data\ManagedConnection.cs" />
<Compile Include="Data\SqliteDisplayPreferencesRepository.cs" />
<Compile Include="Data\SqliteItemRepository.cs" />
@ -63,6 +84,7 @@
<Compile Include="Devices\DeviceRepository.cs" />
<Compile Include="Dto\DtoService.cs" />
<Compile Include="EntryPoints\AutomaticRestartEntryPoint.cs" />
<Compile Include="EntryPoints\ExternalPortForwarding.cs" />
<Compile Include="EntryPoints\KeepServerAwake.cs" />
<Compile Include="EntryPoints\LibraryChangedNotifier.cs" />
<Compile Include="EntryPoints\LoadRegistrations.cs" />
@ -78,6 +100,7 @@
<Compile Include="FFMpeg\FFMpegInfo.cs" />
<Compile Include="FFMpeg\FFMpegInstallInfo.cs" />
<Compile Include="FFMpeg\FFMpegLoader.cs" />
<Compile Include="HttpServerFactory.cs" />
<Compile Include="HttpServer\FileWriter.cs" />
<Compile Include="HttpServer\HttpListenerHost.cs" />
<Compile Include="HttpServer\HttpResultFactory.cs" />
@ -99,7 +122,9 @@
<Compile Include="Images\BaseDynamicImageProvider.cs" />
<Compile Include="IO\AsyncStreamCopier.cs" />
<Compile Include="IO\FileRefresher.cs" />
<Compile Include="IO\LibraryMonitor.cs" />
<Compile Include="IO\MbLinkShortcutHandler.cs" />
<Compile Include="IO\MemoryStreamProvider.cs" />
<Compile Include="IO\ThrottledStream.cs" />
<Compile Include="Library\CoreResolutionIgnoreRule.cs" />
<Compile Include="Library\LibraryManager.cs" />
@ -170,6 +195,8 @@
<Compile Include="LiveTv\TunerHosts\MulticastStream.cs" />
<Compile Include="LiveTv\TunerHosts\QueueStream.cs" />
<Compile Include="Localization\LocalizationManager.cs" />
<Compile Include="Localization\TextLocalizer.cs" />
<Compile Include="Logging\ConsoleLogger.cs" />
<Compile Include="Logging\UnhandledExceptionWriter.cs" />
<Compile Include="MediaEncoder\EncodingManager.cs" />
<Compile Include="Migrations\IVersionMigration.cs" />
@ -249,6 +276,7 @@
<Compile Include="Sorting\StartDateComparer.cs" />
<Compile Include="Sorting\StudioComparer.cs" />
<Compile Include="StartupOptions.cs" />
<Compile Include="SystemEvents.cs" />
<Compile Include="TV\SeriesPostScanTask.cs" />
<Compile Include="TV\TVSeriesManager.cs" />
<Compile Include="Udp\UdpServer.cs" />
@ -260,6 +288,26 @@
<EmbeddedResource Include="Localization\iso6392.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Emby.Common.Implementations\Emby.Common.Implementations.csproj">
<Project>{1e37a338-9f57-4b70-bd6d-bb9c591e319b}</Project>
<Name>Emby.Common.Implementations</Name>
</ProjectReference>
<ProjectReference Include="..\Emby.Dlna\Emby.Dlna.csproj">
<Project>{805844ab-e92f-45e6-9d99-4f6d48d129a5}</Project>
<Name>Emby.Dlna</Name>
</ProjectReference>
<ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj">
<Project>{08fff49b-f175-4807-a2b5-73b0ebd9f716}</Project>
<Name>Emby.Drawing</Name>
</ProjectReference>
<ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj">
<Project>{89ab4548-770d-41fd-a891-8daff44f452c}</Project>
<Name>Emby.Photos</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj">
<Project>{4fd51ac5-2c16-4308-a993-c3a84f3b4582}</Project>
<Name>MediaBrowser.Api</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
<Name>MediaBrowser.Common</Name>
@ -268,6 +316,10 @@
<Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
<Name>MediaBrowser.Controller</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj">
<Project>{7ef9f3e0-697d-42f3-a08f-19deb5f84392}</Project>
<Name>MediaBrowser.LocalMetadata</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
@ -280,10 +332,29 @@
<Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project>
<Name>MediaBrowser.Server.Implementations</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj">
<Project>{5624b7b5-b5a7-41d8-9f10-cc5611109619}</Project>
<Name>MediaBrowser.WebDashboard</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj">
<Project>{23499896-b135-4527-8574-c26e926ea99e}</Project>
<Name>MediaBrowser.XbmcMetadata</Name>
</ProjectReference>
<ProjectReference Include="..\Mono.Nat\Mono.Nat.csproj">
<Project>{cb7f2326-6497-4a3d-ba03-48513b17a7be}</Project>
<Name>Mono.Nat</Name>
</ProjectReference>
<ProjectReference Include="..\OpenSubtitlesHandler\OpenSubtitlesHandler.csproj">
<Project>{4a4402d4-e910-443b-b8fc-2c18286a2ca0}</Project>
<Name>OpenSubtitlesHandler</Name>
</ProjectReference>
<ProjectReference Include="..\SocketHttpListener\SocketHttpListener.csproj">
<Project>{1d74413b-e7cf-455b-b021-f52bdf881542}</Project>
<Name>SocketHttpListener</Name>
</ProjectReference>
<Reference Include="Emby.Server.MediaEncoding">
<HintPath>..\ThirdParty\emby\Emby.Server.MediaEncoding.dll</HintPath>
</Reference>
<Reference Include="Emby.XmlTv, Version=1.0.6387.29335, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Emby.XmlTv.1.0.9\lib\portable-net45+win8\Emby.XmlTv.dll</HintPath>
<Private>True</Private>
@ -292,6 +363,15 @@
<HintPath>..\packages\MediaBrowser.Naming.1.0.5\lib\portable-net45+win8\MediaBrowser.Naming.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.2\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text, Version=4.5.12.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ServiceStack.Text.4.5.12\lib\net45\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>
</Reference>
<Reference Include="SQLitePCL.pretty, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SQLitePCL.pretty.1.1.0\lib\portable-net45+netcore45+wpa81+wp8\SQLitePCL.pretty.dll</HintPath>
<Private>True</Private>
@ -299,10 +379,10 @@
</ItemGroup>
<ItemGroup>
<Reference Include="SQLitePCLRaw.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1488e028ca7ab535, processorArchitecture=MSIL">
<HintPath>..\packages\SQLitePCLRaw.core.1.1.7\lib\net45\SQLitePCLRaw.core.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\SQLitePCLRaw.core.1.1.8\lib\net45\SQLitePCLRaw.core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Linq" />

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Threading.Tasks;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
@ -11,9 +12,9 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Threading;
using Mono.Nat;
using System.Threading.Tasks;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Core.EntryPoints
namespace Emby.Server.Implementations.EntryPoints
{
public class ExternalPortForwarding : IServerEntryPoint
{
@ -50,7 +51,7 @@ namespace Emby.Server.Core.EntryPoints
values.Add(config.EnableHttps.ToString());
values.Add(_appHost.EnableHttps.ToString());
return string.Join("|", values.ToArray());
return string.Join("|", values.ToArray(values.Count));
}
void _config_ConfigurationUpdated(object sender, EventArgs e)

@ -12,6 +12,7 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.EntryPoints
{
@ -58,7 +59,7 @@ namespace Emby.Server.Implementations.EntryPoints
session.ApplicationVersion
};
var key = string.Join("_", keys.ToArray()).GetMD5();
var key = string.Join("_", keys.ToArray(keys.Count)).GetMD5();
_apps.GetOrAdd(key, guid => GetNewClientInfo(session));
}

@ -125,13 +125,6 @@ namespace Emby.Server.Implementations.HttpServer
return _appHost.CreateInstance(type);
}
private ServiceController CreateServiceController()
{
var types = _restServices.Select(r => r.GetType()).ToArray();
return new ServiceController(() => types);
}
/// <summary>
/// Applies the request filters. Returns whether or not the request has been handled
/// and no more processing should be done.
@ -186,7 +179,7 @@ namespace Emby.Server.Implementations.HttpServer
attributes.Sort((x, y) => x.Priority - y.Priority);
return attributes.ToArray();
return attributes.ToArray(attributes.Count);
}
/// <summary>
@ -697,11 +690,13 @@ namespace Emby.Server.Implementations.HttpServer
{
_restServices.AddRange(services);
ServiceController = CreateServiceController();
ServiceController = new ServiceController();
_logger.Info("Calling ServiceStack AppHost.Init");
ServiceController.Init(this);
var types = _restServices.Select(r => r.GetType()).ToArray();
ServiceController.Init(this, types);
var requestFilters = _appHost.GetExports<IRequestFilter>().ToList();
foreach (var filter in requestFilters)
@ -741,7 +736,7 @@ namespace Emby.Server.Implementations.HttpServer
});
}
return routes.ToArray();
return routes.ToArray(routes.Count);
}
public Func<string, object> GetParseFn(Type propertyType)

@ -4,6 +4,7 @@ using System.Globalization;
using System.Linq;
using MediaBrowser.Model.Services;
using SocketHttpListener.Net;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.HttpServer
{
@ -29,7 +30,7 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
var headerText = string.Join(", ", headers.Select(i => i.Name + "=" + i.Value).ToArray());
var headerText = string.Join(", ", headers.Select(i => i.Name + "=" + i.Value).ToArray(headers.Count));
logger.Info("HTTP {0} {1}. {2}", method, url, headerText);
}

@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Text;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.HttpServer.SocketSharp
{
@ -585,7 +586,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
WriteCharBytes(bytes, ch, e);
}
byte[] buf = bytes.ToArray();
byte[] buf = bytes.ToArray(bytes.Count);
bytes = null;
return e.GetString(buf, 0, buf.Length);

@ -1,9 +1,7 @@
using System;
using System.IO;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Emby.Common.Implementations.Net;
using Emby.Server.Implementations.HttpServer;
@ -21,7 +19,7 @@ using MediaBrowser.Model.Text;
using ServiceStack.Text.Jsv;
using SocketHttpListener.Primitives;
namespace Emby.Server.Core
namespace Emby.Server.Implementations
{
/// <summary>
/// Class ServerFactory

@ -13,9 +13,8 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
using Emby.Server.Implementations.IO;
namespace Emby.Server.Core.IO
namespace Emby.Server.Implementations.IO
{
public class LibraryMonitor : ILibraryMonitor
{

@ -2,7 +2,7 @@
using MediaBrowser.Model.IO;
using Microsoft.IO;
namespace Emby.Server.Core.IO
namespace Emby.Server.Implementations.IO
{
public class RecyclableMemoryStreamProvider : IMemoryStreamFactory
{

@ -293,20 +293,16 @@ namespace Emby.Server.Implementations.Images
return true;
}
protected List<BaseItem> GetFinalItems(List<BaseItem> items)
protected List<BaseItem> GetFinalItems(IEnumerable<BaseItem> items)
{
return GetFinalItems(items, 4);
}
protected virtual List<BaseItem> GetFinalItems(List<BaseItem> items, int limit)
protected virtual List<BaseItem> GetFinalItems(IEnumerable<BaseItem> items, int limit)
{
// Rotate the images once every x days
var random = DateTime.Now.DayOfYear % MaxImageAgeDays;
return items
.OrderBy(i => (random + string.Empty + items.IndexOf(i)).GetMD5())
.OrderBy(i => Guid.NewGuid())
.Take(limit)
.OrderBy(i => i.Name)
.ToList();
}

@ -136,14 +136,6 @@ namespace Emby.Server.Implementations.Library
/// <value>The configuration manager.</value>
private IServerConfigurationManager ConfigurationManager { get; set; }
/// <summary>
/// A collection of items that may be referenced from multiple physical places in the library
/// (typically, multiple user roots). We store them here and be sure they all reference a
/// single instance.
/// </summary>
/// <value>The by reference items.</value>
private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; }
private readonly Func<ILibraryMonitor> _libraryMonitorFactory;
private readonly Func<IProviderManager> _providerManagerFactory;
private readonly Func<IUserViewManager> _userviewManager;
@ -186,7 +178,6 @@ namespace Emby.Server.Implementations.Library
_fileSystem = fileSystem;
_providerManagerFactory = providerManagerFactory;
_userviewManager = userviewManager;
ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>();
_libraryItemsCache = new ConcurrentDictionary<Guid, BaseItem>();
ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated;
@ -560,22 +551,6 @@ namespace Emby.Server.Implementations.Library
return key.GetMD5();
}
/// <summary>
/// Ensure supplied item has only one instance throughout
/// </summary>
/// <param name="item">The item.</param>
/// <returns>The proper instance to the item</returns>
public BaseItem GetOrAddByReferenceItem(BaseItem item)
{
// Add this item to our list if not there already
if (!ByReferenceItems.TryAdd(item.Id, item))
{
// Already there - return the existing reference
item = ByReferenceItems[item.Id];
}
return item;
}
public BaseItem ResolvePath(FileSystemMetadata fileInfo,
Folder parent = null)
{
@ -1298,7 +1273,7 @@ namespace Emby.Server.Implementations.Library
return item;
}
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
{
if (query.Recursive && query.ParentId.HasValue)
{
@ -1317,7 +1292,7 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetItemList(query);
}
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query)
public List<BaseItem> GetItemList(InternalItemsQuery query)
{
return GetItemList(query, true);
}
@ -1341,7 +1316,7 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetCount(query);
}
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
public List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
{
SetTopParentIdsOrAncestors(query, parents);
@ -1515,9 +1490,11 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetItems(query);
}
var list = ItemRepository.GetItemList(query);
return new QueryResult<BaseItem>
{
Items = ItemRepository.GetItemList(query).ToArray()
Items = list.ToArray(list.Count)
};
}
@ -2610,7 +2587,7 @@ namespace Emby.Server.Implementations.Library
var resolvers = new IItemResolver[]
{
new GenericVideoResolver<Trailer>(this)
new GenericVideoResolver<Trailer>(this, _fileSystem)
};
return ResolvePaths(files, directoryService, null, new LibraryOptions(), null, resolvers)

@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -45,7 +46,7 @@ namespace Emby.Server.Implementations.Library
Recursive = true,
DtoOptions = new DtoOptions(false)
}).ToArray();
});
var numComplete = 0;
@ -64,7 +65,7 @@ namespace Emby.Server.Implementations.Library
progress.Report(100);
}
private async Task AssignTrailers(IHasTrailers item, BaseItem[] channelTrailers)
private async Task AssignTrailers(IHasTrailers item, IEnumerable<BaseItem> channelTrailers)
{
if (item is Game)
{

@ -19,27 +19,27 @@ namespace Emby.Server.Implementations.Library
_libraryManager = libraryManager;
}
public IEnumerable<Audio> GetInstantMixFromSong(Audio item, User user, DtoOptions dtoOptions)
public List<BaseItem> GetInstantMixFromSong(Audio item, User user, DtoOptions dtoOptions)
{
var list = new List<Audio>
{
item
};
return list.Concat(GetInstantMixFromGenres(item.Genres, user, dtoOptions));
return list.Concat(GetInstantMixFromGenres(item.Genres, user, dtoOptions)).ToList();
}
public IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist item, User user, DtoOptions dtoOptions)
public List<BaseItem> GetInstantMixFromArtist(MusicArtist item, User user, DtoOptions dtoOptions)
{
return GetInstantMixFromGenres(item.Genres, user, dtoOptions);
}
public IEnumerable<Audio> GetInstantMixFromAlbum(MusicAlbum item, User user, DtoOptions dtoOptions)
public List<BaseItem> GetInstantMixFromAlbum(MusicAlbum item, User user, DtoOptions dtoOptions)
{
return GetInstantMixFromGenres(item.Genres, user, dtoOptions);
}
public IEnumerable<Audio> GetInstantMixFromFolder(Folder item, User user, DtoOptions dtoOptions)
public List<BaseItem> GetInstantMixFromFolder(Folder item, User user, DtoOptions dtoOptions)
{
var genres = item
.GetRecursiveChildren(user, new InternalItemsQuery(user)
@ -55,12 +55,12 @@ namespace Emby.Server.Implementations.Library
return GetInstantMixFromGenres(genres, user, dtoOptions);
}
public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user, DtoOptions dtoOptions)
public List<BaseItem> GetInstantMixFromPlaylist(Playlist item, User user, DtoOptions dtoOptions)
{
return GetInstantMixFromGenres(item.Genres, user, dtoOptions);
}
public IEnumerable<Audio> GetInstantMixFromGenres(IEnumerable<string> genres, User user, DtoOptions dtoOptions)
public List<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User user, DtoOptions dtoOptions)
{
var genreIds = genres.DistinctNames().Select(i =>
{
@ -78,7 +78,7 @@ namespace Emby.Server.Implementations.Library
return GetInstantMixFromGenreIds(genreIds, user, dtoOptions);
}
public IEnumerable<Audio> GetInstantMixFromGenreIds(IEnumerable<string> genreIds, User user, DtoOptions dtoOptions)
public List<BaseItem> GetInstantMixFromGenreIds(IEnumerable<string> genreIds, User user, DtoOptions dtoOptions)
{
return _libraryManager.GetItemList(new InternalItemsQuery(user)
{
@ -92,10 +92,10 @@ namespace Emby.Server.Implementations.Library
DtoOptions = dtoOptions
}).Cast<Audio>();
});
}
public IEnumerable<Audio> GetInstantMixFromItem(BaseItem item, User user, DtoOptions dtoOptions)
public List<BaseItem> GetInstantMixFromItem(BaseItem item, User user, DtoOptions dtoOptions)
{
var genre = item as MusicGenre;
if (genre != null)
@ -133,7 +133,7 @@ namespace Emby.Server.Implementations.Library
return GetInstantMixFromFolder(folder, user, dtoOptions);
}
return new Audio[] { };
return new List<BaseItem>();
}
}
}

@ -6,6 +6,7 @@ using System;
using System.IO;
using System.Linq;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
namespace Emby.Server.Implementations.Library.Resolvers
@ -18,9 +19,11 @@ namespace Emby.Server.Implementations.Library.Resolvers
where T : Video, new()
{
protected readonly ILibraryManager LibraryManager;
protected readonly IFileSystem FileSystem;
protected BaseVideoResolver(ILibraryManager libraryManager)
protected BaseVideoResolver(ILibraryManager libraryManager, IFileSystem fileSystem)
{
FileSystem = fileSystem;
LibraryManager = libraryManager;
}
@ -271,7 +274,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
return false;
}
return directoryService.GetFilePaths(fullPath).Any(i => string.Equals(Path.GetExtension(i), ".vob", StringComparison.OrdinalIgnoreCase));
return FileSystem.GetFilePaths(fullPath).Any(i => string.Equals(Path.GetExtension(i), ".vob", StringComparison.OrdinalIgnoreCase));
}
/// <summary>

@ -23,11 +23,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
/// </summary>
public class MovieResolver : BaseVideoResolver<Video>, IMultiItemResolver
{
public MovieResolver(ILibraryManager libraryManager)
: base(libraryManager)
{
}
/// <summary>
/// Gets the priority.
/// </summary>
@ -452,8 +447,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
var folderPaths = multiDiscFolders.Select(i => i.FullName).Where(i =>
{
var subFileEntries = directoryService.GetFileSystemEntries(i)
.ToList();
var subFileEntries = directoryService.GetFileSystemEntries(i);
var subfolders = subFileEntries
.Where(e => e.IsDirectory)
@ -547,5 +541,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
return !validCollectionTypes.Contains(collectionType, StringComparer.OrdinalIgnoreCase);
}
public MovieResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem)
{
}
}
}

@ -44,7 +44,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
var filename = Path.GetFileNameWithoutExtension(args.Path);
// Make sure the image doesn't belong to a video file
if (args.DirectoryService.GetFilePaths(_fileSystem.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(args.GetLibraryOptions(), i, filename)))
if (_fileSystem.GetFilePaths(_fileSystem.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(args.GetLibraryOptions(), i, filename)))
{
return null;
}

@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using System.Linq;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.Library.Resolvers.TV
{
@ -11,10 +12,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
/// </summary>
public class EpisodeResolver : BaseVideoResolver<Episode>
{
public EpisodeResolver(ILibraryManager libraryManager) : base(libraryManager)
{
}
/// <summary>
/// Resolves the specified args.
/// </summary>
@ -76,5 +73,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
return null;
}
public EpisodeResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem)
{
}
}
}

@ -1,6 +1,7 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.Library.Resolvers
{
@ -9,11 +10,6 @@ namespace Emby.Server.Implementations.Library.Resolvers
/// </summary>
public class VideoResolver : BaseVideoResolver<Video>
{
public VideoResolver(ILibraryManager libraryManager)
: base(libraryManager)
{
}
protected override Video Resolve(ItemResolveArgs args)
{
if (args.Parent != null)
@ -33,12 +29,16 @@ namespace Emby.Server.Implementations.Library.Resolvers
{
get { return ResolverPriority.Last; }
}
public VideoResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem)
{
}
}
public class GenericVideoResolver<T> : BaseVideoResolver<T>
where T : Video, new ()
{
public GenericVideoResolver(ILibraryManager libraryManager) : base(libraryManager)
public GenericVideoResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem)
{
}
}

@ -10,6 +10,7 @@ using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Extensions;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Library
{
@ -163,8 +164,8 @@ namespace Emby.Server.Implementations.Library
var mediaItems = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
NameContains = searchTerm,
ExcludeItemTypes = excludeItemTypes.ToArray(),
IncludeItemTypes = includeItemTypes.ToArray(),
ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count),
IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count),
Limit = query.Limit,
IncludeItemsByName = string.IsNullOrWhiteSpace(query.ParentId),
ParentId = string.IsNullOrWhiteSpace(query.ParentId) ? (Guid?)null : new Guid(query.ParentId),

@ -15,6 +15,7 @@ using System.Threading.Tasks;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Library
{
@ -231,7 +232,7 @@ namespace Emby.Server.Implementations.Library
return list;
}
private IEnumerable<BaseItem> GetItemsForLatestItems(User user, LatestItemsQuery request, DtoOptions options)
private List<BaseItem> GetItemsForLatestItems(User user, LatestItemsQuery request, DtoOptions options)
{
var parentId = request.ParentId;
@ -325,7 +326,7 @@ namespace Emby.Server.Implementations.Library
Limit = limit * 5,
IsPlayed = isPlayed,
DtoOptions = options,
MediaTypes = mediaTypes.ToArray()
MediaTypes = mediaTypes.ToArray(mediaTypes.Count)
};
if (parents.Count == 0)

@ -55,28 +55,21 @@ namespace Emby.Server.Implementations.Library.Validators
/// <returns>Task.</returns>
public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
{
var people = _libraryManager.GetPeople(new InternalPeopleQuery());
var dict = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
foreach (var person in people)
{
dict[person.Name] = true;
}
var people = _libraryManager.GetPeopleNames(new InternalPeopleQuery());
var numComplete = 0;
_logger.Debug("Will refresh {0} people", dict.Count);
var numPeople = people.Count;
var numPeople = dict.Count;
_logger.Debug("Will refresh {0} people", numPeople);
foreach (var person in dict)
foreach (var person in people)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
var item = _libraryManager.GetPerson(person.Key);
var item = _libraryManager.GetPerson(person);
var options = new MetadataRefreshOptions(_fileSystem)
{

@ -70,7 +70,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return "ts";
}
return "mp4";
return "mkv";
}
}

@ -176,7 +176,7 @@ namespace Emby.Server.Implementations.LiveTv
{
try
{
dto.ParentBackdropImageTags = new List<string>
dto.ParentBackdropImageTags = new string[]
{
_imageProcessor.GetImageCacheTag(librarySeries, image)
};
@ -218,14 +218,14 @@ namespace Emby.Server.Implementations.LiveTv
}
}
if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Count == 0)
if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Length == 0)
{
image = program.GetImageInfo(ImageType.Backdrop, 0);
if (image != null)
{
try
{
dto.ParentBackdropImageTags = new List<string>
dto.ParentBackdropImageTags = new string[]
{
_imageProcessor.GetImageCacheTag(program, image)
};

@ -173,7 +173,7 @@ namespace Emby.Server.Implementations.LiveTv
}
}
public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken)
public async Task<QueryResult<BaseItem>> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken)
{
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
@ -208,15 +208,7 @@ namespace Emby.Server.Implementations.LiveTv
internalQuery.OrderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending));
}
var channelResult = _libraryManager.GetItemsResult(internalQuery);
var result = new QueryResult<LiveTvChannel>
{
Items = channelResult.Items.Cast<LiveTvChannel>().ToArray(),
TotalRecordCount = channelResult.TotalRecordCount
};
return result;
return _libraryManager.GetItemsResult(internalQuery);
}
public LiveTvChannel GetInternalChannel(string id)
@ -993,7 +985,9 @@ namespace Emby.Server.Implementations.LiveTv
var queryResult = _libraryManager.QueryItems(internalQuery);
var returnArray = (await _dtoService.GetBaseItemDtos(queryResult.Items, options, user).ConfigureAwait(false)).ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(queryResult.Items, options, user)
.ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@ -1077,7 +1071,9 @@ namespace Emby.Server.Implementations.LiveTv
var user = _userManager.GetUserById(query.UserId);
var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
.ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@ -1639,7 +1635,7 @@ namespace Emby.Server.Implementations.LiveTv
{
MediaTypes = new[] { MediaType.Video },
Recursive = true,
AncestorIds = folderIds.Select(i => i.ToString("N")).ToArray(),
AncestorIds = folderIds.Select(i => i.ToString("N")).ToArray(folderIds.Count),
IsFolder = false,
IsVirtualItem = false,
Limit = query.Limit,
@ -1647,9 +1643,9 @@ namespace Emby.Server.Implementations.LiveTv
SortBy = new[] { ItemSortBy.DateCreated },
SortOrder = SortOrder.Descending,
EnableTotalRecordCount = query.EnableTotalRecordCount,
IncludeItemTypes = includeItemTypes.ToArray(),
ExcludeItemTypes = excludeItemTypes.ToArray(),
Genres = genres.ToArray(),
IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count),
ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count),
Genres = genres.ToArray(genres.Count),
DtoOptions = dtoOptions
});
}
@ -1695,17 +1691,20 @@ namespace Emby.Server.Implementations.LiveTv
var internalResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
{
Recursive = true,
AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(),
AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(folders.Count),
Limit = query.Limit,
SortBy = new[] { ItemSortBy.DateCreated },
SortOrder = SortOrder.Descending,
EnableTotalRecordCount = query.EnableTotalRecordCount,
IncludeItemTypes = includeItemTypes.ToArray(),
ExcludeItemTypes = excludeItemTypes.ToArray(),
IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count),
ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count),
DtoOptions = options
});
var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
.ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
return new QueryResult<BaseItemDto>
{
@ -1996,7 +1995,9 @@ namespace Emby.Server.Implementations.LiveTv
var internalResult = await GetInternalRecordings(query, options, cancellationToken).ConfigureAwait(false);
var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
.ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
return new QueryResult<BaseItemDto>
{
@ -2084,7 +2085,7 @@ namespace Emby.Server.Implementations.LiveTv
var returnArray = returnList
.OrderBy(i => i.StartDate)
.ToArray();
.ToArray(returnList.Count);
return new QueryResult<TimerInfoDto>
{
@ -2341,7 +2342,7 @@ namespace Emby.Server.Implementations.LiveTv
TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Result.Id.ToString("N") },
DtoOptions = options
}).ToList() : new List<BaseItem>();
}) : new List<BaseItem>();
RemoveFields(options);
@ -2705,7 +2706,7 @@ namespace Emby.Server.Implementations.LiveTv
return new QueryResult<BaseItemDto>
{
Items = groups.ToArray(),
Items = groups.ToArray(groups.Count),
TotalRecordCount = groups.Count
};
}
@ -2992,7 +2993,7 @@ namespace Emby.Server.Implementations.LiveTv
Name = tunerChannelId,
Value = providerChannelId
});
listingsProviderInfo.ChannelMappings = list.ToArray();
listingsProviderInfo.ChannelMappings = list.ToArray(list.Count);
}
_config.SaveConfiguration("livetv", config);

@ -14,6 +14,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.LiveTv
{
@ -102,7 +103,7 @@ namespace Emby.Server.Implementations.LiveTv
openKeys.Add(item.GetType().Name);
openKeys.Add(item.Id.ToString("N"));
openKeys.Add(source.Id ?? string.Empty);
source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray());
source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray(openKeys.Count));
}
// Dummy this up so that direct play checks can still run

@ -132,7 +132,7 @@ namespace Emby.Server.Implementations.Localization
/// Gets the cultures.
/// </summary>
/// <returns>IEnumerable{CultureDto}.</returns>
public IEnumerable<CultureDto> GetCultures()
public List<CultureDto> GetCultures()
{
var type = GetType();
var path = type.Namespace + ".iso6392.txt";
@ -169,14 +169,14 @@ namespace Emby.Server.Implementations.Localization
return list.Where(i => !string.IsNullOrWhiteSpace(i.Name) &&
!string.IsNullOrWhiteSpace(i.DisplayName) &&
!string.IsNullOrWhiteSpace(i.ThreeLetterISOLanguageName) &&
!string.IsNullOrWhiteSpace(i.TwoLetterISOLanguageName));
!string.IsNullOrWhiteSpace(i.TwoLetterISOLanguageName)).ToList();
}
/// <summary>
/// Gets the countries.
/// </summary>
/// <returns>IEnumerable{CountryInfo}.</returns>
public IEnumerable<CountryInfo> GetCountries()
public List<CountryInfo> GetCountries()
{
var type = GetType();
var path = type.Namespace + ".countries.json";

@ -3,9 +3,8 @@ using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Emby.Server.Implementations.Localization;
namespace Emby.Server.Core.Localization
namespace Emby.Server.Implementations.Localization
{
public class TextLocalizer : ITextLocalizer
{

@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Model.Logging;
namespace Emby.Server.Core.Logging
namespace Emby.Server.Implementations.Logging
{
public class ConsoleLogger : IConsoleLogger
{

@ -12,6 +12,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Notifications;
using SQLitePCL.pretty;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Notifications
{
@ -83,13 +84,13 @@ namespace Emby.Server.Implementations.Notifications
clauses.Add("UserId=?");
paramList.Add(query.UserId.ToGuidBlob());
var whereClause = " where " + string.Join(" And ", clauses.ToArray());
var whereClause = " where " + string.Join(" And ", clauses.ToArray(clauses.Count));
using (WriteLock.Read())
{
using (var connection = CreateConnection(true))
{
result.TotalRecordCount = connection.Query("select count(Id) from Notifications" + whereClause, paramList.ToArray()).SelectScalarInt().First();
result.TotalRecordCount = connection.Query("select count(Id) from Notifications" + whereClause, paramList.ToArray(paramList.Count)).SelectScalarInt().First();
var commandText = string.Format("select Id,UserId,Date,Name,Description,Url,Level,IsRead,Category,RelatedId from Notifications{0} order by IsRead asc, Date desc", whereClause);
@ -110,12 +111,12 @@ namespace Emby.Server.Implementations.Notifications
var resultList = new List<Notification>();
foreach (var row in connection.Query(commandText, paramList.ToArray()))
foreach (var row in connection.Query(commandText, paramList.ToArray(paramList.Count)))
{
resultList.Add(GetNotification(row));
}
result.Notifications = resultList.ToArray();
result.Notifications = resultList.ToArray(resultList.Count);
}
}
@ -280,7 +281,7 @@ namespace Emby.Server.Implementations.Notifications
public async Task MarkRead(IEnumerable<string> notificationIdList, string userId, bool isRead, CancellationToken cancellationToken)
{
var list = notificationIdList.ToList();
var idArray = list.Select(i => new Guid(i)).ToArray();
var idArray = list.Select(i => new Guid(i)).ToArray(list.Count);
await MarkReadInternal(idArray, userId, isRead, cancellationToken).ConfigureAwait(false);
@ -290,7 +291,7 @@ namespace Emby.Server.Implementations.Notifications
{
NotificationsMarkedRead(this, new NotificationReadEventArgs
{
IdList = list.ToArray(),
IdList = list.ToArray(list.Count),
IsRead = isRead,
UserId = userId
});

@ -2,6 +2,7 @@
using MediaBrowser.Controller.Notifications;
using MediaBrowser.Controller.Plugins;
using System.Linq;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Notifications
{
@ -33,7 +34,7 @@ namespace Emby.Server.Implementations.Notifications
list.Add(e.UserId);
list.Add(e.IsRead.ToString().ToLower());
var msg = string.Join("|", list.ToArray());
var msg = string.Join("|", list.ToArray(list.Count));
_serverManager.SendWebSocketMessage("NotificationsMarkedRead", msg);
}

@ -21,7 +21,7 @@ namespace Emby.Server.Implementations.Photos
protected override List<BaseItem> GetItemsWithImages(IHasMetadata item)
{
var photoAlbum = (PhotoAlbum)item;
var items = GetFinalItems(photoAlbum.Children.ToList());
var items = GetFinalItems(photoAlbum.Children);
return items;
}

@ -65,8 +65,7 @@ namespace Emby.Server.Implementations.Playlists
return null;
})
.Where(i => i != null)
.DistinctBy(i => i.Id)
.ToList();
.DistinctBy(i => i.Id);
return GetFinalItems(items);
}
@ -93,7 +92,7 @@ namespace Emby.Server.Implementations.Playlists
ImageTypes = new[] { ImageType.Primary },
DtoOptions = new DtoOptions(false)
}).ToList();
});
return GetFinalItems(items);
}
@ -125,7 +124,7 @@ namespace Emby.Server.Implementations.Playlists
ImageTypes = new[] { ImageType.Primary },
DtoOptions = new DtoOptions(false)
}).ToList();
});
return GetFinalItems(items);
}

@ -15,6 +15,7 @@ using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.ScheduledTasks
{
@ -142,7 +143,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
_fileSystem.CreateDirectory(parentPath);
_fileSystem.WriteAllText(failHistoryPath, string.Join("|", previouslyFailedImages.ToArray()));
_fileSystem.WriteAllText(failHistoryPath, string.Join("|", previouslyFailedImages.ToArray(previouslyFailedImages.Count)));
}
numComplete++;

@ -11,6 +11,7 @@ using MediaBrowser.Controller.Security;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
using SQLitePCL.pretty;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Security
{
@ -174,13 +175,13 @@ namespace Emby.Server.Implementations.Security
var whereTextWithoutPaging = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
if (startIndex > 0)
{
var pagingWhereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM AccessTokens {0} ORDER BY DateCreated LIMIT {1})",
pagingWhereText,
@ -189,7 +190,7 @@ namespace Emby.Server.Implementations.Security
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@ -236,7 +237,7 @@ namespace Emby.Server.Implementations.Security
}
}
result.Items = list.ToArray();
result.Items = list.ToArray(list.Count);
return result;
}, ReadTransactionMode);

@ -15,17 +15,15 @@ namespace Emby.Server.Implementations.Services
public class ServiceController
{
public static ServiceController Instance;
private readonly Func<IEnumerable<Type>> _resolveServicesFn;
public ServiceController(Func<IEnumerable<Type>> resolveServicesFn)
public ServiceController()
{
Instance = this;
_resolveServicesFn = resolveServicesFn;
}
public void Init(HttpListenerHost appHost)
public void Init(HttpListenerHost appHost, Type[] serviceTypes)
{
foreach (var serviceType in _resolveServicesFn())
foreach (var serviceType in serviceTypes)
{
RegisterService(appHost, serviceType);
}

@ -5,6 +5,7 @@ using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Services
{
@ -123,7 +124,7 @@ namespace Emby.Server.Implementations.Services
}
if (reqFilters.Count > 0)
actionCtx.RequestFilters = reqFilters.OrderBy(i => i.Priority).ToArray();
actionCtx.RequestFilters = reqFilters.OrderBy(i => i.Priority).ToArray(reqFilters.Count);
actions.Add(actionCtx);
}

@ -5,6 +5,7 @@ using System.Linq;
using System.Reflection;
using System.Text;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Services
{
@ -142,13 +143,13 @@ namespace Emby.Server.Implementations.Services
}
}
var components = componentsList.ToArray();
var components = componentsList.ToArray(componentsList.Count);
this.TotalComponentsCount = components.Length;
this.literalsToMatch = new string[this.TotalComponentsCount];
this.variablesNames = new string[this.TotalComponentsCount];
this.isWildcard = new bool[this.TotalComponentsCount];
this.componentsWithSeparators = hasSeparators.ToArray();
this.componentsWithSeparators = hasSeparators.ToArray(hasSeparators.Count);
this.PathComponentsCount = this.componentsWithSeparators.Length;
string firstLiteralMatch = null;
@ -268,7 +269,7 @@ namespace Emby.Server.Implementations.Services
propertyInfos.InsertRange(0, newPropertyInfos);
}
return propertyInfos.ToArray();
return propertyInfos.ToArray(propertyInfos.Count);
}
return GetTypesPublicProperties(type)
@ -285,7 +286,7 @@ namespace Emby.Server.Implementations.Services
if (mi != null && mi.IsStatic) continue;
pis.Add(pi);
}
return pis.ToArray();
return pis.ToArray(pis.Count);
}
@ -450,7 +451,7 @@ namespace Emby.Server.Implementations.Services
}
}
withPathInfoParts = totalComponents.ToArray();
withPathInfoParts = totalComponents.ToArray(totalComponents.Count);
return true;
}

@ -32,6 +32,7 @@ using System.Threading.Tasks;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Threading;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Session
{
@ -1000,7 +1001,7 @@ namespace Emby.Server.Implementations.Session
command.PlayCommand = PlayCommand.PlayNow;
}
command.ItemIds = items.Select(i => i.Id.ToString("N")).ToArray();
command.ItemIds = items.Select(i => i.Id.ToString("N")).ToArray(items.Count);
if (user != null)
{
@ -1033,7 +1034,7 @@ namespace Emby.Server.Implementations.Session
if (episodes.Count > 0)
{
command.ItemIds = episodes.Select(i => i.Id.ToString("N")).ToArray();
command.ItemIds = episodes.Select(i => i.Id.ToString("N")).ToArray(episodes.Count);
}
}
}

@ -8,6 +8,7 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Social;
using SQLitePCL.pretty;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Social
{
@ -86,7 +87,7 @@ namespace Emby.Server.Implementations.Social
var paramList = new List<object>();
paramList.Add(id.ToGuidBlob());
foreach (var row in connection.Query(commandText, paramList.ToArray()))
foreach (var row in connection.Query(commandText, paramList.ToArray(paramList.Count)))
{
return GetSocialShareInfo(row);
}

@ -3,7 +3,7 @@ using MediaBrowser.Common.Events;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.System;
namespace MediaBrowser.Server.Startup.Common
namespace Emby.Server.Implementations
{
public class SystemEvents : ISystemEvents
{

@ -91,7 +91,7 @@ namespace Emby.Server.Implementations.UserViews
}).DistinctBy(i => i.Id);
return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8);
return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)), 8);
}
protected override bool Supports(IHasMetadata item)
@ -149,7 +149,7 @@ namespace Emby.Server.Implementations.UserViews
DtoOptions = new DtoOptions(false)
});
return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8);
return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)), 8);
}
protected override bool Supports(IHasMetadata item)

@ -62,9 +62,9 @@ namespace Emby.Server.Implementations.UserViews
IsMovie = true,
DtoOptions = new DtoOptions(false)
}).ToList();
});
return GetFinalItems(programs).ToList();
return GetFinalItems(programs);
}
if (string.Equals(view.ViewType, SpecialFolder.MovieGenre, StringComparison.OrdinalIgnoreCase) ||
@ -133,10 +133,10 @@ namespace Emby.Server.Implementations.UserViews
if (isUsingCollectionStrip)
{
return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8);
return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)), 8);
}
return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary)).ToList());
return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary)));
}
protected override bool Supports(IHasMetadata item)

@ -2,6 +2,9 @@
<packages>
<package id="Emby.XmlTv" version="1.0.9" targetFramework="net46" />
<package id="MediaBrowser.Naming" version="1.0.5" targetFramework="portable45-net45+win8" />
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.2" targetFramework="net46" />
<package id="ServiceStack.Text" version="4.5.12" targetFramework="net46" />
<package id="SimpleInjector" version="4.0.8" targetFramework="net46" />
<package id="SQLitePCL.pretty" version="1.1.0" targetFramework="portable45-net45+win8" />
<package id="SQLitePCLRaw.core" version="1.1.7" targetFramework="net46" />
<package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="net46" />
</packages>

@ -1,27 +1,15 @@
using MediaBrowser.Api.Playback;
using MediaBrowser.Common.Configuration;
using System;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Session;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Threading;
using System.Collections.Generic;
using System.Threading;
namespace MediaBrowser.Api
{
@ -53,11 +41,6 @@ namespace MediaBrowser.Api
public readonly ITimerFactory TimerFactory;
public readonly IProcessFactory ProcessFactory;
/// <summary>
/// The active transcoding jobs
/// </summary>
private readonly List<TranscodingJob> _activeTranscodingJobs = new List<TranscodingJob>();
private readonly Dictionary<string, SemaphoreSlim> _transcodingLocks =
new Dictionary<string, SemaphoreSlim>();
@ -81,39 +64,21 @@ namespace MediaBrowser.Api
ResultFactory = resultFactory;
Instance = this;
_sessionManager.PlaybackProgress += _sessionManager_PlaybackProgress;
_sessionManager.PlaybackStart += _sessionManager_PlaybackStart;
}
public SemaphoreSlim GetTranscodingLock(string outputPath)
public static string[] Split(string value, char separator, bool removeEmpty)
{
lock (_transcodingLocks)
if (string.IsNullOrWhiteSpace(value))
{
SemaphoreSlim result;
if (!_transcodingLocks.TryGetValue(outputPath, out result))
{
result = new SemaphoreSlim(1, 1);
_transcodingLocks[outputPath] = result;
}
return result;
return new string[] { };
}
}
private void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e)
{
if (!string.IsNullOrWhiteSpace(e.PlaySessionId))
if (removeEmpty)
{
PingTranscodingJob(e.PlaySessionId, e.IsPaused);
return value.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries);
}
}
void _sessionManager_PlaybackProgress(object sender, PlaybackProgressEventArgs e)
{
if (!string.IsNullOrWhiteSpace(e.PlaySessionId))
{
PingTranscodingJob(e.PlaySessionId, e.IsPaused);
}
return value.Split(separator);
}
/// <summary>
@ -121,41 +86,6 @@ namespace MediaBrowser.Api
/// </summary>
public void Run()
{
try
{
DeleteEncodedMediaCache();
}
catch (FileNotFoundException)
{
// Don't clutter the log
}
catch (IOException)
{
// Don't clutter the log
}
catch (Exception ex)
{
Logger.ErrorException("Error deleting encoded media cache", ex);
}
}
public EncodingOptions GetEncodingOptions()
{
return _config.GetConfiguration<EncodingOptions>("encoding");
}
/// <summary>
/// Deletes the encoded media cache.
/// </summary>
private void DeleteEncodedMediaCache()
{
var path = _config.ApplicationPaths.TranscodingTempPath;
foreach (var file in _fileSystem.GetFilePaths(path, true)
.ToList())
{
_fileSystem.DeleteFile(file);
}
}
/// <summary>
@ -163,660 +93,6 @@ namespace MediaBrowser.Api
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose)
{
var list = _activeTranscodingJobs.ToList();
var jobCount = list.Count;
Parallel.ForEach(list, j => KillTranscodingJob(j, false, path => true));
// Try to allow for some time to kill the ffmpeg processes and delete the partial stream files
if (jobCount > 0)
{
var task = Task.Delay(1000);
Task.WaitAll(task);
}
}
/// <summary>
/// Called when [transcode beginning].
/// </summary>
/// <param name="path">The path.</param>
/// <param name="playSessionId">The play session identifier.</param>
/// <param name="liveStreamId">The live stream identifier.</param>
/// <param name="transcodingJobId">The transcoding job identifier.</param>
/// <param name="type">The type.</param>
/// <param name="process">The process.</param>
/// <param name="deviceId">The device id.</param>
/// <param name="state">The state.</param>
/// <param name="cancellationTokenSource">The cancellation token source.</param>
/// <returns>TranscodingJob.</returns>
public TranscodingJob OnTranscodeBeginning(string path,
string playSessionId,
string liveStreamId,
string transcodingJobId,
TranscodingJobType type,
IProcess process,
string deviceId,
StreamState state,
CancellationTokenSource cancellationTokenSource)
{
lock (_activeTranscodingJobs)
{
var job = new TranscodingJob(Logger, TimerFactory)
{
Type = type,
Path = path,
Process = process,
ActiveRequestCount = 1,
DeviceId = deviceId,
CancellationTokenSource = cancellationTokenSource,
Id = transcodingJobId,
PlaySessionId = playSessionId,
LiveStreamId = liveStreamId,
MediaSource = state.MediaSource
};
_activeTranscodingJobs.Add(job);
ReportTranscodingProgress(job, state, null, null, null, null, null);
return job;
}
}
public void ReportTranscodingProgress(TranscodingJob job, StreamState state, TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
{
var ticks = transcodingPosition.HasValue ? transcodingPosition.Value.Ticks : (long?)null;
if (job != null)
{
job.Framerate = framerate;
job.CompletionPercentage = percentComplete;
job.TranscodingPositionTicks = ticks;
job.BytesTranscoded = bytesTranscoded;
job.BitRate = bitRate;
}
var deviceId = state.Request.DeviceId;
if (!string.IsNullOrWhiteSpace(deviceId))
{
var audioCodec = state.ActualOutputAudioCodec;
var videoCodec = state.ActualOutputVideoCodec;
_sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo
{
Bitrate = bitRate ?? state.TotalOutputBitrate,
AudioCodec = audioCodec,
VideoCodec = videoCodec,
Container = state.OutputContainer,
Framerate = framerate,
CompletionPercentage = percentComplete,
Width = state.OutputWidth,
Height = state.OutputHeight,
AudioChannels = state.OutputAudioChannels,
IsAudioDirect = string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase),
IsVideoDirect = string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase),
TranscodeReasons = state.TranscodeReasons
});
}
}
/// <summary>
/// <summary>
/// The progressive
/// </summary>
/// Called when [transcode failed to start].
/// </summary>
/// <param name="path">The path.</param>
/// <param name="type">The type.</param>
/// <param name="state">The state.</param>
public void OnTranscodeFailedToStart(string path, TranscodingJobType type, StreamState state)
{
lock (_activeTranscodingJobs)
{
var job = _activeTranscodingJobs.FirstOrDefault(j => j.Type == type && string.Equals(j.Path, path, StringComparison.OrdinalIgnoreCase));
if (job != null)
{
_activeTranscodingJobs.Remove(job);
}
}
lock (_transcodingLocks)
{
_transcodingLocks.Remove(path);
}
if (!string.IsNullOrWhiteSpace(state.Request.DeviceId))
{
_sessionManager.ClearTranscodingInfo(state.Request.DeviceId);
}
}
/// <summary>
/// Determines whether [has active transcoding job] [the specified path].
/// </summary>
/// <param name="path">The path.</param>
/// <param name="type">The type.</param>
/// <returns><c>true</c> if [has active transcoding job] [the specified path]; otherwise, <c>false</c>.</returns>
public bool HasActiveTranscodingJob(string path, TranscodingJobType type)
{
return GetTranscodingJob(path, type) != null;
}
public TranscodingJob GetTranscodingJob(string path, TranscodingJobType type)
{
lock (_activeTranscodingJobs)
{
return _activeTranscodingJobs.FirstOrDefault(j => j.Type == type && string.Equals(j.Path, path, StringComparison.OrdinalIgnoreCase));
}
}
public TranscodingJob GetTranscodingJob(string playSessionId)
{
lock (_activeTranscodingJobs)
{
return _activeTranscodingJobs.FirstOrDefault(j => string.Equals(j.PlaySessionId, playSessionId, StringComparison.OrdinalIgnoreCase));
}
}
/// <summary>
/// Called when [transcode begin request].
/// </summary>
/// <param name="path">The path.</param>
/// <param name="type">The type.</param>
public TranscodingJob OnTranscodeBeginRequest(string path, TranscodingJobType type)
{
lock (_activeTranscodingJobs)
{
var job = _activeTranscodingJobs.FirstOrDefault(j => j.Type == type && string.Equals(j.Path, path, StringComparison.OrdinalIgnoreCase));
if (job == null)
{
return null;
}
OnTranscodeBeginRequest(job);
return job;
}
}
public void OnTranscodeBeginRequest(TranscodingJob job)
{
job.ActiveRequestCount++;
if (string.IsNullOrWhiteSpace(job.PlaySessionId) || job.Type == TranscodingJobType.Progressive)
{
job.StopKillTimer();
}
}
public void OnTranscodeEndRequest(TranscodingJob job)
{
job.ActiveRequestCount--;
//Logger.Debug("OnTranscodeEndRequest job.ActiveRequestCount={0}", job.ActiveRequestCount);
if (job.ActiveRequestCount <= 0)
{
PingTimer(job, false);
}
}
internal void PingTranscodingJob(string playSessionId, bool? isUserPaused)
{
if (string.IsNullOrEmpty(playSessionId))
{
throw new ArgumentNullException("playSessionId");
}
//Logger.Debug("PingTranscodingJob PlaySessionId={0} isUsedPaused: {1}", playSessionId, isUserPaused);
List<TranscodingJob> jobs;
lock (_activeTranscodingJobs)
{
// This is really only needed for HLS.
// Progressive streams can stop on their own reliably
jobs = _activeTranscodingJobs.Where(j => string.Equals(playSessionId, j.PlaySessionId, StringComparison.OrdinalIgnoreCase)).ToList();
}
foreach (var job in jobs)
{
if (isUserPaused.HasValue)
{
//Logger.Debug("Setting job.IsUserPaused to {0}. jobId: {1}", isUserPaused, job.Id);
job.IsUserPaused = isUserPaused.Value;
}
PingTimer(job, true);
}
}
private void PingTimer(TranscodingJob job, bool isProgressCheckIn)
{
if (job.HasExited)
{
job.StopKillTimer();
return;
}
var timerDuration = 10000;
if (job.Type != TranscodingJobType.Progressive)
{
timerDuration = 60000;
}
job.PingTimeout = timerDuration;
job.LastPingDate = DateTime.UtcNow;
// Don't start the timer for playback checkins with progressive streaming
if (job.Type != TranscodingJobType.Progressive || !isProgressCheckIn)
{
job.StartKillTimer(OnTranscodeKillTimerStopped);
}
else
{
job.ChangeKillTimerIfStarted();
}
}
/// <summary>
/// Called when [transcode kill timer stopped].
/// </summary>
/// <param name="state">The state.</param>
private void OnTranscodeKillTimerStopped(object state)
{
var job = (TranscodingJob)state;
if (!job.HasExited && job.Type != TranscodingJobType.Progressive)
{
var timeSinceLastPing = (DateTime.UtcNow - job.LastPingDate).TotalMilliseconds;
if (timeSinceLastPing < job.PingTimeout)
{
job.StartKillTimer(OnTranscodeKillTimerStopped, job.PingTimeout);
return;
}
}
Logger.Info("Transcoding kill timer stopped for JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId);
KillTranscodingJob(job, true, path => true);
}
/// <summary>
/// Kills the single transcoding job.
/// </summary>
/// <param name="deviceId">The device id.</param>
/// <param name="playSessionId">The play session identifier.</param>
/// <param name="deleteFiles">The delete files.</param>
/// <returns>Task.</returns>
internal void KillTranscodingJobs(string deviceId, string playSessionId, Func<string, bool> deleteFiles)
{
KillTranscodingJobs(j =>
{
if (!string.IsNullOrWhiteSpace(playSessionId))
{
return string.Equals(playSessionId, j.PlaySessionId, StringComparison.OrdinalIgnoreCase);
}
return string.Equals(deviceId, j.DeviceId, StringComparison.OrdinalIgnoreCase);
}, deleteFiles);
}
/// <summary>
/// Kills the transcoding jobs.
/// </summary>
/// <param name="killJob">The kill job.</param>
/// <param name="deleteFiles">The delete files.</param>
/// <returns>Task.</returns>
private void KillTranscodingJobs(Func<TranscodingJob, bool> killJob, Func<string, bool> deleteFiles)
{
var jobs = new List<TranscodingJob>();
lock (_activeTranscodingJobs)
{
// This is really only needed for HLS.
// Progressive streams can stop on their own reliably
jobs.AddRange(_activeTranscodingJobs.Where(killJob));
}
if (jobs.Count == 0)
{
return;
}
foreach (var job in jobs)
{
KillTranscodingJob(job, false, deleteFiles);
}
}
/// <summary>
/// Kills the transcoding job.
/// </summary>
/// <param name="job">The job.</param>
/// <param name="closeLiveStream">if set to <c>true</c> [close live stream].</param>
/// <param name="delete">The delete.</param>
private async void KillTranscodingJob(TranscodingJob job, bool closeLiveStream, Func<string, bool> delete)
{
job.DisposeKillTimer();
Logger.Debug("KillTranscodingJob - JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId);
lock (_activeTranscodingJobs)
{
_activeTranscodingJobs.Remove(job);
if (!job.CancellationTokenSource.IsCancellationRequested)
{
job.CancellationTokenSource.Cancel();
}
}
lock (_transcodingLocks)
{
_transcodingLocks.Remove(job.Path);
}
lock (job.ProcessLock)
{
if (job.TranscodingThrottler != null)
{
job.TranscodingThrottler.Stop();
}
var process = job.Process;
var hasExited = job.HasExited;
if (!hasExited)
{
try
{
Logger.Info("Stopping ffmpeg process with q command for {0}", job.Path);
//process.Kill();
process.StandardInput.WriteLine("q");
// Need to wait because killing is asynchronous
if (!process.WaitForExit(5000))
{
Logger.Info("Killing ffmpeg process for {0}", job.Path);
process.Kill();
}
}
catch (Exception ex)
{
Logger.ErrorException("Error killing transcoding job for {0}", ex, job.Path);
}
}
}
if (delete(job.Path))
{
DeletePartialStreamFiles(job.Path, job.Type, 0, 1500);
}
if (closeLiveStream && !string.IsNullOrWhiteSpace(job.LiveStreamId))
{
try
{
await _mediaSourceManager.CloseLiveStream(job.LiveStreamId).ConfigureAwait(false);
}
catch (Exception ex)
{
Logger.ErrorException("Error closing live stream for {0}", ex, job.Path);
}
}
}
private async void DeletePartialStreamFiles(string path, TranscodingJobType jobType, int retryCount, int delayMs)
{
if (retryCount >= 10)
{
return;
}
Logger.Info("Deleting partial stream file(s) {0}", path);
await Task.Delay(delayMs).ConfigureAwait(false);
try
{
if (jobType == TranscodingJobType.Progressive)
{
DeleteProgressivePartialStreamFiles(path);
}
else
{
DeleteHlsPartialStreamFiles(path);
}
}
catch (FileNotFoundException)
{
}
catch (IOException)
{
//Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, path);
DeletePartialStreamFiles(path, jobType, retryCount + 1, 500);
}
catch
{
//Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, path);
}
}
/// <summary>
/// Deletes the progressive partial stream files.
/// </summary>
/// <param name="outputFilePath">The output file path.</param>
private void DeleteProgressivePartialStreamFiles(string outputFilePath)
{
_fileSystem.DeleteFile(outputFilePath);
}
/// <summary>
/// Deletes the HLS partial stream files.
/// </summary>
/// <param name="outputFilePath">The output file path.</param>
private void DeleteHlsPartialStreamFiles(string outputFilePath)
{
var directory = _fileSystem.GetDirectoryName(outputFilePath);
var name = Path.GetFileNameWithoutExtension(outputFilePath);
var filesToDelete = _fileSystem.GetFilePaths(directory)
.Where(f => f.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1)
.ToList();
Exception e = null;
foreach (var file in filesToDelete)
{
try
{
//Logger.Debug("Deleting HLS file {0}", file);
_fileSystem.DeleteFile(file);
}
catch (FileNotFoundException)
{
}
catch (IOException ex)
{
e = ex;
//Logger.ErrorException("Error deleting HLS file {0}", ex, file);
}
}
if (e != null)
{
throw e;
}
}
}
/// <summary>
/// Class TranscodingJob
/// </summary>
public class TranscodingJob
{
/// <summary>
/// Gets or sets the play session identifier.
/// </summary>
/// <value>The play session identifier.</value>
public string PlaySessionId { get; set; }
/// <summary>
/// Gets or sets the live stream identifier.
/// </summary>
/// <value>The live stream identifier.</value>
public string LiveStreamId { get; set; }
public bool IsLiveOutput { get; set; }
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public MediaSourceInfo MediaSource { get; set; }
public string Path { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
public TranscodingJobType Type { get; set; }
/// <summary>
/// Gets or sets the process.
/// </summary>
/// <value>The process.</value>
public IProcess Process { get; set; }
public ILogger Logger { get; private set; }
/// <summary>
/// Gets or sets the active request count.
/// </summary>
/// <value>The active request count.</value>
public int ActiveRequestCount { get; set; }
/// <summary>
/// Gets or sets the kill timer.
/// </summary>
/// <value>The kill timer.</value>
private ITimer KillTimer { get; set; }
private readonly ITimerFactory _timerFactory;
public string DeviceId { get; set; }
public CancellationTokenSource CancellationTokenSource { get; set; }
public object ProcessLock = new object();
public bool HasExited { get; set; }
public bool IsUserPaused { get; set; }
public string Id { get; set; }
public float? Framerate { get; set; }
public double? CompletionPercentage { get; set; }
public long? BytesDownloaded { get; set; }
public long? BytesTranscoded { get; set; }
public int? BitRate { get; set; }
public long? TranscodingPositionTicks { get; set; }
public long? DownloadPositionTicks { get; set; }
public TranscodingThrottler TranscodingThrottler { get; set; }
private readonly object _timerLock = new object();
public DateTime LastPingDate { get; set; }
public int PingTimeout { get; set; }
public TranscodingJob(ILogger logger, ITimerFactory timerFactory)
{
Logger = logger;
_timerFactory = timerFactory;
}
public void StopKillTimer()
{
lock (_timerLock)
{
if (KillTimer != null)
{
KillTimer.Change(Timeout.Infinite, Timeout.Infinite);
}
}
}
public void DisposeKillTimer()
{
lock (_timerLock)
{
if (KillTimer != null)
{
KillTimer.Dispose();
KillTimer = null;
}
}
}
public void StartKillTimer(Action<object> callback)
{
StartKillTimer(callback, PingTimeout);
}
public void StartKillTimer(Action<object> callback, int intervalMs)
{
if (HasExited)
{
return;
}
lock (_timerLock)
{
if (KillTimer == null)
{
//Logger.Debug("Starting kill timer at {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
KillTimer = _timerFactory.Create(callback, this, intervalMs, Timeout.Infinite);
}
else
{
//Logger.Debug("Changing kill timer to {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
KillTimer.Change(intervalMs, Timeout.Infinite);
}
}
}
public void ChangeKillTimerIfStarted()
{
if (HasExited)
{
return;
}
lock (_timerLock)
{
if (KillTimer != null)
{
var intervalMs = PingTimeout;
//Logger.Debug("Changing kill timer to {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
KillTimer.Change(intervalMs, Timeout.Infinite);
}
}
}
}
}

@ -63,7 +63,7 @@ namespace MediaBrowser.Api
var result = ((Folder)item).GetItemList(GetItemsQuery(request, user));
return ToOptimizedResult(GetFilters(result.ToArray()));
return ToOptimizedResult(GetFilters(result));
}
private QueryFilters GetFilters(BaseItem[] items)

@ -12,6 +12,7 @@ using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api
{
@ -227,11 +228,13 @@ namespace MediaBrowser.Api
SimilarTo = item,
DtoOptions = dtoOptions
}).ToList();
});
var returnList = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false));
var result = new QueryResult<BaseItemDto>
{
Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(),
Items = returnList.ToArray(returnList.Count),
TotalRecordCount = itemsResult.Count
};

@ -279,13 +279,16 @@ namespace MediaBrowser.Api.Images
var itemImages = item.ImageInfos;
foreach (var image in itemImages.Where(i => !item.AllowsMultipleImages(i.Type)))
foreach (var image in itemImages)
{
var info = GetImageInfo(item, image, null);
if (info != null)
if (!item.AllowsMultipleImages(image.Type))
{
list.Add(info);
var info = GetImageInfo(item, image, null);
if (info != null)
{
list.Add(info);
}
}
}

@ -66,8 +66,8 @@ namespace MediaBrowser.Api
{
ParentalRatingOptions = _localizationManager.GetParentalRatings().ToList(),
ExternalIdInfos = _providerManager.GetExternalIdInfos(item).ToList(),
Countries = _localizationManager.GetCountries().ToList(),
Cultures = _localizationManager.GetCultures().ToList()
Countries = _localizationManager.GetCountries(),
Cultures = _localizationManager.GetCultures()
};
if (!item.IsVirtualItem && !(item is ICollectionFolder) && !(item is UserView) && !(item is AggregateFolder) && !(item is LiveTvChannel) && !(item is IItemByName) &&
@ -269,7 +269,7 @@ namespace MediaBrowser.Api
if (request.Studios != null)
{
item.Studios = request.Studios.Select(x => x.Name).ToList();
item.Studios = request.Studios.Select(x => x.Name).ToArray();
}
if (request.DateCreated.HasValue)
@ -285,7 +285,7 @@ namespace MediaBrowser.Api
if (request.ProductionLocations != null)
{
item.ProductionLocations = request.ProductionLocations.ToList();
item.ProductionLocations = request.ProductionLocations;
}
item.PreferredMetadataCountryCode = request.PreferredMetadataCountryCode;

@ -29,6 +29,7 @@ using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Services;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api.Library
{
@ -460,22 +461,22 @@ namespace MediaBrowser.Api.Library
EnableImages = false
}
}).ToArray();
});
if (!string.IsNullOrWhiteSpace(request.ImdbId))
{
movies = movies.Where(i => string.Equals(request.ImdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)).ToArray();
movies = movies.Where(i => string.Equals(request.ImdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)).ToList();
}
else if (!string.IsNullOrWhiteSpace(request.TmdbId))
{
movies = movies.Where(i => string.Equals(request.TmdbId, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase)).ToArray();
movies = movies.Where(i => string.Equals(request.TmdbId, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase)).ToList();
}
else
{
movies = new BaseItem[] { };
movies = new List<BaseItem>();
}
if (movies.Length > 0)
if (movies.Count > 0)
{
foreach (var item in movies)
{
@ -732,7 +733,8 @@ namespace MediaBrowser.Api.Library
{
DeleteFileLocation = true
});
}).ToArray();
}).ToArray(ids.Length);
Task.WaitAll(tasks);
}
@ -758,7 +760,7 @@ namespace MediaBrowser.Api.Library
{
var reviews = _itemRepo.GetCriticReviews(new Guid(request.Id));
var reviewsArray = reviews.ToArray();
var reviewsArray = reviews.ToArray(reviews.Count);
var result = new QueryResult<ItemReview>
{
@ -833,7 +835,7 @@ namespace MediaBrowser.Api.Library
throw new ResourceNotFoundException("Item not found.");
}
while (item.ThemeSongIds.Count == 0 && request.InheritFromParent && item.GetParent() != null)
while (item.ThemeSongIds.Length == 0 && request.InheritFromParent && item.GetParent() != null)
{
item = item.GetParent();
}
@ -882,7 +884,7 @@ namespace MediaBrowser.Api.Library
throw new ResourceNotFoundException("Item not found.");
}
while (item.ThemeVideoIds.Count == 0 && request.InheritFromParent && item.GetParent() != null)
while (item.ThemeVideoIds.Length == 0 && request.InheritFromParent && item.GetParent() != null)
{
item = item.GetParent();
}

@ -16,13 +16,12 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
using MediaBrowser.Api.Playback.Progressive;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api.LiveTv
{
@ -734,7 +733,7 @@ namespace MediaBrowser.Api.LiveTv
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path);
return new ProgressiveFileCopier(_fileSystem, path, outputHeaders, null, Logger, _environment, CancellationToken.None)
return new ProgressiveFileCopier(_fileSystem, path, outputHeaders, Logger, _environment, CancellationToken.None)
{
AllowEndOfFile = false
};
@ -753,7 +752,7 @@ namespace MediaBrowser.Api.LiveTv
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container);
return new ProgressiveFileCopier(directStreamProvider, outputHeaders, null, Logger, _environment, CancellationToken.None)
return new ProgressiveFileCopier(directStreamProvider, outputHeaders, Logger, _environment, CancellationToken.None)
{
AllowEndOfFile = false
};
@ -921,7 +920,9 @@ namespace MediaBrowser.Api.LiveTv
options.AddCurrentProgram = request.AddCurrentProgram;
var returnArray = (await _dtoService.GetBaseItemDtos(channelResult.Items, options, user).ConfigureAwait(false)).ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(channelResult.Items, options, user)
.ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto>
{
@ -962,7 +963,7 @@ namespace MediaBrowser.Api.LiveTv
{
var query = new ProgramQuery
{
ChannelIds = (request.ChannelIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(),
ChannelIds = ApiEntryPoint.Split(request.ChannelIds, ',', true),
UserId = request.UserId,
HasAired = request.HasAired,
EnableTotalRecordCount = request.EnableTotalRecordCount

@ -1,23 +1,19 @@
using MediaBrowser.Model.Logging;
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Net;
using System.Collections.Generic;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.System;
namespace MediaBrowser.Api.Playback.Progressive
namespace MediaBrowser.Api.LiveTv
{
public class ProgressiveFileCopier : IAsyncStreamWriter, IHasHeaders
{
private readonly IFileSystem _fileSystem;
private readonly TranscodingJob _job;
private readonly ILogger _logger;
private readonly string _path;
private readonly CancellationToken _cancellationToken;
@ -32,22 +28,20 @@ namespace MediaBrowser.Api.Playback.Progressive
private readonly IDirectStreamProvider _directStreamProvider;
private readonly IEnvironmentInfo _environment;
public ProgressiveFileCopier(IFileSystem fileSystem, string path, Dictionary<string, string> outputHeaders, TranscodingJob job, ILogger logger, IEnvironmentInfo environment, CancellationToken cancellationToken)
public ProgressiveFileCopier(IFileSystem fileSystem, string path, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment, CancellationToken cancellationToken)
{
_fileSystem = fileSystem;
_path = path;
_outputHeaders = outputHeaders;
_job = job;
_logger = logger;
_cancellationToken = cancellationToken;
_environment = environment;
}
public ProgressiveFileCopier(IDirectStreamProvider directStreamProvider, Dictionary<string, string> outputHeaders, TranscodingJob job, ILogger logger, IEnvironmentInfo environment, CancellationToken cancellationToken)
public ProgressiveFileCopier(IDirectStreamProvider directStreamProvider, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment, CancellationToken cancellationToken)
{
_directStreamProvider = directStreamProvider;
_outputHeaders = outputHeaders;
_job = job;
_logger = logger;
_cancellationToken = cancellationToken;
_environment = environment;
@ -77,61 +71,48 @@ namespace MediaBrowser.Api.Playback.Progressive
{
cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _cancellationToken).Token;
try
if (_directStreamProvider != null)
{
if (_directStreamProvider != null)
{
await _directStreamProvider.CopyToAsync(outputStream, cancellationToken).ConfigureAwait(false);
return;
}
await _directStreamProvider.CopyToAsync(outputStream, cancellationToken).ConfigureAwait(false);
return;
}
var eofCount = 0;
var eofCount = 0;
// use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
var allowAsyncFileRead = _environment.OperatingSystem != OperatingSystem.Windows;
// use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
var allowAsyncFileRead = _environment.OperatingSystem != OperatingSystem.Windows;
using (var inputStream = GetInputStream(allowAsyncFileRead))
using (var inputStream = GetInputStream(allowAsyncFileRead))
{
if (StartPosition > 0)
{
if (StartPosition > 0)
inputStream.Position = StartPosition;
}
while (eofCount < 20 || !AllowEndOfFile)
{
int bytesRead;
if (allowAsyncFileRead)
{
bytesRead = await CopyToInternalAsync(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
}
else
{
inputStream.Position = StartPosition;
bytesRead = await CopyToInternalAsyncWithSyncRead(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
}
while (eofCount < 20 || !AllowEndOfFile)
//var position = fs.Position;
//_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path);
if (bytesRead == 0)
{
int bytesRead;
if (allowAsyncFileRead)
{
bytesRead = await CopyToInternalAsync(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
}
else
{
bytesRead = await CopyToInternalAsyncWithSyncRead(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
}
//var position = fs.Position;
//_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path);
if (bytesRead == 0)
{
if (_job == null || _job.HasExited)
{
eofCount++;
}
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
}
else
{
eofCount = 0;
}
eofCount++;
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
}
else
{
eofCount = 0;
}
}
}
finally
{
if (_job != null)
{
ApiEntryPoint.Instance.OnTranscodeEndRequest(_job);
}
}
}
@ -152,11 +133,6 @@ namespace MediaBrowser.Api.Playback.Progressive
_bytesWritten += bytesRead;
totalBytesRead += bytesRead;
if (_job != null)
{
_job.BytesDownloaded = Math.Max(_job.BytesDownloaded ?? _bytesWritten, _bytesWritten);
}
}
}
@ -179,11 +155,6 @@ namespace MediaBrowser.Api.Playback.Progressive
_bytesWritten += bytesRead;
totalBytesRead += bytesRead;
if (_job != null)
{
_job.BytesDownloaded = Math.Max(_job.BytesDownloaded ?? _bytesWritten, _bytesWritten);
}
}
}

@ -85,7 +85,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetCountries request)
{
var result = _localization.GetCountries().ToList();
var result = _localization.GetCountries();
return ToOptimizedResult(result);
}
@ -97,7 +97,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetCultures request)
{
var result = _localization.GetCultures().ToList();
var result = _localization.GetCultures();
return ToOptimizedResult(result);
}

@ -48,9 +48,7 @@
<Compile Include="Dlna\DlnaService.cs" />
<Compile Include="FilterService.cs" />
<Compile Include="IHasDtoOptions.cs" />
<Compile Include="Playback\MediaInfoService.cs" />
<Compile Include="Playback\TranscodingThrottler.cs" />
<Compile Include="Playback\UniversalAudioService.cs" />
<Compile Include="LiveTv\ProgressiveFileCopier.cs" />
<Compile Include="PlaylistService.cs" />
<Compile Include="Reports\Activities\ReportActivitiesBuilder.cs" />
<Compile Include="Reports\Common\HeaderActivitiesMetadata.cs" />
@ -101,18 +99,6 @@
<Compile Include="NotificationsService.cs" />
<Compile Include="PackageReviewService.cs" />
<Compile Include="PackageService.cs" />
<Compile Include="Playback\Hls\BaseHlsService.cs" />
<Compile Include="Playback\Hls\DynamicHlsService.cs" />
<Compile Include="Playback\Hls\HlsSegmentService.cs" />
<Compile Include="Playback\Hls\VideoHlsService.cs" />
<Compile Include="Playback\Progressive\AudioService.cs" />
<Compile Include="Playback\Progressive\BaseProgressiveStreamingService.cs" />
<Compile Include="Playback\BaseStreamingService.cs" />
<Compile Include="Playback\Progressive\ProgressiveStreamWriter.cs" />
<Compile Include="Playback\StaticRemoteStreamWriter.cs" />
<Compile Include="Playback\StreamRequest.cs" />
<Compile Include="Playback\StreamState.cs" />
<Compile Include="Playback\Progressive\VideoService.cs" />
<Compile Include="PluginService.cs" />
<Compile Include="Images\RemoteImageService.cs" />
<Compile Include="ScheduledTasks\ScheduledTaskService.cs" />
@ -126,7 +112,6 @@
<Compile Include="System\ActivityLogWebSocketListener.cs" />
<Compile Include="System\SystemService.cs" />
<Compile Include="Movies\TrailersService.cs" />
<Compile Include="TestService.cs" />
<Compile Include="TvShowsService.cs" />
<Compile Include="UserLibrary\ArtistsService.cs" />
<Compile Include="UserLibrary\BaseItemsByNameService.cs" />
@ -136,7 +121,6 @@
<Compile Include="UserLibrary\ItemsService.cs" />
<Compile Include="UserLibrary\MusicGenresService.cs" />
<Compile Include="UserLibrary\PersonsService.cs" />
<Compile Include="UserLibrary\PlaystateService.cs" />
<Compile Include="UserLibrary\StudiosService.cs" />
<Compile Include="UserLibrary\UserLibraryService.cs" />
<Compile Include="UserLibrary\UserViewsService.cs" />

@ -158,17 +158,19 @@ namespace MediaBrowser.Api.Movies
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
Limit = request.Limit,
IncludeItemTypes = itemTypes.ToArray(),
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IsMovie = true,
SimilarTo = item,
EnableGroupByMetadataKey = true,
DtoOptions = dtoOptions
}).ToList();
});
var returnList = await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false);
var result = new QueryResult<BaseItemDto>
{
Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(),
Items = returnList.ToArray(returnList.Count),
TotalRecordCount = itemsResult.Count
};
@ -200,7 +202,7 @@ namespace MediaBrowser.Api.Movies
DtoOptions = dtoOptions
};
var recentlyPlayedMovies = _libraryManager.GetItemList(query).ToList();
var recentlyPlayedMovies = _libraryManager.GetItemList(query);
var itemTypes = new List<string> { typeof(Movie).Name };
if (_config.Configuration.EnableExternalContentInSuggestions)
@ -211,19 +213,19 @@ namespace MediaBrowser.Api.Movies
var likedMovies = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
IncludeItemTypes = itemTypes.ToArray(),
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IsMovie = true,
SortBy = new[] { ItemSortBy.Random },
SortOrder = SortOrder.Descending,
Limit = 10,
IsFavoriteOrLiked = true,
ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray(),
ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray(recentlyPlayedMovies.Count),
EnableGroupByMetadataKey = true,
ParentId = parentIdGuid,
Recursive = true,
DtoOptions = dtoOptions
}).ToList();
});
var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList();
// Get recently played directors
@ -300,7 +302,7 @@ namespace MediaBrowser.Api.Movies
// Account for duplicates by imdb id, since the database doesn't support this yet
Limit = itemLimit + 2,
PersonTypes = new[] { PersonType.Director },
IncludeItemTypes = itemTypes.ToArray(),
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IsMovie = true,
EnableGroupByMetadataKey = true,
DtoOptions = dtoOptions
@ -311,12 +313,14 @@ namespace MediaBrowser.Api.Movies
if (items.Count > 0)
{
var returnItems = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result;
yield return new RecommendationDto
{
BaselineItemName = name,
CategoryId = name.GetMD5().ToString("N"),
RecommendationType = type,
Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray()
Items = returnItems.ToArray(returnItems.Count)
};
}
}
@ -338,7 +342,7 @@ namespace MediaBrowser.Api.Movies
Person = name,
// Account for duplicates by imdb id, since the database doesn't support this yet
Limit = itemLimit + 2,
IncludeItemTypes = itemTypes.ToArray(),
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IsMovie = true,
EnableGroupByMetadataKey = true,
DtoOptions = dtoOptions
@ -349,12 +353,14 @@ namespace MediaBrowser.Api.Movies
if (items.Count > 0)
{
var returnItems = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result;
yield return new RecommendationDto
{
BaselineItemName = name,
CategoryId = name.GetMD5().ToString("N"),
RecommendationType = type,
Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray()
Items = returnItems.ToArray(returnItems.Count)
};
}
}
@ -374,28 +380,30 @@ namespace MediaBrowser.Api.Movies
var similar = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
Limit = itemLimit,
IncludeItemTypes = itemTypes.ToArray(),
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IsMovie = true,
SimilarTo = item,
EnableGroupByMetadataKey = true,
DtoOptions = dtoOptions
}).ToList();
});
if (similar.Count > 0)
{
var returnItems = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).Result;
yield return new RecommendationDto
{
BaselineItemName = item.Name,
CategoryId = item.Id.ToString("N"),
RecommendationType = type,
Items = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).Result.ToArray()
Items = returnItems.ToArray(returnItems.Count)
};
}
}
}
private IEnumerable<string> GetActors(IEnumerable<BaseItem> items)
private IEnumerable<string> GetActors(List<BaseItem> items)
{
var people = _libraryManager.GetPeople(new InternalPeopleQuery
{
@ -406,7 +414,7 @@ namespace MediaBrowser.Api.Movies
MaxListOrder = 3
});
var itemIds = items.Select(i => i.Id).ToList();
var itemIds = items.Select(i => i.Id).ToList(items.Count);
return people
.Where(i => itemIds.Contains(i.ItemId))
@ -414,7 +422,7 @@ namespace MediaBrowser.Api.Movies
.DistinctNames();
}
private IEnumerable<string> GetDirectors(IEnumerable<BaseItem> items)
private IEnumerable<string> GetDirectors(List<BaseItem> items)
{
var people = _libraryManager.GetPeople(new InternalPeopleQuery
{
@ -424,7 +432,7 @@ namespace MediaBrowser.Api.Movies
}
});
var itemIds = items.Select(i => i.Id).ToList();
var itemIds = items.Select(i => i.Id).ToList(items.Count);
return people
.Where(i => itemIds.Contains(i.ItemId))

@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api.Music
{
@ -180,16 +181,19 @@ namespace MediaBrowser.Api.Music
return GetResult(items, user, request, dtoOptions);
}
private async Task<object> GetResult(IEnumerable<Audio> items, User user, BaseGetSimilarItems request, DtoOptions dtoOptions)
private async Task<object> GetResult(List<BaseItem> items, User user, BaseGetSimilarItems request, DtoOptions dtoOptions)
{
var list = items.ToList();
var list = items;
var result = new ItemsResult
{
TotalRecordCount = list.Count
};
result.Items = (await _dtoService.GetBaseItemDtos(list.Take(request.Limit ?? list.Count), dtoOptions, user).ConfigureAwait(false)).ToArray();
var returnList = (await _dtoService.GetBaseItemDtos(list.Take(request.Limit ?? list.Count), dtoOptions, user)
.ConfigureAwait(false));
result.Items = returnList.ToArray(returnList.Count);
return ToOptimizedResult(result);
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save