Пример #1
0
        /// <summary>
        /// Called when [pre fetch].
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="mount">The mount.</param>
        /// <param name="blurayDiscInfo">The bluray disc information.</param>
        private void OnPreFetch(Video item, IIsoMount mount, BlurayDiscInfo blurayDiscInfo)
        {
            if (item.VideoType == VideoType.Iso)
            {
                item.IsoType = DetermineIsoType(mount);
            }

            if (item.VideoType == VideoType.Dvd || (item.IsoType.HasValue && item.IsoType == IsoType.Dvd))
            {
                FetchFromDvdLib(item, mount);
            }

            if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType.Value == IsoType.BluRay))
            {
                item.PlayableStreamFileNames = blurayDiscInfo.Files.ToList();
            }
        }
Пример #2
0
        /// <summary>
        /// Fills video properties from the VideoStream of the largest playlist
        /// </summary>
        /// <param name="video">The video.</param>
        /// <param name="inputPath">The input path.</param>
        /// <param name="stream">The stream.</param>
        private void Fetch(Video video, string inputPath, BlurayDiscInfo stream)
        {
            // Check all input for null/empty/zero

            video.MediaStreams = stream.MediaStreams;

            if (stream.RunTimeTicks.HasValue && stream.RunTimeTicks.Value > 0)
            {
                video.RunTimeTicks = stream.RunTimeTicks;
            }

            video.PlayableStreamFileNames = stream.Files.ToList();

            if (stream.Chapters != null)
            {
                video.Chapters = stream.Chapters.Select(c => new ChapterInfo
                {
                    StartPositionTicks = TimeSpan.FromSeconds(c).Ticks
                }).ToList();
            }
        }
Пример #3
0
        private void FetchBdInfo(BaseItem item, List <ChapterInfo> chapters, List <MediaStream> mediaStreams, BlurayDiscInfo blurayInfo)
        {
            var video = (Video)item;

            //video.PlayableStreamFileNames = blurayInfo.Files.ToList();

            // Use BD Info if it has multiple m2ts. Otherwise, treat it like a video file and rely more on ffprobe output
            if (blurayInfo.Files.Length > 1)
            {
                int?currentHeight  = null;
                int?currentWidth   = null;
                int?currentBitRate = null;

                var videoStream = mediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video);

                // Grab the values that ffprobe recorded
                if (videoStream != null)
                {
                    currentBitRate = videoStream.BitRate;
                    currentWidth   = videoStream.Width;
                    currentHeight  = videoStream.Height;
                }

                // Fill video properties from the BDInfo result
                mediaStreams.Clear();
                mediaStreams.AddRange(blurayInfo.MediaStreams);

                if (blurayInfo.RunTimeTicks.HasValue && blurayInfo.RunTimeTicks.Value > 0)
                {
                    video.RunTimeTicks = blurayInfo.RunTimeTicks;
                }

                if (blurayInfo.Chapters != null)
                {
                    chapters.Clear();

                    chapters.AddRange(blurayInfo.Chapters.Select(c => new ChapterInfo
                    {
                        StartPositionTicks = TimeSpan.FromSeconds(c).Ticks
                    }));
                }

                videoStream = mediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video);

                // Use the ffprobe values if these are empty
                if (videoStream != null)
                {
                    videoStream.BitRate = IsEmpty(videoStream.BitRate) ? currentBitRate : videoStream.BitRate;
                    videoStream.Width   = IsEmpty(videoStream.Width) ? currentWidth : videoStream.Width;
                    videoStream.Height  = IsEmpty(videoStream.Height) ? currentHeight : videoStream.Height;
                }
            }
        }
Пример #4
0
        protected async Task Fetch(Video video,
                                   CancellationToken cancellationToken,
                                   Model.MediaInfo.MediaInfo mediaInfo,
                                   BlurayDiscInfo blurayInfo,
                                   MetadataRefreshOptions options)
        {
            List <MediaStream> mediaStreams;
            List <ChapterInfo> chapters;

            if (mediaInfo != null)
            {
                mediaStreams = mediaInfo.MediaStreams;

                video.TotalBitrate = mediaInfo.Bitrate;
                //video.FormatName = (mediaInfo.Container ?? string.Empty)
                //    .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase);

                // For dvd's this may not always be accurate, so don't set the runtime if the item already has one
                var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0;

                if (needToSetRuntime)
                {
                    video.RunTimeTicks = mediaInfo.RunTimeTicks;
                }
                video.Size = mediaInfo.Size;

                if (video.VideoType == VideoType.VideoFile)
                {
                    var extension = (Path.GetExtension(video.Path) ?? string.Empty).TrimStart('.');

                    video.Container = extension;
                }
                else
                {
                    video.Container = null;
                }
                video.Container = mediaInfo.Container;

                chapters = mediaInfo.Chapters == null ? new List <ChapterInfo>() : mediaInfo.Chapters.ToList();
                if (blurayInfo != null)
                {
                    FetchBdInfo(video, chapters, mediaStreams, blurayInfo);
                }
            }
            else
            {
                mediaStreams = new List <MediaStream>();
                chapters     = new List <ChapterInfo>();
            }

            await AddExternalSubtitles(video, mediaStreams, options, cancellationToken).ConfigureAwait(false);

            var libraryOptions = _libraryManager.GetLibraryOptions(video);

            if (mediaInfo != null)
            {
                FetchEmbeddedInfo(video, mediaInfo, options, libraryOptions);
                FetchPeople(video, mediaInfo, options);
                video.Timestamp     = mediaInfo.Timestamp;
                video.Video3DFormat = video.Video3DFormat ?? mediaInfo.Video3DFormat;
            }

            var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);

            video.Height = videoStream == null ? 0 : videoStream.Height ?? 0;
            video.Width  = videoStream == null ? 0 : videoStream.Width ?? 0;

            video.DefaultVideoStreamIndex = videoStream == null ? (int?)null : videoStream.Index;

            video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);

            _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken);

            if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh ||
                options.MetadataRefreshMode == MetadataRefreshMode.Default)
            {
                if (chapters.Count == 0 && mediaStreams.Any(i => i.Type == MediaStreamType.Video))
                {
                    AddDummyChapters(video, chapters);
                }

                NormalizeChapterNames(chapters);

                var extractDuringScan = false;
                if (libraryOptions != null)
                {
                    extractDuringScan = libraryOptions.ExtractChapterImagesDuringLibraryScan;
                }

                await _encodingManager.RefreshChapterImages(video, options.DirectoryService, chapters, extractDuringScan, false, cancellationToken).ConfigureAwait(false);

                _chapterManager.SaveChapters(video.Id.ToString(), chapters);
            }
        }
Пример #5
0
        /// <summary>
        /// Gets the disc info.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>BlurayDiscInfo.</returns>
        public BlurayDiscInfo GetDiscInfo(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            var bdrom = new BDROM(BdInfoDirectoryInfo.FromFileSystemPath(_fileSystem, path));

            bdrom.Scan();

            // Get the longest playlist
            var playlist = bdrom.PlaylistFiles.Values.OrderByDescending(p => p.TotalLength).FirstOrDefault(p => p.IsValid);

            var outputStream = new BlurayDiscInfo
            {
                MediaStreams = new MediaStream[] { }
            };

            if (playlist == null)
            {
                return(outputStream);
            }

            outputStream.Chapters = playlist.Chapters.ToArray();

            outputStream.RunTimeTicks = TimeSpan.FromSeconds(playlist.TotalLength).Ticks;

            var mediaStreams = new List <MediaStream>();

            foreach (var stream in playlist.SortedStreams)
            {
                var videoStream = stream as TSVideoStream;

                if (videoStream != null)
                {
                    AddVideoStream(mediaStreams, videoStream);
                    continue;
                }

                var audioStream = stream as TSAudioStream;

                if (audioStream != null)
                {
                    AddAudioStream(mediaStreams, audioStream);
                    continue;
                }

                var textStream = stream as TSTextStream;

                if (textStream != null)
                {
                    AddSubtitleStream(mediaStreams, textStream);
                    continue;
                }

                var graphicsStream = stream as TSGraphicsStream;

                if (graphicsStream != null)
                {
                    AddSubtitleStream(mediaStreams, graphicsStream);
                }
            }

            outputStream.MediaStreams = mediaStreams.ToArray();

            outputStream.PlaylistName = playlist.Name;

            if (playlist.StreamClips != null && playlist.StreamClips.Any())
            {
                // Get the files in the playlist
                outputStream.Files = playlist.StreamClips.Select(i => i.StreamFile.Name).ToArray();
            }

            return(outputStream);
        }
Пример #6
0
        public async Task <ItemUpdateType> ProbeVideo <T>(T item,
                                                          MetadataRefreshOptions options,
                                                          CancellationToken cancellationToken)
            where T : Video
        {
            if (item.IsArchive)
            {
                var ext = Path.GetExtension(item.Path) ?? string.Empty;
                item.Container = ext.TrimStart('.');
                return(ItemUpdateType.MetadataImport);
            }

            var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false);

            BlurayDiscInfo blurayDiscInfo = null;

            try
            {
                if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay))
                {
                    var inputPath = isoMount != null ? isoMount.MountedPath : item.Path;

                    blurayDiscInfo = GetBDInfo(inputPath);
                }

                OnPreFetch(item, isoMount, blurayDiscInfo);

                // If we didn't find any satisfying the min length, just take them all
                if (item.VideoType == VideoType.Dvd || (item.IsoType.HasValue && item.IsoType == IsoType.Dvd))
                {
                    if (item.PlayableStreamFileNames.Count == 0)
                    {
                        _logger.Error("No playable vobs found in dvd structure, skipping ffprobe.");
                        return(ItemUpdateType.MetadataImport);
                    }
                }

                if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay))
                {
                    if (item.PlayableStreamFileNames.Count == 0)
                    {
                        _logger.Error("No playable vobs found in bluray structure, skipping ffprobe.");
                        return(ItemUpdateType.MetadataImport);
                    }
                }

                var result = await GetMediaInfo(item, isoMount, cancellationToken).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();

                FFProbeHelpers.NormalizeFFProbeResult(result);

                cancellationToken.ThrowIfCancellationRequested();

                await Fetch(item, cancellationToken, result, isoMount, blurayDiscInfo, options).ConfigureAwait(false);
            }
            finally
            {
                if (isoMount != null)
                {
                    isoMount.Dispose();
                }
            }

            return(ItemUpdateType.MetadataImport);
        }
Пример #7
0
        protected async Task Fetch(Video video,
                                   CancellationToken cancellationToken,
                                   InternalMediaInfoResult data,
                                   IIsoMount isoMount,
                                   BlurayDiscInfo blurayInfo,
                                   MetadataRefreshOptions options)
        {
            var mediaInfo    = MediaEncoderHelpers.GetMediaInfo(data);
            var mediaStreams = mediaInfo.MediaStreams;

            video.TotalBitrate = mediaInfo.TotalBitrate;
            video.FormatName   = (mediaInfo.Format ?? string.Empty)
                                 .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase);

            if (data.format != null)
            {
                // For dvd's this may not always be accurate, so don't set the runtime if the item already has one
                var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0;

                if (needToSetRuntime && !string.IsNullOrEmpty(data.format.duration))
                {
                    video.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, _usCulture)).Ticks;
                }

                if (video.VideoType == VideoType.VideoFile)
                {
                    var extension = (Path.GetExtension(video.Path) ?? string.Empty).TrimStart('.');

                    video.Container = extension;
                }
                else
                {
                    video.Container = null;
                }

                if (!string.IsNullOrEmpty(data.format.size))
                {
                    video.Size = long.Parse(data.format.size, _usCulture);
                }
                else
                {
                    video.Size = null;
                }
            }

            var mediaChapters = (data.Chapters ?? new MediaChapter[] { }).ToList();
            var chapters      = mediaChapters.Select(GetChapterInfo).ToList();

            if (video.VideoType == VideoType.BluRay || (video.IsoType.HasValue && video.IsoType.Value == IsoType.BluRay))
            {
                FetchBdInfo(video, chapters, mediaStreams, blurayInfo);
            }

            await AddExternalSubtitles(video, mediaStreams, options, cancellationToken).ConfigureAwait(false);

            FetchWtvInfo(video, data);

            video.IsHD = mediaStreams.Any(i => i.Type == MediaStreamType.Video && i.Width.HasValue && i.Width.Value >= 1270);

            var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);

            video.VideoBitRate            = videoStream == null ? null : videoStream.BitRate;
            video.DefaultVideoStreamIndex = videoStream == null ? (int?)null : videoStream.Index;

            video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);

            ExtractTimestamp(video);
            UpdateFromMediaInfo(video, videoStream);

            await _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken).ConfigureAwait(false);

            if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh ||
                options.MetadataRefreshMode == MetadataRefreshMode.Default)
            {
                var chapterOptions = _chapterManager.GetConfiguration();

                try
                {
                    var remoteChapters = await DownloadChapters(video, chapters, chapterOptions, cancellationToken).ConfigureAwait(false);

                    if (remoteChapters.Count > 0)
                    {
                        chapters = remoteChapters;
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error downloading chapters", ex);
                }

                if (chapters.Count == 0 && mediaStreams.Any(i => i.Type == MediaStreamType.Video))
                {
                    AddDummyChapters(video, chapters);
                }

                NormalizeChapterNames(chapters);

                await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions
                {
                    Chapters      = chapters,
                    Video         = video,
                    ExtractImages = chapterOptions.ExtractDuringLibraryScan,
                    SaveChapters  = false
                }, cancellationToken).ConfigureAwait(false);

                await _chapterManager.SaveChapters(video.Id.ToString(), chapters, cancellationToken).ConfigureAwait(false);
            }
        }
Пример #8
0
        public async Task <ItemUpdateType> ProbeVideo <T>(T item,
                                                          MetadataRefreshOptions options,
                                                          CancellationToken cancellationToken)
            where T : Video
        {
            var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false);

            BlurayDiscInfo blurayDiscInfo = null;

            try
            {
                List <string> streamFileNames = null;

                if (item.VideoType == VideoType.Iso)
                {
                    item.IsoType = DetermineIsoType(isoMount);
                }

                if (item.VideoType == VideoType.Dvd || (item.IsoType.HasValue && item.IsoType == IsoType.Dvd))
                {
                    streamFileNames = FetchFromDvdLib(item, isoMount);

                    if (streamFileNames.Count == 0)
                    {
                        _logger.Error("No playable vobs found in dvd structure, skipping ffprobe.");
                        return(ItemUpdateType.MetadataImport);
                    }
                }

                else if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay))
                {
                    var inputPath = isoMount != null ? isoMount.MountedPath : item.Path;

                    blurayDiscInfo = GetBDInfo(inputPath);

                    streamFileNames = blurayDiscInfo.Files;

                    if (streamFileNames.Count == 0)
                    {
                        _logger.Error("No playable vobs found in bluray structure, skipping ffprobe.");
                        return(ItemUpdateType.MetadataImport);
                    }
                }

                if (streamFileNames == null)
                {
                    streamFileNames = new List <string>();
                }

                var result = await GetMediaInfo(item, isoMount, streamFileNames, cancellationToken).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();

                await Fetch(item, cancellationToken, result, isoMount, blurayDiscInfo, options).ConfigureAwait(false);
            }
            finally
            {
                if (isoMount != null)
                {
                    isoMount.Dispose();
                }
            }

            return(ItemUpdateType.MetadataImport);
        }
Пример #9
0
        protected async Task Fetch(Video video,
                                   CancellationToken cancellationToken,
                                   Model.MediaInfo.MediaInfo mediaInfo,
                                   IIsoMount isoMount,
                                   BlurayDiscInfo blurayInfo,
                                   MetadataRefreshOptions options)
        {
            var mediaStreams = mediaInfo.MediaStreams;

            video.TotalBitrate = mediaInfo.Bitrate;
            //video.FormatName = (mediaInfo.Container ?? string.Empty)
            //    .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase);

            // For dvd's this may not always be accurate, so don't set the runtime if the item already has one
            var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0;

            if (needToSetRuntime)
            {
                video.RunTimeTicks = mediaInfo.RunTimeTicks;
            }

            if (video.VideoType == VideoType.VideoFile)
            {
                var extension = (Path.GetExtension(video.Path) ?? string.Empty).TrimStart('.');

                video.Container = extension;
            }
            else
            {
                video.Container = null;
            }

            var chapters = mediaInfo.Chapters ?? new List <ChapterInfo>();

            if (blurayInfo != null)
            {
                FetchBdInfo(video, chapters, mediaStreams, blurayInfo);
            }

            await AddExternalSubtitles(video, mediaStreams, options, cancellationToken).ConfigureAwait(false);

            FetchEmbeddedInfo(video, mediaInfo, options);
            await FetchPeople(video, mediaInfo, options).ConfigureAwait(false);

            video.IsHD = mediaStreams.Any(i => i.Type == MediaStreamType.Video && i.Width.HasValue && i.Width.Value >= 1270);

            var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);

            video.VideoBitRate            = videoStream == null ? null : videoStream.BitRate;
            video.DefaultVideoStreamIndex = videoStream == null ? (int?)null : videoStream.Index;

            video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);
            video.Timestamp    = mediaInfo.Timestamp;

            await _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken).ConfigureAwait(false);

            if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh ||
                options.MetadataRefreshMode == MetadataRefreshMode.Default)
            {
                var chapterOptions = _chapterManager.GetConfiguration();

                try
                {
                    var remoteChapters = await DownloadChapters(video, chapters, chapterOptions, cancellationToken).ConfigureAwait(false);

                    if (remoteChapters.Count > 0)
                    {
                        chapters = remoteChapters;
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error downloading chapters", ex);
                }

                if (chapters.Count == 0 && mediaStreams.Any(i => i.Type == MediaStreamType.Video))
                {
                    AddDummyChapters(video, chapters);
                }

                NormalizeChapterNames(chapters);

                await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions
                {
                    Chapters      = chapters,
                    Video         = video,
                    ExtractImages = chapterOptions.ExtractDuringLibraryScan,
                    SaveChapters  = false
                }, cancellationToken).ConfigureAwait(false);

                await _chapterManager.SaveChapters(video.Id.ToString(), chapters, cancellationToken).ConfigureAwait(false);
            }
        }
Пример #10
0
        protected async Task Fetch(
            Video video,
            CancellationToken cancellationToken,
            Model.MediaInfo.MediaInfo mediaInfo,
            BlurayDiscInfo blurayInfo,
            MetadataRefreshOptions options)
        {
            List <MediaStream> mediaStreams;
            IReadOnlyList <MediaAttachment> mediaAttachments;

            ChapterInfo[] chapters;

            if (mediaInfo != null)
            {
                mediaStreams     = mediaInfo.MediaStreams.ToList();
                mediaAttachments = mediaInfo.MediaAttachments;

                video.TotalBitrate = mediaInfo.Bitrate;
                // video.FormatName = (mediaInfo.Container ?? string.Empty)
                //    .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase);

                // For dvd's this may not always be accurate, so don't set the runtime if the item already has one
                var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0;

                if (needToSetRuntime)
                {
                    video.RunTimeTicks = mediaInfo.RunTimeTicks;
                }

                video.Size = mediaInfo.Size;

                if (video.VideoType == VideoType.VideoFile)
                {
                    var extension = (Path.GetExtension(video.Path) ?? string.Empty).TrimStart('.');

                    video.Container = extension;
                }
                else
                {
                    video.Container = null;
                }

                video.Container = mediaInfo.Container;

                chapters = mediaInfo.Chapters ?? Array.Empty <ChapterInfo>();
                if (blurayInfo != null)
                {
                    FetchBdInfo(video, ref chapters, mediaStreams, blurayInfo);
                }
            }
            else
            {
                mediaStreams     = new List <MediaStream>();
                mediaAttachments = Array.Empty <MediaAttachment>();
                chapters         = Array.Empty <ChapterInfo>();
            }

            await AddExternalSubtitles(video, mediaStreams, options, cancellationToken).ConfigureAwait(false);

            await AddExternalAudioAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false);

            var libraryOptions = _libraryManager.GetLibraryOptions(video);

            if (mediaInfo != null)
            {
                FetchEmbeddedInfo(video, mediaInfo, options, libraryOptions);
                FetchPeople(video, mediaInfo, options);
                video.Timestamp = mediaInfo.Timestamp;
                video.Video3DFormat ??= mediaInfo.Video3DFormat;
            }

            if (libraryOptions.AllowEmbeddedSubtitles == EmbeddedSubtitleOptions.AllowText || libraryOptions.AllowEmbeddedSubtitles == EmbeddedSubtitleOptions.AllowNone)
            {
                _logger.LogDebug("Disabling embedded image subtitles for {Path} due to DisableEmbeddedImageSubtitles setting", video.Path);
                mediaStreams.RemoveAll(i => i.Type == MediaStreamType.Subtitle && !i.IsExternal && !i.IsTextSubtitleStream);
            }

            if (libraryOptions.AllowEmbeddedSubtitles == EmbeddedSubtitleOptions.AllowImage || libraryOptions.AllowEmbeddedSubtitles == EmbeddedSubtitleOptions.AllowNone)
            {
                _logger.LogDebug("Disabling embedded text subtitles for {Path} due to DisableEmbeddedTextSubtitles setting", video.Path);
                mediaStreams.RemoveAll(i => i.Type == MediaStreamType.Subtitle && !i.IsExternal && i.IsTextSubtitleStream);
            }

            var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);

            video.Height = videoStream?.Height ?? 0;
            video.Width  = videoStream?.Width ?? 0;

            video.DefaultVideoStreamIndex = videoStream?.Index;

            video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);

            _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken);
            _itemRepo.SaveMediaAttachments(video.Id, mediaAttachments, cancellationToken);

            if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh ||
                options.MetadataRefreshMode == MetadataRefreshMode.Default)
            {
                if (chapters.Length == 0 && mediaStreams.Any(i => i.Type == MediaStreamType.Video))
                {
                    chapters = CreateDummyChapters(video);
                }

                NormalizeChapterNames(chapters);

                var extractDuringScan = false;
                if (libraryOptions != null)
                {
                    extractDuringScan = libraryOptions.ExtractChapterImagesDuringLibraryScan;
                }

                await _encodingManager.RefreshChapterImages(video, options.DirectoryService, chapters, extractDuringScan, false, cancellationToken).ConfigureAwait(false);

                _chapterManager.SaveChapters(video.Id, chapters);
            }
        }
Пример #11
0
        protected async Task Fetch(Video video, CancellationToken cancellationToken, InternalMediaInfoResult data, IIsoMount isoMount, BlurayDiscInfo blurayInfo, IDirectoryService directoryService)
        {
            if (data.format != null)
            {
                // For dvd's this may not always be accurate, so don't set the runtime if the item already has one
                var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0;

                if (needToSetRuntime && !string.IsNullOrEmpty(data.format.duration))
                {
                    video.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, _usCulture)).Ticks;
                }
            }

            var mediaStreams = MediaEncoderHelpers.GetMediaInfo(data).MediaStreams;

            var chapters = data.Chapters ?? new List <ChapterInfo>();

            if (video.VideoType == VideoType.BluRay || (video.IsoType.HasValue && video.IsoType.Value == IsoType.BluRay))
            {
                FetchBdInfo(video, chapters, mediaStreams, blurayInfo);
            }

            AddExternalSubtitles(video, mediaStreams, directoryService);

            FetchWtvInfo(video, data);

            video.IsHD = mediaStreams.Any(i => i.Type == MediaStreamType.Video && i.Width.HasValue && i.Width.Value >= 1270);

            if (chapters.Count == 0 && mediaStreams.Any(i => i.Type == MediaStreamType.Video))
            {
                AddDummyChapters(video, chapters);
            }

            var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);

            video.VideoBitRate            = videoStream == null ? null : videoStream.BitRate;
            video.DefaultVideoStreamIndex = videoStream == null ? (int?)null : videoStream.Index;

            video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);

            await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions
            {
                Chapters      = chapters,
                Video         = video,
                ExtractImages = false,
                SaveChapters  = false
            }, cancellationToken).ConfigureAwait(false);

            await _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken).ConfigureAwait(false);

            await _itemRepo.SaveChapters(video.Id, chapters, cancellationToken).ConfigureAwait(false);
        }
Пример #12
0
        /// <summary>
        /// Gets the disc info.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>BlurayDiscInfo.</returns>
        public BlurayDiscInfo GetDiscInfo(string path)
        {
            var bdrom = new BDROM(path);

            bdrom.Scan();

            // Get the longest playlist
            var playlist = bdrom.PlaylistFiles.Values.OrderByDescending(p => p.TotalLength).FirstOrDefault(p => p.IsValid);

            var outputStream = new BlurayDiscInfo
            {
                MediaStreams = new List <MediaStream>()
            };

            if (playlist == null)
            {
                return(outputStream);
            }

            outputStream.Chapters = playlist.Chapters;

            outputStream.RunTimeTicks = TimeSpan.FromSeconds(playlist.TotalLength).Ticks;

            var mediaStreams = new List <MediaStream> {
            };

            foreach (var stream in playlist.SortedStreams)
            {
                var videoStream = stream as TSVideoStream;

                if (videoStream != null)
                {
                    AddVideoStream(mediaStreams, videoStream);
                    continue;
                }

                var audioStream = stream as TSAudioStream;

                if (audioStream != null)
                {
                    AddAudioStream(mediaStreams, audioStream);
                    continue;
                }

                var textStream = stream as TSTextStream;

                if (textStream != null)
                {
                    AddSubtitleStream(mediaStreams, textStream);
                    continue;
                }

                var graphicsStream = stream as TSGraphicsStream;

                if (graphicsStream != null)
                {
                    AddSubtitleStream(mediaStreams, graphicsStream);
                }
            }

            outputStream.MediaStreams = mediaStreams;

            outputStream.PlaylistName = playlist.Name;

            if (playlist.StreamClips != null && playlist.StreamClips.Any())
            {
                // Get the files in the playlist
                outputStream.Files = playlist.StreamClips.Select(i => i.StreamFile.Name).ToList();
            }

            return(outputStream);
        }