using System; using System.Collections.Generic; using System.IO; using System.Text; namespace Nikse.SubtitleEdit.Core.SubtitleFormats { /// /// Timeline - THE MOVIE TITRE EDITOR - http://www.pld.ttu.ee/~priidu/timeline/ by priidu@pld.ttu.ee /// public class TimeLineMvt : SubtitleFormat { public override string Extension { get { return ".mvt"; } } public override string Name { get { return "Timeline mvt"; } } public override bool IsTimeBased { get { return true; } } public override bool IsMine(List lines, string fileName) { var subtitle = new Subtitle(); LoadSubtitle(subtitle, lines, fileName); return subtitle.Paragraphs.Count > _errorCount; } public override string ToText(Subtitle subtitle, string title) { return string.Empty; } public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName) { var bytes = File.ReadAllBytes(fileName); if (bytes.Length < 100 || bytes[0] != 0x54 || bytes[1] != 0x50 || bytes[2] != 0x46) { return; } // title int index = 9; while (index < bytes.Length && bytes[index] != 0x6) { index++; } if (index + 1 >= bytes.Length) { return; } string title = Encoding.UTF8.GetString(bytes, 9, index - 9); Console.WriteLine(title); // language1 index += 2; int start = index; while (index < bytes.Length && bytes[index] != 0x6) { index++; } if (index + 1 >= bytes.Length) { return; } string language1 = Encoding.UTF8.GetString(bytes, start, index - start); Console.WriteLine(language1); // language2 index += 2; start = index; while (index < bytes.Length && bytes[index] != 0x6) { index++; } if (index + 1 >= bytes.Length) { return; } string language2 = Encoding.UTF8.GetString(bytes, start, index - start); Console.WriteLine(language2); Encoding encoding1 = GetEncodingFromLanguage(language1); Encoding encoding2 = GetEncodingFromLanguage(language2); _errorCount = 0; while (index < bytes.Length - 20) { if (bytes[index] == 5 && bytes[index + 1] == 0 && bytes[index + 2] == 0) // find subtitle { // time codes int timeCodeIndexStart = index + 4; int timeCodeIndexEnd = index + 15; index += 22; while (index < bytes.Length && bytes[index] != 0x6) { index++; } index += 2; while (index < bytes.Length && bytes[index] == 0x6) { index += 2; } if (index < bytes.Length - 3) { // first line start = index; while (index < bytes.Length && bytes[index] != 0x6) { index++; } if (index < bytes.Length - 3) { string text1 = encoding1.GetString(bytes, start, index - start); index += 2; // second line start = index; while (index < bytes.Length && bytes[index] != 0x5) { index++; } if (index + 1 < bytes.Length) { string text2 = encoding2.GetString(bytes, start, index - start); var p = new Paragraph { Text = text1 + Environment.NewLine + text2, StartTime = { TotalMilliseconds = GetTimeCode(bytes, timeCodeIndexStart) }, EndTime = { TotalMilliseconds = GetTimeCode(bytes, timeCodeIndexEnd) } }; subtitle.Paragraphs.Add(p); index--; } } } } index++; } subtitle.Renumber(); } private double GetTimeCode(byte[] bytes, int timeCodeIndex) { //TODO: figure out how to get time code from these 7 bytes! if (bytes == null || bytes.Length < timeCodeIndex + 8) return 0; Console.WriteLine(bytes[timeCodeIndex + 0].ToString("X2") + " " + bytes[timeCodeIndex + 1].ToString("X2") + " " + bytes[timeCodeIndex + 2].ToString("X2") + " " + bytes[timeCodeIndex + 3].ToString("X2") + " " + bytes[timeCodeIndex + 4].ToString("X2") + " " + bytes[timeCodeIndex + 5].ToString("X2") + " " + bytes[timeCodeIndex + 6].ToString("X2")); return ((bytes[timeCodeIndex + 5] << 24) + (bytes[timeCodeIndex + 4] << 16) + (bytes[timeCodeIndex + 3] << 8) + (bytes[timeCodeIndex + 2])) / 1800.0; } private Encoding GetEncodingFromLanguage(string language) { if (language == "Russian") return Encoding.GetEncoding(1251); if (language == "Estonian" || language == "Latvian" || language == "Lithuanian") return Encoding.GetEncoding(1257); return Encoding.GetEncoding(1252); } } }