/// <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(); } }
/// <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(); } }
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; } } }
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); } }
/// <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); }
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); }
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); } }
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); }
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); } }
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); } }
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); }
/// <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); }