diff --git a/CUETools.Codecs.BDLPCM/BDLPCMReaderSettings.cs b/CUETools.Codecs.BDLPCM/BDLPCMReaderSettings.cs index 3822dd5..0ea451a 100644 --- a/CUETools.Codecs.BDLPCM/BDLPCMReaderSettings.cs +++ b/CUETools.Codecs.BDLPCM/BDLPCMReaderSettings.cs @@ -9,8 +9,12 @@ namespace CUETools.Codecs.BDLPCM { public BDLPCMReaderSettings() { + IgnoreShortItems = true; } - + + [Browsable(false)] + public bool IgnoreShortItems { get; set; } + [Browsable(false)] public int? Stream { get; set; } diff --git a/CUETools.Codecs.BDLPCM/MPLSReader.cs b/CUETools.Codecs.BDLPCM/MPLSReader.cs index 0e88327..6f7db4b 100644 --- a/CUETools.Codecs.BDLPCM/MPLSReader.cs +++ b/CUETools.Codecs.BDLPCM/MPLSReader.cs @@ -57,9 +57,10 @@ namespace CUETools.Codecs.BDLPCM foreach (var audio in item.audio) { if (audio.coding_type != 0x80 /* LPCM */) continue; + if (settings.IgnoreShortItems && item.out_time - item.in_time < shortItemDuration) continue; if (audio.pid == chosenPid) { - var parent = Directory.GetParent(System.IO.Path.GetDirectoryName(_path)); + var parent = Directory.GetParent(System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(_path))); var m2ts = System.IO.Path.Combine( System.IO.Path.Combine(parent.FullName, "STREAM"), item.clip_id + ".m2ts"); @@ -299,7 +300,10 @@ namespace CUETools.Codecs.BDLPCM uint totalLength = 0; foreach (var item in hdr_m.play_item) { - totalLength += item.out_time - item.in_time; + if (item.num_audio == 0) continue; + uint item_duration = item.out_time - item.in_time; + if (settings.IgnoreShortItems && item_duration < shortItemDuration) continue; + totalLength += item_duration; } return TimeSpan.FromSeconds(totalLength / 45000.0); @@ -371,6 +375,48 @@ namespace CUETools.Codecs.BDLPCM } } + public List Chapters + { + get + { + //settings.IgnoreShortItems + var res = new List(); + if (hdr_m.play_mark.Count < 1) return res; + if (hdr_m.play_item.Count < 1) return res; + res.Add(0); + for (int i = 0; i < hdr_m.mark_count; i++) + { + ushort mark_item = hdr_m.play_mark[i].play_item_ref; + uint item_in_time = hdr_m.play_item[mark_item].in_time; + uint item_out_time = hdr_m.play_item[mark_item].out_time; + if (settings.IgnoreShortItems && item_out_time - item_in_time < shortItemDuration) continue; + uint item_offset = 0; + for (int j = 0; j < mark_item; j++) + { + if (hdr_m.play_item[j].num_audio == 0) continue; + uint item_duration = hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time; + if (settings.IgnoreShortItems && item_duration < shortItemDuration) continue; + item_offset += item_duration; + } + res.Add(hdr_m.play_mark[i].time - item_in_time + item_offset); + } + uint end_offset = 0; + for (int j = 0; j < hdr_m.play_item.Count; j++) + { + if (hdr_m.play_item[j].num_audio == 0) continue; + uint item_duration = hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time; + if (settings.IgnoreShortItems && item_duration < shortItemDuration) continue; + end_offset += hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time; + } + res.Add(end_offset); + while (res.Count > 1 && res[1] - res[0] < 45000) res.RemoveAt(1); + while (res.Count > 1 && res[res.Count - 1] - res[res.Count - 2] < 45000) res.RemoveAt(res.Count - 2); + return res; + } + } + + readonly static int shortItemDuration = 45000 * 30; + string _path; Stream _IO; byte[] contents; @@ -583,26 +629,5 @@ namespace CUETools.Codecs.BDLPCM public List play_item; public List play_mark; - - public List Chapters - { - get - { - var res = new List(); - if (play_mark.Count < 1) return res; - if (play_item.Count < 1) return res; - uint start = play_item[0].in_time; - uint end = play_item[play_item.Count - 1].out_time; - if (play_mark[0].time - start > 45000) - res.Add(0); - for (int i = 0; i < mark_count; i++) - { - if (end - play_mark[i].time > 45000) - res.Add(play_mark[i].time - start); - } - res.Add(end - start); - return res; - } - } } } diff --git a/CUETools.eac3to/Program.cs b/CUETools.eac3to/Program.cs index 9cda30c..f062162 100644 --- a/CUETools.eac3to/Program.cs +++ b/CUETools.eac3to/Program.cs @@ -8,6 +8,7 @@ using System.Collections.Specialized; using CUETools.Codecs.BDLPCM; using CUETools.CDImage; using CUETools.CTDB; +using System.Text; namespace CUETools.eac3to { @@ -128,7 +129,7 @@ namespace CUETools.eac3to Console.ForegroundColor = ConsoleColor.White; int frameRate = 0; bool interlaced = false; - var chapters = audioSource.MPLSHeader.Chapters; + var chapters = audioSource.Chapters; var videos = new List(); var audios = new List(); audioSource.MPLSHeader.play_item.ForEach(i => i.video.ForEach(v => { if (!videos.Exists(v1 => v1.pid == v.pid)) videos.Add(v); })); @@ -177,21 +178,59 @@ namespace CUETools.eac3to int chapterStreams = chapters.Count > 1 ? 1 : 0; if (stream <= chapterStreams) { - string extension = Path.GetExtension(destFile).ToLower(); - if (!extension.StartsWith(".")) - throw new Exception("Unknown encoder format: " + destFile); - encoderFormat = extension.Substring(1); + if (destFile == "-" || destFile == "nul") + { + encoderFormat = "txt"; + } + else + { + string extension = Path.GetExtension(destFile).ToLower(); + if (!extension.StartsWith(".")) + encoderFormat = destFile; + else + encoderFormat = extension.Substring(1); + if (encoderFormat != "txt" && encoderFormat != "cue") + { + Console.BackgroundColor = ConsoleColor.DarkRed; + Console.Error.Write("Unsupported chapters file format \"{0}\"", encoderFormat); + Console.BackgroundColor = ConsoleColor.Black; + Console.Error.WriteLine(); + return 0; + } + } + + string strtoc = ""; + for (int i = 0; i < chapters.Count; i++) + strtoc += string.Format(" {0}", chapters[i] / 600); + strtoc = strtoc.Substring(1); + CDImageLayout toc = new CDImageLayout(strtoc); + CTDBResponseMeta meta = null; + bool queryMeta = true; + if (queryMeta) + { + var ctdb = new CUEToolsDB(toc, null); + Console.Error.WriteLine("Contacting CTDB..."); + ctdb.ContactDB(null, "CUETools.eac3to 2.1.7", "", false, true, CTDBMetadataSearch.Extensive); + foreach (var imeta in ctdb.Metadata) + { + meta = imeta; + break; + } + } if (encoderFormat == "txt") { Console.Error.WriteLine("Creating file \"{0}\"...", destFile); - using (StreamWriter sw = new StreamWriter(destFile)) + using (TextWriter sw = destFile == "nul" ? (TextWriter)new StringWriter() : destFile == "-" ? Console.Out : (TextWriter)new StreamWriter(destFile)) { for (int i = 0; i < chapters.Count - 1; i++) { sw.WriteLine("CHAPTER{0:00}={1}", i + 1, CDImageLayout.TimeToString(TimeSpan.FromSeconds(chapters[i] / 45000.0))); - sw.WriteLine("CHAPTER{0:00}NAME=", i + 1); + if (meta != null && meta.track.Length >= toc[i+1].Number) + sw.WriteLine("CHAPTER{0:00}NAME={1}", i + 1, meta.track[(int)toc[i+1].Number - 1].name); + else + sw.WriteLine("CHAPTER{0:00}NAME=", i + 1); } } Console.BackgroundColor = ConsoleColor.DarkGreen; @@ -204,24 +243,6 @@ namespace CUETools.eac3to if (encoderFormat == "cue") { Console.Error.WriteLine("Creating file \"{0}\"...", destFile); - string strtoc = ""; - for (int i = 0; i < chapters.Count; i++) - strtoc += string.Format(" {0}", chapters[i] / 600); - strtoc = strtoc.Substring(1); - CDImageLayout toc = new CDImageLayout(strtoc); - CTDBResponseMeta meta = null; - bool queryMeta = true; - if (queryMeta) - { - var ctdb = new CUEToolsDB(toc, null); - Console.Error.WriteLine("Contacting CTDB..."); - ctdb.ContactDB(null, "CUETools.eac3to 2.1.7", "", false, true, CTDBMetadataSearch.Extensive); - foreach (var imeta in ctdb.Metadata) - { - meta = imeta; - break; - } - } //if (outputPath == null) //{ // if (meta != null) @@ -229,7 +250,7 @@ namespace CUETools.eac3to // else // outputPath = "unknown.cue"; //} - using (StreamWriter cueWriter = new StreamWriter(destFile)) + using (StreamWriter cueWriter = new StreamWriter(destFile, false, Encoding.UTF8)) { cueWriter.WriteLine("REM COMMENT \"{0}\"", "Created by CUETools.eac3to"); if (meta != null && meta.year != null) @@ -282,8 +303,7 @@ namespace CUETools.eac3to return 0; } - Console.Error.WriteLine("Unsupported chapters file format \"{0}\"", encoderFormat); - return 0; + throw new Exception("Unknown encoder format: " + destFile); } if (stream - chapterStreams <= videos.Count) {