From 0b7d024afd5c539251a1a51b712d9d839771d8e3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 5 Feb 2016 00:59:09 -0500 Subject: [PATCH] support codec intros --- .../Configuration/CinemaModeConfiguration.cs | 2 - .../Intros/DefaultIntroProvider.cs | 142 +++++++++++++++++- 2 files changed, 139 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs b/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs index dd6c77e66d..c4b96ea2ef 100644 --- a/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs +++ b/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" }; } } } diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs index edc329ec42..5b72860b6e 100644 --- a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs +++ b/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> 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(); + var mediaInfoIntros = !string.IsNullOrWhiteSpace(config.MediaInfoIntroPath) ? + GetMediaInfoIntros(config, item) : + new List(); + 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 GetMediaInfoIntros(CinemaModeConfiguration options, BaseItem item) + { + try + { + var hasMediaSources = item as IHasMediaSources; + + if (hasMediaSources == null) + { + return new List(); + } + + var mediaSource = _mediaSourceManager.GetStaticMediaSources(hasMediaSources, false) + .FirstOrDefault(); + + if (mediaSource == null) + { + return new List(); + } + + 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(); + + 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(); + } + } + + private IEnumerable GetMediaInfoIntrosByVideoStream(List allIntros, MediaStream stream) + { + var codec = stream.Codec; + + if (string.IsNullOrWhiteSpace(codec)) + { + return new List(); + } + + return allIntros + .Where(i => IsMatch(i.Path, codec)); + } + + private IEnumerable GetMediaInfoIntrosByAudioStream(List allIntros, MediaStream stream) + { + var codec = stream.Codec; + + if (string.IsNullOrWhiteSpace(codec)) + { + return new List(); + } + + return allIntros + .Where(i => IsAudioMatch(i.Path, stream)); + } + + private IEnumerable GetMediaInfoIntrosByTags(List allIntros, List 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 GetCustomIntroFiles(CinemaModeConfiguration options, bool enableCustomIntros, bool enableMediaInfoIntros) { var list = new List();