浏览代码

support codec intros

Luke Pulverenti 9 年之前
父节点
当前提交
0b7d024afd

+ 0 - 2
MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs

@@ -16,14 +16,12 @@ namespace MediaBrowser.Model.Configuration
         public bool EnableIntrosFromUpcomingStreamingMovies { get; set; }
 
         public int TrailerLimit { get; set; }
-        public string[] Tags { get; set; }
         
         public CinemaModeConfiguration()
         {
             EnableIntrosParentalControl = true;
             EnableIntrosFromSimilarMovies = true;
             TrailerLimit = 2;
-            Tags = new[] { "thx" };
         }
     }
 }

+ 139 - 3
MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs

@@ -17,6 +17,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
 using MediaBrowser.Common.IO;
+using MoreLinq;
 
 namespace MediaBrowser.Server.Implementations.Intros
 {
@@ -28,8 +29,9 @@ namespace MediaBrowser.Server.Implementations.Intros
         private readonly IConfigurationManager _serverConfig;
         private readonly ILibraryManager _libraryManager;
         private readonly IFileSystem _fileSystem;
+        private readonly IMediaSourceManager _mediaSourceManager;
 
-        public DefaultIntroProvider(ISecurityManager security, IChannelManager channelManager, ILocalizationManager localization, IConfigurationManager serverConfig, ILibraryManager libraryManager, IFileSystem fileSystem)
+        public DefaultIntroProvider(ISecurityManager security, IChannelManager channelManager, ILocalizationManager localization, IConfigurationManager serverConfig, ILibraryManager libraryManager, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager)
         {
             _security = security;
             _channelManager = channelManager;
@@ -37,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Intros
             _serverConfig = serverConfig;
             _libraryManager = libraryManager;
             _fileSystem = fileSystem;
+            _mediaSourceManager = mediaSourceManager;
         }
 
         public async Task<IEnumerable<IntroInfo>> GetIntros(BaseItem item, User user)
@@ -82,7 +85,7 @@ namespace MediaBrowser.Server.Implementations.Intros
                 {
                     IncludeItemTypes = new[] { typeof(Movie).Name }
 
-                }, new string[]{});
+                }, new string[] { });
 
                 var itemsWithTrailers = inputItems
                     .Where(i =>
@@ -164,6 +167,10 @@ namespace MediaBrowser.Server.Implementations.Intros
                 GetCustomIntros(config) :
                 new List<IntroInfo>();
 
+            var mediaInfoIntros = !string.IsNullOrWhiteSpace(config.MediaInfoIntroPath) ?
+                GetMediaInfoIntros(config, item) :
+                new List<IntroInfo>();
+
             var trailerLimit = config.TrailerLimit;
 
             // Avoid implicitly captured closure
@@ -185,7 +192,8 @@ namespace MediaBrowser.Server.Implementations.Intros
                 .ThenByDescending(i => (i.IsPlayed ? 0 : 1))
                 .Select(i => i.IntroInfo)
                 .Take(trailerLimit)
-                .Concat(customIntros.Take(1));
+                .Concat(customIntros.Take(1))
+                .Concat(mediaInfoIntros);
         }
 
         private bool IsDuplicate(BaseItem playingContent, BaseItem test)
@@ -228,6 +236,134 @@ namespace MediaBrowser.Server.Implementations.Intros
             }
         }
 
+        private IEnumerable<IntroInfo> GetMediaInfoIntros(CinemaModeConfiguration options, BaseItem item)
+        {
+            try
+            {
+                var hasMediaSources = item as IHasMediaSources;
+
+                if (hasMediaSources == null)
+                {
+                    return new List<IntroInfo>();
+                }
+
+                var mediaSource = _mediaSourceManager.GetStaticMediaSources(hasMediaSources, false)
+                    .FirstOrDefault();
+
+                if (mediaSource == null)
+                {
+                    return new List<IntroInfo>();
+                }
+
+                var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
+                var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
+
+                var allIntros = GetCustomIntroFiles(options, false, true)
+                    .OrderBy(i => Guid.NewGuid())
+                    .Select(i => new IntroInfo
+                    {
+                        Path = i
+
+                    }).ToList();
+
+                var returnResult = new List<IntroInfo>();
+
+                if (videoStream != null)
+                {
+                    returnResult.AddRange(GetMediaInfoIntrosByVideoStream(allIntros, videoStream).Take(1));
+                }
+
+                if (audioStream != null)
+                {
+                    returnResult.AddRange(GetMediaInfoIntrosByAudioStream(allIntros, audioStream).Take(1));
+                }
+
+                returnResult.AddRange(GetMediaInfoIntrosByTags(allIntros, item.Tags).Take(1));
+                
+                return returnResult.DistinctBy(i => i.Path, StringComparer.OrdinalIgnoreCase);
+            }
+            catch (IOException)
+            {
+                return new List<IntroInfo>();
+            }
+        }
+
+        private IEnumerable<IntroInfo> GetMediaInfoIntrosByVideoStream(List<IntroInfo> allIntros, MediaStream stream)
+        {
+            var codec = stream.Codec;
+
+            if (string.IsNullOrWhiteSpace(codec))
+            {
+                return new List<IntroInfo>();
+            }
+
+            return allIntros
+                .Where(i => IsMatch(i.Path, codec));
+        }
+
+        private IEnumerable<IntroInfo> GetMediaInfoIntrosByAudioStream(List<IntroInfo> allIntros, MediaStream stream)
+        {
+            var codec = stream.Codec;
+
+            if (string.IsNullOrWhiteSpace(codec))
+            {
+                return new List<IntroInfo>();
+            }
+
+            return allIntros
+                .Where(i => IsAudioMatch(i.Path, stream));
+        }
+
+        private IEnumerable<IntroInfo> GetMediaInfoIntrosByTags(List<IntroInfo> allIntros, List<string> tags)
+        {
+            return allIntros
+                .Where(i => tags.Any(t => IsMatch(i.Path, t)));
+        }
+
+        private bool IsMatch(string file, string attribute)
+        {
+            var filename = Path.GetFileNameWithoutExtension(file) ?? string.Empty;
+            filename = Normalize(filename);
+
+            if (string.IsNullOrWhiteSpace(filename))
+            {
+                return false;
+            }
+
+            attribute = Normalize(attribute);
+            if (string.IsNullOrWhiteSpace(attribute))
+            {
+                return false;
+            }
+
+            return string.Equals(filename, attribute, StringComparison.OrdinalIgnoreCase);
+        }
+
+        private string Normalize(string value)
+        {
+            return value;
+        }
+
+        private bool IsAudioMatch(string path, MediaStream stream)
+        {
+            if (!string.IsNullOrWhiteSpace(stream.Codec))
+            {
+                if (IsMatch(path, stream.Codec))
+                {
+                    return true;
+                }
+            }
+            if (!string.IsNullOrWhiteSpace(stream.Profile))
+            {
+                if (IsMatch(path, stream.Profile))
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
         private IEnumerable<string> GetCustomIntroFiles(CinemaModeConfiguration options, bool enableCustomIntros, bool enableMediaInfoIntros)
         {
             var list = new List<string>();