jellyfin/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs

251 lines
9.0 KiB
C#
Raw Normal View History

using System;
2019-01-26 14:31:59 -07:00
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Channels;
2014-06-09 12:16:14 -07:00
using MediaBrowser.Controller.Chapters;
2014-05-06 19:28:19 -07:00
using MediaBrowser.Controller.Configuration;
2014-02-09 14:11:11 -07:00
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
2014-02-20 09:37:41 -07:00
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
2014-05-06 19:28:19 -07:00
using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
2014-02-10 11:39:41 -07:00
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Providers.MediaInfo
{
public class FFProbeProvider : ICustomMetadataProvider<Episode>,
ICustomMetadataProvider<MusicVideo>,
ICustomMetadataProvider<Movie>,
2016-05-07 14:01:21 -07:00
ICustomMetadataProvider<Trailer>,
ICustomMetadataProvider<Video>,
ICustomMetadataProvider<Audio>,
2017-01-07 13:52:56 -07:00
ICustomMetadataProvider<AudioBook>,
2014-02-18 22:21:03 -07:00
IHasOrder,
2015-03-04 23:34:36 -07:00
IForcedProvider,
2018-09-12 10:26:21 -07:00
IPreRefreshProvider,
IHasItemChangeMonitor
{
2020-06-05 17:15:56 -07:00
private readonly ILogger<FFProbeProvider> _logger;
private readonly IIsoManager _isoManager;
private readonly IMediaEncoder _mediaEncoder;
private readonly IItemRepository _itemRepo;
private readonly IBlurayExaminer _blurayExaminer;
private readonly ILocalizationManager _localization;
2014-02-09 14:11:11 -07:00
private readonly IApplicationPaths _appPaths;
private readonly IJsonSerializer _json;
2014-02-20 09:37:41 -07:00
private readonly IEncodingManager _encodingManager;
2014-05-06 19:28:19 -07:00
private readonly IServerConfigurationManager _config;
private readonly ISubtitleManager _subtitleManager;
2014-06-09 12:16:14 -07:00
private readonly IChapterManager _chapterManager;
2015-06-28 18:10:45 -07:00
private readonly ILibraryManager _libraryManager;
2018-09-12 10:26:21 -07:00
private readonly IChannelManager _channelManager;
private readonly IMediaSourceManager _mediaSourceManager;
public string Name => "ffprobe";
2018-09-12 10:26:21 -07:00
public bool HasChanged(BaseItem item, IDirectoryService directoryService)
{
2018-09-12 10:26:21 -07:00
var video = item as Video;
if (video == null || video.VideoType == VideoType.VideoFile || video.VideoType == VideoType.Iso)
{
var path = item.Path;
if (!string.IsNullOrWhiteSpace(path) && item.IsFileProtocol)
{
var file = directoryService.GetFile(path);
if (file != null && file.LastWriteTimeUtc != item.DateModified)
{
_logger.LogDebug("Refreshing {0} due to date modified timestamp change.", path);
2018-09-12 10:26:21 -07:00
return true;
}
}
}
if (item.SupportsLocalMetadata && video != null && !video.IsPlaceHolder
&& !video.SubtitleFiles.SequenceEqual(
_subtitleResolver.GetExternalSubtitleFiles(video, directoryService, false), StringComparer.Ordinal))
2018-09-12 10:26:21 -07:00
{
_logger.LogDebug("Refreshing {0} due to external subtitles change.", item.Path);
return true;
2018-09-12 10:26:21 -07:00
}
return false;
}
2018-09-12 10:26:21 -07:00
public Task<ItemUpdateType> FetchAsync(Episode item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
2014-06-09 12:16:14 -07:00
return FetchVideoInfo(item, options, cancellationToken);
}
2018-09-12 10:26:21 -07:00
public Task<ItemUpdateType> FetchAsync(MusicVideo item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
2014-06-09 12:16:14 -07:00
return FetchVideoInfo(item, options, cancellationToken);
}
2018-09-12 10:26:21 -07:00
public Task<ItemUpdateType> FetchAsync(Movie item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
2014-06-09 12:16:14 -07:00
return FetchVideoInfo(item, options, cancellationToken);
}
2016-05-07 14:01:21 -07:00
public Task<ItemUpdateType> FetchAsync(Trailer item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
return FetchVideoInfo(item, options, cancellationToken);
}
2014-06-09 12:16:14 -07:00
public Task<ItemUpdateType> FetchAsync(Video item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
2014-06-09 12:16:14 -07:00
return FetchVideoInfo(item, options, cancellationToken);
}
2014-06-09 12:16:14 -07:00
public Task<ItemUpdateType> FetchAsync(Audio item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
2018-09-12 10:26:21 -07:00
return FetchAudioInfo(item, options, cancellationToken);
2017-01-07 13:52:56 -07:00
}
public Task<ItemUpdateType> FetchAsync(AudioBook item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
2018-09-12 10:26:21 -07:00
return FetchAudioInfo(item, options, cancellationToken);
}
2018-09-12 10:26:21 -07:00
private SubtitleResolver _subtitleResolver;
public FFProbeProvider(
ILogger<FFProbeProvider> logger,
IMediaSourceManager mediaSourceManager,
IChannelManager channelManager,
IIsoManager isoManager,
IMediaEncoder mediaEncoder,
IItemRepository itemRepo,
IBlurayExaminer blurayExaminer,
ILocalizationManager localization,
IApplicationPaths appPaths,
IJsonSerializer json,
IEncodingManager encodingManager,
IServerConfigurationManager config,
ISubtitleManager subtitleManager,
IChapterManager chapterManager,
ILibraryManager libraryManager)
{
_logger = logger;
_isoManager = isoManager;
_mediaEncoder = mediaEncoder;
_itemRepo = itemRepo;
_blurayExaminer = blurayExaminer;
_localization = localization;
2014-02-09 14:11:11 -07:00
_appPaths = appPaths;
_json = json;
2014-02-22 23:14:48 -07:00
_encodingManager = encodingManager;
2014-05-06 19:28:19 -07:00
_config = config;
_subtitleManager = subtitleManager;
2014-06-09 12:16:14 -07:00
_chapterManager = chapterManager;
2015-06-28 18:10:45 -07:00
_libraryManager = libraryManager;
2018-09-12 10:26:21 -07:00
_channelManager = channelManager;
_mediaSourceManager = mediaSourceManager;
_subtitleResolver = new SubtitleResolver(BaseItem.LocalizationManager);
}
2014-02-10 11:39:41 -07:00
private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.None);
2014-06-09 12:16:14 -07:00
public Task<ItemUpdateType> FetchVideoInfo<T>(T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
where T : Video
{
2018-09-12 10:26:21 -07:00
if (item.VideoType == VideoType.Iso)
{
return _cachedTask;
}
2018-09-12 10:26:21 -07:00
if (item.IsPlaceHolder)
{
return _cachedTask;
}
2018-09-12 10:26:21 -07:00
if (!item.IsCompleteMedia)
{
return _cachedTask;
}
2018-09-12 10:26:21 -07:00
if (item.IsVirtualItem)
{
return _cachedTask;
}
if (!options.EnableRemoteContentProbe && !item.IsFileProtocol)
2017-09-18 09:52:22 -07:00
{
return _cachedTask;
}
if (item.IsShortcut)
{
FetchShortcutInfo(item);
}
2015-06-28 18:10:45 -07:00
2020-02-23 02:53:51 -07:00
var prober = new FFProbeVideoInfo(
_logger,
_mediaSourceManager,
_mediaEncoder,
_itemRepo,
_blurayExaminer,
_localization,
_encodingManager,
_config,
_subtitleManager,
_chapterManager,
_libraryManager);
2014-06-09 12:16:14 -07:00
return prober.ProbeVideo(item, options, cancellationToken);
}
2018-09-12 10:26:21 -07:00
private string NormalizeStrmLine(string line)
{
2018-09-12 10:26:21 -07:00
return line.Replace("\t", string.Empty)
2017-11-01 12:50:16 -07:00
.Replace("\r", string.Empty)
.Replace("\n", string.Empty)
.Trim();
}
2018-09-12 10:26:21 -07:00
private void FetchShortcutInfo(BaseItem item)
{
2019-01-26 14:31:59 -07:00
item.ShortcutPath = File.ReadAllLines(item.Path)
2018-09-12 10:26:21 -07:00
.Select(NormalizeStrmLine)
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i) && !i.StartsWith("#", StringComparison.OrdinalIgnoreCase));
}
public Task<ItemUpdateType> FetchAudioInfo<T>(T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
where T : Audio
{
2018-09-12 10:26:21 -07:00
if (item.IsVirtualItem)
{
return _cachedTask;
}
if (!options.EnableRemoteContentProbe && !item.IsFileProtocol)
{
return _cachedTask;
}
2018-09-12 10:26:21 -07:00
if (item.IsShortcut)
{
FetchShortcutInfo(item);
}
var prober = new FFProbeAudioInfo(_mediaSourceManager, _mediaEncoder, _itemRepo, _appPaths, _json, _libraryManager);
2018-09-12 10:26:21 -07:00
return prober.Probe(item, options, cancellationToken);
}
// Run last
public int Order => 100;
}
}