aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-11-02 16:53:50 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-11-02 16:53:50 -0400
commitd71d2a5d02cf31b67420b54160868247f23546bb (patch)
tree264b96d3ac4ca7cf2040344ffa57e8418b2b5554 /Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
parent8f64a5555b055f42d4c3814725a4e961c2fc980d (diff)
move classes to portable server project
Diffstat (limited to 'Emby.Server.Implementations/Intros/DefaultIntroProvider.cs')
-rw-r--r--Emby.Server.Implementations/Intros/DefaultIntroProvider.cs384
1 files changed, 384 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs b/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
new file mode 100644
index 000000000..180f6aba7
--- /dev/null
+++ b/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
@@ -0,0 +1,384 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Security;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Entities;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.Globalization;
+
+namespace Emby.Server.Implementations.Intros
+{
+ public class DefaultIntroProvider : IIntroProvider
+ {
+ private readonly ISecurityManager _security;
+ private readonly ILocalizationManager _localization;
+ private readonly IConfigurationManager _serverConfig;
+ private readonly ILibraryManager _libraryManager;
+ private readonly IFileSystem _fileSystem;
+ private readonly IMediaSourceManager _mediaSourceManager;
+
+ public DefaultIntroProvider(ISecurityManager security, ILocalizationManager localization, IConfigurationManager serverConfig, ILibraryManager libraryManager, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager)
+ {
+ _security = security;
+ _localization = localization;
+ _serverConfig = serverConfig;
+ _libraryManager = libraryManager;
+ _fileSystem = fileSystem;
+ _mediaSourceManager = mediaSourceManager;
+ }
+
+ public async Task<IEnumerable<IntroInfo>> GetIntros(BaseItem item, User user)
+ {
+ var config = GetOptions();
+
+ if (item is Movie)
+ {
+ if (!config.EnableIntrosForMovies)
+ {
+ return new List<IntroInfo>();
+ }
+ }
+ else if (item is Episode)
+ {
+ if (!config.EnableIntrosForEpisodes)
+ {
+ return new List<IntroInfo>();
+ }
+ }
+ else
+ {
+ return new List<IntroInfo>();
+ }
+
+ var ratingLevel = string.IsNullOrWhiteSpace(item.OfficialRating)
+ ? null
+ : _localization.GetRatingLevel(item.OfficialRating);
+
+ var candidates = new List<ItemWithTrailer>();
+
+ var trailerTypes = new List<TrailerType>();
+ var sourceTypes = new List<SourceType>();
+
+ if (config.EnableIntrosFromMoviesInLibrary)
+ {
+ trailerTypes.Add(TrailerType.LocalTrailer);
+ sourceTypes.Add(SourceType.Library);
+ }
+
+ if (IsSupporter)
+ {
+ if (config.EnableIntrosFromUpcomingTrailers)
+ {
+ trailerTypes.Add(TrailerType.ComingSoonToTheaters);
+ sourceTypes.Clear();
+ }
+ if (config.EnableIntrosFromUpcomingDvdMovies)
+ {
+ trailerTypes.Add(TrailerType.ComingSoonToDvd);
+ sourceTypes.Clear();
+ }
+ if (config.EnableIntrosFromUpcomingStreamingMovies)
+ {
+ trailerTypes.Add(TrailerType.ComingSoonToStreaming);
+ sourceTypes.Clear();
+ }
+ if (config.EnableIntrosFromSimilarMovies)
+ {
+ trailerTypes.Add(TrailerType.Archive);
+ sourceTypes.Clear();
+ }
+ }
+
+ if (trailerTypes.Count > 0)
+ {
+ var trailerResult = _libraryManager.GetItemList(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(Trailer).Name },
+ TrailerTypes = trailerTypes.ToArray(),
+ SimilarTo = item,
+ IsPlayed = config.EnableIntrosForWatchedContent ? (bool?)null : false,
+ MaxParentalRating = config.EnableIntrosParentalControl ? ratingLevel : null,
+ BlockUnratedItems = config.EnableIntrosParentalControl ? new[] { UnratedItem.Trailer } : new UnratedItem[] { },
+
+ // Account for duplicates by imdb id, since the database doesn't support this yet
+ Limit = config.TrailerLimit * 2,
+ SourceTypes = sourceTypes.ToArray()
+
+ }).Where(i => string.IsNullOrWhiteSpace(i.GetProviderId(MetadataProviders.Imdb)) || !string.Equals(i.GetProviderId(MetadataProviders.Imdb), item.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)).Take(config.TrailerLimit);
+
+ candidates.AddRange(trailerResult.Select(i => new ItemWithTrailer
+ {
+ Item = i,
+ Type = i.SourceType == SourceType.Channel ? ItemWithTrailerType.ChannelTrailer : ItemWithTrailerType.ItemWithTrailer,
+ LibraryManager = _libraryManager
+ }));
+ }
+
+ return GetResult(item, candidates, config);
+ }
+
+ private IEnumerable<IntroInfo> GetResult(BaseItem item, IEnumerable<ItemWithTrailer> candidates, CinemaModeConfiguration config)
+ {
+ var customIntros = !string.IsNullOrWhiteSpace(config.CustomIntroPath) ?
+ GetCustomIntros(config) :
+ new List<IntroInfo>();
+
+ var mediaInfoIntros = !string.IsNullOrWhiteSpace(config.MediaInfoIntroPath) ?
+ GetMediaInfoIntros(config, item) :
+ new List<IntroInfo>();
+
+ // Avoid implicitly captured closure
+ return candidates.Select(i => i.IntroInfo)
+ .Concat(customIntros.Take(1))
+ .Concat(mediaInfoIntros);
+ }
+
+ private CinemaModeConfiguration GetOptions()
+ {
+ return _serverConfig.GetConfiguration<CinemaModeConfiguration>("cinemamode");
+ }
+
+ private List<IntroInfo> GetCustomIntros(CinemaModeConfiguration options)
+ {
+ try
+ {
+ return GetCustomIntroFiles(options, true, false)
+ .OrderBy(i => Guid.NewGuid())
+ .Select(i => new IntroInfo
+ {
+ Path = i
+
+ }).ToList();
+ }
+ catch (IOException)
+ {
+ return new List<IntroInfo>();
+ }
+ }
+
+ 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))
+ .OrderBy(i => Guid.NewGuid());
+ }
+
+ 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))
+ .OrderBy(i => Guid.NewGuid());
+ }
+
+ private IEnumerable<IntroInfo> GetMediaInfoIntrosByTags(List<IntroInfo> allIntros, List<string> tags)
+ {
+ return allIntros
+ .Where(i => tags.Any(t => IsMatch(i.Path, t)))
+ .OrderBy(i => Guid.NewGuid());
+ }
+
+ 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>();
+
+ if (enableCustomIntros && !string.IsNullOrWhiteSpace(options.CustomIntroPath))
+ {
+ list.AddRange(_fileSystem.GetFilePaths(options.CustomIntroPath, true)
+ .Where(_libraryManager.IsVideoFile));
+ }
+
+ if (enableMediaInfoIntros && !string.IsNullOrWhiteSpace(options.MediaInfoIntroPath))
+ {
+ list.AddRange(_fileSystem.GetFilePaths(options.MediaInfoIntroPath, true)
+ .Where(_libraryManager.IsVideoFile));
+ }
+
+ return list.Distinct(StringComparer.OrdinalIgnoreCase);
+ }
+
+ public IEnumerable<string> GetAllIntroFiles()
+ {
+ return GetCustomIntroFiles(GetOptions(), true, true);
+ }
+
+ private bool IsSupporter
+ {
+ get { return _security.IsMBSupporter; }
+ }
+
+ public string Name
+ {
+ get { return "Default"; }
+ }
+
+ internal class ItemWithTrailer
+ {
+ internal BaseItem Item;
+ internal ItemWithTrailerType Type;
+ internal ILibraryManager LibraryManager;
+
+ public IntroInfo IntroInfo
+ {
+ get
+ {
+ var id = Item.Id;
+
+ if (Type == ItemWithTrailerType.ItemWithTrailer)
+ {
+ var hasTrailers = Item as IHasTrailers;
+
+ if (hasTrailers != null)
+ {
+ id = hasTrailers.LocalTrailerIds.FirstOrDefault();
+ }
+ }
+ return new IntroInfo
+ {
+ ItemId = id
+ };
+ }
+ }
+ }
+
+ internal enum ItemWithTrailerType
+ {
+ ChannelTrailer,
+ ItemWithTrailer
+ }
+ }
+
+ public class CinemaModeConfigurationFactory : IConfigurationFactory
+ {
+ public IEnumerable<ConfigurationStore> GetConfigurations()
+ {
+ return new[]
+ {
+ new ConfigurationStore
+ {
+ ConfigurationType = typeof(CinemaModeConfiguration),
+ Key = "cinemamode"
+ }
+ };
+ }
+ }
+
+}