< Summary - Jellyfin

Information
Class: MediaBrowser.Providers.MediaInfo.ProbeProvider
Assembly: MediaBrowser.Providers
File(s): /srv/git/jellyfin/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs
Line coverage
31%
Covered lines: 28
Uncovered lines: 61
Coverable lines: 89
Total lines: 299
Line coverage: 31.4%
Branch coverage
0%
Covered branches: 0
Total branches: 50
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Name()100%210%
get_Order()100%210%
HasChanged(...)0%930300%
FetchAsync(...)100%210%
FetchAsync(...)100%210%
FetchAsync(...)100%210%
FetchAsync(...)100%210%
FetchAsync(...)100%210%
FetchAsync(...)100%210%
FetchAsync(...)100%210%
FetchVideoInfo(...)0%156120%
NormalizeStrmLine(...)100%210%
FetchShortcutInfo(...)100%210%
FetchAudioInfo(...)0%7280%

File(s)

/srv/git/jellyfin/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs

#LineLine coverage
 1#nullable disable
 2
 3using System;
 4using System.Collections.Generic;
 5using System.IO;
 6using System.Linq;
 7using System.Threading;
 8using System.Threading.Tasks;
 9using Emby.Naming.Common;
 10using MediaBrowser.Controller.Chapters;
 11using MediaBrowser.Controller.Configuration;
 12using MediaBrowser.Controller.Entities;
 13using MediaBrowser.Controller.Entities.Audio;
 14using MediaBrowser.Controller.Entities.Movies;
 15using MediaBrowser.Controller.Entities.TV;
 16using MediaBrowser.Controller.Library;
 17using MediaBrowser.Controller.Lyrics;
 18using MediaBrowser.Controller.MediaEncoding;
 19using MediaBrowser.Controller.Persistence;
 20using MediaBrowser.Controller.Providers;
 21using MediaBrowser.Controller.Subtitles;
 22using MediaBrowser.Model.Entities;
 23using MediaBrowser.Model.Globalization;
 24using MediaBrowser.Model.IO;
 25using MediaBrowser.Model.MediaInfo;
 26using Microsoft.Extensions.Logging;
 27
 28namespace MediaBrowser.Providers.MediaInfo
 29{
 30    /// <summary>
 31    /// The probe provider.
 32    /// </summary>
 33    public class ProbeProvider : ICustomMetadataProvider<Episode>,
 34        ICustomMetadataProvider<MusicVideo>,
 35        ICustomMetadataProvider<Movie>,
 36        ICustomMetadataProvider<Trailer>,
 37        ICustomMetadataProvider<Video>,
 38        ICustomMetadataProvider<Audio>,
 39        ICustomMetadataProvider<AudioBook>,
 40        IHasOrder,
 41        IForcedProvider,
 42        IPreRefreshProvider,
 43        IHasItemChangeMonitor
 44    {
 45        private readonly ILogger<ProbeProvider> _logger;
 46        private readonly AudioResolver _audioResolver;
 47        private readonly SubtitleResolver _subtitleResolver;
 48        private readonly LyricResolver _lyricResolver;
 49        private readonly FFProbeVideoInfo _videoProber;
 50        private readonly AudioFileProber _audioProber;
 2251        private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.None);
 52
 53        /// <summary>
 54        /// Initializes a new instance of the <see cref="ProbeProvider"/> class.
 55        /// </summary>
 56        /// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
 57        /// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
 58        /// <param name="itemRepo">Instance of the <see cref="IItemRepository"/> interface.</param>
 59        /// <param name="blurayExaminer">Instance of the <see cref="IBlurayExaminer"/> interface.</param>
 60        /// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
 61        /// <param name="encodingManager">Instance of the <see cref="IEncodingManager"/> interface.</param>
 62        /// <param name="config">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
 63        /// <param name="subtitleManager">Instance of the <see cref="ISubtitleManager"/> interface.</param>
 64        /// <param name="chapterManager">Instance of the <see cref="IChapterManager"/> interface.</param>
 65        /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
 66        /// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/>.</param>
 67        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 68        /// <param name="namingOptions">The <see cref="NamingOptions"/>.</param>
 69        /// <param name="lyricManager">Instance of the <see cref="ILyricManager"/> interface.</param>
 70        public ProbeProvider(
 71            IMediaSourceManager mediaSourceManager,
 72            IMediaEncoder mediaEncoder,
 73            IItemRepository itemRepo,
 74            IBlurayExaminer blurayExaminer,
 75            ILocalizationManager localization,
 76            IEncodingManager encodingManager,
 77            IServerConfigurationManager config,
 78            ISubtitleManager subtitleManager,
 79            IChapterManager chapterManager,
 80            ILibraryManager libraryManager,
 81            IFileSystem fileSystem,
 82            ILoggerFactory loggerFactory,
 83            NamingOptions namingOptions,
 84            ILyricManager lyricManager)
 85        {
 2286            _logger = loggerFactory.CreateLogger<ProbeProvider>();
 2287            _audioResolver = new AudioResolver(loggerFactory.CreateLogger<AudioResolver>(), localization, mediaEncoder, 
 2288            _subtitleResolver = new SubtitleResolver(loggerFactory.CreateLogger<SubtitleResolver>(), localization, media
 2289            _lyricResolver = new LyricResolver(loggerFactory.CreateLogger<LyricResolver>(), localization, mediaEncoder, 
 90
 2291            _videoProber = new FFProbeVideoInfo(
 2292                loggerFactory.CreateLogger<FFProbeVideoInfo>(),
 2293                mediaSourceManager,
 2294                mediaEncoder,
 2295                itemRepo,
 2296                blurayExaminer,
 2297                localization,
 2298                encodingManager,
 2299                config,
 22100                subtitleManager,
 22101                chapterManager,
 22102                libraryManager,
 22103                _audioResolver,
 22104                _subtitleResolver);
 105
 22106            _audioProber = new AudioFileProber(
 22107                loggerFactory.CreateLogger<AudioFileProber>(),
 22108                mediaSourceManager,
 22109                mediaEncoder,
 22110                itemRepo,
 22111                libraryManager,
 22112                _lyricResolver,
 22113                lyricManager);
 22114        }
 115
 116        /// <inheritdoc />
 0117        public string Name => "Probe Provider";
 118
 119        /// <inheritdoc />
 0120        public int Order => 100;
 121
 122        /// <inheritdoc />
 123        public bool HasChanged(BaseItem item, IDirectoryService directoryService)
 124        {
 0125            var video = item as Video;
 0126            if (video is null || video.VideoType == VideoType.VideoFile || video.VideoType == VideoType.Iso)
 127            {
 0128                var path = item.Path;
 129
 0130                if (!string.IsNullOrWhiteSpace(path) && item.IsFileProtocol)
 131                {
 0132                    var file = directoryService.GetFile(path);
 0133                    if (file is not null && file.LastWriteTimeUtc != item.DateModified)
 134                    {
 0135                        _logger.LogDebug("Refreshing {ItemPath} due to date modified timestamp change.", path);
 0136                        return true;
 137                    }
 138                }
 139            }
 140
 0141            if (video is not null
 0142                && item.SupportsLocalMetadata
 0143                && !video.IsPlaceHolder)
 144            {
 0145                var externalFiles = new HashSet<string>(_subtitleResolver.GetExternalFiles(video, directoryService, fals
 0146                if (!new HashSet<string>(video.SubtitleFiles, StringComparer.Ordinal).SetEquals(externalFiles))
 147                {
 0148                    _logger.LogDebug("Refreshing {ItemPath} due to external subtitles change.", item.Path);
 0149                    return true;
 150                }
 151
 0152                externalFiles = new HashSet<string>(_audioResolver.GetExternalFiles(video, directoryService, false).Sele
 0153                if (!new HashSet<string>(video.AudioFiles, StringComparer.Ordinal).SetEquals(externalFiles))
 154                {
 0155                    _logger.LogDebug("Refreshing {ItemPath} due to external audio change.", item.Path);
 0156                    return true;
 157                }
 158            }
 159
 0160            if (item is Audio audio
 0161                && item.SupportsLocalMetadata)
 162            {
 0163                var externalFiles = new HashSet<string>(_lyricResolver.GetExternalFiles(audio, directoryService, false).
 0164                if (!new HashSet<string>(audio.LyricFiles, StringComparer.Ordinal).SetEquals(externalFiles))
 165                {
 0166                    _logger.LogDebug("Refreshing {ItemPath} due to external lyrics change.", item.Path);
 0167                    return true;
 168                }
 169            }
 170
 0171            return false;
 172        }
 173
 174        /// <inheritdoc />
 175        public Task<ItemUpdateType> FetchAsync(Episode item, MetadataRefreshOptions options, CancellationToken cancellat
 176        {
 0177            return FetchVideoInfo(item, options, cancellationToken);
 178        }
 179
 180        /// <inheritdoc />
 181        public Task<ItemUpdateType> FetchAsync(MusicVideo item, MetadataRefreshOptions options, CancellationToken cancel
 182        {
 0183            return FetchVideoInfo(item, options, cancellationToken);
 184        }
 185
 186        /// <inheritdoc />
 187        public Task<ItemUpdateType> FetchAsync(Movie item, MetadataRefreshOptions options, CancellationToken cancellatio
 188        {
 0189            return FetchVideoInfo(item, options, cancellationToken);
 190        }
 191
 192        /// <inheritdoc />
 193        public Task<ItemUpdateType> FetchAsync(Trailer item, MetadataRefreshOptions options, CancellationToken cancellat
 194        {
 0195            return FetchVideoInfo(item, options, cancellationToken);
 196        }
 197
 198        /// <inheritdoc />
 199        public Task<ItemUpdateType> FetchAsync(Video item, MetadataRefreshOptions options, CancellationToken cancellatio
 200        {
 0201            return FetchVideoInfo(item, options, cancellationToken);
 202        }
 203
 204        /// <inheritdoc />
 205        public Task<ItemUpdateType> FetchAsync(Audio item, MetadataRefreshOptions options, CancellationToken cancellatio
 206        {
 0207            return FetchAudioInfo(item, options, cancellationToken);
 208        }
 209
 210        /// <inheritdoc />
 211        public Task<ItemUpdateType> FetchAsync(AudioBook item, MetadataRefreshOptions options, CancellationToken cancell
 212        {
 0213            return FetchAudioInfo(item, options, cancellationToken);
 214        }
 215
 216        /// <summary>
 217        /// Fetches video information for an item.
 218        /// </summary>
 219        /// <param name="item">The item.</param>
 220        /// <param name="options">The <see cref="MetadataRefreshOptions"/>.</param>
 221        /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
 222        /// <typeparam name="T">The type of item to resolve.</typeparam>
 223        /// <returns>A <see cref="Task"/> fetching the <see cref="ItemUpdateType"/> for an item.</returns>
 224        public Task<ItemUpdateType> FetchVideoInfo<T>(T item, MetadataRefreshOptions options, CancellationToken cancella
 225            where T : Video
 226        {
 0227            if (item.IsPlaceHolder)
 228            {
 0229                return _cachedTask;
 230            }
 231
 0232            if (!item.IsCompleteMedia)
 233            {
 0234                return _cachedTask;
 235            }
 236
 0237            if (item.IsVirtualItem)
 238            {
 0239                return _cachedTask;
 240            }
 241
 0242            if (!options.EnableRemoteContentProbe && !item.IsFileProtocol)
 243            {
 0244                return _cachedTask;
 245            }
 246
 0247            if (item.IsShortcut)
 248            {
 0249                FetchShortcutInfo(item);
 250            }
 251
 0252            return _videoProber.ProbeVideo(item, options, cancellationToken);
 253        }
 254
 255        private string NormalizeStrmLine(string line)
 256        {
 0257            return line.Replace("\t", string.Empty, StringComparison.Ordinal)
 0258                .Replace("\r", string.Empty, StringComparison.Ordinal)
 0259                .Replace("\n", string.Empty, StringComparison.Ordinal)
 0260                .Trim();
 261        }
 262
 263        private void FetchShortcutInfo(BaseItem item)
 264        {
 0265            item.ShortcutPath = File.ReadAllLines(item.Path)
 0266                .Select(NormalizeStrmLine)
 0267                .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i) && !i.StartsWith('#'));
 0268        }
 269
 270        /// <summary>
 271        /// Fetches audio information for an item.
 272        /// </summary>
 273        /// <param name="item">The item.</param>
 274        /// <param name="options">The <see cref="MetadataRefreshOptions"/>.</param>
 275        /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
 276        /// <typeparam name="T">The type of item to resolve.</typeparam>
 277        /// <returns>A <see cref="Task"/> fetching the <see cref="ItemUpdateType"/> for an item.</returns>
 278        public Task<ItemUpdateType> FetchAudioInfo<T>(T item, MetadataRefreshOptions options, CancellationToken cancella
 279            where T : Audio
 280        {
 0281            if (item.IsVirtualItem)
 282            {
 0283                return _cachedTask;
 284            }
 285
 0286            if (!options.EnableRemoteContentProbe && !item.IsFileProtocol)
 287            {
 0288                return _cachedTask;
 289            }
 290
 0291            if (item.IsShortcut)
 292            {
 0293                FetchShortcutInfo(item);
 294            }
 295
 0296            return _audioProber.Probe(item, options, cancellationToken);
 297        }
 298    }
 299}

Methods/Properties

.ctor(MediaBrowser.Controller.Library.IMediaSourceManager,MediaBrowser.Controller.MediaEncoding.IMediaEncoder,MediaBrowser.Controller.Persistence.IItemRepository,MediaBrowser.Model.MediaInfo.IBlurayExaminer,MediaBrowser.Model.Globalization.ILocalizationManager,MediaBrowser.Controller.MediaEncoding.IEncodingManager,MediaBrowser.Controller.Configuration.IServerConfigurationManager,MediaBrowser.Controller.Subtitles.ISubtitleManager,MediaBrowser.Controller.Chapters.IChapterManager,MediaBrowser.Controller.Library.ILibraryManager,MediaBrowser.Model.IO.IFileSystem,Microsoft.Extensions.Logging.ILoggerFactory,Emby.Naming.Common.NamingOptions,MediaBrowser.Controller.Lyrics.ILyricManager)
get_Name()
get_Order()
HasChanged(MediaBrowser.Controller.Entities.BaseItem,MediaBrowser.Controller.Providers.IDirectoryService)
FetchAsync(MediaBrowser.Controller.Entities.TV.Episode,MediaBrowser.Controller.Providers.MetadataRefreshOptions,System.Threading.CancellationToken)
FetchAsync(MediaBrowser.Controller.Entities.MusicVideo,MediaBrowser.Controller.Providers.MetadataRefreshOptions,System.Threading.CancellationToken)
FetchAsync(MediaBrowser.Controller.Entities.Movies.Movie,MediaBrowser.Controller.Providers.MetadataRefreshOptions,System.Threading.CancellationToken)
FetchAsync(MediaBrowser.Controller.Entities.Trailer,MediaBrowser.Controller.Providers.MetadataRefreshOptions,System.Threading.CancellationToken)
FetchAsync(MediaBrowser.Controller.Entities.Video,MediaBrowser.Controller.Providers.MetadataRefreshOptions,System.Threading.CancellationToken)
FetchAsync(MediaBrowser.Controller.Entities.Audio.Audio,MediaBrowser.Controller.Providers.MetadataRefreshOptions,System.Threading.CancellationToken)
FetchAsync(MediaBrowser.Controller.Entities.AudioBook,MediaBrowser.Controller.Providers.MetadataRefreshOptions,System.Threading.CancellationToken)
FetchVideoInfo(T,MediaBrowser.Controller.Providers.MetadataRefreshOptions,System.Threading.CancellationToken)
NormalizeStrmLine(System.String)
FetchShortcutInfo(MediaBrowser.Controller.Entities.BaseItem)
FetchAudioInfo(T,MediaBrowser.Controller.Providers.MetadataRefreshOptions,System.Threading.CancellationToken)