private void LoadVobSubFromMatroska(MatroskaSubtitleInfo matroskaSubtitleInfo, string fileName) { if (matroskaSubtitleInfo.ContentEncodingType == 1) { MessageBox.Show("Encrypted vobsub content not supported"); } bool isValid; var matroska = new Matroska(); ShowStatus(_language.ParsingMatroskaFile); Refresh(); Cursor.Current = Cursors.WaitCursor; List<SubtitleSequence> sub = matroska.GetMatroskaSubtitle(fileName, (int)matroskaSubtitleInfo.TrackNumber, out isValid, MatroskaProgress); Cursor.Current = Cursors.Default; if (isValid) { MakeHistoryForUndo(_language.BeforeImportFromMatroskaFile); _subtitleListViewIndex = -1; _subtitle.Paragraphs.Clear(); List<VobSubMergedPack> mergedVobSubPacks = new List<VobSubMergedPack>(); Nikse.SubtitleEdit.Logic.VobSub.Idx idx = new Logic.VobSub.Idx(matroskaSubtitleInfo.CodecPrivate.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries)); foreach (SubtitleSequence p in sub) { if (matroskaSubtitleInfo.ContentEncodingType == 0) // compressed with zlib { bool error = false; MemoryStream outStream = new MemoryStream(); ComponentAce.Compression.Libs.zlib.ZOutputStream outZStream = new ComponentAce.Compression.Libs.zlib.ZOutputStream(outStream); MemoryStream inStream = new MemoryStream(p.BinaryData); byte[] buffer = null; try { CopyStream(inStream, outZStream); buffer = new byte[outZStream.TotalOut]; outStream.Position = 0; outStream.Read(buffer, 0, buffer.Length); } catch (Exception exception) { MessageBox.Show(exception.Message + Environment.NewLine + Environment.NewLine + exception.StackTrace); error = true; } finally { outStream.Close(); outZStream.Close(); inStream.Close(); } if (!error) mergedVobSubPacks.Add(new VobSubMergedPack(buffer, TimeSpan.FromMilliseconds(p.StartMilliseconds), 32, null)); } else { mergedVobSubPacks.Add(new VobSubMergedPack(p.BinaryData, TimeSpan.FromMilliseconds(p.StartMilliseconds), 32, null)); } mergedVobSubPacks[mergedVobSubPacks.Count - 1].EndTime = TimeSpan.FromMilliseconds(p.EndMilliseconds); // fix overlapping (some versions of Handbrake makes overlapping time codes - thx Hawke) if (mergedVobSubPacks.Count > 1 && mergedVobSubPacks[mergedVobSubPacks.Count - 2].EndTime > mergedVobSubPacks[mergedVobSubPacks.Count - 1].StartTime) mergedVobSubPacks[mergedVobSubPacks.Count - 2].EndTime = TimeSpan.FromMilliseconds(mergedVobSubPacks[mergedVobSubPacks.Count - 1].StartTime.TotalMilliseconds - 1); } var formSubOcr = new VobSubOcr(); _formPositionsAndSizes.SetPositionAndSize(formSubOcr); formSubOcr.Initialize(mergedVobSubPacks, idx.Palette, Configuration.Settings.VobSubOcr, null); //TODO - language??? if (_loading) { formSubOcr.Icon = (Icon)this.Icon.Clone(); formSubOcr.ShowInTaskbar = true; formSubOcr.ShowIcon = true; } if (formSubOcr.ShowDialog(this) == DialogResult.OK) { ResetSubtitle(); _subtitle.Paragraphs.Clear(); _subtitle.WasLoadedWithFrameNumbers = false; foreach (Paragraph p in formSubOcr.SubtitleFromOcr.Paragraphs) _subtitle.Paragraphs.Add(p); ShowSource(); SubtitleListview1.Fill(_subtitle, _subtitleAlternate); _subtitleListViewIndex = -1; SubtitleListview1.FirstVisibleIndex = -1; SubtitleListview1.SelectIndexAndEnsureVisible(0); _fileName = Path.GetFileNameWithoutExtension(fileName); _converted = true; Text = Title; Configuration.Settings.Save(); } _formPositionsAndSizes.SavePositionAndSize(formSubOcr); } }
private void LoadBluRaySubFromMatroska(MatroskaSubtitleInfo matroskaSubtitleInfo, string fileName) { if (matroskaSubtitleInfo.ContentEncodingType == 1) { MessageBox.Show("Encrypted vobsub content not supported"); } bool isValid; var matroska = new Matroska(); ShowStatus(_language.ParsingMatroskaFile); Refresh(); Cursor.Current = Cursors.WaitCursor; List<SubtitleSequence> sub = matroska.GetMatroskaSubtitle(fileName, (int)matroskaSubtitleInfo.TrackNumber, out isValid, MatroskaProgress); Cursor.Current = Cursors.Default; int noOfErrors = 0; string lastError = string.Empty; if (isValid) { MakeHistoryForUndo(_language.BeforeImportFromMatroskaFile); _subtitleListViewIndex = -1; _subtitle.Paragraphs.Clear(); var subtitles = new List<Nikse.SubtitleEdit.Logic.BluRaySup.BluRaySupParser.PcsData>(); StringBuilder log = new StringBuilder(); foreach (SubtitleSequence p in sub) { byte[] buffer = null; if (matroskaSubtitleInfo.ContentEncodingType == 0) // compressed with zlib { MemoryStream outStream = new MemoryStream(); ComponentAce.Compression.Libs.zlib.ZOutputStream outZStream = new ComponentAce.Compression.Libs.zlib.ZOutputStream(outStream); MemoryStream inStream = new MemoryStream(p.BinaryData); try { CopyStream(inStream, outZStream); buffer = new byte[outZStream.TotalOut]; outStream.Position = 0; outStream.Read(buffer, 0, buffer.Length); } catch (Exception exception) { TimeCode tc = new TimeCode(TimeSpan.FromMilliseconds(p.StartMilliseconds)); lastError = tc.ToString() + ": " + exception.Message + ": " + exception.StackTrace; noOfErrors++; } finally { outStream.Close(); outZStream.Close(); inStream.Close(); } } else { buffer = p.BinaryData; } if (buffer != null && buffer.Length > 100) { MemoryStream ms = new MemoryStream(buffer); var list = BluRaySupParser.ParseBluRaySup(ms, log, true); foreach (var sup in list) { sup.StartTime = (long) ((p.StartMilliseconds - 1)*90.0); sup.EndTime = (long) ((p.EndMilliseconds - 1)*90.0); subtitles.Add(sup); // fix overlapping if (subtitles.Count > 1 && sub[subtitles.Count - 2].EndMilliseconds > sub[subtitles.Count - 1].StartMilliseconds) subtitles[subtitles.Count - 2].EndTime = subtitles[subtitles.Count - 1].StartTime - 1; } ms.Close(); } else if (subtitles.Count > 0) { var lastSub = subtitles[subtitles.Count - 1]; if (lastSub.StartTime == lastSub.EndTime) { lastSub.EndTime = (long)((p.StartMilliseconds - 1) * 90.0); if (lastSub.EndTime - lastSub.StartTime > 1000000) lastSub.EndTime = lastSub.StartTime; } } } if (noOfErrors > 0) { MessageBox.Show(string.Format("{0} errror(s) occured during extraction of bdsup\r\n\r\n{1}", noOfErrors, lastError)); } var formSubOcr = new VobSubOcr(); _formPositionsAndSizes.SetPositionAndSize(formSubOcr); formSubOcr.Initialize(subtitles, Configuration.Settings.VobSubOcr, fileName); if (_loading) { formSubOcr.Icon = (Icon)Icon.Clone(); formSubOcr.ShowInTaskbar = true; formSubOcr.ShowIcon = true; } if (formSubOcr.ShowDialog(this) == DialogResult.OK) { MakeHistoryForUndo(_language.BeforeImportingDvdSubtitle); _subtitle.Paragraphs.Clear(); SetCurrentFormat(Configuration.Settings.General.DefaultSubtitleFormat); _subtitle.WasLoadedWithFrameNumbers = false; _subtitle.CalculateFrameNumbersFromTimeCodes(CurrentFrameRate); foreach (Paragraph p in formSubOcr.SubtitleFromOcr.Paragraphs) { _subtitle.Paragraphs.Add(p); } ShowSource(); SubtitleListview1.Fill(_subtitle, _subtitleAlternate); _subtitleListViewIndex = -1; SubtitleListview1.FirstVisibleIndex = -1; SubtitleListview1.SelectIndexAndEnsureVisible(0); _fileName = string.Empty; Text = Title; Configuration.Settings.Save(); } _formPositionsAndSizes.SavePositionAndSize(formSubOcr); } }
internal Subtitle LoadMatroskaSubtitleForSync(MatroskaSubtitleInfo matroskaSubtitleInfo, string fileName) { Subtitle subtitle = new Subtitle(); bool isValid; bool isSsa = false; var matroska = new Matroska(); SubtitleFormat format; if (matroskaSubtitleInfo.CodecId.ToUpper() == "S_VOBSUB") { return subtitle; } if (matroskaSubtitleInfo.CodecId.ToUpper() == "S_HDMV/PGS") { return subtitle; } List<SubtitleSequence> sub = matroska.GetMatroskaSubtitle(fileName, (int)matroskaSubtitleInfo.TrackNumber, out isValid, MatroskaProgress); if (isValid) { if (matroskaSubtitleInfo.CodecPrivate.ToLower().Contains("[script info]")) { if (matroskaSubtitleInfo.CodecPrivate.ToLower().Contains("[V4 Styles]".ToLower())) format = new SubStationAlpha(); else format = new AdvancedSubStationAlpha(); isSsa = true; } else { format = new SubRip(); } if (isSsa) { foreach (Paragraph p in LoadMatroskaSSa(matroskaSubtitleInfo, fileName, format, sub).Paragraphs) { subtitle.Paragraphs.Add(p); } } else { foreach (SubtitleSequence p in sub) { subtitle.Paragraphs.Add(new Paragraph(p.Text, p.StartMilliseconds, p.EndMilliseconds)); } } } return subtitle; }
public static Subtitle LoadMatroskaSSa(MatroskaSubtitleInfo matroskaSubtitleInfo, string fileName, SubtitleFormat format, List<SubtitleSequence> sub) { var subtitle = new Subtitle(); subtitle.Header = matroskaSubtitleInfo.CodecPrivate; var lines = new List<string>(); foreach (string l in subtitle.Header.Trim().Replace(Environment.NewLine, "\n").Split('\n')) lines.Add(l); var footer = new StringBuilder(); var comments = new Subtitle(); if (!string.IsNullOrEmpty(matroskaSubtitleInfo.CodecPrivate)) { bool footerOn = false; foreach (string line in lines) { if (footerOn) { footer.AppendLine(line); } else if (line.Trim() == "[Events]") { footerOn = false; } else if (line.Trim() == "[Fonts]" || line.Trim() == "[Graphics]") { footerOn = true; footer.AppendLine(); footer.AppendLine(); footer.AppendLine(line); } else if (line.StartsWith("Comment:")) { var arr = line.Split(','); if (arr.Length > 3) { arr = arr[1].Split(":.".ToCharArray()); if (arr.Length == 4) { int hour; int min; int sec; int ms; if (int.TryParse(arr[0], out hour) && int.TryParse(arr[1], out min) && int.TryParse(arr[2], out sec) && int.TryParse(arr[3], out ms)) { comments.Paragraphs.Add(new Paragraph(new TimeCode(hour, min, sec, ms * 10), new TimeCode(0, 0, 0, 0), line)); } } } } } } if (!subtitle.Header.Contains("[Events]")) { subtitle.Header = subtitle.Header.Trim() + Environment.NewLine + Environment.NewLine + "[Events]" + Environment.NewLine + "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" + Environment.NewLine; } else { subtitle.Header = subtitle.Header.Remove(subtitle.Header.IndexOf("[Events]")); subtitle.Header = subtitle.Header.Trim() + Environment.NewLine + Environment.NewLine + "[Events]" + Environment.NewLine + "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" + Environment.NewLine; } lines = new List<string>(); foreach (string l in subtitle.Header.Trim().Replace(Environment.NewLine, "\n").Split('\n')) lines.Add(l); const string timeCodeFormat = "{0}:{1:00}:{2:00}.{3:00}"; // h:mm:ss.cc foreach (SubtitleSequence mp in sub) { Paragraph p = new Paragraph(string.Empty, mp.StartMilliseconds, mp.EndMilliseconds); string start = string.Format(timeCodeFormat, p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, p.StartTime.Milliseconds / 10); string end = string.Format(timeCodeFormat, p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, p.EndTime.Milliseconds / 10); //MKS contains this: ReadOrder, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, Text for (int commentIndex = 0; commentIndex < comments.Paragraphs.Count; commentIndex++) { var cp = comments.Paragraphs[commentIndex]; if (cp.StartTime.TotalMilliseconds <= p.StartTime.TotalMilliseconds) lines.Add(cp.Text); } for (int commentIndex = comments.Paragraphs.Count - 1; commentIndex >= 0; commentIndex--) { var cp = comments.Paragraphs[commentIndex]; if (cp.StartTime.TotalMilliseconds <= p.StartTime.TotalMilliseconds) comments.Paragraphs.RemoveAt(commentIndex); } string text = mp.Text.Replace(Environment.NewLine, "\\N"); int idx = text.IndexOf(',') + 1; if (idx > 0 && idx < text.Length) { text = text.Remove(0, idx); // remove ReadOrder idx = text.IndexOf(','); text = text.Insert(idx, "," + start + "," + end); lines.Add("Dialogue: " + text); } } for (int commentIndex = 0; commentIndex < comments.Paragraphs.Count; commentIndex++) { var cp = comments.Paragraphs[commentIndex]; lines.Add(cp.Text); } foreach (string l in footer.ToString().Replace(Environment.NewLine, "\n").Split('\n')) lines.Add(l); format.LoadSubtitle(subtitle, lines, fileName); return subtitle; }
internal void LoadMatroskaSubtitle(MatroskaSubtitleInfo matroskaSubtitleInfo, string fileName, bool batchMode) { bool isValid; bool isSsa = false; var matroska = new Matroska(); SubtitleFormat format; if (matroskaSubtitleInfo.CodecId.ToUpper() == "S_VOBSUB") { if (batchMode) return; LoadVobSubFromMatroska(matroskaSubtitleInfo, fileName); return; } if (matroskaSubtitleInfo.CodecId.ToUpper() == "S_HDMV/PGS") { if (batchMode) return; LoadBluRaySubFromMatroska(matroskaSubtitleInfo, fileName); return; } ShowStatus(_language.ParsingMatroskaFile); Refresh(); Cursor.Current = Cursors.WaitCursor; List<SubtitleSequence> sub = matroska.GetMatroskaSubtitle(fileName, (int)matroskaSubtitleInfo.TrackNumber, out isValid, MatroskaProgress); Cursor.Current = Cursors.Default; if (isValid) { MakeHistoryForUndo(_language.BeforeImportFromMatroskaFile); _subtitleListViewIndex = -1; if (!batchMode) ResetSubtitle(); _subtitle.Paragraphs.Clear(); if (matroskaSubtitleInfo.CodecPrivate.ToLower().Contains("[script info]")) { if (matroskaSubtitleInfo.CodecPrivate.ToLower().Contains("[V4 Styles]".ToLower())) format = new SubStationAlpha(); else format = new AdvancedSubStationAlpha(); isSsa = true; if (_networkSession == null) { SubtitleListview1.ShowExtraColumn(Configuration.Settings.Language.General.Style); SubtitleListview1.DisplayExtraFromExtra = true; } } else { format = new SubRip(); if (_networkSession == null && SubtitleListview1.IsExtraColumnVisible) SubtitleListview1.HideExtraColumn(); } comboBoxSubtitleFormats.SelectedIndexChanged -= ComboBoxSubtitleFormatsSelectedIndexChanged; SetCurrentFormat(format); comboBoxSubtitleFormats.SelectedIndexChanged += ComboBoxSubtitleFormatsSelectedIndexChanged; if (isSsa) { foreach (Paragraph p in LoadMatroskaSSa(matroskaSubtitleInfo, fileName, format, sub).Paragraphs) { _subtitle.Paragraphs.Add(p); } if (!string.IsNullOrEmpty(matroskaSubtitleInfo.CodecPrivate)) { bool eventsStarted = false; bool fontsStarted = false; bool graphicsStarted = false; var header = new StringBuilder(); foreach (string line in matroskaSubtitleInfo.CodecPrivate.Replace(Environment.NewLine, "\n").Split('\n')) { if (!eventsStarted && !fontsStarted && !graphicsStarted) { header.AppendLine(line); } else if (line.Trim().ToLower().StartsWith("dialogue:")) { eventsStarted = true; fontsStarted = false; graphicsStarted = false; } else if (line.Trim().ToLower() == "[events]") { eventsStarted = true; fontsStarted = false; graphicsStarted = false; } else if (line.Trim().ToLower() == "[fonts]") { eventsStarted = false; fontsStarted = true; graphicsStarted = false; } else if (line.Trim().ToLower() == "[graphics]") { eventsStarted = false; fontsStarted = false; graphicsStarted = true; } } _subtitle.Header = header.ToString(); } } else { foreach (SubtitleSequence p in sub) { _subtitle.Paragraphs.Add(new Paragraph(p.Text, p.StartMilliseconds, p.EndMilliseconds)); } } SetEncoding(Encoding.UTF8); ShowStatus(_language.SubtitleImportedFromMatroskaFile); _subtitle.Renumber(1); _subtitle.WasLoadedWithFrameNumbers = false; if (fileName.ToLower().EndsWith(".mkv") || fileName.ToLower().EndsWith(".mks")) { _fileName = fileName.Substring(0, fileName.Length - 4); Text = Title + " - " + _fileName; } else { Text = Title; } _fileDateTime = new DateTime(); _converted = true; if (batchMode) return; SubtitleListview1.Fill(_subtitle, _subtitleAlternate); if (_subtitle.Paragraphs.Count > 0) SubtitleListview1.SelectIndexAndEnsureVisible(0); ShowSource(); } }