فهرست منبع

Merge branch 'beta' of https://github.com/MediaBrowser/Emby into beta

Luke Pulverenti 9 سال پیش
والد
کامیت
c2e75e99f4

+ 13 - 0
Emby.Drawing/ImageMagick/ImageMagickEncoder.cs

@@ -155,6 +155,7 @@ namespace Emby.Drawing.ImageMagick
                         AutoOrientImage(originalImage);
                     }
 
+                    AddForegroundLayer(originalImage, options);
                     DrawIndicator(originalImage, width, height, options);
 
                     originalImage.CurrentImage.CompressionQuality = quality;
@@ -177,6 +178,8 @@ namespace Emby.Drawing.ImageMagick
                         }
 
                         wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0);
+
+                        AddForegroundLayer(wand, options);
                         DrawIndicator(wand, width, height, options);
 
                         wand.CurrentImage.CompressionQuality = quality;
@@ -189,6 +192,16 @@ namespace Emby.Drawing.ImageMagick
             SaveDelay();
         }
 
+        private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options)
+        {
+            if (string.IsNullOrWhiteSpace(options.ForegroundLayer))
+            {
+                return;
+            }
+            
+            // TODO
+        }
+
         private void AutoOrientImage(MagickWand wand)
         {
             wand.CurrentImage.AutoOrientImage();

+ 7 - 2
Emby.Drawing/ImageProcessor.cs

@@ -234,7 +234,7 @@ namespace Emby.Drawing
             var quality = options.Quality;
 
             var outputFormat = GetOutputFormat(options.SupportedOutputFormats[0]);
-            var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor);
+            var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor, options.ForegroundLayer);
 
             var semaphore = GetLock(cacheFilePath);
 
@@ -473,7 +473,7 @@ namespace Emby.Drawing
         /// <summary>
         /// Gets the cache file path based on a set of parameters
         /// </summary>
-        private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor)
+        private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor, string foregroundLayer)
         {
             var filename = originalPath;
 
@@ -507,6 +507,11 @@ namespace Emby.Drawing
                 filename += "b=" + backgroundColor;
             }
 
+            if (!string.IsNullOrEmpty(foregroundLayer))
+            {
+                filename += "fl=" + foregroundLayer;
+            }
+
             filename += "v=" + Version;
 
             return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());

+ 4 - 1
MediaBrowser.Api/Images/ImageRequest.cs

@@ -66,7 +66,10 @@ namespace MediaBrowser.Api.Images
 
         [ApiMember(Name = "BackgroundColor", Description = "Optional. Apply a background color for transparent images.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
         public string BackgroundColor { get; set; }
-        
+
+        [ApiMember(Name = "ForegroundLayer", Description = "Optional. Apply a foreground layer on top of the image.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public string ForegroundLayer { get; set; }
+
         public ImageRequest()
         {
             EnableImageEnhancers = true;

+ 1 - 0
MediaBrowser.Api/Images/ImageService.cs

@@ -624,6 +624,7 @@ namespace MediaBrowser.Api.Images
                 PercentPlayed = request.PercentPlayed ?? 0,
                 UnplayedCount = request.UnplayedCount,
                 BackgroundColor = request.BackgroundColor,
+                ForegroundLayer = request.ForegroundLayer,
                 SupportedOutputFormats = supportedFormats
             };
 

+ 9 - 5
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -477,7 +477,7 @@ namespace MediaBrowser.Api.Playback
 
             var pts = string.Empty;
 
-            if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream)
+            if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && !state.VideoRequest.CopyTimestamps)
             {
                 var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds;
 
@@ -604,6 +604,10 @@ namespace MediaBrowser.Api.Playback
         {
             var seconds = Math.Round(TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds);
 
+            var setPtsParam = state.VideoRequest.CopyTimestamps
+                ? string.Empty
+                : string.Format(",setpts=PTS -{0}/TB", seconds.ToString(UsCulture));
+
             if (state.SubtitleStream.IsExternal)
             {
                 var subtitlePath = state.SubtitleStream.Path;
@@ -621,18 +625,18 @@ namespace MediaBrowser.Api.Playback
                 }
 
                 // TODO: Perhaps also use original_size=1920x800 ??
-                return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB",
+                return string.Format("subtitles=filename='{0}'{1}{2}",
                     MediaEncoder.EscapeSubtitleFilterPath(subtitlePath),
                     charsetParam,
-                    seconds.ToString(UsCulture));
+                    setPtsParam);
             }
 
             var mediaPath = state.MediaPath ?? string.Empty;
 
-            return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB",
+            return string.Format("subtitles='{0}:si={1}'{2}",
                 MediaEncoder.EscapeSubtitleFilterPath(mediaPath),
                 state.InternalSubtitleStreamOffset.ToString(UsCulture),
-                seconds.ToString(UsCulture));
+                setPtsParam);
         }
 
         /// <summary>

+ 15 - 7
MediaBrowser.Api/Playback/Progressive/VideoService.cs

@@ -65,7 +65,8 @@ namespace MediaBrowser.Api.Playback.Progressive
     /// </summary>
     public class VideoService : BaseProgressiveStreamingService
     {
-        public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, imageProcessor, httpClient)
+        public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient)
+            : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, imageProcessor, httpClient)
         {
         }
 
@@ -137,11 +138,6 @@ namespace MediaBrowser.Api.Playback.Progressive
 
             var isOutputMkv = string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase);
 
-            if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
-            {
-                args += " -copyts -avoid_negative_ts disabled -start_at_zero";
-            }
-            
             if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
             {
                 if (state.VideoStream != null && IsH264(state.VideoStream) &&
@@ -160,10 +156,22 @@ namespace MediaBrowser.Api.Playback.Progressive
 
             var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
 
+            var hasCopyTs = false;
             // Add resolution params, if specified
             if (!hasGraphicalSubs)
             {
-                args += GetOutputSizeParam(state, videoCodec);
+                var outputSizeParam = GetOutputSizeParam(state, videoCodec);
+                args += outputSizeParam;
+                hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
+            }
+
+            if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
+            {
+                if (!hasCopyTs)
+                {
+                    args += " -copyts";
+                }
+                args += " -avoid_negative_ts disabled -start_at_zero";
             }
 
             var qualityParam = GetVideoQualityParam(state, videoCodec);

+ 10 - 14
MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs

@@ -20,7 +20,7 @@ namespace MediaBrowser.Common.Implementations.Networking
             Logger = logger;
         }
 
-		private volatile List<IPAddress> _localIpAddresses;
+		private List<IPAddress> _localIpAddresses;
         private readonly object _localIpAddressSyncLock = new object();
 
         /// <summary>
@@ -29,24 +29,20 @@ namespace MediaBrowser.Common.Implementations.Networking
         /// <returns>IPAddress.</returns>
 		public IEnumerable<IPAddress> GetLocalIpAddresses()
         {
-            const int cacheMinutes = 3;
-            var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
+            const int cacheMinutes = 5;
 
-            if (_localIpAddresses == null || forceRefresh)
+            lock (_localIpAddressSyncLock)
             {
-                lock (_localIpAddressSyncLock)
-                {
-                    forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
+                var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
 
-                    if (_localIpAddresses == null || forceRefresh)
-                    {
-                        var addresses = GetLocalIpAddressesInternal().ToList();
+                if (_localIpAddresses == null || forceRefresh)
+                {
+                    var addresses = GetLocalIpAddressesInternal().ToList();
 
-                        _localIpAddresses = addresses;
-                        _lastRefresh = DateTime.UtcNow;
+                    _localIpAddresses = addresses;
+                    _lastRefresh = DateTime.UtcNow;
 
-                        return addresses;
-                    }
+                    return addresses;
                 }
             }
 

+ 8 - 17
MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs

@@ -103,7 +103,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
             Logger = logger;
             _fileSystem = fileSystem;
 
-            ReloadTriggerEvents(true);
+            InitTriggerEvents();
         }
 
         /// <summary>
@@ -233,11 +233,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
         /// <summary>
         /// The _triggers
         /// </summary>
-        private volatile List<ITaskTrigger> _triggers;
-        /// <summary>
-        /// The _triggers sync lock
-        /// </summary>
-        private readonly object _triggersSyncLock = new object();
+        private List<ITaskTrigger> _triggers;
         /// <summary>
         /// Gets the triggers that define when the task will run
         /// </summary>
@@ -247,17 +243,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
         {
             get
             {
-                if (_triggers == null)
-                {
-                    lock (_triggersSyncLock)
-                    {
-                        if (_triggers == null)
-                        {
-                            _triggers = LoadTriggers();
-                        }
-                    }
-                }
-
                 return _triggers;
             }
             set
@@ -303,6 +288,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
             }
         }
 
+        private void InitTriggerEvents()
+        {
+            _triggers = LoadTriggers();
+            ReloadTriggerEvents(true);
+        }
+
         public void ReloadTriggerEvents()
         {
             ReloadTriggerEvents(false);

+ 3 - 1
MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs

@@ -39,6 +39,7 @@ namespace MediaBrowser.Controller.Drawing
         public double PercentPlayed { get; set; }
 
         public string BackgroundColor { get; set; }
+        public string ForegroundLayer { get; set; }
 
         public bool HasDefaultOptions(string originalImagePath)
         {
@@ -83,7 +84,8 @@ namespace MediaBrowser.Controller.Drawing
                 !AddPlayedIndicator &&
                 PercentPlayed.Equals(0) &&
                 !UnplayedCount.HasValue &&
-                string.IsNullOrEmpty(BackgroundColor);
+                string.IsNullOrEmpty(BackgroundColor) &&
+                string.IsNullOrEmpty(ForegroundLayer);
         }
 
         private bool IsFormatSupported(string originalImagePath)

+ 2 - 0
MediaBrowser.Model/LiveTv/LiveTvOptions.cs

@@ -31,6 +31,7 @@ namespace MediaBrowser.Model.LiveTv
         public string Type { get; set; }
         public bool ImportFavoritesOnly { get; set; }
         public bool IsEnabled { get; set; }
+        public string GuideGroup { get; set; }
 
         public TunerHostInfo()
         {
@@ -48,5 +49,6 @@ namespace MediaBrowser.Model.LiveTv
         public string ZipCode { get; set; }
         public string Country { get; set; }
         public string Path { get; set; }
+        public string GuideGroup { get; set; }
     }
 }

+ 1 - 1
MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs

@@ -135,7 +135,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
             if (previousResult != null)
             {
                 // Don't keep saving the same result over and over if nothing has changed
-                if (previousResult.Status == result.Status && result.Status != FileSortingStatus.Success)
+                if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)
                 {
                     return previousResult;
                 }

+ 13 - 2
MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs

@@ -125,10 +125,21 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
                     validIds.Add(item.Id);
 
+                    var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview);
+                    var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 30;
+
+                    var defaultMetadataRefreshMode = performFullRefresh
+                        ? MetadataRefreshMode.FullRefresh
+                        : MetadataRefreshMode.Default;
+
+                    var imageRefreshMode = performFullRefresh
+                        ? ImageRefreshMode.FullRefresh
+                        : ImageRefreshMode.Default;
+
                     var options = new MetadataRefreshOptions(_fileSystem)
                     {
-                        MetadataRefreshMode = person.Value ? MetadataRefreshMode.Default : MetadataRefreshMode.ValidationOnly,
-                        ImageRefreshMode = person.Value ? ImageRefreshMode.Default : ImageRefreshMode.ValidationOnly
+                        MetadataRefreshMode = person.Value ? defaultMetadataRefreshMode : MetadataRefreshMode.ValidationOnly,
+                        ImageRefreshMode = person.Value ? imageRefreshMode : ImageRefreshMode.ValidationOnly
                     };
 
                     await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false);

+ 5 - 8
MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs

@@ -13,7 +13,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
         where T : class
     {
         private readonly object _fileDataLock = new object();
-        private volatile List<T> _items;
+        private List<T> _items;
         private readonly IJsonSerializer _jsonSerializer;
         protected readonly ILogger Logger;
         private readonly string _dataPath;
@@ -31,17 +31,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
 
         public IReadOnlyList<T> GetAll()
         {
-            if (_items == null)
+            lock (_fileDataLock)
             {
-                lock (_fileDataLock)
+                if (_items == null)
                 {
-                    if (_items == null)
-                    {
-                        _items = GetItemsFromFile(_dataPath);
-                    }
+                    _items = GetItemsFromFile(_dataPath);
                 }
+                return _items;
             }
-            return _items;
         }
 
         private List<T> GetItemsFromFile(string path)

+ 45 - 9
MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj

@@ -466,12 +466,6 @@
     <Content Include="dashboard-ui\components\tvproviders\schedulesdirect.template.html">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
-    <Content Include="dashboard-ui\voice\textprocessor-en-us.js">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="dashboard-ui\voice\voice.css">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
     <Content Include="dashboard-ui\dashboardhosting.html">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
@@ -550,9 +544,6 @@
     <Content Include="dashboard-ui\scripts\userpassword.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
-    <Content Include="dashboard-ui\voice\voice.js">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
     <Content Include="dashboard-ui\scripts\wizardagreement.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
@@ -1402,6 +1393,42 @@
     <Content Include="dashboard-ui\userpassword.html">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+    <Content Include="dashboard-ui\voice\commands\controlcommands.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\commands\disablecommands.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\commands\enablecommands.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\commands\playcommands.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\commands\searchcommands.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\commands\showcommands.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\commands\togglecommands.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\grammarprocessor.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\voicedialog.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\voice.css">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\voice.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\voice\voicecommands.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="dashboard-ui\wizardagreement.html">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
@@ -2232,6 +2259,15 @@
     </None>
     <None Include="dashboard-ui\thirdparty\social-share-kit-1.0.4\LICENSE" />
     <None Include="dashboard-ui\thirdparty\social-share-kit-1.0.4\README.md" />
+    <None Include="dashboard-ui\voice\grammar\en-US.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="dashboard-ui\voice\grammar\grammar.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="dashboard-ui\voice\Readme.md">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
     <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup />

+ 2 - 5
MediaBrowser.sln

@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
+# Visual Studio 14
+VisualStudioVersion = 14.0.24720.0
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E64C-2A6F-4E35-9533-D53AC07C2CD1}"
 EndProject
@@ -521,7 +521,4 @@ Global
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
-	GlobalSection(Performance) = preSolution
-		HasPerformanceSessions = true
-	EndGlobalSection
 EndGlobal