public void MatroskaTestSrtContent() { string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_MKV_SRT.mkv"); using (var parser = new MatroskaFile(fileName)) { var tracks = parser.GetTracks(true); var subtitles = parser.GetSubtitle(Convert.ToInt32(tracks[0].TrackNumber), null); Assert.IsTrue(subtitles.Count == 2); Assert.IsTrue(subtitles[0].Text == "Line 1"); Assert.IsTrue(subtitles[1].Text == "Line 2"); } }
public void MatroskaTestVobSubPgsContent() { string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_MKV_VobSub_PGS.mkv"); using (var parser = new MatroskaFile(fileName)) { var tracks = parser.GetTracks(true); var subtitles = parser.GetSubtitle(Convert.ToInt32(tracks[0].TrackNumber), null); Assert.IsTrue(subtitles.Count == 2); // TODO: Check bitmaps //subtitles = parser.GetSubtitle(Convert.ToInt32(tracks[1].TrackNumber), null); //Assert.IsTrue(subtitles.Count == 2); //check bitmaps } }
private bool LoadBluRaySubFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska) { if (matroskaSubtitleInfo.ContentEncodingType == 1) { MessageBox.Show(_language.NoSupportEncryptedVobSub); } ShowStatus(_language.ParsingMatroskaFile); Refresh(); Cursor.Current = Cursors.WaitCursor; var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, MatroskaProgress); TaskbarList.SetProgressState(Handle, TaskbarButtonProgressFlags.NoProgress); Cursor.Current = Cursors.Default; int noOfErrors = 0; string lastError = string.Empty; MakeHistoryForUndo(_language.BeforeImportFromMatroskaFile); _subtitleListViewIndex = -1; _subtitle.Paragraphs.Clear(); var subtitles = new List<BluRaySupParser.PcsData>(); var log = new StringBuilder(); foreach (var p in sub) { byte[] buffer = null; if (matroskaSubtitleInfo.ContentEncodingType == 0) // compressed with zlib { var outStream = new MemoryStream(); var outZStream = new zlib.ZOutputStream(outStream); var inStream = new MemoryStream(p.Data); try { CopyStream(inStream, outZStream); buffer = new byte[outZStream.TotalOut]; outStream.Position = 0; outStream.Read(buffer, 0, buffer.Length); } catch (Exception exception) { var tc = new TimeCode(p.Start); lastError = tc + ": " + exception.Message + ": " + exception.StackTrace; noOfErrors++; } finally { outZStream.Close(); inStream.Close(); } } else { buffer = p.Data; } if (buffer != null && buffer.Length > 100) { var ms = new MemoryStream(buffer); var list = BluRaySupParser.ParseBluRaySup(ms, log, true); foreach (var sup in list) { sup.StartTime = (long)((p.Start - 1) * 90.0); sup.EndTime = (long)((p.End - 1) * 90.0); subtitles.Add(sup); // fix overlapping if (subtitles.Count > 1 && sub[subtitles.Count - 2].End > sub[subtitles.Count - 1].Start) 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.Start - 1) * 90.0); if (lastSub.EndTime - lastSub.StartTime > 1000000) lastSub.EndTime = lastSub.StartTime; } } } if (noOfErrors > 0) { MessageBox.Show(string.Format("{0} error(s) occurred during extraction of bdsup\r\n\r\n{1}", noOfErrors, lastError)); } using (var formSubOcr = new VobSubOcr()) { formSubOcr.Initialize(subtitles, Configuration.Settings.VobSubOcr, matroska.Path); 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 (var 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(); return true; } } return false; }
private bool LoadVobSubFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska) { if (matroskaSubtitleInfo.ContentEncodingType == 1) { MessageBox.Show(_language.NoSupportEncryptedVobSub); } ShowStatus(_language.ParsingMatroskaFile); Refresh(); Cursor.Current = Cursors.WaitCursor; var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, MatroskaProgress); TaskbarList.SetProgressState(Handle, TaskbarButtonProgressFlags.NoProgress); Cursor.Current = Cursors.Default; MakeHistoryForUndo(_language.BeforeImportFromMatroskaFile); _subtitleListViewIndex = -1; _subtitle.Paragraphs.Clear(); List<VobSubMergedPack> mergedVobSubPacks = new List<VobSubMergedPack>(); var idx = new Core.VobSub.Idx(matroskaSubtitleInfo.CodecPrivate.SplitToLines()); foreach (var p in sub) { if (matroskaSubtitleInfo.ContentEncodingType == 0) // compressed with zlib { bool error = false; var outStream = new MemoryStream(); var outZStream = new zlib.ZOutputStream(outStream); var inStream = new MemoryStream(p.Data); 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 { outZStream.Close(); inStream.Close(); } if (!error && buffer.Length > 2) mergedVobSubPacks.Add(new VobSubMergedPack(buffer, TimeSpan.FromMilliseconds(p.Start), 32, null)); } else { mergedVobSubPacks.Add(new VobSubMergedPack(p.Data, TimeSpan.FromMilliseconds(p.Start), 32, null)); } if (mergedVobSubPacks.Count > 0) mergedVobSubPacks[mergedVobSubPacks.Count - 1].EndTime = TimeSpan.FromMilliseconds(p.End); // 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); } using (var formSubOcr = new VobSubOcr()) { formSubOcr.Initialize(mergedVobSubPacks, idx.Palette, Configuration.Settings.VobSubOcr, null); // TODO: language??? if (_loading) { formSubOcr.Icon = (Icon)Icon.Clone(); formSubOcr.ShowInTaskbar = true; formSubOcr.ShowIcon = true; } if (formSubOcr.ShowDialog(this) == DialogResult.OK) { ResetSubtitle(); _subtitle.Paragraphs.Clear(); _subtitle.WasLoadedWithFrameNumbers = false; foreach (var 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(matroska.Path); _converted = true; Text = Title; Configuration.Settings.Save(); return true; } } return false; }
private bool LoadTextSTFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska, bool batchMode) { ShowStatus(_language.ParsingMatroskaFile); Refresh(); Cursor.Current = Cursors.WaitCursor; var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, MatroskaProgress); TaskbarList.SetProgressState(Handle, TaskbarButtonProgressFlags.NoProgress); Cursor.Current = Cursors.Default; MakeHistoryForUndo(_language.BeforeImportFromMatroskaFile); _subtitleListViewIndex = -1; if (!batchMode) ResetSubtitle(); _subtitle.Paragraphs.Clear(); Utilities.LoadMatroskaTextSubtitle(matroskaSubtitleInfo, matroska, sub, _subtitle); for (int index = 0; index < sub.Count; index++) { try { var msub = sub[index]; int idx = -6; // MakeMKV starts at DialogPresentationSegment if (VobSubParser.IsPrivateStream2(msub.Data, 0)) idx = 0; // starts with MPEG2 private stream 2 (just to be sure) var dps = new Nikse.SubtitleEdit.Core.SubtitleFormats.TextST.DialogPresentationSegment(msub.Data, idx); _subtitle.Paragraphs[index].Text = dps.Text; } catch (Exception exception) { _subtitle.Paragraphs[index].Text = exception.Message; } } if (_networkSession == null && SubtitleListview1.IsExtraColumnVisible) { SubtitleListview1.HideExtraColumn(); } comboBoxSubtitleFormats.SelectedIndexChanged -= ComboBoxSubtitleFormatsSelectedIndexChanged; SetCurrentFormat(Configuration.Settings.General.DefaultSubtitleFormat); comboBoxSubtitleFormats.SelectedIndexChanged += ComboBoxSubtitleFormatsSelectedIndexChanged; SetEncoding(Encoding.UTF8); ShowStatus(_language.SubtitleImportedFromMatroskaFile); _subtitle.Renumber(); _subtitle.WasLoadedWithFrameNumbers = false; if (matroska.Path.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase) || matroska.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase)) { _fileName = matroska.Path.Remove(matroska.Path.Length - 4); Text = Title + " - " + _fileName; } else { Text = Title; } _fileDateTime = new DateTime(); _converted = true; if (batchMode) return true; SubtitleListview1.Fill(_subtitle, _subtitleAlternate); if (_subtitle.Paragraphs.Count > 0) SubtitleListview1.SelectIndexAndEnsureVisible(0); ShowSource(); return true; }
private bool LoadMatroskaSubtitle(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska, bool batchMode) { if (matroskaSubtitleInfo.CodecId.Equals("S_VOBSUB", StringComparison.OrdinalIgnoreCase)) { if (batchMode) return false; return LoadVobSubFromMatroska(matroskaSubtitleInfo, matroska); } if (matroskaSubtitleInfo.CodecId.Equals("S_HDMV/PGS", StringComparison.OrdinalIgnoreCase)) { if (batchMode) return false; return LoadBluRaySubFromMatroska(matroskaSubtitleInfo, matroska); } if (matroskaSubtitleInfo.CodecId.Equals("S_HDMV/TEXTST", StringComparison.OrdinalIgnoreCase)) { if (batchMode) return false; return LoadTextSTFromMatroska(matroskaSubtitleInfo, matroska, batchMode); } ShowStatus(_language.ParsingMatroskaFile); Refresh(); Cursor.Current = Cursors.WaitCursor; var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, MatroskaProgress); TaskbarList.SetProgressState(Handle, TaskbarButtonProgressFlags.NoProgress); Cursor.Current = Cursors.Default; MakeHistoryForUndo(_language.BeforeImportFromMatroskaFile); _subtitleListViewIndex = -1; if (!batchMode) ResetSubtitle(); _subtitle.Paragraphs.Clear(); var format = Utilities.LoadMatroskaTextSubtitle(matroskaSubtitleInfo, matroska, sub, _subtitle); if (matroskaSubtitleInfo.CodecPrivate.Contains("[script info]", StringComparison.OrdinalIgnoreCase)) { if (_networkSession == null) { SubtitleListview1.ShowExtraColumn(_languageGeneral.Style); SubtitleListview1.DisplayExtraFromExtra = true; } } else if (_networkSession == null && SubtitleListview1.IsExtraColumnVisible) { SubtitleListview1.HideExtraColumn(); } comboBoxSubtitleFormats.SelectedIndexChanged -= ComboBoxSubtitleFormatsSelectedIndexChanged; SetCurrentFormat(format); comboBoxSubtitleFormats.SelectedIndexChanged += ComboBoxSubtitleFormatsSelectedIndexChanged; SetEncoding(Encoding.UTF8); ShowStatus(_language.SubtitleImportedFromMatroskaFile); _subtitle.Renumber(); _subtitle.WasLoadedWithFrameNumbers = false; if (matroska.Path.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase) || matroska.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase)) { _fileName = matroska.Path.Remove(matroska.Path.Length - 4); Text = Title + " - " + _fileName; } else { Text = Title; } _fileDateTime = new DateTime(); _converted = true; if (batchMode) return true; SubtitleListview1.Fill(_subtitle, _subtitleAlternate); if (_subtitle.Paragraphs.Count > 0) SubtitleListview1.SelectIndexAndEnsureVisible(0); ShowSource(); return true; }
private Subtitle LoadMatroskaSubtitleForSync(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska) { var subtitle = new Subtitle(); bool isSsa = false; if (matroskaSubtitleInfo.CodecId.Equals("S_VOBSUB", StringComparison.OrdinalIgnoreCase)) { return subtitle; } if (matroskaSubtitleInfo.CodecId.Equals("S_HDMV/PGS", StringComparison.OrdinalIgnoreCase)) { return subtitle; } SubtitleFormat format; if (matroskaSubtitleInfo.CodecPrivate.Contains("[script info]", StringComparison.OrdinalIgnoreCase)) { if (matroskaSubtitleInfo.CodecPrivate.Contains("[V4 Styles]", StringComparison.OrdinalIgnoreCase)) format = new SubStationAlpha(); else format = new AdvancedSubStationAlpha(); isSsa = true; } else { format = new SubRip(); } var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, MatroskaProgress); TaskbarList.SetProgressState(Handle, TaskbarButtonProgressFlags.NoProgress); if (isSsa) { foreach (var p in Utilities.LoadMatroskaSSA(matroskaSubtitleInfo, matroska.Path, format, sub).Paragraphs) { subtitle.Paragraphs.Add(p); } } else { foreach (var p in sub) { subtitle.Paragraphs.Add(new Paragraph(p.Text, p.Start, p.End)); } } return subtitle; }
private void buttonConvert_Click(object sender, EventArgs e) { if (listViewInputFiles.Items.Count == 0) { MessageBox.Show(Configuration.Settings.Language.BatchConvert.NothingToConvert); return; } if (!checkBoxOverwriteOriginalFiles.Checked) { if (textBoxOutputFolder.Text.Length < 2) { MessageBox.Show(Configuration.Settings.Language.BatchConvert.PleaseChooseOutputFolder); return; } if (!Directory.Exists(textBoxOutputFolder.Text)) { try { Directory.CreateDirectory(textBoxOutputFolder.Text); } catch (Exception exception) { MessageBox.Show(exception.Message); return; } } } _converting = true; buttonConvert.Enabled = false; buttonCancel.Enabled = false; progressBar1.Style = ProgressBarStyle.Blocks; progressBar1.Maximum = listViewInputFiles.Items.Count; progressBar1.Value = 0; progressBar1.Visible = progressBar1.Maximum > 2; string toFormat = comboBoxSubtitleFormats.Text; groupBoxOutput.Enabled = false; groupBoxConvertOptions.Enabled = false; buttonInputBrowse.Enabled = false; buttonSearchFolder.Enabled = false; comboBoxFilter.Enabled = false; textBoxFilter.Enabled = false; _count = 0; _converted = 0; _errors = 0; _abort = false; var worker1 = new BackgroundWorker(); var worker2 = new BackgroundWorker(); var worker3 = new BackgroundWorker(); worker1.DoWork += DoThreadWork; worker1.RunWorkerCompleted += ThreadWorkerCompleted; worker2.DoWork += DoThreadWork; worker2.RunWorkerCompleted += ThreadWorkerCompleted; worker3.DoWork += DoThreadWork; worker3.RunWorkerCompleted += ThreadWorkerCompleted; listViewInputFiles.BeginUpdate(); foreach (ListViewItem item in listViewInputFiles.Items) item.SubItems[3].Text = "-"; listViewInputFiles.EndUpdate(); Refresh(); int index = 0; while (index < listViewInputFiles.Items.Count && _abort == false) { ListViewItem item = listViewInputFiles.Items[index]; string fileName = item.Text; try { SubtitleFormat format = null; var sub = new Subtitle(); var fi = new FileInfo(fileName); if (fi.Length < 1024 * 1024) // max 1 mb { Encoding encoding; format = sub.LoadSubtitle(fileName, out encoding, null); if (format == null) { var ebu = new Ebu(); if (ebu.IsMine(null, fileName)) { ebu.LoadSubtitle(sub, null, fileName); format = ebu; } } if (format == null) { var pac = new Pac(); if (pac.IsMine(null, fileName)) { pac.BatchMode = true; pac.LoadSubtitle(sub, null, fileName); format = pac; } } if (format == null) { var cavena890 = new Cavena890(); if (cavena890.IsMine(null, fileName)) { cavena890.LoadSubtitle(sub, null, fileName); format = cavena890; } } if (format == null) { var spt = new Spt(); if (spt.IsMine(null, fileName)) { spt.LoadSubtitle(sub, null, fileName); format = spt; } } if (format == null) { var cheetahCaption = new CheetahCaption(); if (cheetahCaption.IsMine(null, fileName)) { cheetahCaption.LoadSubtitle(sub, null, fileName); format = cheetahCaption; } } if (format == null) { var capMakerPlus = new CapMakerPlus(); if (capMakerPlus.IsMine(null, fileName)) { capMakerPlus.LoadSubtitle(sub, null, fileName); format = capMakerPlus; } } if (format == null) { var captionate = new Captionate(); if (captionate.IsMine(null, fileName)) { captionate.LoadSubtitle(sub, null, fileName); format = captionate; } } if (format == null) { var ultech130 = new Ultech130(); if (ultech130.IsMine(null, fileName)) { ultech130.LoadSubtitle(sub, null, fileName); format = ultech130; } } if (format == null) { var nciCaption = new NciCaption(); if (nciCaption.IsMine(null, fileName)) { nciCaption.LoadSubtitle(sub, null, fileName); format = nciCaption; } } if (format == null) { var avidStl = new AvidStl(); if (avidStl.IsMine(null, fileName)) { avidStl.LoadSubtitle(sub, null, fileName); format = avidStl; } } if (format == null) { var elr = new ELRStudioClosedCaption(); if (elr.IsMine(null, fileName)) { elr.LoadSubtitle(sub, null, fileName); format = elr; } } if (format == null) { var enc = LanguageAutoDetect.GetEncodingFromFile(fileName); var s = File.ReadAllText(fileName, enc); // check for RTF file if (fileName.EndsWith(".rtf", StringComparison.OrdinalIgnoreCase) && s.TrimStart().StartsWith("{\\rtf", StringComparison.Ordinal)) { using (var rtb = new RichTextBox { Rtf = s }) { s = rtb.Text; } } var uknownFormatImporter = new UknownFormatImporter { UseFrames = true }; var genericParseSubtitle = uknownFormatImporter.AutoGuessImport(s.SplitToLines()); if (genericParseSubtitle.Paragraphs.Count > 1) { sub = genericParseSubtitle; format = new SubRip(); } } if (format != null && format.GetType() == typeof(MicroDvd)) { if (sub != null && sub.Paragraphs.Count > 0 && sub.Paragraphs[0].Duration.TotalMilliseconds < 1001) { if (sub.Paragraphs[0].Text.StartsWith("29.", StringComparison.Ordinal) || sub.Paragraphs[0].Text.StartsWith("23.", StringComparison.Ordinal) || sub.Paragraphs[0].Text.StartsWith("29,", StringComparison.Ordinal) || sub.Paragraphs[0].Text.StartsWith("23,", StringComparison.Ordinal) || sub.Paragraphs[0].Text == "24" || sub.Paragraphs[0].Text == "25" || sub.Paragraphs[0].Text == "30" || sub.Paragraphs[0].Text == "60") sub.Paragraphs.RemoveAt(0); } } } var bluRaySubtitles = new List<BluRaySupParser.PcsData>(); bool isVobSub = false; bool isMatroska = false; if (format == null && fileName.EndsWith(".sup", StringComparison.OrdinalIgnoreCase) && FileUtil.IsBluRaySup(fileName)) { var log = new StringBuilder(); bluRaySubtitles = BluRaySupParser.ParseBluRaySup(fileName, log); } else if (format == null && fileName.EndsWith(".sub", StringComparison.OrdinalIgnoreCase) && FileUtil.IsVobSub(fileName)) { isVobSub = true; } else if (format == null && (fileName.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".mks", StringComparison.OrdinalIgnoreCase)) && item.SubItems[2].Text.StartsWith("Matroska")) { isMatroska = true; } if (format == null && bluRaySubtitles.Count == 0 && !isVobSub && !isMatroska) { IncrementAndShowProgress(); } else { if (isMatroska && (Path.GetExtension(fileName).Equals(".mkv", StringComparison.OrdinalIgnoreCase) || Path.GetExtension(fileName).Equals(".mks", StringComparison.OrdinalIgnoreCase))) { using (var matroska = new MatroskaFile(fileName)) { if (matroska.IsValid) { foreach (var track in matroska.GetTracks(true)) { if (track.CodecId.Equals("S_VOBSUB", StringComparison.OrdinalIgnoreCase)) { // TODO: Convert from VobSub image based format! } else if (track.CodecId.Equals("S_HDMV/PGS", StringComparison.OrdinalIgnoreCase)) { // TODO: Convert from Blu-ray image based format! } else if (track.CodecId.Equals("S_TEXT/UTF8", StringComparison.OrdinalIgnoreCase) || track.CodecId.Equals("S_TEXT/SSA", StringComparison.OrdinalIgnoreCase) || track.CodecId.Equals("S_TEXT/ASS", StringComparison.OrdinalIgnoreCase)) { var mkvSub = matroska.GetSubtitle(track.TrackNumber, null); Utilities.LoadMatroskaTextSubtitle(track, matroska, mkvSub, sub); break; } } } } } else if (bluRaySubtitles.Count > 0) { item.SubItems[3].Text = Configuration.Settings.Language.BatchConvert.Ocr; using (var vobSubOcr = new VobSubOcr()) { vobSubOcr.FileName = Path.GetFileName(fileName); vobSubOcr.InitializeBatch(bluRaySubtitles, Configuration.Settings.VobSubOcr, fileName); sub = vobSubOcr.SubtitleFromOcr; } } else if (isVobSub) { item.SubItems[3].Text = Configuration.Settings.Language.BatchConvert.Ocr; using (var vobSubOcr = new VobSubOcr()) { vobSubOcr.InitializeBatch(fileName, Configuration.Settings.VobSubOcr); sub = vobSubOcr.SubtitleFromOcr; } } if (comboBoxSubtitleFormats.Text == AdvancedSubStationAlpha.NameOfFormat && _assStyle != null) { sub.Header = _assStyle; } else if (comboBoxSubtitleFormats.Text == SubStationAlpha.NameOfFormat && _ssaStyle != null) { sub.Header = _ssaStyle; } bool skip = CheckSkipFilter(fileName, format, sub); if (skip) { item.SubItems[3].Text = Configuration.Settings.Language.BatchConvert.FilterSkipped; } else { foreach (Paragraph p in sub.Paragraphs) { if (checkBoxRemoveTextForHI.Checked) { p.Text = _removeTextForHearingImpaired.RemoveTextFromHearImpaired(p.Text); } if (checkBoxRemoveFormatting.Checked) { p.Text = HtmlUtil.RemoveHtmlTags(p.Text, true); } } sub.RemoveEmptyLines(); if (checkBoxFixCasing.Checked) { _changeCasing.FixCasing(sub, LanguageAutoDetect.AutoDetectGoogleLanguage(sub)); _changeCasingNames.Initialize(sub); _changeCasingNames.FixCasing(); } double fromFrameRate; double toFrameRate; if (double.TryParse(comboBoxFrameRateFrom.Text.Replace(',', '.'), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out fromFrameRate) && double.TryParse(comboBoxFrameRateTo.Text.Replace(',', '.'), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out toFrameRate)) { sub.ChangeFrameRate(fromFrameRate, toFrameRate); } if (timeUpDownAdjust.TimeCode.TotalMilliseconds > 0.00001) { var totalMilliseconds = timeUpDownAdjust.TimeCode.TotalMilliseconds; if (radioButtonShowEarlier.Checked) totalMilliseconds *= -1; sub.AddTimeToAllParagraphs(TimeSpan.FromMilliseconds(totalMilliseconds)); } while (worker1.IsBusy && worker2.IsBusy && worker3.IsBusy) { Application.DoEvents(); System.Threading.Thread.Sleep(100); } var parameter = new ThreadDoWorkParameter(checkBoxFixCommonErrors.Checked, checkBoxMultipleReplace.Checked, checkBoxSplitLongLines.Checked, checkBoxAutoBalance.Checked, checkBoxSetMinimumDisplayTimeBetweenSubs.Checked, item, sub, GetCurrentSubtitleFormat(), GetCurrentEncoding(), Configuration.Settings.Tools.BatchConvertLanguage, fileName, toFormat, format); if (!worker1.IsBusy) worker1.RunWorkerAsync(parameter); else if (!worker2.IsBusy) worker2.RunWorkerAsync(parameter); else if (!worker3.IsBusy) worker3.RunWorkerAsync(parameter); } } } catch { IncrementAndShowProgress(); } index++; } while (worker1.IsBusy || worker2.IsBusy || worker3.IsBusy) { try { Application.DoEvents(); } catch { } System.Threading.Thread.Sleep(100); } _converting = false; labelStatus.Text = string.Empty; progressBar1.Visible = false; TaskbarList.SetProgressState(Handle, TaskbarButtonProgressFlags.NoProgress); buttonConvert.Enabled = true; buttonCancel.Enabled = true; groupBoxOutput.Enabled = true; groupBoxConvertOptions.Enabled = true; buttonInputBrowse.Enabled = true; buttonSearchFolder.Enabled = true; comboBoxFilter.Enabled = true; textBoxFilter.Enabled = true; }
// E.g.: /convert *.txt SubRip public static void Convert(string title, string[] args) { const int ATTACH_PARENT_PROCESS = -1; if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux()) NativeMethods.AttachConsole(ATTACH_PARENT_PROCESS); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(title + " - Batch converter"); Console.WriteLine(); Console.WriteLine("- Syntax: SubtitleEdit /convert <pattern> <name-of-format-without-spaces> [/offset:hh:mm:ss:ms] [/encoding:<encoding name>] [/fps:<frame rate>] [/targetfps:<frame rate>] [/inputfolder:<input folder>] [/outputfolder:<output folder>] [/pac-codepage:<code page>]"); Console.WriteLine(); Console.WriteLine(" example: SubtitleEdit /convert *.srt sami"); Console.WriteLine(" list available formats: SubtitleEdit /convert /list"); Console.WriteLine(); string currentDir = Directory.GetCurrentDirectory(); if (args.Length < 4) { if (args.Length == 3 && (args[2].Equals("/list", StringComparison.OrdinalIgnoreCase) || args[2].Equals("-list", StringComparison.OrdinalIgnoreCase))) { Console.WriteLine("- Supported formats (input/output):"); foreach (SubtitleFormat format in SubtitleFormat.AllSubtitleFormats) { Console.WriteLine(" " + format.Name.Replace(" ", string.Empty)); } Console.WriteLine(); Console.WriteLine("- Supported formats (input only):"); Console.WriteLine(" " + CapMakerPlus.NameOfFormat); Console.WriteLine(" " + Captionate.NameOfFormat); Console.WriteLine(" " + Cavena890.NameOfFormat); Console.WriteLine(" " + CheetahCaption.NameOfFormat); Console.WriteLine(" " + Chk.NameOfFormat); Console.WriteLine(" Matroska (.mkv)"); Console.WriteLine(" Matroska subtitle (.mks)"); Console.WriteLine(" " + NciCaption.NameOfFormat); Console.WriteLine(" " + AvidStl.NameOfFormat); Console.WriteLine(" " + Pac.NameOfFormat); Console.WriteLine(" " + Spt.NameOfFormat); Console.WriteLine(" " + Ultech130.NameOfFormat); Console.WriteLine("- For Blu-ray .sup output use: '" + BatchConvert.BluRaySubtitle.Replace(" ", string.Empty) + "'"); } Console.WriteLine(); Console.Write(currentDir + ">"); if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux()) NativeMethods.FreeConsole(); Environment.Exit(1); } int count = 0; int converted = 0; int errors = 0; try { string pattern = args[2]; string toFormat = args[3]; string offset = GetArgument(args, "/offset:"); var fps = GetArgument(args, "/fps:"); if (fps.Length > 6) { fps = fps.Remove(0, 5).Replace(',', '.').Trim(); double d; if (double.TryParse(fps, System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.CultureInfo.InvariantCulture, out d)) { Configuration.Settings.General.CurrentFrameRate = d; } } var targetFps = GetArgument(args, "/targetfps:"); double? targetFrameRate = null; if (targetFps.Length > 12) { targetFps = targetFps.Remove(0, 11).Replace(',', '.').Trim(); double d; if (double.TryParse(targetFps, System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.CultureInfo.InvariantCulture, out d)) { targetFrameRate = d; } } var targetEncodingName = GetArgument(args, "/encoding:"); ; var targetEncoding = Encoding.UTF8; try { if (!string.IsNullOrEmpty(targetEncodingName)) { targetEncodingName = targetEncodingName.Substring(10); if (!string.IsNullOrEmpty(targetEncodingName)) targetEncoding = Encoding.GetEncoding(targetEncodingName); } } catch (Exception exception) { Console.WriteLine("Unable to set encoding (" + exception.Message + ") - using UTF-8"); targetEncoding = Encoding.UTF8; } var outputFolder = GetArgument(args, "/outputfolder:"); ; if (outputFolder.Length > "/outputFolder:".Length) { outputFolder = outputFolder.Remove(0, "/outputFolder:".Length); if (!Directory.Exists(outputFolder)) outputFolder = string.Empty; } var inputFolder = GetArgument(args, "/inputFolder:", Directory.GetCurrentDirectory()); if (inputFolder.Length > "/inputFolder:".Length) { inputFolder = inputFolder.Remove(0, "/inputFolder:".Length); if (!Directory.Exists(inputFolder)) inputFolder = Directory.GetCurrentDirectory(); } var pacCodePage = GetArgument(args, "/pac-codepage:"); if (pacCodePage.Length > "/pac-codepage:".Length) { pacCodePage = pacCodePage.Remove(0, "/pac-codepage:".Length); if (string.Compare("Latin", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0) pacCodePage = "0"; else if (string.Compare("Greek", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0) pacCodePage = "1"; else if (string.Compare("Czech", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0) pacCodePage = "2"; else if (string.Compare("Arabic", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0) pacCodePage = "3"; else if (string.Compare("Hebrew", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0) pacCodePage = "4"; else if (string.Compare("Encoding", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0) pacCodePage = "5"; else if (string.Compare("Cyrillic", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0) pacCodePage = "6"; } bool overwrite = GetArgument(args, "/overwrite", string.Empty).Equals("/overwrite"); string[] files; string inputDirectory = Directory.GetCurrentDirectory(); if (!string.IsNullOrEmpty(inputFolder)) inputDirectory = inputFolder; if (pattern.Contains(',') && !File.Exists(pattern)) { files = pattern.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int k = 0; k < files.Length; k++) files[k] = files[k].Trim(); } else { int indexOfDirectorySeparatorChar = pattern.LastIndexOf(Path.DirectorySeparatorChar); if (indexOfDirectorySeparatorChar > 0 && indexOfDirectorySeparatorChar < pattern.Length) { pattern = pattern.Substring(indexOfDirectorySeparatorChar + 1); inputDirectory = args[2].Substring(0, indexOfDirectorySeparatorChar); } files = Directory.GetFiles(inputDirectory, pattern); } var formats = SubtitleFormat.AllSubtitleFormats; foreach (string fName in files) { string fileName = fName; count++; if (!string.IsNullOrEmpty(inputFolder) && File.Exists(Path.Combine(inputFolder, fileName))) { fileName = Path.Combine(inputFolder, fileName); } if (File.Exists(fileName)) { var sub = new Subtitle(); SubtitleFormat format = null; bool done = false; if (Path.GetExtension(fileName).Equals(".mkv", StringComparison.OrdinalIgnoreCase) || Path.GetExtension(fileName).Equals(".mks", StringComparison.OrdinalIgnoreCase)) { using (var matroska = new MatroskaFile(fileName)) { if (matroska.IsValid) { var tracks = matroska.GetTracks(); if (tracks.Count > 0) { foreach (var track in tracks) { if (track.CodecId.Equals("S_VOBSUB", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("{0}: {1} - Cannot convert from VobSub image based format!", fileName, toFormat); } else if (track.CodecId.Equals("S_HDMV/PGS", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("{0}: {1} - Cannot convert from Blu-ray image based format!", fileName, toFormat); } else { var ss = matroska.GetSubtitle(track.TrackNumber, null); format = Utilities.LoadMatroskaTextSubtitle(track, matroska, ss, sub); string newFileName = fileName; if (tracks.Count > 1) newFileName = fileName.Insert(fileName.Length - 4, "_" + track.TrackNumber + "_" + track.Language.Replace("?", string.Empty).Replace("!", string.Empty).Replace("*", string.Empty).Replace(",", string.Empty).Replace("/", string.Empty).Trim()); if (format.GetType() == typeof(AdvancedSubStationAlpha) || format.GetType() == typeof(SubStationAlpha)) { if (toFormat.ToLower() != AdvancedSubStationAlpha.NameOfFormat.ToLower().Replace(" ", string.Empty) && toFormat.ToLower() != SubStationAlpha.NameOfFormat.ToLower().Replace(" ", string.Empty)) { foreach (SubtitleFormat sf in formats) { if (sf.Name.Replace(" ", string.Empty).Equals(toFormat, StringComparison.OrdinalIgnoreCase) || sf.Name.Replace(" ", string.Empty).Equals(toFormat.Replace(" ", string.Empty), StringComparison.OrdinalIgnoreCase)) { format.RemoveNativeFormatting(sub, sf); break; } } } } BatchConvertSave(toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, newFileName, sub, format, overwrite, pacCodePage, targetFrameRate); done = true; } } } } } } if (FileUtil.IsBluRaySup(fileName)) { Console.WriteLine("Found Blu-Ray subtitle format"); ConvertBluRaySubtitle(fileName, toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate); done = true; } if (!done && FileUtil.IsVobSub(fileName)) { Console.WriteLine("Found VobSub subtitle format"); ConvertVobSubSubtitle(fileName, toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate); done = true; } var fi = new FileInfo(fileName); if (fi.Length < 10 * 1024 * 1024 && !done) // max 10 mb { Encoding encoding; format = sub.LoadSubtitle(fileName, out encoding, null, true); if (format == null || format.GetType() == typeof(Ebu)) { var ebu = new Ebu(); if (ebu.IsMine(null, fileName)) { ebu.LoadSubtitle(sub, null, fileName); format = ebu; } } if (format == null) { var pac = new Pac(); if (pac.IsMine(null, fileName)) { pac.BatchMode = true; if (!string.IsNullOrEmpty(pacCodePage) && Utilities.IsInteger(pacCodePage)) pac.CodePage = int.Parse(pacCodePage); else pac.CodePage = -1; pac.LoadSubtitle(sub, null, fileName); format = pac; } } if (format == null) { var cavena890 = new Cavena890(); if (cavena890.IsMine(null, fileName)) { cavena890.LoadSubtitle(sub, null, fileName); format = cavena890; } } if (format == null) { var spt = new Spt(); if (spt.IsMine(null, fileName)) { spt.LoadSubtitle(sub, null, fileName); format = spt; } } if (format == null) { var cheetahCaption = new CheetahCaption(); if (cheetahCaption.IsMine(null, fileName)) { cheetahCaption.LoadSubtitle(sub, null, fileName); format = cheetahCaption; } } if (format == null) { var chk = new Chk(); if (chk.IsMine(null, fileName)) { chk.LoadSubtitle(sub, null, fileName); format = chk; } } if (format == null) { var ayato = new Ayato(); if (ayato.IsMine(null, fileName)) { ayato.LoadSubtitle(sub, null, fileName); format = ayato; } } if (format == null) { var capMakerPlus = new CapMakerPlus(); if (capMakerPlus.IsMine(null, fileName)) { capMakerPlus.LoadSubtitle(sub, null, fileName); format = capMakerPlus; } } if (format == null) { var captionate = new Captionate(); if (captionate.IsMine(null, fileName)) { captionate.LoadSubtitle(sub, null, fileName); format = captionate; } } if (format == null) { var ultech130 = new Ultech130(); if (ultech130.IsMine(null, fileName)) { ultech130.LoadSubtitle(sub, null, fileName); format = ultech130; } } if (format == null) { var nciCaption = new NciCaption(); if (nciCaption.IsMine(null, fileName)) { nciCaption.LoadSubtitle(sub, null, fileName); format = nciCaption; } } if (format == null) { var tsb4 = new TSB4(); if (tsb4.IsMine(null, fileName)) { tsb4.LoadSubtitle(sub, null, fileName); format = tsb4; } } if (format == null) { var avidStl = new AvidStl(); if (avidStl.IsMine(null, fileName)) { avidStl.LoadSubtitle(sub, null, fileName); format = avidStl; } } if (format == null) { var elr = new ELRStudioClosedCaption(); if (elr.IsMine(null, fileName)) { elr.LoadSubtitle(sub, null, fileName); format = elr; } } } if (format == null) { if (fi.Length < 1024 * 1024) // max 1 mb Console.WriteLine("{0}: {1} - input file format unknown!", fileName, toFormat); else Console.WriteLine("{0}: {1} - input file too large!", fileName, toFormat); } else if (!done) { BatchConvertSave(toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, fileName, sub, format, overwrite, pacCodePage, targetFrameRate); } } else { Console.WriteLine("{0}: {1} - file not found!", count, fileName); errors++; } } } catch (Exception exception) { Console.WriteLine(); Console.WriteLine("Ups - an error occured: " + exception.Message); Console.WriteLine(); } Console.WriteLine(); Console.WriteLine("{0} file(s) converted", converted); Console.WriteLine(); Console.Write(currentDir + ">"); if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux()) NativeMethods.FreeConsole(); if (count == converted && errors == 0) Environment.Exit(0); else Environment.Exit(1); }
private bool LoadDvbFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska, bool batchMode) { ShowStatus(_language.ParsingMatroskaFile); Refresh(); Cursor.Current = Cursors.WaitCursor; var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, MatroskaProgress); TaskbarList.SetProgressState(Handle, TaskbarButtonProgressFlags.NoProgress); Cursor.Current = Cursors.Default; MakeHistoryForUndo(_language.BeforeImportFromMatroskaFile); _subtitleListViewIndex = -1; if (!batchMode) ResetSubtitle(); _subtitle.Paragraphs.Clear(); var subtitleImages = new List<DvbSubPes>(); var subtitle = new Subtitle(); Utilities.LoadMatroskaTextSubtitle(matroskaSubtitleInfo, matroska, sub, _subtitle); for (int index = 0; index < sub.Count; index++) { try { var msub = sub[index]; DvbSubPes pes = null; if (msub.Data.Length > 9 && msub.Data[0] == 15 && msub.Data[1] >= SubtitleSegment.PageCompositionSegment && msub.Data[1] <= SubtitleSegment.DisplayDefinitionSegment) // sync byte + segment id { var buffer = new byte[msub.Data.Length + 3]; Buffer.BlockCopy(msub.Data, 0, buffer, 2, msub.Data.Length); buffer[0] = 32; buffer[1] = 0; buffer[buffer.Length - 1] = 255; pes = new DvbSubPes(0, buffer); } else if (VobSubParser.IsMpeg2PackHeader(msub.Data)) { pes = new DvbSubPes(msub.Data, Mpeg2Header.Length); } else if (VobSubParser.IsPrivateStream1(msub.Data, 0)) { pes = new DvbSubPes(msub.Data, 0); } else if (msub.Data.Length > 9 && msub.Data[0] == 32 && msub.Data[1] == 0 && msub.Data[2] == 14 && msub.Data[3] == 16) { pes = new DvbSubPes(0, msub.Data); } if (pes == null && subtitle.Paragraphs.Count > 0) { var last = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1]; if (last.Duration.TotalMilliseconds < 100) { last.EndTime.TotalMilliseconds = msub.Start; if (last.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds) { last.EndTime.TotalMilliseconds = last.StartTime.TotalMilliseconds + 3000; } } } if (pes != null && pes.PageCompositions != null && pes.PageCompositions.Any(p => p.Regions.Count > 0)) { subtitleImages.Add(pes); subtitle.Paragraphs.Add(new Paragraph(string.Empty, msub.Start, msub.End)); } } catch { // continue } } if (subtitleImages.Count == 0) { return false; } for (int index = 0; index < subtitle.Paragraphs.Count; index++) { var p = subtitle.Paragraphs[index]; if (p.Duration.TotalMilliseconds < 200) { p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + 3000; } var next = subtitle.GetParagraphOrDefault(index + 1); if (next != null && next.StartTime.TotalMilliseconds < p.EndTime.TotalMilliseconds) { p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines; } } using (var formSubOcr = new VobSubOcr()) { formSubOcr.Initialize(subtitle, subtitleImages, Configuration.Settings.VobSubOcr, null); // TODO: language??? if (_loading) { formSubOcr.Icon = (Icon)Icon.Clone(); formSubOcr.ShowInTaskbar = true; formSubOcr.ShowIcon = true; } if (formSubOcr.ShowDialog(this) == DialogResult.OK) { ResetSubtitle(); _subtitle.Paragraphs.Clear(); _subtitle.WasLoadedWithFrameNumbers = false; foreach (var 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(matroska.Path); _converted = true; Text = Title; Configuration.Settings.Save(); return true; } } return false; }
// E.g.: /convert *.txt SubRip public static void Convert(string title, string[] arguments) { const int ATTACH_PARENT_PROCESS = -1; if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux()) NativeMethods.AttachConsole(ATTACH_PARENT_PROCESS); var currentFolder = Directory.GetCurrentDirectory(); Console.WriteLine(); Console.WriteLine(title + " - Batch converter"); Console.WriteLine(); if (arguments.Length < 4) { if (arguments.Length == 3 && (arguments[2].Equals("/list", StringComparison.OrdinalIgnoreCase) || arguments[2].Equals("-list", StringComparison.OrdinalIgnoreCase))) { Console.WriteLine("- Supported formats (input/output):"); foreach (SubtitleFormat format in SubtitleFormat.AllSubtitleFormats) { Console.WriteLine(" " + format.Name.Replace(" ", string.Empty)); } Console.WriteLine(); Console.WriteLine("- Supported formats (input only):"); Console.WriteLine(" " + CapMakerPlus.NameOfFormat); Console.WriteLine(" " + Captionate.NameOfFormat); Console.WriteLine(" " + Cavena890.NameOfFormat); Console.WriteLine(" " + CheetahCaption.NameOfFormat); Console.WriteLine(" " + Chk.NameOfFormat); Console.WriteLine(" Matroska (.mkv)"); Console.WriteLine(" Matroska subtitle (.mks)"); Console.WriteLine(" " + NciCaption.NameOfFormat); Console.WriteLine(" " + AvidStl.NameOfFormat); Console.WriteLine(" " + Pac.NameOfFormat); Console.WriteLine(" " + Spt.NameOfFormat); Console.WriteLine(" " + Ultech130.NameOfFormat); Console.WriteLine("- For Blu-ray .sup output use: '" + BatchConvert.BluRaySubtitle.Replace(" ", string.Empty) + "'"); Console.WriteLine("- For VobSub .sub output use: '" + BatchConvert.VobSubSubtitle.Replace(" ", string.Empty) + "'"); } else { Console.WriteLine("- Usage: SubtitleEdit /convert <pattern> <name-of-format-without-spaces> [<optional-parameters>]"); Console.WriteLine(); Console.WriteLine(" pattern:"); Console.WriteLine(" one or more file name patterns separated by commas"); Console.WriteLine(" relative patterns are relative to /inputfolder if specified"); Console.WriteLine(" optional-parameters:"); Console.WriteLine(" /offset:hh:mm:ss:ms"); Console.WriteLine(" /fps:<frame rate>"); Console.WriteLine(" /targetfps:<frame rate>"); Console.WriteLine(" /encoding:<encoding name>"); Console.WriteLine(" /pac-codepage:<code page>"); Console.WriteLine(" /inputfolder:<folder name>"); Console.WriteLine(" /outputfolder:<folder name>"); Console.WriteLine(" /overwrite"); Console.WriteLine(" /multiplereplace:<comma separated file name list> ('.' represents the default replace rules)"); Console.WriteLine(" /multiplereplace (equivalent to /multiplereplace:.)"); Console.WriteLine(" /removetextforhi"); Console.WriteLine(" /fixcommonerrors"); Console.WriteLine(" /redocasing"); Console.WriteLine(); Console.WriteLine(" example: SubtitleEdit /convert *.srt sami"); Console.WriteLine(" list available formats: SubtitleEdit /convert /list"); } Console.WriteLine(); if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux()) { Console.Write(currentFolder + ">"); NativeMethods.FreeConsole(); } Environment.Exit(1); } int count = 0; int converted = 0; int errors = 0; try { var pattern = arguments[2].Trim(); var targetFormat = arguments[3].Trim().Replace(" ", string.Empty).ToLowerInvariant(); if (targetFormat == "ass") { targetFormat = AdvancedSubStationAlpha.NameOfFormat.Replace(" ", string.Empty).ToLowerInvariant(); } else if (targetFormat == "ssa") { targetFormat = SubStationAlpha.NameOfFormat.Replace(" ", string.Empty).ToLowerInvariant(); } else if (targetFormat == "srt") { targetFormat = SubRip.NameOfFormat.Replace(" ", string.Empty).ToLowerInvariant(); } else if (targetFormat == "smi") { targetFormat = "sami"; } else if (targetFormat == "itt") { targetFormat = ItunesTimedText.NameOfFormat.Replace(" ", string.Empty).ToLowerInvariant(); } else if (targetFormat == "ttml") { targetFormat = TimedText10.NameOfFormat.Replace(" ", string.Empty).ToLowerInvariant(); } var args = new List<string>(arguments.Skip(4).Select(s => s.Trim())); var offset = GetArgument(args, "offset:"); var targetFrameRate = GetFrameRate(args, "targetfps"); var frameRate = GetFrameRate(args, "fps"); if (frameRate.HasValue) { Configuration.Settings.General.CurrentFrameRate = frameRate.Value; } var targetEncoding = Encoding.UTF8; try { var encodingName = GetArgument(args, "encoding:"); if (encodingName.Length > 0) { targetEncoding = Encoding.GetEncoding(encodingName); } } catch (Exception exception) { Console.WriteLine("Unable to set encoding (" + exception.Message + ") - using UTF-8"); } var outputFolder = string.Empty; { var folder = GetArgument(args, "outputfolder:"); if (folder.Length > 0) { if (Directory.Exists(folder)) { outputFolder = folder; } else { throw new Exception("The /outputfolder '" + folder + "' does not exist."); } } } var inputFolder = currentFolder; { var folder = GetArgument(args, "inputfolder:"); if (folder.Length > 0) { if (Directory.Exists(folder)) { inputFolder = folder; } else { throw new Exception("The /inputfolder '" + folder + "' does not exist."); } } } int pacCodePage = -1; { var pcp = GetArgument(args, "pac-codepage:"); if (pcp.Length > 0) { if (pcp.Equals("Latin", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageLatin; else if (pcp.Equals("Greek", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageGreek; else if (pcp.Equals("Czech", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageLatinCzech; else if (pcp.Equals("Arabic", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageArabic; else if (pcp.Equals("Hebrew", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageHebrew; else if (pcp.Equals("Thai", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageThai; else if (pcp.Equals("Cyrillic", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageCyrillic; else if (pcp.Equals("CHT", StringComparison.OrdinalIgnoreCase) || pcp.Replace(" ", string.Empty).Equals("TraditionalChinese", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageChineseTraditional; else if (pcp.Equals("CHS", StringComparison.OrdinalIgnoreCase) || pcp.Replace(" ", string.Empty).Equals("SimplifiedChinese", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageChineseSimplified; else if (pcp.Equals("Korean", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageKorean; else if (pcp.Equals("Japanese", StringComparison.OrdinalIgnoreCase)) pacCodePage = Pac.CodePageJapanese; else if (!int.TryParse(pcp, out pacCodePage) || !Pac.IsValidCodePage(pacCodePage)) { throw new Exception("The /pac-codepage value '" + pcp + "' is invalid."); } } } var multipleReplaceImportFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase); { var mra = GetArgument(args, "multiplereplace:"); if (mra.Length > 0) { if (mra.Contains(',') && !File.Exists(mra)) { foreach (var fn in mra.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { var fileName = fn.Trim(); if (fileName.Length > 0) multipleReplaceImportFiles.Add(fileName); } } else { multipleReplaceImportFiles.Add(mra); } } else if (GetArgument(args, "multiplereplace").Equals("multiplereplace")) { multipleReplaceImportFiles.Add("."); } } bool overwrite = GetArgument(args, "overwrite").Equals("overwrite"); bool removeTextForHi = GetArgument(args, "removetextforhi").Equals("removetextforhi"); bool fixCommonErrors = GetArgument(args, "fixcommonerrors").Equals("fixcommonerrors"); bool redoCasing = GetArgument(args, "redocasing").Equals("redocasing"); var patterns = Enumerable.Empty<string>(); if (pattern.Contains(',') && !File.Exists(pattern)) { patterns = pattern.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(fn => fn.Trim()).Where(fn => fn.Length > 0); } else { patterns = patterns.DefaultIfEmpty(pattern); } var files = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (var p in patterns) { var folderName = Path.GetDirectoryName(p); var fileName = Path.GetFileName(p); if (string.IsNullOrEmpty(folderName) || string.IsNullOrEmpty(fileName)) { folderName = inputFolder; fileName = p; } else if (!Path.IsPathRooted(folderName)) { folderName = Path.Combine(inputFolder, folderName); } foreach (var fn in Directory.EnumerateFiles(folderName, fileName)) { files.Add(fn); // silently ignore duplicates } } if (args.Count > 0) { foreach (var argument in args) { if (argument.StartsWith('/') || argument.StartsWith('-')) Console.WriteLine("ERROR: Unknown or multiply defined option '" + argument + "'."); else Console.WriteLine("ERROR: Unexpected argument '" + argument + "'."); } throw new Exception(string.Empty); } var formats = SubtitleFormat.AllSubtitleFormats; foreach (var fileName in files) { count++; var fileInfo = new FileInfo(fileName); if (fileInfo.Exists) { var sub = new Subtitle(); SubtitleFormat format = null; bool done = false; if (fileInfo.Extension.Equals(".mkv", StringComparison.OrdinalIgnoreCase) || fileInfo.Extension.Equals(".mks", StringComparison.OrdinalIgnoreCase)) { using (var matroska = new MatroskaFile(fileName)) { if (matroska.IsValid) { var tracks = matroska.GetTracks(true); if (tracks.Count > 0) { foreach (var track in tracks) { if (track.CodecId.Equals("S_VOBSUB", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("{0}: {1} - Cannot convert from VobSub image based format!", fileName, targetFormat); } else if (track.CodecId.Equals("S_HDMV/PGS", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("{0}: {1} - Cannot convert from Blu-ray image based format!", fileName, targetFormat); } else { var ss = matroska.GetSubtitle(track.TrackNumber, null); format = Utilities.LoadMatroskaTextSubtitle(track, matroska, ss, sub); string newFileName = fileName; if (tracks.Count > 1) newFileName = fileName.Insert(fileName.Length - 4, "_" + track.TrackNumber + "_" + track.Language.Replace("?", string.Empty).Replace("!", string.Empty).Replace("*", string.Empty).Replace(",", string.Empty).Replace("/", string.Empty).Trim()); if (format.GetType() == typeof(AdvancedSubStationAlpha) || format.GetType() == typeof(SubStationAlpha)) { if (!AdvancedSubStationAlpha.NameOfFormat.Replace(" ", string.Empty).Equals(targetFormat, StringComparison.OrdinalIgnoreCase) && !SubStationAlpha.NameOfFormat.Replace(" ", string.Empty).Equals(targetFormat, StringComparison.OrdinalIgnoreCase)) { foreach (SubtitleFormat sf in formats) { if (sf.Name.Replace(" ", string.Empty).Equals(targetFormat, StringComparison.OrdinalIgnoreCase)) { format.RemoveNativeFormatting(sub, sf); break; } } } } BatchConvertSave(targetFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, newFileName, sub, format, overwrite, pacCodePage, targetFrameRate, multipleReplaceImportFiles, removeTextForHi, fixCommonErrors, redoCasing); done = true; } } } } } } if (!done && FileUtil.IsBluRaySup(fileName)) { Console.WriteLine("Found Blu-Ray subtitle format"); ConvertBluRaySubtitle(fileName, targetFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate, multipleReplaceImportFiles, removeTextForHi, fixCommonErrors, redoCasing); done = true; } if (!done && FileUtil.IsVobSub(fileName)) { Console.WriteLine("Found VobSub subtitle format"); ConvertVobSubSubtitle(fileName, targetFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate, multipleReplaceImportFiles, removeTextForHi, fixCommonErrors, redoCasing); done = true; } if (!done && fileInfo.Length < 10 * 1024 * 1024) // max 10 mb { Encoding encoding; format = sub.LoadSubtitle(fileName, out encoding, null, true, frameRate); if (format == null || format.GetType() == typeof(Ebu)) { var ebu = new Ebu(); if (ebu.IsMine(null, fileName)) { ebu.LoadSubtitle(sub, null, fileName); format = ebu; } } if (format == null) { var pac = new Pac(); if (pac.IsMine(null, fileName)) { pac.BatchMode = true; pac.CodePage = pacCodePage; pac.LoadSubtitle(sub, null, fileName); format = pac; } } if (format == null) { var cavena890 = new Cavena890(); if (cavena890.IsMine(null, fileName)) { cavena890.LoadSubtitle(sub, null, fileName); format = cavena890; } } if (format == null) { var spt = new Spt(); if (spt.IsMine(null, fileName)) { spt.LoadSubtitle(sub, null, fileName); format = spt; } } if (format == null) { var cheetahCaption = new CheetahCaption(); if (cheetahCaption.IsMine(null, fileName)) { cheetahCaption.LoadSubtitle(sub, null, fileName); format = cheetahCaption; } } if (format == null) { var chk = new Chk(); if (chk.IsMine(null, fileName)) { chk.LoadSubtitle(sub, null, fileName); format = chk; } } if (format == null) { var ayato = new Ayato(); if (ayato.IsMine(null, fileName)) { ayato.LoadSubtitle(sub, null, fileName); format = ayato; } } if (format == null) { var capMakerPlus = new CapMakerPlus(); if (capMakerPlus.IsMine(null, fileName)) { capMakerPlus.LoadSubtitle(sub, null, fileName); format = capMakerPlus; } } if (format == null) { var captionate = new Captionate(); if (captionate.IsMine(null, fileName)) { captionate.LoadSubtitle(sub, null, fileName); format = captionate; } } if (format == null) { var ultech130 = new Ultech130(); if (ultech130.IsMine(null, fileName)) { ultech130.LoadSubtitle(sub, null, fileName); format = ultech130; } } if (format == null) { var nciCaption = new NciCaption(); if (nciCaption.IsMine(null, fileName)) { nciCaption.LoadSubtitle(sub, null, fileName); format = nciCaption; } } if (format == null) { var tsb4 = new TSB4(); if (tsb4.IsMine(null, fileName)) { tsb4.LoadSubtitle(sub, null, fileName); format = tsb4; } } if (format == null) { var avidStl = new AvidStl(); if (avidStl.IsMine(null, fileName)) { avidStl.LoadSubtitle(sub, null, fileName); format = avidStl; } } if (format == null) { var elr = new ELRStudioClosedCaption(); if (elr.IsMine(null, fileName)) { elr.LoadSubtitle(sub, null, fileName); format = elr; } } } if (format == null) { if (fileInfo.Length < 1024 * 1024) // max 1 mb Console.WriteLine("{0}: {1} - input file format unknown!", fileName, targetFormat); else Console.WriteLine("{0}: {1} - input file too large!", fileName, targetFormat); } else if (!done) { BatchConvertSave(targetFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, fileName, sub, format, overwrite, pacCodePage, targetFrameRate, multipleReplaceImportFiles, removeTextForHi, fixCommonErrors, redoCasing); } } else { Console.WriteLine("{0}: {1} - file not found!", count, fileName); errors++; } } } catch (Exception exception) { if (exception.Message.Length > 0) { Console.WriteLine(); Console.WriteLine("ERROR: " + exception.Message); } else { Console.WriteLine("Try 'SubtitleEdit /?' for more information."); } Console.WriteLine(); errors++; } if (count > 0) { Console.WriteLine(); Console.WriteLine("{0} file(s) converted", converted); Console.WriteLine(); } if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux()) { Console.Write(currentFolder + ">"); NativeMethods.FreeConsole(); } if (count == converted && errors == 0) Environment.Exit(0); else Environment.Exit(1); }