diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs index 3ed4f650f7..6cbf397585 100644 --- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs @@ -392,10 +392,27 @@ namespace Emby.Common.Implementations.IO if (_supportsAsyncFileStreams && isAsync) { - return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), 262144, true); + return GetFileStream(path, mode, access, share, FileOpenOptions.Asynchronous); } - return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), 262144); + return GetFileStream(path, mode, access, share, FileOpenOptions.None); + } + + public Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, FileOpenOptions fileOpenOptions) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileStream(path, mode, access, share); + } + + var defaultBufferSize = 4096; + return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), defaultBufferSize, GetFileOptions(fileOpenOptions)); + } + + private FileOptions GetFileOptions(FileOpenOptions mode) + { + var val = (int)mode; + return (FileOptions)val; } private FileMode GetFileMode(FileOpenMode mode) diff --git a/Emby.Common.Implementations/project.json b/Emby.Common.Implementations/project.json index 674101e8a7..ff60c740e8 100644 --- a/Emby.Common.Implementations/project.json +++ b/Emby.Common.Implementations/project.json @@ -45,7 +45,7 @@ "System.Net.Requests": "4.3.0", "System.Xml.ReaderWriter": "4.3.0", "System.Xml.XmlSerializer": "4.3.0", - "System.Net.Http": "4.3.0", + "System.Net.Http": "4.3.2", "System.Net.Primitives": "4.3.0", "System.Net.Sockets": "4.3.0", "System.Net.NetworkInformation": "4.3.0", diff --git a/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj b/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj new file mode 100644 index 0000000000..8d1e221d0a --- /dev/null +++ b/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj @@ -0,0 +1,74 @@ + + + + + 11.0 + Debug + AnyCPU + {2312DA6D-FF86-4597-9777-BCEEC32D96DD} + Library + Properties + Emby.Drawing.Skia + Emby.Drawing.Skia + en-US + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Profile7 + v4.5 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + {9142eefa-7570-41e1-bfcc-468bb571af2f} + MediaBrowser.Common + + + {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} + MediaBrowser.Controller + + + {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + MediaBrowser.Model + + + + + Properties\SharedVersion.cs + + + + + + ..\packages\SkiaSharp.1.57.1\lib\portable-net45+win8+wpa81+wp8\SkiaSharp.dll + True + + + + + + + + \ No newline at end of file diff --git a/Emby.Drawing.Skia/Properties/AssemblyInfo.cs b/Emby.Drawing.Skia/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..c0dc7c5b4b --- /dev/null +++ b/Emby.Drawing.Skia/Properties/AssemblyInfo.cs @@ -0,0 +1,25 @@ +using System.Resources; +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.Drawing.Skia")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Emby.Drawing.Skia")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: NeutralResourcesLanguage("en")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// \ No newline at end of file diff --git a/Emby.Drawing.Skia/packages.config b/Emby.Drawing.Skia/packages.config new file mode 100644 index 0000000000..0743c38094 --- /dev/null +++ b/Emby.Drawing.Skia/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Emby.Server.Core/ApplicationHost.cs b/Emby.Server.Core/ApplicationHost.cs index 78bdc11898..6a3881caf8 100644 --- a/Emby.Server.Core/ApplicationHost.cs +++ b/Emby.Server.Core/ApplicationHost.cs @@ -1132,7 +1132,8 @@ namespace Emby.Server.Core // Custom cert return new CertificateInfo { - Path = ServerConfigurationManager.Configuration.CertificatePath + Path = ServerConfigurationManager.Configuration.CertificatePath, + Password = ServerConfigurationManager.Configuration.CertificatePassword }; } diff --git a/Emby.Server.Core/project.json b/Emby.Server.Core/project.json index 70543d7df1..fd4f9d6cf7 100644 --- a/Emby.Server.Core/project.json +++ b/Emby.Server.Core/project.json @@ -68,7 +68,7 @@ "System.AppDomain": "2.0.11", "System.Globalization.Extensions": "4.3.0", "System.IO.FileSystem.Watcher": "4.3.0", - "System.Net.Security": "4.3.0", + "System.Net.Security": "4.3.1", "System.Security.Cryptography.X509Certificates": "4.3.0", "System.Runtime.Extensions": "4.3.0", "MediaBrowser.Model": { diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index d4766e1ec7..b2f1f0ceb6 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -308,7 +308,7 @@ True - ..\packages\SQLitePCLRaw.core.1.1.2\lib\portable-net45+netcore45+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\SQLitePCLRaw.core.dll + ..\packages\SQLitePCLRaw.core.1.1.5\lib\portable-net45+netcore45+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\SQLitePCLRaw.core.dll True diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index ee5245a69a..5e96eda94a 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -228,7 +228,8 @@ namespace Emby.Server.Implementations.HttpServer _streamFactory, _enableDualModeSockets, GetRequest, - _fileSystem); + _fileSystem, + _environment); } private IHttpRequest GetRequest(HttpListenerContext httpContext) @@ -452,6 +453,7 @@ namespace Emby.Server.Implementations.HttpServer var date = DateTime.Now; var httpRes = httpReq.Response; bool enableLog = false; + bool logHeaders = false; string urlToLog = null; string remoteIp = null; @@ -490,13 +492,14 @@ namespace Emby.Server.Implementations.HttpServer var urlString = url.OriginalString; enableLog = EnableLogging(urlString, localPath); urlToLog = urlString; + logHeaders = enableLog && urlToLog.IndexOf("/videos/", StringComparison.OrdinalIgnoreCase) != -1; if (enableLog) { urlToLog = GetUrlToLog(urlString); remoteIp = httpReq.RemoteIp; - LoggerUtils.LogRequest(_logger, urlToLog, httpReq.HttpMethod, httpReq.UserAgent); + LoggerUtils.LogRequest(_logger, urlToLog, httpReq.HttpMethod, httpReq.UserAgent, logHeaders ? httpReq.Headers : null); } if (string.Equals(localPath, "/emby/", StringComparison.OrdinalIgnoreCase) || @@ -611,7 +614,7 @@ namespace Emby.Server.Implementations.HttpServer var duration = DateTime.Now - date; - LoggerUtils.LogResponse(_logger, statusCode, urlToLog, remoteIp, duration); + LoggerUtils.LogResponse(_logger, statusCode, urlToLog, remoteIp, duration, logHeaders ? httpRes.Headers : null); } } } diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs index 687bd62b06..0af88595f9 100644 --- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -353,31 +353,28 @@ namespace Emby.Server.Implementations.HttpServer /// /// Pres the process optimized result. /// - /// The request context. - /// The responseHeaders. - /// The cache key. - /// The cache key string. - /// The last date modified. - /// Duration of the cache. - /// Type of the content. - /// System.Object. private object GetCachedResult(IRequest requestContext, IDictionary responseHeaders, Guid cacheKey, string cacheKeyString, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType) { responseHeaders["ETag"] = string.Format("\"{0}\"", cacheKeyString); - if (IsNotModified(requestContext, cacheKey, lastDateModified, cacheDuration)) + var noCache = (requestContext.Headers.Get("Cache-Control") ?? string.Empty).IndexOf("no-cache", StringComparison.OrdinalIgnoreCase) != -1; + + if (!noCache) { - AddAgeHeader(responseHeaders, lastDateModified); - AddExpiresHeader(responseHeaders, cacheKeyString, cacheDuration); + if (IsNotModified(requestContext, cacheKey, lastDateModified, cacheDuration)) + { + AddAgeHeader(responseHeaders, lastDateModified); + AddExpiresHeader(responseHeaders, cacheKeyString, cacheDuration, noCache); - var result = new HttpResult(new byte[] { }, contentType ?? "text/html", HttpStatusCode.NotModified); + var result = new HttpResult(new byte[] { }, contentType ?? "text/html", HttpStatusCode.NotModified); - AddResponseHeaders(result, responseHeaders); + AddResponseHeaders(result, responseHeaders); - return result; + return result; + } } - AddCachingHeaders(responseHeaders, cacheKeyString, lastDateModified, cacheDuration); + AddCachingHeaders(responseHeaders, cacheKeyString, lastDateModified, cacheDuration, noCache); return null; } @@ -673,11 +670,7 @@ namespace Emby.Server.Implementations.HttpServer /// /// Adds the caching responseHeaders. /// - /// The responseHeaders. - /// The cache key. - /// The last date modified. - /// Duration of the cache. - private void AddCachingHeaders(IDictionary responseHeaders, string cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration) + private void AddCachingHeaders(IDictionary responseHeaders, string cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, bool noCache) { // Don't specify both last modified and Etag, unless caching unconditionally. They are redundant // https://developers.google.com/speed/docs/best-practices/caching#LeverageBrowserCaching @@ -687,11 +680,11 @@ namespace Emby.Server.Implementations.HttpServer responseHeaders["Last-Modified"] = lastDateModified.Value.ToString("r"); } - if (cacheDuration.HasValue) + if (!noCache && cacheDuration.HasValue) { responseHeaders["Cache-Control"] = "public, max-age=" + Convert.ToInt32(cacheDuration.Value.TotalSeconds); } - else if (!string.IsNullOrEmpty(cacheKey)) + else if (!noCache && !string.IsNullOrEmpty(cacheKey)) { responseHeaders["Cache-Control"] = "public"; } @@ -701,18 +694,15 @@ namespace Emby.Server.Implementations.HttpServer responseHeaders["pragma"] = "no-cache, no-store, must-revalidate"; } - AddExpiresHeader(responseHeaders, cacheKey, cacheDuration); + AddExpiresHeader(responseHeaders, cacheKey, cacheDuration, noCache); } /// /// Adds the expires header. /// - /// The responseHeaders. - /// The cache key. - /// Duration of the cache. - private void AddExpiresHeader(IDictionary responseHeaders, string cacheKey, TimeSpan? cacheDuration) + private void AddExpiresHeader(IDictionary responseHeaders, string cacheKey, TimeSpan? cacheDuration, bool noCache) { - if (cacheDuration.HasValue) + if (!noCache && cacheDuration.HasValue) { responseHeaders["Expires"] = DateTime.UtcNow.Add(cacheDuration.Value).ToString("r"); } diff --git a/Emby.Server.Implementations/HttpServer/LoggerUtils.cs b/Emby.Server.Implementations/HttpServer/LoggerUtils.cs index 8fc92a09a7..f0e75eea48 100644 --- a/Emby.Server.Implementations/HttpServer/LoggerUtils.cs +++ b/Emby.Server.Implementations/HttpServer/LoggerUtils.cs @@ -1,6 +1,8 @@ using MediaBrowser.Model.Logging; using System; using System.Globalization; +using System.Linq; +using MediaBrowser.Model.Services; using SocketHttpListener.Net; namespace Emby.Server.Implementations.HttpServer @@ -19,9 +21,18 @@ namespace Emby.Server.Implementations.HttpServer logger.Info("{0} {1}. UserAgent: {2}", request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod, url, request.UserAgent ?? string.Empty); } - public static void LogRequest(ILogger logger, string url, string method, string userAgent) + public static void LogRequest(ILogger logger, string url, string method, string userAgent, QueryParamCollection headers) { - logger.Info("{0} {1}. UserAgent: {2}", "HTTP " + method, url, userAgent ?? string.Empty); + if (headers == null) + { + logger.Info("{0} {1}. UserAgent: {2}", "HTTP " + method, url, userAgent ?? string.Empty); + } + else + { + var headerText = string.Join(", ", headers.Select(i => i.Name + "=" + i.Value).ToArray()); + + logger.Info("HTTP {0} {1}. {2}", method, url, headerText); + } } /// @@ -32,12 +43,13 @@ namespace Emby.Server.Implementations.HttpServer /// The URL. /// The end point. /// The duration. - public static void LogResponse(ILogger logger, int statusCode, string url, string endPoint, TimeSpan duration) + public static void LogResponse(ILogger logger, int statusCode, string url, string endPoint, TimeSpan duration, QueryParamCollection headers) { var durationMs = duration.TotalMilliseconds; var logSuffix = durationMs >= 1000 && durationMs < 60000 ? "ms (slow)" : "ms"; - logger.Info("HTTP Response {0} to {1}. Time: {2}{3}. {4}", statusCode, endPoint, Convert.ToInt32(durationMs).ToString(CultureInfo.InvariantCulture), logSuffix, url); + var headerText = headers == null ? string.Empty : "Headers: " + string.Join(", ", headers.Where(i => i.Name.IndexOf("Access-", StringComparison.OrdinalIgnoreCase) == -1).Select(i => i.Name + "=" + i.Value).ToArray()); + logger.Info("HTTP Response {0} to {1}. Time: {2}{3}. {4} {5}", statusCode, endPoint, Convert.ToInt32(durationMs).ToString(CultureInfo.InvariantCulture), logSuffix, url, headerText); } } } diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index b11b2fe88f..682fa7a0b8 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; using MediaBrowser.Model.Services; +using MediaBrowser.Model.System; using MediaBrowser.Model.Text; using SocketHttpListener.Primitives; @@ -30,8 +31,9 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp private readonly IFileSystem _fileSystem; private readonly Func _httpRequestFactory; private readonly bool _enableDualMode; + private readonly IEnvironmentInfo _environment; - public WebSocketSharpListener(ILogger logger, ICertificate certificate, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, INetworkManager networkManager, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, bool enableDualMode, Func httpRequestFactory, IFileSystem fileSystem) + public WebSocketSharpListener(ILogger logger, ICertificate certificate, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, INetworkManager networkManager, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, bool enableDualMode, Func httpRequestFactory, IFileSystem fileSystem, IEnvironmentInfo environment) { _logger = logger; _certificate = certificate; @@ -44,6 +46,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp _enableDualMode = enableDualMode; _httpRequestFactory = httpRequestFactory; _fileSystem = fileSystem; + _environment = environment; } public Action ErrorHandler { get; set; } @@ -56,7 +59,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp public void Start(IEnumerable urlPrefixes) { if (_listener == null) - _listener = new HttpListener(_logger, _cryptoProvider, _streamFactory, _socketFactory, _networkManager, _textEncoding, _memoryStreamProvider, _fileSystem); + _listener = new HttpListener(_logger, _cryptoProvider, _streamFactory, _socketFactory, _networkManager, _textEncoding, _memoryStreamProvider, _fileSystem, _environment); _listener.EnableDualMode = _enableDualMode; diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs index fd30b227f0..9e58ee57cd 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Services; using SocketHttpListener.Net; using HttpListenerResponse = SocketHttpListener.Net.HttpListenerResponse; using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse; @@ -66,6 +67,14 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp _response.AddHeader(name, value); } + public QueryParamCollection Headers + { + get + { + return _response.Headers; + } + } + public string GetHeader(string name) { return _response.Headers[name]; diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs index 2677f7b2ad..b2ec84a82a 100644 --- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs @@ -258,7 +258,7 @@ namespace Emby.Server.Implementations.Images { return await CreateSquareCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); } - if (item is Playlist || item is MusicGenre || item is Genre || item is GameGenre) + if (item is Playlist || item is MusicGenre || item is Genre || item is GameGenre || item is PhotoAlbum) { return await CreateSquareCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); } diff --git a/Emby.Server.Implementations/packages.config b/Emby.Server.Implementations/packages.config index e4c75e1e92..5ce754d3ff 100644 --- a/Emby.Server.Implementations/packages.config +++ b/Emby.Server.Implementations/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index daec00e10b..67921ab348 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -671,12 +671,15 @@ namespace MediaBrowser.Api.Playback request.AudioCodec = EncodingHelper.InferAudioCodec(url); } + var enableDlnaHeaders = !string.IsNullOrWhiteSpace(request.Params) /*|| + string.Equals(Request.Headers.Get("GetContentFeatures.DLNA.ORG"), "1", StringComparison.OrdinalIgnoreCase)*/; + var state = new StreamState(MediaSourceManager, Logger, TranscodingJobType) { Request = request, RequestedUrl = url, UserAgent = Request.UserAgent, - EnableDlnaHeaders = !string.IsNullOrWhiteSpace(request.Params) + EnableDlnaHeaders = enableDlnaHeaders }; var auth = AuthorizationContext.GetAuthorizationInfo(Request); diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 838111a383..60bbf62404 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -55,6 +55,7 @@ namespace MediaBrowser.Model.Configuration /// /// The value pointing to the file system where the ssl certiifcate is located.. public string CertificatePath { get; set; } + public string CertificatePassword { get; set; } /// /// Gets or sets a value indicating whether this instance is port authorized. diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs index 26de9332e3..92112f4ae3 100644 --- a/MediaBrowser.Model/IO/IFileSystem.cs +++ b/MediaBrowser.Model/IO/IFileSystem.cs @@ -108,6 +108,8 @@ namespace MediaBrowser.Model.IO /// FileStream. Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, bool isAsync = false); + Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, FileOpenOptions fileOpenOptions); + /// /// Opens the read. /// @@ -402,4 +404,46 @@ namespace MediaBrowser.Model.IO ReadWrite = 3 } + // + // Summary: + // Represents advanced options for creating a System.IO.FileStream object. + [Flags] + public enum FileOpenOptions + { + // + // Summary: + // Indicates that the system should write through any intermediate cache and go + // directly to disk. + WriteThrough = int.MinValue, + // + // Summary: + // Indicates that no additional options should be used when creating a System.IO.FileStream + // object. + None = 0, + // + // Summary: + // Indicates that a file is encrypted and can be decrypted only by using the same + // user account used for encryption. + Encrypted = 16384, + // + // Summary: + // Indicates that a file is automatically deleted when it is no longer in use. + DeleteOnClose = 67108864, + // + // Summary: + // Indicates that the file is to be accessed sequentially from beginning to end. + // The system can use this as a hint to optimize file caching. If an application + // moves the file pointer for random access, optimum caching may not occur; however, + // correct operation is still guaranteed. + SequentialScan = 134217728, + // + // Summary: + // Indicates that the file is accessed randomly. The system can use this as a hint + // to optimize file caching. + RandomAccess = 268435456, + // + // Summary: + // Indicates that a file can be used for asynchronous reading and writing. + Asynchronous = 1073741824 + } } diff --git a/MediaBrowser.Model/Services/IRequest.cs b/MediaBrowser.Model/Services/IRequest.cs index 115ba25ce0..f056c7410a 100644 --- a/MediaBrowser.Model/Services/IRequest.cs +++ b/MediaBrowser.Model/Services/IRequest.cs @@ -155,6 +155,8 @@ namespace MediaBrowser.Model.Services //Add Metadata to Response Dictionary Items { get; } + QueryParamCollection Headers { get; } + Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs index f544c09dc1..d5494c21fd 100644 --- a/MediaBrowser.Providers/Manager/ProviderUtils.cs +++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs @@ -200,6 +200,7 @@ namespace MediaBrowser.Providers.Manager MergeCriticRating(source, target, lockedFields, replaceData); MergeAwards(source, target, lockedFields, replaceData); MergeTrailers(source, target, lockedFields, replaceData); + MergeVideoInfo(source, target, lockedFields, replaceData); if (mergeMetadataSettings) { @@ -307,5 +308,19 @@ namespace MediaBrowser.Providers.Manager } } } + + private static void MergeVideoInfo(BaseItem source, BaseItem target, List lockedFields, bool replaceData) + { + var sourceCast = source as Video; + var targetCast = target as Video; + + if (sourceCast != null && targetCast != null) + { + if (replaceData || targetCast.Video3DFormat == null) + { + targetCast.Video3DFormat = sourceCast.Video3DFormat; + } + } + } } } diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index bcdfa858ff..e4bde07c7d 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -94,11 +94,11 @@ True - ..\packages\SQLitePCLRaw.core.1.1.2\lib\net45\SQLitePCLRaw.core.dll + ..\packages\SQLitePCLRaw.core.1.1.5\lib\net45\SQLitePCLRaw.core.dll True - ..\packages\SQLitePCLRaw.provider.sqlite3.net45.1.1.2\lib\net45\SQLitePCLRaw.provider.sqlite3.dll + ..\packages\SQLitePCLRaw.provider.sqlite3.net45.1.1.5\lib\net45\SQLitePCLRaw.provider.sqlite3.dll True diff --git a/MediaBrowser.Server.Mono/packages.config b/MediaBrowser.Server.Mono/packages.config index 81da308f52..de26c7666e 100644 --- a/MediaBrowser.Server.Mono/packages.config +++ b/MediaBrowser.Server.Mono/packages.config @@ -5,6 +5,6 @@ - - + + \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 749468fe2b..1b1446d2c5 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -99,12 +99,16 @@ ..\packages\SimpleInjector.3.3.2\lib\net45\SimpleInjector.dll True + + ..\packages\SkiaSharp.1.57.1\lib\net45\SkiaSharp.dll + True + - ..\packages\SQLitePCLRaw.core.1.1.2\lib\net45\SQLitePCLRaw.core.dll + ..\packages\SQLitePCLRaw.core.1.1.5\lib\net45\SQLitePCLRaw.core.dll True - ..\packages\SQLitePCLRaw.provider.sqlite3.net45.1.1.2\lib\net45\SQLitePCLRaw.provider.sqlite3.dll + ..\packages\SQLitePCLRaw.provider.sqlite3.net45.1.1.5\lib\net45\SQLitePCLRaw.provider.sqlite3.dll True @@ -1174,6 +1178,13 @@ + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + +