|
|
|
@ -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>();
|
|
|
|
|