/// <summary> /// check if audio stream is dvd compatible /// </summary> /// <param name="aud"></param> /// <returns>true if stream is dvd compatible, false otherwise</returns> public static bool CheckAudioDvdCompatible(AudioInfo aud) { string ext = StreamFormat.GetFormatExtension(aud.Format, aud.FormatProfile, false); bool compat = true; Log.Info("Check if audio is compatible with DVD Spec"); Log.InfoFormat("Format: {0:s}, Profile: {1:s}", aud.Format, aud.FormatProfile); Log.InfoFormat("Bitrate: {0:g}, Samplerate: {1:g}, Channel Count: {2:g}", aud.Bitrate, aud.SampleRate, aud.ChannelCount); if (ext != "ac3") { Log.Info("Format is not AC3"); compat = false; } if (compat) { if (ext == "ac3") { if (aud.Bitrate > 448000) { Log.InfoFormat("Bitrate is higher than 448kbit/s"); compat = false; } } } if (compat) { if (aud.ChannelCount > 6) { Log.InfoFormat("This channel configuration is not supported"); compat = false; } } if (compat) { if (aud.SampleRate != 48000) { Log.InfoFormat("Samplerate != 48000Hz"); compat = false; } } return compat; }
/// <summary> /// reserved for future development /// </summary> /// <param name="aud"></param> /// <returns></returns> public static bool CheckAudioBluRayCompatible(AudioInfo aud) { string ext = StreamFormat.GetFormatExtension(aud.Format, aud.FormatProfile, false); bool compat = !(ext != "ac3" && ext != "eac3" && ext != "dts" && ext != "dtshd" && ext != "mp2" && ext != "truehd"); return compat; }
private void GetDVDTitleList() { string strChapters = Processing.GetResourceString("streamselect_chapters"); string strVideo = Processing.GetResourceString("streamselect_video"); string strAudio = Processing.GetResourceString("streamselect_audio"); string strSubtitles = Processing.GetResourceString("streamselect_subtitles"); string dvdTitleFormat = Processing.GetResourceString("streamselect_dvd_general"); string dvdAudioFormat = Processing.GetResourceString("streamselect_dvd_audio"); string dvdSubFormat = Processing.GetResourceString("streamselect_dvd_subtitle"); const string dvdVideoStreamFormat = "MPEG-2 {1:g}x{2:g} {4}{5} {0} {3:f} fps"; LsDvd lsdvd = new LsDvd(); string lines = lsdvd.GetDvdInfo(JobInfo.InputFile); XmlDocument dvdInfo = new XmlDocument(); dvdInfo.LoadXml(lines); if (dvdInfo.DocumentElement == null) return; XmlNodeList tracks = dvdInfo.DocumentElement.SelectNodes("//track"); XmlNode longestTrack = dvdInfo.DocumentElement.SelectSingleNode("//longest_track"); if (longestTrack == null) return; if (tracks == null) return; int longest = Convert.ToInt32(longestTrack.InnerText); foreach (XmlNode track in tracks) { int videoId = 0; float fps = 0; string videoFormat = string.Empty; string aspect = string.Empty; int width = 0; int height = 0; string letterboxed = string.Empty; int vtsID = 0; float lengthTemp = 0; XmlNode tempNode = track.SelectSingleNode("ix"); if (tempNode != null) videoId = Convert.ToInt32(tempNode.InnerText); tempNode = track.SelectSingleNode("fps"); if (tempNode != null) fps = Convert.ToSingle(tempNode.InnerText, AppSettings.CInfo); tempNode = track.SelectSingleNode("format"); if (tempNode != null) videoFormat = tempNode.InnerText; tempNode = track.SelectSingleNode("aspect"); if (tempNode != null) aspect = tempNode.InnerText; tempNode = track.SelectSingleNode("width"); if (tempNode != null) width = Convert.ToInt32(tempNode.InnerText); tempNode = track.SelectSingleNode("height"); if (tempNode != null) height = Convert.ToInt32(tempNode.InnerText); tempNode = track.SelectSingleNode("df"); if (tempNode != null) { string df = tempNode.InnerText; letterboxed = df == "?" ? string.Empty : " (" + df + ")"; } tempNode = track.SelectSingleNode("vts"); if (tempNode != null) vtsID = Convert.ToInt32(tempNode.InnerText); tempNode = track.SelectSingleNode("length"); if (tempNode != null) lengthTemp = Convert.ToSingle(tempNode.InnerText, AppSettings.CInfo); TimeSpan length = new TimeSpan(0, 0, 0, (int) Math.Truncate(lengthTemp), (int) ((lengthTemp - Math.Truncate(lengthTemp))*1000)); XmlNodeList audioTracks = track.SelectNodes("audio"); XmlNodeList chapters = track.SelectNodes("chapter"); XmlNodeList subtitles = track.SelectNodes("subp"); List<TimeSpan> tempChapters = new List<TimeSpan>(); DateTime duration = new DateTime(); duration = duration.AddSeconds(length.TotalSeconds); string treeRoot = string.Format(dvdTitleFormat, videoId, duration.ToString("H:mm:ss.fff")); Dictionary<string, object> treeData = new Dictionary<string, object> {{"Name", JobInfo.InputFile}, {"TrackID", videoId}}; TreeNode root = new TreeNode { ID = _treeNodeID++, Name = treeRoot, Data = treeData, Children = new List<TreeNode>(), IsChecked = true, }; root.IsExpanded = root.IsChecked; _tree.Add(root); TreeNode chaptersTree = CreateNode(root, strChapters, null); TreeNode videoTree = CreateNode(root, strVideo, null); TreeNode audioTree = CreateNode(root, strAudio, null); TreeNode subTree = CreateNode(root, strSubtitles, null); if (chapters != null && chapters.Count > 0) { TimeSpan chapLength = new TimeSpan(0, 0, 0, 0, 0); tempChapters.Add(chapLength); } if (chapters != null) tempChapters.AddRange( chapters.Cast<XmlNode>().Select( chapterTemp => { XmlNode node = chapterTemp.SelectSingleNode("length"); return node != null ? Convert.ToSingle(node.InnerText, AppSettings.CInfo) : 0; }).Select( chapterLengthTemp => new TimeSpan(0, 0, 0, (int) Math.Truncate(chapterLengthTemp), (int) ((chapterLengthTemp - Math.Truncate(chapterLengthTemp))*1000)))); if (tempChapters.Count > 0) { string chaptersFormat = string.Format("{0:0} {1}", tempChapters.Count, strChapters); CreateNode(chaptersTree, chaptersFormat, tempChapters); } string videoStream = string.Format(dvdVideoStreamFormat, videoFormat, width, height, fps, aspect, letterboxed); VideoInfo vid = new VideoInfo { VtsId = vtsID, TrackId = videoId, StreamId = 1, FPS = fps, Interlaced = true, Format = "MPEG-2", FrameCount = 0, Width = width, Height = height, Encoded = false, IsRawStream = false, DemuxStreamNames = new List<string>(), StreamSize = 0, Length = lengthTemp }; if (aspect != "4/3") Single.TryParse(aspect, NumberStyles.Number, AppSettings.CInfo, out vid.AspectRatio); else vid.AspectRatio = 4f / 3f; Processing.GetFPSNumDenom(fps, out vid.FrameRateEnumerator, out vid.FrameRateDenominator); CreateNode(videoTree, videoStream, vid); int audioTracksCount = 0; if (audioTracks != null) { audioTracksCount = audioTracks.Count; foreach (XmlNode audio in audioTracks) { int audioID = 0; string langCode = string.Empty; string language = string.Empty; string format = string.Empty; int frequency = 0; string quantization = string.Empty; int channels = 0; string content = string.Empty; int streamID = 0; tempNode = audio.SelectSingleNode("ix"); if (tempNode != null) audioID = Convert.ToInt32(tempNode.InnerText); tempNode = audio.SelectSingleNode("langcode"); if (tempNode != null) langCode = tempNode.InnerText; tempNode = audio.SelectSingleNode("language"); if (tempNode != null) language = tempNode.InnerText; tempNode = audio.SelectSingleNode("format"); if (tempNode != null) format = tempNode.InnerText; tempNode = audio.SelectSingleNode("frequency"); if (tempNode != null) frequency = Convert.ToInt32(tempNode.InnerText); tempNode = audio.SelectSingleNode("quantization"); if (tempNode != null) quantization = tempNode.InnerText; tempNode = audio.SelectSingleNode("channels"); if (tempNode != null) channels = Convert.ToInt32(tempNode.InnerText); tempNode = audio.SelectSingleNode("content"); if (tempNode != null) content = tempNode.InnerText; tempNode = audio.SelectSingleNode("streamid"); if (tempNode != null) streamID = Int32.Parse(tempNode.InnerText.Replace("0x", string.Empty), NumberStyles.HexNumber); string audioStream = string.Format(dvdAudioFormat, audioID, streamID, langCode, language, content, format, channels, frequency, quantization); AudioInfo aud = new AudioInfo { Format = format, FormatProfile = string.Empty, Id = audioID, StreamId = streamID, LangCode = langCode, TempFile = string.Empty, OriginalId = audioID, Delay = 0, Bitrate = 0, SampleRate = frequency, ChannelCount = channels, ShortLang = langCode, StreamSize = 0, IsHdStream = false }; CreateNode(audioTree, audioStream, aud); } } if (subtitles == null) continue; foreach (XmlNode subtitle in subtitles) { int subID = 0; string langCode = string.Empty; string language = string.Empty; string content = string.Empty; int streamID = 0; tempNode = subtitle.SelectSingleNode("ix"); if (tempNode != null) subID = Convert.ToInt32(tempNode.InnerText); tempNode = subtitle.SelectSingleNode("langcode"); if (tempNode != null) langCode = tempNode.InnerText; tempNode = subtitle.SelectSingleNode("language"); if (tempNode != null) language = tempNode.InnerText; tempNode = subtitle.SelectSingleNode("content"); if (tempNode != null) content = tempNode.InnerText; tempNode = subtitle.SelectSingleNode("streamid"); if (tempNode != null) streamID = Int32.Parse(tempNode.InnerText.Replace("0x", string.Empty), NumberStyles.HexNumber); string subtitleStream = string.Format(dvdSubFormat, subID, streamID, langCode, language, content); SubtitleInfo subInfo = new SubtitleInfo { Id = subID + audioTracksCount, StreamId = streamID, TempFile = string.Empty, LangCode = langCode, Format = "VobSub", Delay = 0, StreamSize = 0 }; CreateNode(subTree, subtitleStream, subInfo); } } _defaultSelection = longest - 1; }
private void GetFileInfo() { MediaInfoContainer mi = new MediaInfoContainer(); try { mi = Processing.GetMediaInfo(JobInfo.InputFile); } catch (TimeoutException ex) { Log.Error(ex); } JobInfo.MediaInfo = mi; string fileTitleFormat = Processing.GetResourceString("streamselect_single_file_general"); string fileAudioFormat = Processing.GetResourceString("streamselect_single_file_audio"); string fileVideoFormat = Processing.GetResourceString("streamselect_single_file_video"); string strChapters = Processing.GetResourceString("streamselect_chapters"); string strVideo = Processing.GetResourceString("streamselect_video"); string strAudio = Processing.GetResourceString("streamselect_audio"); string strSubtitles = Processing.GetResourceString("streamselect_subtitles"); string containerFormat = mi.General.Format; string duration = mi.General.DurationTime.ToString("H:mm:ss.fff"); string shortFileName = mi.General.FileName + "." + mi.General.FileExtension; string treeRoot = string.Format(fileTitleFormat, shortFileName, containerFormat, duration); TreeNode root = new TreeNode { ID = _treeNodeID++, Name = treeRoot, Data = JobInfo.InputFile, IsChecked = true, IsExpanded = true, Children = new List<TreeNode>() }; _tree.Add(root); TreeNode chaptersTree = CreateNode(root, strChapters, null); TreeNode videoTree = CreateNode(root, strVideo, null); TreeNode audioTree = CreateNode(root, strAudio, null); TreeNode subTree = CreateNode(root, strSubtitles, null); if (mi.Chapters.Count > 0) { string chaptersTitle = string.Format("{0:0} {1}", mi.Chapters.Count, strChapters); CreateNode(chaptersTree, chaptersTitle, mi.Chapters); } else chaptersTree.IsChecked = false; int streamIndex = 0; foreach (MediaInfoContainer.VideoStreamInfo clip in mi.Video) { streamIndex++; int videoPid = clip.ID; string videoCodec = clip.FormatInfo; string videoCodecShort = clip.Format; string videoDesc = string.Format(fileVideoFormat, clip.Width, clip.Height, clip.ScanType, clip.FormatProfile, clip.FrameRate); string videoStreamTitle = string.Format("{3:g}: {0} ({1}), {2}", videoCodec, videoCodecShort, videoDesc, streamIndex); VideoInfo vid = new VideoInfo(); if (JobInfo.Input == InputType.InputAvi) vid.StreamId = 0; else vid.StreamId = videoPid == 0 ? streamIndex : videoPid; vid.FPS = clip.FrameRate; vid.PicSize = clip.VideoSize; vid.Interlaced = clip.ScanType == "Interlaced"; vid.Format = clip.Format; vid.FormatProfile = clip.FormatProfile; vid.Height = clip.Height; vid.Width = clip.Width; vid.FrameCount = clip.FrameCount; vid.StreamSize = clip.StreamSize; vid.Length = mi.General.DurationTime.TimeOfDay.TotalSeconds; Single.TryParse(clip.DisplayAspectRatio, NumberStyles.Number, AppSettings.CInfo, out vid.AspectRatio); vid.FrameRateEnumerator = clip.FrameRateEnumerator; vid.FrameRateDenominator = clip.FrameRateDenominator; CreateNode(videoTree, videoStreamTitle, vid); } videoTree.IsChecked = videoTree.Children.Count > 0; foreach (MediaInfoContainer.AudioStreamInfo audio in mi.Audio) { streamIndex++; int audioPid = audio.ID; string audioCodec = audio.FormatInfo; string audioCodecShort = audio.Format; string audioLangCode = audio.LanguageIso6392; string audioLanguage = audio.LanguageFull; int audioStreamKindID = audio.StreamKindID; string audioDesc = string.Format(fileAudioFormat, audio.Channels, audio.ChannelPositions, audio.SamplingRate, audio.BitDepth, audio.BitRate/1000); string audioStreamTitle = string.Format("{5:g}: {0} ({1}) / {2} ({3}) / {4}", audioCodec, audioCodecShort, audioLangCode, audioLanguage, audioDesc, streamIndex); if (JobInfo.Input == InputType.InputAvi) audioPid += 1; else audioPid = audioPid == 0 ? streamIndex : audioPid; AudioInfo aud = new AudioInfo { Id = audioPid, Format = audioCodecShort, FormatProfile = audio.FormatProfile, StreamId = streamIndex, LangCode = audioLangCode, OriginalId = audioPid, StreamKindId = audioStreamKindID, Delay = audio.Delay, Bitrate = audio.BitRate, SampleRate = audio.SamplingRate, ChannelCount = audio.Channels, BitDepth = audio.BitDepth, ShortLang = audio.LanguageIso6391, StreamSize = audio.StreamSize, Length = mi.General.DurationTime.TimeOfDay.TotalSeconds, IsHdStream = audio.CompressionMode == "Lossless" }; CreateNode(audioTree, audioStreamTitle, aud); } audioTree.IsChecked = audioTree.Children.Count > 0; foreach (MediaInfoContainer.TextStreamInfo sub in mi.Text) { streamIndex++; string subCodec = sub.CodecIDInfo; string subCodecShort = sub.Format; string subLangCode = sub.LanguageIso6392; string subLanguage = sub.LanguageFull; int subStreamKindID = sub.StreamKindID; string subStreamTitle = string.Format("{4:g}: {0} ({1}) / {2} ({3})", subCodec, subCodecShort, subLangCode, subLanguage, streamIndex); SubtitleInfo subInfo = new SubtitleInfo { Id = sub.ID, StreamId = streamIndex, LangCode = subLangCode, Format = subCodecShort, StreamKindId = subStreamKindID, Delay = sub.Delay, StreamSize = sub.StreamSize }; CreateNode(subTree, subStreamTitle, subInfo); } foreach (MediaInfoContainer.ImageStreamInfo sub in mi.Image) { streamIndex++; string subCodec = sub.CodecIDInfo; string subCodecShort = sub.Format; string subLangCode = sub.LanguageIso6392; string subLanguage = sub.LanguageFull; int subStreamKindID = sub.StreamKindID; string subStreamTitle = string.Format("{4:g}: {0} ({1}) / {2} ({3})", subCodec, subCodecShort, subLangCode, subLanguage, streamIndex); SubtitleInfo subInfo = new SubtitleInfo { Id = sub.ID, StreamId = streamIndex, LangCode = subLangCode, Format = subCodecShort, StreamKindId = subStreamKindID, Delay = 0, StreamSize = sub.StreamSize }; CreateNode(subTree, subStreamTitle, subInfo); } subTree.IsChecked = subTree.Children.Count > 0; }
private void GetBDInfo() { string strChapters = Processing.GetResourceString("streamselect_chapters"); string strVideo = Processing.GetResourceString("streamselect_video"); string strAudio = Processing.GetResourceString("streamselect_audio"); string strSubtitles = Processing.GetResourceString("streamselect_subtitles"); string bdTitleFormat = Processing.GetResourceString("streamselect_bd_general"); const string bdAudioFormat = "{5:g}: {0} ({1}) / {2} ({3}) / {4}"; const string bdSubFormat = "{3:g}: {0} / {1} ({2}); {4}"; _bdInfo = new BDROM(JobInfo.InputFile); _bdInfo.Scan(); int longestClip = GetLongestBDPlaylist(); int playlistIndex = 1; foreach (TSPlaylistFile item in _bdInfo.PlaylistFiles.Values) { if (!item.IsValid) { playlistIndex++; continue; } int streamIndex = 0; DateTime duration = new DateTime(); duration = duration.AddSeconds(item.TotalLength); string treeRoot = string.Format(bdTitleFormat, playlistIndex, item.Name, duration.ToString("H:mm:ss.fff")); Dictionary<string, object> treeData = new Dictionary<string, object> { { "Name", Path.Combine(_bdInfo.DirectoryPLAYLIST.FullName, item.Name) }, {"PlaylistIndex", playlistIndex} }; TreeNode root = new TreeNode { ID = _treeNodeID++, Name = treeRoot, Data = treeData, Children = new List<TreeNode>(), IsChecked = true, }; root.IsExpanded = root.IsChecked; _tree.Add(root); TreeNode chaptersTree = CreateNode(root, strChapters, null); TreeNode videoTree = CreateNode(root, strVideo, null); TreeNode audioTree = CreateNode(root, strAudio, null); TreeNode subTree = CreateNode(root, strSubtitles, null); List<TimeSpan> streamChapters = new List<TimeSpan>(); if (item.Chapters.Count > 1) { streamIndex++; streamChapters.AddRange(item.Chapters.Select(TimeSpan.FromSeconds)); string chaptersFormat = string.Format("{0:0} {1}", streamChapters.Count, strChapters); CreateNode(chaptersTree, chaptersFormat, streamChapters); } string videoDescStereo = string.Empty; int leftVideoStreamID = -1; foreach (TSVideoStream clip in item.VideoStreams) { streamIndex++; string videoCodec = clip.CodecName; string videoCodecShort = clip.CodecShortName; string videoDesc = clip.Description; if ((clip.StreamType == TSStreamType.AVC_VIDEO) && (item.VideoStreams.Count > 1) && (item.VideoStreams[0].PID == clip.PID) && (item.VideoStreams[item.VideoStreams.Count - 1].StreamType == TSStreamType.MVC_VIDEO)) { videoDescStereo = videoDesc; videoCodec += " (left eye)"; leftVideoStreamID = streamIndex; } if ((clip.StreamType == TSStreamType.MVC_VIDEO) && (item.VideoStreams.Count > 1) && (item.VideoStreams[item.VideoStreams.Count - 1].PID == clip.PID) && (item.VideoStreams[0].StreamType == TSStreamType.AVC_VIDEO)) { videoDesc = videoDescStereo; videoCodec = "MPEG-4 MVC Video (right eye)"; } /* */ string videoStreamFormat = string.Format("{3:g}: {0} ({1}), {2}", videoCodec, videoCodecShort, videoDesc, streamIndex); switch (clip.StreamType) { case TSStreamType.AVC_VIDEO: case TSStreamType.MPEG2_VIDEO: case TSStreamType.MPEG1_VIDEO: case TSStreamType.VC1_VIDEO: { VideoInfo vid = new VideoInfo { StreamId = streamIndex, TrackId = playlistIndex, FPS = (float) clip.FrameRateEnumerator/clip.FrameRateDenominator, PicSize = (VideoFormat) clip.VideoFormat, Interlaced = clip.IsInterlaced, Format = clip.CodecShortName, DemuxStreamId = clip.PID, FrameCount = 0, Encoded = false, IsRawStream = false, StreamSize = 0, Length = item.TotalLength, FrameRateEnumerator = clip.FrameRateEnumerator, FrameRateDenominator = clip.FrameRateDenominator, Height = clip.Height }; Int32.TryParse(item.Name.Substring(0, item.Name.LastIndexOf('.')), NumberStyles.Number, AppSettings.CInfo, out vid.DemuxPlayList); foreach (TSStreamClip streamClip in item.StreamClips) vid.DemuxStreamNames.Add(streamClip.StreamFile.FileInfo.FullName); float mod; switch (clip.AspectRatio) { case TSAspectRatio.ASPECT_16_9: mod = (float) 1.777778; break; default: mod = (float) 1.333333; break; } vid.Width = (int) (vid.Height*mod); vid.AspectRatio = mod; CreateNode(videoTree, videoStreamFormat, vid); } break; case TSStreamType.MVC_VIDEO: { StereoVideoInfo vid = new StereoVideoInfo { RightStreamId = streamIndex, LeftStreamId = leftVideoStreamID }; CreateNode(videoTree, videoStreamFormat, vid); } break; } } foreach (TSAudioStream audio in item.AudioStreams) { streamIndex++; string audioCodec = audio.CodecName; string audioCodecShort = audio.CodecShortName; string audioDesc = audio.Description; string audioLangCode = audio.LanguageCode; string audioLanguage = audio.LanguageName; string audioStreamFormat = string.Format(bdAudioFormat, audioCodec, audioCodecShort, audioLangCode, audioLanguage, audioDesc, streamIndex); AudioInfo aud = new AudioInfo { Format = audioCodecShort, FormatProfile = string.Empty, Id = streamIndex, StreamId = streamIndex, LangCode = audioLangCode, TempFile = string.Empty, OriginalId = streamIndex, Delay = 0, Bitrate = audio.BitRate, DemuxStreamId = audio.PID, SampleRate = audio.SampleRate, ChannelCount = audio.ChannelCount + audio.LFE, BitDepth = audio.BitDepth, ShortLang = audio.LanguageCode, StreamSize = 0, Length = item.TotalLength, IsHdStream = audio.CoreStream != null }; CreateNode(audioTree, audioStreamFormat, aud); } foreach (TSTextStream sub in item.TextStreams) { streamIndex++; string subCodecShort = sub.CodecShortName; string subDesc = sub.Description; string subLangCode = sub.LanguageCode; string subLanguage = sub.LanguageName; string subStreamFormat = string.Format(bdSubFormat, subCodecShort, subLangCode, subLanguage, streamIndex, subDesc); SubtitleInfo subInfo = new SubtitleInfo { Id = streamIndex, StreamId = streamIndex, TempFile = string.Empty, LangCode = subLangCode, Format = subCodecShort, Delay = 0, DemuxStreamId = sub.PID, StreamSize = 0 }; CreateNode(subTree, subStreamFormat, subInfo); } foreach (TSGraphicsStream sub in item.GraphicsStreams) { streamIndex++; string subCodecShort = sub.CodecShortName; string subDesc = sub.Description; string subLangCode = sub.LanguageCode; string subLanguage = sub.LanguageName; string subStreamFormat = string.Format(bdSubFormat, subCodecShort, subLangCode, subLanguage, streamIndex, subDesc); SubtitleInfo subInfo = new SubtitleInfo { Id = streamIndex, StreamId = streamIndex, TempFile = string.Empty, LangCode = subLangCode, Format = subCodecShort, DemuxStreamId = sub.PID, StreamSize = 0 }; CreateNode(subTree, subStreamFormat, subInfo); } playlistIndex++; } _defaultSelection = longestClip - 1; }