using System; using System.Collections.Generic; using System.Linq; using BDInfo; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.BdInfo; /// /// Class BdInfoExaminer. /// public class BdInfoExaminer : IBlurayExaminer { private readonly IFileSystem _fileSystem; /// /// Initializes a new instance of the class. /// /// The filesystem. public BdInfoExaminer(IFileSystem fileSystem) { _fileSystem = fileSystem; } /// /// Gets the disc info. /// /// The path. /// BlurayDiscInfo. 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 = Array.Empty() }; if (playlist is null) { return outputStream; } outputStream.Chapters = playlist.Chapters.ToArray(); outputStream.RunTimeTicks = TimeSpan.FromSeconds(playlist.TotalLength).Ticks; var sortedStreams = playlist.SortedStreams; var mediaStreams = new List(sortedStreams.Count); foreach (var stream in sortedStreams) { switch (stream) { case TSVideoStream videoStream: AddVideoStream(mediaStreams, videoStream); break; case TSAudioStream audioStream: AddAudioStream(mediaStreams, audioStream); break; case TSTextStream textStream: AddSubtitleStream(mediaStreams, textStream); break; case TSGraphicsStream graphicStream: AddSubtitleStream(mediaStreams, graphicStream); break; } } outputStream.MediaStreams = mediaStreams.ToArray(); outputStream.PlaylistName = playlist.Name; if (playlist.StreamClips is not null && playlist.StreamClips.Count > 0) { // Get the files in the playlist outputStream.Files = playlist.StreamClips.Select(i => i.StreamFile.Name).ToArray(); } return outputStream; } /// /// Adds the video stream. /// /// The streams. /// The video stream. private void AddVideoStream(List streams, TSVideoStream videoStream) { var mediaStream = new MediaStream { BitRate = Convert.ToInt32(videoStream.BitRate), Width = videoStream.Width, Height = videoStream.Height, Codec = videoStream.CodecShortName, IsInterlaced = videoStream.IsInterlaced, Type = MediaStreamType.Video, Index = streams.Count }; if (videoStream.FrameRateDenominator > 0) { float frameRateEnumerator = videoStream.FrameRateEnumerator; float frameRateDenominator = videoStream.FrameRateDenominator; mediaStream.AverageFrameRate = mediaStream.RealFrameRate = frameRateEnumerator / frameRateDenominator; } streams.Add(mediaStream); } /// /// Adds the audio stream. /// /// The streams. /// The audio stream. private void AddAudioStream(List streams, TSAudioStream audioStream) { var stream = new MediaStream { Codec = audioStream.CodecShortName, Language = audioStream.LanguageCode, Channels = audioStream.ChannelCount, SampleRate = audioStream.SampleRate, Type = MediaStreamType.Audio, Index = streams.Count }; var bitrate = Convert.ToInt32(audioStream.BitRate); if (bitrate > 0) { stream.BitRate = bitrate; } if (audioStream.LFE > 0) { stream.Channels = audioStream.ChannelCount + 1; } streams.Add(stream); } /// /// Adds the subtitle stream. /// /// The streams. /// The text stream. private void AddSubtitleStream(List streams, TSTextStream textStream) { streams.Add(new MediaStream { Language = textStream.LanguageCode, Codec = textStream.CodecShortName, Type = MediaStreamType.Subtitle, Index = streams.Count }); } /// /// Adds the subtitle stream. /// /// The streams. /// The text stream. private void AddSubtitleStream(List streams, TSGraphicsStream textStream) { streams.Add(new MediaStream { Language = textStream.LanguageCode, Codec = textStream.CodecShortName, Type = MediaStreamType.Subtitle, Index = streams.Count }); } }