public override string ToText(Subtitle subtitle, string title) { var language = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); var userId = "0"; var duration = "0"; var last = subtitle.Paragraphs.LastOrDefault(); if (last != null) { duration = (last.StartTime.TotalSeconds + last.Duration.TotalSeconds).ToString(CultureInfo.InvariantCulture); } var createdAt = ""; var id = "0"; var sb = new StringBuilder(); sb.AppendLine("{" + Environment.NewLine + " \"job\": {" + Environment.NewLine + " \"lang\": \"" + language + "\"," + Environment.NewLine + " \"user_id\": \"" + userId + "\"," + Environment.NewLine + " \"name\": \"" + Json.EncodeJsonText(title) + "\"," + Environment.NewLine + " \"duration\": \"" + duration + "\"," + Environment.NewLine + " \"created_at\": \"" + createdAt + "\"," + Environment.NewLine + " \"id\": \"" + id + "\"," + Environment.NewLine + " }," + Environment.NewLine + " \"speakers\": ["); int count = 0; foreach (Paragraph p in subtitle.Paragraphs) { if (count > 0) { sb.AppendLine(", "); } sb.AppendLine(" {"); sb.AppendLine(" \"duration\": \"" + p.Duration.TotalSeconds.ToString(CultureInfo.InvariantCulture) + "\","); sb.AppendLine(" \"confidence\": null,"); sb.AppendLine(" \"name\": \"" + Json.EncodeJsonText(p.Text) + "\","); sb.AppendLine(" \"time\": \"" + p.StartTime.TotalSeconds.ToString(CultureInfo.InvariantCulture) + "\""); sb.Append(" }"); count++; } sb.AppendLine(); sb.AppendLine(" ],"); sb.AppendLine(" \"format\": \"1.0\""); sb.AppendLine("}"); return(sb.ToString().Trim()); }
public void Initialize(Subtitle subtitle) { _subtitle = subtitle; _language = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitle); if (string.IsNullOrEmpty(_language)) { _language = "en_US"; } _nameList = new NameList(Configuration.DictionariesDirectory, _language, Configuration.Settings.WordLists.UseOnlineNames, Configuration.Settings.WordLists.NamesUrl); _nameListInclMulti = _nameList.GetAllNames(); // Will contains both one word names and multi names FindAllNames(); GeneratePreview(); }
public void Initialize(Subtitle subtitle, bool autoBalance) { _language = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); _modeAutoBalance = autoBalance; _paragraphs = new List <Paragraph>(); foreach (Paragraph p in subtitle.Paragraphs) { _paragraphs.Add(p); } if (autoBalance) { labelCondition.Text = Configuration.Settings.Language.AutoBreakUnbreakLines.OnlyBreakLinesLongerThan; const int start = 10; const int max = 60; for (int i = start; i <= max; i++) { comboBoxConditions.Items.Add(i.ToString(CultureInfo.InvariantCulture)); } int index = Configuration.Settings.Tools.MergeLinesShorterThan - (start + 1); if (index > 0 && index < max) { comboBoxConditions.SelectedIndex = index; } else { comboBoxConditions.SelectedIndex = 30; } AutoBalance(); } else { labelCondition.Text = Configuration.Settings.Language.AutoBreakUnbreakLines.OnlyUnbreakLinesLongerThan; for (int i = 5; i < 51; i++) { comboBoxConditions.Items.Add(i.ToString(CultureInfo.InvariantCulture)); } comboBoxConditions.SelectedIndex = 5; Unbreak(); } comboBoxConditions.SelectedIndexChanged += ComboBoxConditionsSelectedIndexChanged; }
public async Task InitializeLiveSpellCheck(Subtitle subtitle, int lineNumber) { if (lineNumber < 0) { return; } if (_spellCheckWordLists is null && _hunspell is null) { var detectedLanguage = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); var downloadedDictionaries = Utilities.GetDictionaryLanguagesCultureNeutral(); var isDictionaryAvailable = false; foreach (var downloadedDictionary in downloadedDictionaries) { if (downloadedDictionary.Contains($"[{detectedLanguage}]")) { isDictionaryAvailable = true; break; } } if (isDictionaryAvailable) { IsDictionaryDownloaded = true; var languageName = LanguageAutoDetect.AutoDetectLanguageName(string.Empty, subtitle); if (languageName.Split(new char[] { '_', '-' })[0] != detectedLanguage) { return; } await LoadDictionariesAsync(languageName); IsSpellCheckerInitialized = true; IsSpellCheckRequested = true; TextChangedHighlight(this, EventArgs.Empty); } else { IsDictionaryDownloaded = false; } LanguageChanged = true; CurrentLanguage = detectedLanguage; } }
public MainForm(Subtitle sub, string title, string description, Form parentForm) : this() { Text = title; _subtitle = sub; _subtitleOriginal = new Subtitle(sub); foreach (var p in sub.Paragraphs) { p.Text = string.Empty; } _from = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitleOriginal); SetLanguages(comboBoxLanguageFrom, _from); GeneratePreview(); RestoreSettings(); var languages = DeepLScreenScraper.Translator.DeepLScreenScraper.GetTranslationPairs().Select(p => p.Code).ToList(); if (string.IsNullOrEmpty(_to) || _to == _from) { _to = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; if (_to == _from) { foreach (InputLanguage language in InputLanguage.InstalledInputLanguages) { if (languages.Contains(language.Culture.TwoLetterISOLanguageName)) { _to = language.Culture.TwoLetterISOLanguageName; if (_to != _from) { break; } } } } } if (_to == _from && _from == "en") { _to = "de"; } if (_to == _from && _from == "es") { _to = "de"; } SetLanguages(comboBoxLanguageTo, _to); }
public MainForm(Subtitle sub, string title, string description, Form parentForm) : this() { Text = title; _subtitle = sub; _subtitleOriginal = new Subtitle(sub); foreach (var p in sub.Paragraphs) { p.Text = string.Empty; } var languageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitleOriginal); _formattingTypes = new FormattingType[_subtitle.Paragraphs.Count]; _autoSplit = new bool[_subtitle.Paragraphs.Count]; SetLanguages(comboBoxLanguageFrom, languageCode); SetLanguages(comboBoxLanguageTo, "DE"); GeneratePreview(false); }
public static string EvaluateDefaultSourceLanguageCode(Encoding encoding, Subtitle subtitle) { string defaultSourceLanguageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(encoding); // Guess language via encoding if (string.IsNullOrEmpty(defaultSourceLanguageCode)) { defaultSourceLanguageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); // Guess language based on subtitle contents } //convert new Hebrew code (he) to old Hebrew code (iw) http://www.mathguide.de/info/tools/languagecode.html //brummochse: why get it converted to the old code? if (defaultSourceLanguageCode == "he") { defaultSourceLanguageCode = "iw"; } return(defaultSourceLanguageCode); }
private void ButtonOpenSubtitle1Click(object sender, EventArgs e) { openFileDialog1.FileName = string.Empty; if (openFileDialog1.ShowDialog() == DialogResult.OK) { if (FileUtil.IsVobSub(openFileDialog1.FileName) || FileUtil.IsBluRaySup(openFileDialog1.FileName)) { MessageBox.Show(Configuration.Settings.Language.CompareSubtitles.CannotCompareWithImageBasedSubtitles); return; } LoadAndCompare(1, openFileDialog1.FileName); labelSubtitle1.Text = openFileDialog1.FileName; _language = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitle1); buttonReloadSubtitle1.Enabled = true; } }
public MainForm(Subtitle sub, string title, string description, Form parentForm) : this() { Text = title; _subtitle = sub; _subtitleOriginal = new Subtitle(sub); foreach (var p in sub.Paragraphs) { p.Text = string.Empty; } _from = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitleOriginal); SetLanguages(comboBoxLanguageFrom, _from); GeneratePreview(); RestoreSettings(); if (string.IsNullOrEmpty(_to) || _to == _from) { _to = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; if (_to == _from) { foreach (InputLanguage language in InputLanguage.InstalledInputLanguages) { _to = language.Culture.TwoLetterISOLanguageName; if (_to != _from) { break; } } } } if (_to == _from && _from == "en") { _to = "es"; } if (_to == _from && _from == "es") { _to = "en"; } SetLanguages(comboBoxLanguageTo, _to); if (listView1.Items.Count > 0) { listView1.Items[0].Selected = true; listView1.Items[0].Focused = true; } }
private void ImportAutoSplit(string[] textLines) { var sub = new Subtitle(); foreach (var line in textLines) { sub.Paragraphs.Add(new Paragraph(line, 0, 0)); } var language = LanguageAutoDetect.AutoDetectGoogleLanguage(sub); var plainTextImporter = new PlainTextImporter(checkBoxAutoSplitAtBlankLines.Checked, checkBoxAutoSplitRemoveLinesNoLetters.Checked, (int)numericUpDownAutoSplitMaxLines.Value, checkBoxAutoSplitAtEnd.Checked ? textBoxAsEnd.Text : string.Empty, (int)numericUpDownSubtitleLineMaximumLength.Value, language); ImportLineMode(plainTextImporter.ImportAutoSplit(textLines)); }
public void Initialize(Subtitle subtitle1, string subtitleFileName1, Subtitle subtitle2, string subtitleFileName2) { Compare_Resize(null, null); labelStatus.Text = string.Empty; _subtitle1 = subtitle1; labelSubtitle1.Text = subtitleFileName1; _subtitle2 = subtitle2; labelSubtitle2.Text = subtitleFileName2; _language1 = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitle1); CompareSubtitles(); if (!string.IsNullOrEmpty(subtitleFileName1) && File.Exists(subtitleFileName1)) { openFileDialog1.InitialDirectory = Path.GetDirectoryName(subtitleFileName1); } subtitleListView1.SelectIndexAndEnsureVisible(0); subtitleListView2.SelectIndexAndEnsureVisible(0); }
private static string GetOriginatingSwift(Subtitle subtitle) { string lang = "English (USA)"; string languageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); if (languageCode == "nl") { lang = "Dutch (Netherlands)"; } else if (languageCode == "de") { lang = "German (German)"; } return("Open 25 " + lang); // examples: // Line21 30 DROP English (USA) // Open 25 German (German) // Open 25 Dutch (Netherlands) //TODO: Frame rate }
public override string ToText(Subtitle subtitle, string title) { string languageCode; string languageDisplayName; try { languageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); var ci = new CultureInfo(languageCode); languageDisplayName = ci.DisplayName; } catch { languageCode = "en"; languageDisplayName = "English"; } var sb = new StringBuilder("{\"subtitle\":[{\"captions\":["); int count = 0; foreach (Paragraph p in subtitle.Paragraphs) { if (count > 0) { sb.Append(','); } sb.Append("{\"duration\":"); sb.Append(p.Duration.TotalMilliseconds.ToString(System.Globalization.CultureInfo.InvariantCulture)); sb.Append(",\"content\":\""); sb.Append(Json.EncodeJsonText(p.Text) + "\""); sb.Append(",\"startOfParagraph\":true"); sb.Append(",\"startTime\":"); sb.Append(p.StartTime.TotalMilliseconds.ToString(System.Globalization.CultureInfo.InvariantCulture)); sb.Append('}'); count++; } sb.Append("],\"lang\":\"" + languageCode + "\", \"langDisplayName\":\"" + languageDisplayName + "\"}],\"introDuration\":0}"); return(sb.ToString().Trim()); }
private void InitializeLanguage(Encoding encoding) { _autoDetectGoogleLanguage = LanguageAutoDetect.AutoDetectGoogleLanguage(encoding); // Guess language via encoding if (string.IsNullOrEmpty(_autoDetectGoogleLanguage)) { _autoDetectGoogleLanguage = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitle); // Guess language based on subtitle contents } if (_autoDetectGoogleLanguage.Equals("zh", StringComparison.OrdinalIgnoreCase)) { _autoDetectGoogleLanguage = "zh-CHS"; // Note that "zh-CHS" (Simplified Chinese) and "zh-CHT" (Traditional Chinese) are neutral cultures } CultureInfo ci = CultureInfo.GetCultureInfo(_autoDetectGoogleLanguage); string threeLetterIsoLanguageName = ci.ThreeLetterISOLanguageName; _popUpLanguage.RemoveAllItems(); foreach (CultureInfo x in CultureInfo.GetCultures(CultureTypes.NeutralCultures)) { _languages.Add(x); } _languages = _languages.Where(p => !string.IsNullOrEmpty(p.EnglishName) && p.TwoLetterISOLanguageName != "iv").OrderBy(p => p.ToString()).ToList(); int languageIndex = 0; int j = 0; foreach (var xci in _languages) { _popUpLanguage.AddItem(xci.EnglishName); if (xci.TwoLetterISOLanguageName == ci.TwoLetterISOLanguageName) { languageIndex = j; } j++; } _popUpLanguage.SelectItem((nint)languageIndex); _popUpLanguage.Activated += (object sender, EventArgs e) => { _fixActions = InitializeRules(); ShowFixRules(); }; }
public NetflixFixErrors(Subtitle subtitle, SubtitleFormat subtitleFormat, string subtitleFileName, string videoFileName, double frameRate) { UiUtil.PreInitialize(this); InitializeComponent(); UiUtil.FixFonts(this); if (Configuration.Settings.General.UseDarkTheme) { listViewFixes.GridLines = Configuration.Settings.General.DarkThemeShowListViewGridLines; } _subtitle = subtitle; _subtitleFormat = subtitleFormat; _subtitleFileName = subtitleFileName; _videoFileName = videoFileName; _frameRate = frameRate; labelTotal.Text = string.Empty; linkLabelOpenReportFolder.Text = string.Empty; Text = LanguageSettings.Current.Main.Menu.ToolBar.NetflixQualityCheck; labelLanguage.Text = LanguageSettings.Current.ChooseLanguage.Language; groupBoxRules.Text = LanguageSettings.Current.Settings.Rules; checkBoxMinDuration.Text = LanguageSettings.Current.NetflixQualityCheck.MinimumDuration; buttonFixesSelectAll.Text = LanguageSettings.Current.FixCommonErrors.SelectAll; buttonFixesInverse.Text = LanguageSettings.Current.FixCommonErrors.InverseSelection; buttonOK.Text = LanguageSettings.Current.General.Ok; _loading = true; var language = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitle); InitializeLanguages(language); RefreshCheckBoxes(language); _loading = false; RuleCheckedChanged(null, null); UiUtil.FixLargeFonts(this, buttonOK); listViewFixes.ListViewItemSorter = new ListViewSorter { ColumnNumber = 0, IsNumber = true }; }
private void ButtonOpenSubtitle1Click(object sender, EventArgs e) { openFileDialog1.FileName = string.Empty; if (openFileDialog1.ShowDialog() == DialogResult.OK) { if (FileUtil.IsVobSub(openFileDialog1.FileName) || FileUtil.IsBluRaySup(openFileDialog1.FileName)) { MessageBox.Show(Configuration.Settings.Language.CompareSubtitles.CannotCompareWithImageBasedSubtitles); return; } _subtitle1 = LoadSubtitle(openFileDialog1.FileName); subtitleListView1.Fill(_subtitle1); subtitleListView1.SelectIndexAndEnsureVisible(0); subtitleListView2.SelectIndexAndEnsureVisible(0); labelSubtitle1.Text = openFileDialog1.FileName; _language1 = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitle1); if (_subtitle1.Paragraphs.Count > 0 && _subtitle2?.Paragraphs.Count > 0) { CompareSubtitles(); } } }
private void AutoBalance() { listViewFixes.ItemChecked -= listViewFixes_ItemChecked; _notAllowedFixes = new HashSet <string>(); _fixedText = new Dictionary <string, string>(); int minLength = MinimumLength; Text = Configuration.Settings.Language.AutoBreakUnbreakLines.TitleAutoBreak; var sub = new Subtitle(); foreach (Paragraph p in _paragraphs) { sub.Paragraphs.Add(p); } var language = LanguageAutoDetect.AutoDetectGoogleLanguage(sub); listViewFixes.BeginUpdate(); listViewFixes.Items.Clear(); foreach (Paragraph p in _paragraphs) { if (HtmlUtil.RemoveHtmlTags(p.Text, true).Length > minLength || p.Text.Contains(Environment.NewLine)) { var text = Utilities.AutoBreakLine(p.Text, 5, MergeLinesShorterThan, language); if (text != p.Text) { AddToListView(p, text); _fixedText.Add(p.ID, text); _changes++; } } } listViewFixes.EndUpdate(); groupBoxLinesFound.Text = string.Format(Configuration.Settings.Language.AutoBreakUnbreakLines.LinesFoundX, listViewFixes.Items.Count); listViewFixes.ItemChecked += listViewFixes_ItemChecked; }
public NetflixFixErrors(Subtitle subtitle, SubtitleFormat subtitleFormat, string subtitleFileName) { InitializeComponent(); _subtitle = subtitle; _subtitleFormat = subtitleFormat; _subtitleFileName = subtitleFileName; labelTotal.Text = string.Empty; linkLabelOpenReportFolder.Text = string.Empty; Text = Configuration.Settings.Language.Main.Menu.ToolBar.NetflixQualityCheck; labelLanguage.Text = Configuration.Settings.Language.ChooseLanguage.Language; groupBoxRules.Text = Configuration.Settings.Language.Settings.Rules; checkBoxMinDuration.Text = Configuration.Settings.Language.NetflixQualityCheck.MinimumDuration; buttonOK.Text = Configuration.Settings.Language.General.Ok; buttonCancel.Text = Configuration.Settings.Language.General.Cancel; _loading = true; var language = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitle); InitializeLanguages(language); RefreshCheckBoxes(language); _loading = false; RuleCheckedChanged(null, null); }
public void Initialize(Subtitle subtitle) { if (subtitle.Paragraphs.Count > 0) { subtitle.Renumber(subtitle.Paragraphs[0].Number); } Text = Configuration.Settings.Language.MergeTextWithSameTimeCodes.Title; labelMaxDifferenceMS.Text = Configuration.Settings.Language.MergeTextWithSameTimeCodes.MaxDifferenceMilliseconds; checkBoxAutoBreakOn.Text = Configuration.Settings.Language.MergeTextWithSameTimeCodes.ReBreakLines; listViewFixes.Columns[0].Text = Configuration.Settings.Language.General.Apply; listViewFixes.Columns[1].Text = Configuration.Settings.Language.General.LineNumber; listViewFixes.Columns[2].Text = Configuration.Settings.Language.MergeTextWithSameTimeCodes.MergedText; buttonOK.Text = Configuration.Settings.Language.General.Ok; buttonCancel.Text = Configuration.Settings.Language.General.Cancel; SubtitleListview1.InitializeLanguage(Configuration.Settings.Language.General, Configuration.Settings); UiUtil.InitializeSubtitleFont(SubtitleListview1); SubtitleListview1.AutoSizeAllColumns(this); NumberOfMerges = 0; _subtitle = subtitle; MergeTextWithSameTimeCodes_ResizeEnd(null, null); _language = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); }
internal void Initialize(Subtitle subtitle, Subtitle target, string title, bool googleTranslate, Encoding encoding) { if (title != null) { Text = title; } _googleTranslate = googleTranslate; if (!_googleTranslate) { _translator = new MicrosoftTranslator(Configuration.Settings.Tools.MicrosoftTranslatorApiKey, Configuration.Settings.Tools.MicrosoftTranslatorTokenEndpoint, Configuration.Settings.Tools.MicrosoftTranslatorCategory); linkLabelPoweredByGoogleTranslate.Text = Configuration.Settings.Language.GoogleTranslate.PoweredByMicrosoftTranslate; } labelPleaseWait.Visible = false; progressBar1.Visible = false; _subtitle = subtitle; if (target != null) { TranslatedSubtitle = new Subtitle(target); subtitleListViewTo.Fill(TranslatedSubtitle); } else { TranslatedSubtitle = new Subtitle(subtitle); foreach (var paragraph in TranslatedSubtitle.Paragraphs) { paragraph.Text = string.Empty; } } string defaultFromLanguage = LanguageAutoDetect.AutoDetectGoogleLanguage(encoding); // Guess language via encoding if (string.IsNullOrEmpty(defaultFromLanguage)) { defaultFromLanguage = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); // Guess language based on subtitle contents } if (defaultFromLanguage == "he") { defaultFromLanguage = "iw"; } FillComboWithLanguages(comboBoxFrom); int i = 0; foreach (ComboBoxItem item in comboBoxFrom.Items) { if (item.Value == defaultFromLanguage) { comboBoxFrom.SelectedIndex = i; break; } i++; } var installedLanguages = new List <InputLanguage>(); foreach (InputLanguage language in InputLanguage.InstalledInputLanguages) { installedLanguages.Add(language); } FillComboWithLanguages(comboBoxTo); i = 0; string uiCultureTargetLanguage = Configuration.Settings.Tools.GoogleTranslateLastTargetLanguage; if (uiCultureTargetLanguage == defaultFromLanguage) { foreach (string s in Utilities.GetDictionaryLanguages()) { string temp = s.Replace("[", string.Empty).Replace("]", string.Empty); if (temp.Length > 4) { temp = temp.Substring(temp.Length - 5, 2).ToLowerInvariant(); if (temp != defaultFromLanguage && installedLanguages.Any(p => p.Culture.TwoLetterISOLanguageName.Contains(temp))) { uiCultureTargetLanguage = temp; break; } } } } if (uiCultureTargetLanguage == defaultFromLanguage) { foreach (InputLanguage language in installedLanguages) { if (language.Culture.TwoLetterISOLanguageName != defaultFromLanguage) { uiCultureTargetLanguage = language.Culture.TwoLetterISOLanguageName; break; } } } if (uiCultureTargetLanguage == defaultFromLanguage && defaultFromLanguage == "en") { uiCultureTargetLanguage = "es"; } if (uiCultureTargetLanguage == defaultFromLanguage) { uiCultureTargetLanguage = "en"; } comboBoxTo.SelectedIndex = 0; foreach (ComboBoxItem item in comboBoxTo.Items) { if (item.Value == uiCultureTargetLanguage) { comboBoxTo.SelectedIndex = i; break; } i++; } subtitleListViewFrom.Fill(subtitle); GoogleTranslate_Resize(null, null); _formattingTypes = new FormattingType[_subtitle.Paragraphs.Count]; _autoSplit = new bool[_subtitle.Paragraphs.Count]; }
private void VerifyDragDrop(ListView listView, DragEventArgs e) { var files = e.Data.GetData(DataFormats.FileDrop) as string[]; if (files == null) { return; } if (files.Length > 1) { MessageBox.Show(Configuration.Settings.Language.Main.DropOnlyOneFile, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } string filePath = files[0]; if (FileUtil.IsDirectory(filePath)) { MessageBox.Show(Configuration.Settings.Language.Main.ErrorDirectoryDropNotAllowed, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var listExt = new List <string>(); foreach (var s in UiUtil.SubtitleExtensionFilter.Value.Split(new[] { '*' }, StringSplitOptions.RemoveEmptyEntries)) { if (s.EndsWith(';')) { listExt.Add(s.Trim(';')); } } if (!listExt.Contains(Path.GetExtension(filePath))) { return; } if (FileUtil.IsVobSub(filePath) || FileUtil.IsBluRaySup(filePath)) { MessageBox.Show(Configuration.Settings.Language.CompareSubtitles.CannotCompareWithImageBasedSubtitles); return; } if (listView.Name == "subtitleListView1") { _subtitle1 = new Subtitle(); _subtitle1.LoadSubtitle(filePath, out _, null); subtitleListView1.Fill(_subtitle1); subtitleListView1.SelectIndexAndEnsureVisible(0); subtitleListView2.SelectIndexAndEnsureVisible(0); labelSubtitle1.Text = filePath; _language1 = LanguageAutoDetect.AutoDetectGoogleLanguage(_subtitle1); if (_subtitle1.Paragraphs.Count > 0) { CompareSubtitles(); } } else { _subtitle2 = new Subtitle(); _subtitle2.LoadSubtitle(filePath, out _, null); subtitleListView2.Fill(_subtitle2); subtitleListView1.SelectIndexAndEnsureVisible(0); subtitleListView2.SelectIndexAndEnsureVisible(0); labelSubtitle2.Text = filePath; if (_subtitle2.Paragraphs.Count > 0) { CompareSubtitles(); } } }
public override string ToText(Subtitle subtitle, string title) { bool convertedFromSubStationAlpha = false; if (subtitle.Header != null) { XmlNode styleHead = null; try { var x = new XmlDocument(); x.LoadXml(subtitle.Header); var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); if (x.DocumentElement != null) { styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); } } catch { styleHead = null; } if (styleHead == null && (subtitle.Header.Contains("[V4+ Styles]") || subtitle.Header.Contains("[V4 Styles]"))) { var x = new XmlDocument(); x.LoadXml(new ItunesTimedText().ToText(new Subtitle(), "tt")); // load default xml var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); if (x.DocumentElement != null) { styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); styleHead.SelectSingleNode("ttml:styling", xnsmgr).RemoveAll(); foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header)) { try { var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header); string fontStyle = "normal"; if (ssaStyle.Italic) { fontStyle = "italic"; } string fontWeight = "normal"; if (ssaStyle.Bold) { fontWeight = "bold"; } AddStyleToXml(x, styleHead, xnsmgr, ssaStyle.Name, ssaStyle.FontName, fontWeight, fontStyle, Utilities.ColorToHex(ssaStyle.Primary), ssaStyle.FontSize.ToString()); convertedFromSubStationAlpha = true; } catch { // ignored } } } subtitle.Header = x.OuterXml; // save new xml with styles in header } } var xml = new XmlDocument { XmlResolver = null }; var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); nsmgr.AddNamespace("ttp", "http://www.w3.org/ns/10/ttml#parameter"); nsmgr.AddNamespace("tts", "http://www.w3.org/ns/10/ttml#style"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); nsmgr.AddNamespace("smpte", "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt"); nsmgr.AddNamespace("m608", "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608"); const string xmlStructure = @"<?xml version='1.0' encoding='utf-8'?> <tt xml:lang='[LANG]' xmlns='http://www.w3.org/ns/ttml' xmlns:tts='http://www.w3.org/ns/ttml#styling' xmlns:ttm='http://www.w3.org/ns/ttml#metadata' xmlns:ttp='http://www.w3.org/ns/ttml#parameter' ttp:timeBase='media' ttp:frameRate='24' ttp:frameRateMultiplier='1000 1001' xmlns:smpte='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt' xmlns:m608='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608'> <head> <metadata> <ttm:title>SMPTE-TT 2052 subtitle</ttm:title> <ttm:desc>SMPTE Timed Text document created by Subtitle Edit</ttm:desc> <smpte:information xmlns:m608='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608' origin='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608' mode='Preserved' m608:channel='CC1' m608:programName='Demo' m608:captionService='F1C1CC'/> </metadata> <styling> <style xml:id='basic' tts:color='white' tts:fontFamily='Arial' tts:backgroundColor='transparent' tts:fontSize='21' tts:fontWeight='normal' tts:fontStyle='normal' /> </styling> <layout> <region xml:id='bottom' tts:backgroundColor='transparent' tts:showBackground='whenActive' tts:origin='80% 80%' tts:extent='80% 80%' tts:displayAlign='after' /> </layout> </head> <body> <div></div> </body> </tt>"; var languageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); xml.LoadXml(xmlStructure.Replace("[LANG]", languageCode)); if (!string.IsNullOrWhiteSpace(title)) { var headNode = xml.DocumentElement.SelectSingleNode("//ttml:head", nsmgr); var metadataNode = headNode?.SelectSingleNode("ttml:metadata", nsmgr); var titleNode = metadataNode?.FirstChild; if (titleNode != null) { titleNode.InnerText = title; } } var div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr); bool hasBottomCenterRegion = false; bool hasTopCenterRegion = false; foreach (XmlNode node in xml.DocumentElement.SelectNodes("//ttml:head/ttml:layout/ttml:region", nsmgr)) { string id = null; if (node.Attributes["xml:id"] != null) { id = node.Attributes["xml:id"].Value; } else if (node.Attributes["id"] != null) { id = node.Attributes["id"].Value; } if (id != null && id == "bottom") { hasBottomCenterRegion = true; } if (id != null && id == "topCenter") { hasTopCenterRegion = true; } } foreach (var p in subtitle.Paragraphs) { XmlNode paragraph = xml.CreateElement("p", "http://www.w3.org/ns/ttml"); string text = p.Text; XmlAttribute start = xml.CreateAttribute("begin"); start.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}:{3:00}", p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds)); paragraph.Attributes.Append(start); XmlAttribute end = xml.CreateAttribute("end"); end.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}:{3:00}", p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds)); paragraph.Attributes.Append(end); XmlAttribute style = xml.CreateAttribute("style"); style.InnerText = "basic"; paragraph.Attributes.Append(style); XmlAttribute regionP = xml.CreateAttribute("region"); if (text.StartsWith("{\\an7}", StringComparison.Ordinal) || text.StartsWith("{\\an8}", StringComparison.Ordinal) || text.StartsWith("{\\an9}", StringComparison.Ordinal)) { if (hasTopCenterRegion) { regionP.InnerText = "top"; paragraph.Attributes.Append(regionP); } } else if (hasBottomCenterRegion) { regionP.InnerText = "bottom"; paragraph.Attributes.Append(regionP); } if (text.StartsWith("{\\an", StringComparison.Ordinal) && text.Length > 6 && text[5] == '}') { text = text.Remove(0, 6); } XmlAttribute styleAttribute = xml.CreateAttribute("style"); styleAttribute.InnerText = "basic"; paragraph.Attributes.Append(styleAttribute); if (convertedFromSubStationAlpha) { if (string.IsNullOrEmpty(p.Style)) { p.Style = p.Extra; } } bool first = true; bool italicOn = false; foreach (string line in text.SplitToLines()) { if (!first) { XmlNode br = xml.CreateElement("br", "http://www.w3.org/ns/ttml"); paragraph.AppendChild(br); } var styles = new Stack <XmlNode>(); XmlNode currentStyle = xml.CreateTextNode(string.Empty); paragraph.AppendChild(currentStyle); int skipCount = 0; for (int i = 0; i < line.Length; i++) { if (skipCount > 0) { skipCount--; } else if (line.Substring(i).StartsWith("<i>", StringComparison.Ordinal)) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); skipCount = 2; italicOn = true; } else if (line.Substring(i).StartsWith("<b>", StringComparison.Ordinal)) { currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontWeight", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "bold"; currentStyle.Attributes.Append(attr); skipCount = 2; } else if (line.Substring(i).StartsWith("<font ", StringComparison.Ordinal)) { int endIndex = line.Substring(i + 1).IndexOf('>'); if (endIndex > 0) { skipCount = endIndex + 1; string fontContent = line.Substring(i, skipCount); if (fontContent.Contains(" color=")) { var arr = fontContent.Substring(fontContent.IndexOf(" color=", StringComparison.Ordinal) + 7).Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string fontColor = arr[0].Trim('\'').Trim('"').Trim('\''); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:color", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = fontColor; currentStyle.Attributes.Append(attr); } } } else { skipCount = line.Length; } } else if (line.Substring(i).StartsWith("</i>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</b>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</font>", StringComparison.Ordinal)) { currentStyle = xml.CreateTextNode(string.Empty); if (styles.Count > 0) { currentStyle = styles.Pop().CloneNode(true); currentStyle.InnerText = string.Empty; } paragraph.AppendChild(currentStyle); if (line.Substring(i).StartsWith("</font>", StringComparison.Ordinal)) { skipCount = 6; } else { skipCount = 3; } italicOn = false; } else { if (i == 0 && italicOn && !(line.Substring(i).StartsWith("<i>", StringComparison.Ordinal))) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); } currentStyle.InnerText = currentStyle.InnerText + line[i]; } } first = false; } div.AppendChild(paragraph); } string xmlString = ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty).Replace(" xmlns:tts=\"http://www.w3.org/ns/10/ttml#style\">", ">").Replace("<br />", "<br/>"); if (subtitle.Header == null) { subtitle.Header = xmlString; } return(xmlString); }
public override void LoadSubtitle(Subtitle subtitle, List <string> lines, string fileName) { var sb = new StringBuilder(); foreach (string line in lines) { sb.AppendLine(line); } var rtf = sb.ToString().Trim(); if (!rtf.StartsWith("{\\rtf", StringComparison.Ordinal)) { return; } lines = rtf.FromRtf().SplitToLines(); _errorCount = 0; var p = new Paragraph { StartTime = { TotalMilliseconds = -1 } }; var text = new StringBuilder(); foreach (string line in lines) { string s = line.Trim(); if (RegexTimeCodes.Match(s).Success) { try { if (p.StartTime.TotalMilliseconds >= 0 && text.Length > 0) { p.Text = text.ToString().Trim(); subtitle.Paragraphs.Add(p); } text = new StringBuilder(); var arr = s.Split(':'); if (arr.Length == 4) { p = new Paragraph { StartTime = DecodeTimeCodeFramesFourParts(arr) }; } else { _errorCount++; p = new Paragraph { StartTime = { TotalMilliseconds = -1 } }; } } catch { _errorCount++; } } else if (s.Length > 0) { text.AppendLine(s); if (text.Length > 2000) { _errorCount++; return; } } } if (p.StartTime.TotalMilliseconds >= 0 && text.Length > 0) { p.Text = text.ToString().Trim(); subtitle.Paragraphs.Add(p); } int index = 1; var language = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); foreach (var paragraph in subtitle.Paragraphs) { paragraph.Text = Utilities.AutoBreakLine(paragraph.Text, language); var next = subtitle.GetParagraphOrDefault(index); if (next != null) { paragraph.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - 1; } if (paragraph.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds) { paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(paragraph.Text); } index++; } subtitle.RemoveEmptyLines(); subtitle.Renumber(); }
public Subtitle SplitLongLinesInSubtitle(Subtitle subtitle, List <int> splittedIndexes, List <int> autoBreakedIndexes, out int numberOfSplits, int totalLineMaxCharacters, int singleLineMaxCharacters, bool clearFixes) { listViewFixes.ItemChecked -= listViewFixes_ItemChecked; if (clearFixes) { listViewFixes.Items.Clear(); } numberOfSplits = 0; string language = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); var splittedSubtitle = new Subtitle(); string[] expectedPunctuations = { ". -", "! -", "? -" }; for (int i = 0; i < subtitle.Paragraphs.Count; i++) { bool added = false; var p = subtitle.Paragraphs[i]; if (p != null && p.Text != null) { if (SplitLongLinesHelper.QualifiesForSplit(p.Text, singleLineMaxCharacters, totalLineMaxCharacters) && IsFixAllowed(p)) { string oldText = HtmlUtil.RemoveHtmlTags(p.Text); bool isDialog = false; string dialogText = string.Empty; if (p.Text.Contains('-')) { dialogText = Utilities.AutoBreakLine(p.Text, 5, 1, language); var tempText = p.Text.Replace(Environment.NewLine, " ").Replace(" ", " "); if (Utilities.CountTagInText(tempText, '-') == 2 && (p.Text.StartsWith('-') || p.Text.StartsWith("<i>-", StringComparison.Ordinal))) { int idx = tempText.IndexOfAny(expectedPunctuations, StringComparison.Ordinal); if (idx > 1) { dialogText = tempText.Remove(idx + 1, 1).Insert(idx + 1, Environment.NewLine); } } var arr = dialogText.SplitToLines(); if (arr.Length == 2 && (arr[0].StartsWith('-') || arr[0].StartsWith("<i>-", StringComparison.Ordinal)) && (arr[1].StartsWith('-') || arr[1].StartsWith("<i>-", StringComparison.Ordinal))) { isDialog = true; } } if (!isDialog && !SplitLongLinesHelper.QualifiesForSplit(Utilities.AutoBreakLine(p.Text, language), singleLineMaxCharacters, totalLineMaxCharacters)) { var newParagraph = new Paragraph(p) { Text = Utilities.AutoBreakLine(p.Text, language) }; if (clearFixes) { AddToListView(p, (splittedSubtitle.Paragraphs.Count + 1).ToString(CultureInfo.InvariantCulture), oldText); } autoBreakedIndexes.Add(splittedSubtitle.Paragraphs.Count); splittedSubtitle.Paragraphs.Add(newParagraph); added = true; numberOfSplits++; } else { string text = Utilities.AutoBreakLine(p.Text, language); if (isDialog) { text = dialogText; } if (isDialog || text.Contains(Environment.NewLine)) { var arr = text.SplitToLines(); if (arr.Length == 2) { int spacing1 = Configuration.Settings.General.MinimumMillisecondsBetweenLines / 2; int spacing2 = Configuration.Settings.General.MinimumMillisecondsBetweenLines / 2; if (Configuration.Settings.General.MinimumMillisecondsBetweenLines % 2 == 1) { spacing2++; } var newParagraph1 = new Paragraph(p); var newParagraph2 = new Paragraph(p); newParagraph1.Text = Utilities.AutoBreakLine(arr[0], language); double middle = p.StartTime.TotalMilliseconds + (p.Duration.TotalMilliseconds / 2); if (!string.IsNullOrWhiteSpace(oldText)) { var startFactor = (double)HtmlUtil.RemoveHtmlTags(newParagraph1.Text).Length / oldText.Length; if (startFactor < 0.25) { startFactor = 0.25; } if (startFactor > 0.75) { startFactor = 0.75; } middle = p.StartTime.TotalMilliseconds + (p.Duration.TotalMilliseconds * startFactor); } newParagraph1.EndTime.TotalMilliseconds = middle - spacing1; newParagraph2.Text = Utilities.AutoBreakLine(arr[1], language); newParagraph2.StartTime.TotalMilliseconds = newParagraph1.EndTime.TotalMilliseconds + spacing2; if (clearFixes) { AddToListView(p, (splittedSubtitle.Paragraphs.Count + 1).ToString(CultureInfo.InvariantCulture), oldText); } splittedIndexes.Add(splittedSubtitle.Paragraphs.Count); splittedIndexes.Add(splittedSubtitle.Paragraphs.Count + 1); string p1 = HtmlUtil.RemoveHtmlTags(newParagraph1.Text).TrimEnd(); if (p1.EndsWith('.') || p1.EndsWith('!') || p1.EndsWith('?') || p1.EndsWith(':') || p1.EndsWith(')') || p1.EndsWith(']') || p1.EndsWith('♪')) { if (newParagraph1.Text.StartsWith('-') && newParagraph2.Text.StartsWith('-')) { newParagraph1.Text = newParagraph1.Text.Remove(0, 1).Trim(); newParagraph2.Text = newParagraph2.Text.Remove(0, 1).Trim(); } else if (newParagraph1.Text.StartsWith("<i>-", StringComparison.Ordinal) && newParagraph2.Text.StartsWith('-')) { newParagraph1.Text = newParagraph1.Text.Remove(3, 1).Trim(); if (newParagraph1.Text.StartsWith("<i> ", StringComparison.Ordinal)) { newParagraph1.Text = newParagraph1.Text.Remove(3, 1).Trim(); } newParagraph2.Text = newParagraph2.Text.Remove(0, 1).Trim(); } } else { bool endsWithComma = newParagraph1.Text.EndsWith(',') || newParagraph1.Text.EndsWith(",</i>", StringComparison.Ordinal); string post = string.Empty; if (newParagraph1.Text.EndsWith("</i>", StringComparison.Ordinal)) { post = "</i>"; newParagraph1.Text = newParagraph1.Text.Remove(newParagraph1.Text.Length - post.Length); } if (endsWithComma) { newParagraph1.Text += post; } else { newParagraph1.Text += comboBoxLineContinuationEnd.Text.TrimEnd() + post; } string pre = string.Empty; if (newParagraph2.Text.StartsWith("<i>", StringComparison.Ordinal)) { pre = "<i>"; newParagraph2.Text = newParagraph2.Text.Remove(0, pre.Length); } if (endsWithComma) { newParagraph2.Text = pre + newParagraph2.Text; } else { newParagraph2.Text = pre + comboBoxLineContinuationBegin.Text + newParagraph2.Text; } } var italicStart1 = newParagraph1.Text.IndexOf("<i>", StringComparison.Ordinal); if (italicStart1 >= 0 && italicStart1 < 10 && newParagraph1.Text.IndexOf("</i>", StringComparison.Ordinal) < 0 && newParagraph2.Text.Contains("</i>") && newParagraph2.Text.IndexOf("<i>", StringComparison.Ordinal) < 0) { newParagraph1.Text += "</i>"; newParagraph2.Text = "<i>" + newParagraph2.Text; } splittedSubtitle.Paragraphs.Add(newParagraph1); splittedSubtitle.Paragraphs.Add(newParagraph2); added = true; numberOfSplits++; } } } } if (!added) { splittedSubtitle.Paragraphs.Add(new Paragraph(p)); } } } listViewFixes.ItemChecked += listViewFixes_ItemChecked; splittedSubtitle.Renumber(); return(splittedSubtitle); }
public override string ToText(Subtitle subtitle, string title) { string languageEnglishName; try { string languageShortName = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); var ci = CultureInfo.CreateSpecificCulture(languageShortName); languageEnglishName = ci.EnglishName; int indexOfStartP = languageEnglishName.IndexOf('('); if (indexOfStartP > 1) { languageEnglishName = languageEnglishName.Remove(indexOfStartP).Trim(); } } catch { languageEnglishName = "English"; } string hex = Guid.NewGuid().ToString().Replace("-", string.Empty); hex = hex.Insert(8, "-").Insert(13, "-").Insert(18, "-").Insert(23, "-"); string xmlStructure = "<DCSubtitle Version=\"1.0\">" + Environment.NewLine + " <SubtitleID>" + hex.ToLower() + "</SubtitleID>" + Environment.NewLine + " <MovieTitle></MovieTitle>" + Environment.NewLine + " <ReelNumber>1</ReelNumber>" + Environment.NewLine + " <Language>" + languageEnglishName + "</Language>" + Environment.NewLine + " <LoadFont URI=\"" + Configuration.Settings.SubtitleSettings.DCinemaFontFile + "\" Id=\"Font1\"/>" + Environment.NewLine + " <Font Id=\"Font1\" Color=\"FFFFFFFF\" Effect=\"border\" EffectColor=\"FF000000\" Italic=\"no\" Underlined=\"no\" Script=\"normal\" Size=\"42\">" + Environment.NewLine + " </Font>" + Environment.NewLine + "</DCSubtitle>"; XmlDocument xml = new XmlDocument(); xml.LoadXml(xmlStructure); xml.PreserveWhitespace = true; var ss = Configuration.Settings.SubtitleSettings; string loadedFontId = "Font1"; if (!string.IsNullOrEmpty(ss.CurrentDCinemaFontId)) { loadedFontId = ss.CurrentDCinemaFontId; } if (string.IsNullOrEmpty(ss.CurrentDCinemaMovieTitle)) { ss.CurrentDCinemaMovieTitle = title; } if (ss.CurrentDCinemaFontSize == 0 || string.IsNullOrEmpty(ss.CurrentDCinemaFontEffect)) { Configuration.Settings.SubtitleSettings.InitializeDCinameSettings(true); } xml.DocumentElement.SelectSingleNode("MovieTitle").InnerText = ss.CurrentDCinemaMovieTitle; xml.DocumentElement.SelectSingleNode("SubtitleID").InnerText = ss.CurrentDCinemaSubtitleId.Replace("urn:uuid:", string.Empty); xml.DocumentElement.SelectSingleNode("ReelNumber").InnerText = ss.CurrentDCinemaReelNumber; xml.DocumentElement.SelectSingleNode("Language").InnerText = ss.CurrentDCinemaLanguage; xml.DocumentElement.SelectSingleNode("LoadFont").Attributes["URI"].InnerText = ss.CurrentDCinemaFontUri; xml.DocumentElement.SelectSingleNode("LoadFont").Attributes["Id"].InnerText = loadedFontId; int fontSize = ss.CurrentDCinemaFontSize; xml.DocumentElement.SelectSingleNode("Font").Attributes["Id"].InnerText = loadedFontId; xml.DocumentElement.SelectSingleNode("Font").Attributes["Color"].InnerText = "FF" + Utilities.ColorToHex(ss.CurrentDCinemaFontColor).TrimStart('#').ToUpper(); xml.DocumentElement.SelectSingleNode("Font").Attributes["Effect"].InnerText = ss.CurrentDCinemaFontEffect; xml.DocumentElement.SelectSingleNode("Font").Attributes["EffectColor"].InnerText = "FF" + Utilities.ColorToHex(ss.CurrentDCinemaFontEffectColor).TrimStart('#').ToUpper(); xml.DocumentElement.SelectSingleNode("Font").Attributes["Size"].InnerText = ss.CurrentDCinemaFontSize.ToString(); XmlNode mainListFont = xml.DocumentElement.SelectSingleNode("Font"); int no = 0; foreach (Paragraph p in subtitle.Paragraphs) { if (!string.IsNullOrEmpty(p.Text)) { XmlNode subNode = xml.CreateElement("Subtitle"); XmlAttribute id = xml.CreateAttribute("SpotNumber"); id.InnerText = (no + 1).ToString(); subNode.Attributes.Append(id); XmlAttribute fadeUpTime = xml.CreateAttribute("FadeUpTime"); fadeUpTime.InnerText = Configuration.Settings.SubtitleSettings.DCinemaFadeUpTime.ToString(); subNode.Attributes.Append(fadeUpTime); XmlAttribute fadeDownTime = xml.CreateAttribute("FadeDownTime"); fadeDownTime.InnerText = Configuration.Settings.SubtitleSettings.DCinemaFadeDownTime.ToString(); subNode.Attributes.Append(fadeDownTime); XmlAttribute start = xml.CreateAttribute("TimeIn"); start.InnerText = ConvertToTimeString(p.StartTime); subNode.Attributes.Append(start); XmlAttribute end = xml.CreateAttribute("TimeOut"); end.InnerText = ConvertToTimeString(p.EndTime); subNode.Attributes.Append(end); bool alignLeft = p.Text.StartsWith("{\\a1}") || p.Text.StartsWith("{\\a5}") || p.Text.StartsWith("{\\a9}") || // sub station alpha p.Text.StartsWith("{\\an1}") || p.Text.StartsWith("{\\an4}") || p.Text.StartsWith("{\\an7}"); // advanced sub station alpha bool alignRight = p.Text.StartsWith("{\\a3}") || p.Text.StartsWith("{\\a7}") || p.Text.StartsWith("{\\a11}") || // sub station alpha p.Text.StartsWith("{\\an3}") || p.Text.StartsWith("{\\an6}") || p.Text.StartsWith("{\\an9}"); // advanced sub station alpha bool alignVTop = p.Text.StartsWith("{\\a5}") || p.Text.StartsWith("{\\a6}") || p.Text.StartsWith("{\\a7}") || // sub station alpha p.Text.StartsWith("{\\an7}") || p.Text.StartsWith("{\\an8}") || p.Text.StartsWith("{\\an9}"); // advanced sub station alpha bool alignVCenter = p.Text.StartsWith("{\\a9}") || p.Text.StartsWith("{\\a10}") || p.Text.StartsWith("{\\a11}") || // sub station alpha p.Text.StartsWith("{\\an4}") || p.Text.StartsWith("{\\an5}") || p.Text.StartsWith("{\\an6}"); // advanced sub station alpha // remove styles for display text (except italic) string text = RemoveSubStationAlphaFormatting(p.Text); var lines = text.SplitToLines(); int vPos = 1 + lines.Length * 7; int vPosFactor = (int)Math.Round(fontSize / 7.4); if (alignVTop) { vPos = Configuration.Settings.SubtitleSettings.DCinemaBottomMargin; // Bottom margin is normally 8 } else if (alignVCenter) { vPos = (int)Math.Round((lines.Length * vPosFactor * -1) / 2.0); } else { vPos = (lines.Length * vPosFactor) - vPosFactor + Configuration.Settings.SubtitleSettings.DCinemaBottomMargin; // Bottom margin is normally 8 } bool isItalic = false; int fontNo = 0; Stack <string> fontColors = new Stack <string>(); foreach (string line in lines) { XmlNode textNode = xml.CreateElement("Text"); XmlAttribute vPosition = xml.CreateAttribute("VPosition"); vPosition.InnerText = vPos.ToString(); textNode.Attributes.Append(vPosition); if (Configuration.Settings.SubtitleSettings.DCinemaZPosition != 0) { XmlAttribute zPosition = xml.CreateAttribute("ZPosition"); zPosition.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:0.00}", Configuration.Settings.SubtitleSettings.DCinemaZPosition); textNode.Attributes.Append(zPosition); } XmlAttribute vAlign = xml.CreateAttribute("VAlign"); if (alignVTop) { vAlign.InnerText = "top"; } else if (alignVCenter) { vAlign.InnerText = "center"; } else { vAlign.InnerText = "bottom"; } textNode.Attributes.Append(vAlign); XmlAttribute hAlign = xml.CreateAttribute("HAlign"); if (alignLeft) { hAlign.InnerText = "left"; } else if (alignRight) { hAlign.InnerText = "right"; } else { hAlign.InnerText = "center"; } textNode.Attributes.Append(hAlign); XmlAttribute direction = xml.CreateAttribute("Direction"); direction.InnerText = "horizontal"; textNode.Attributes.Append(direction); int i = 0; var txt = new StringBuilder(); var html = new StringBuilder(); XmlNode nodeTemp = xml.CreateElement("temp"); while (i < line.Length) { if (!isItalic && line.Substring(i).StartsWith("<i>")) { if (txt.Length > 0) { nodeTemp.InnerText = txt.ToString(); html.Append(nodeTemp.InnerXml); txt = new StringBuilder(); } isItalic = true; i += 2; } else if (isItalic && line.Substring(i).StartsWith("</i>")) { if (txt.Length > 0) { XmlNode fontNode = xml.CreateElement("Font"); XmlAttribute italic = xml.CreateAttribute("Italic"); italic.InnerText = "yes"; fontNode.Attributes.Append(italic); if (!string.IsNullOrEmpty(ss.CurrentDCinemaFontEffect)) { XmlAttribute fontEffect = xml.CreateAttribute("Effect"); fontEffect.InnerText = ss.CurrentDCinemaFontEffect; fontNode.Attributes.Append(fontEffect); } if (line.Length > i + 5 && line.Substring(i + 4).StartsWith("</font>")) { XmlAttribute fontColor = xml.CreateAttribute("Color"); fontColor.InnerText = fontColors.Pop(); fontNode.Attributes.Append(fontColor); fontNo--; i += 7; } fontNode.InnerText = HtmlUtil.RemoveHtmlTags(txt.ToString()); html.Append(fontNode.OuterXml); txt = new StringBuilder(); } isItalic = false; i += 3; } else if (line.Substring(i).StartsWith("<font color=") && line.Substring(i + 3).Contains('>')) { int endOfFont = line.IndexOf('>', i); if (txt.Length > 0) { nodeTemp.InnerText = txt.ToString(); html.Append(nodeTemp.InnerXml); txt = new StringBuilder(); } string c = line.Substring(i + 12, endOfFont - (i + 12)); c = c.Trim('"').Trim('\'').Trim(); if (c.StartsWith('#')) { c = c.TrimStart('#').ToUpper().PadLeft(8, 'F'); } fontColors.Push(c); fontNo++; i += endOfFont - i; } else if (fontNo > 0 && line.Substring(i).StartsWith("</font>")) { if (txt.Length > 0) { XmlNode fontNode = xml.CreateElement("Font"); XmlAttribute fontColor = xml.CreateAttribute("Color"); fontColor.InnerText = fontColors.Pop(); fontNode.Attributes.Append(fontColor); if (line.Length > i + 9 && line.Substring(i + 7).StartsWith("</i>")) { XmlAttribute italic = xml.CreateAttribute("Italic"); italic.InnerText = "yes"; fontNode.Attributes.Append(italic); isItalic = false; i += 4; } if (!string.IsNullOrEmpty(ss.CurrentDCinemaFontEffect)) { XmlAttribute fontEffect = xml.CreateAttribute("Effect"); fontEffect.InnerText = ss.CurrentDCinemaFontEffect; fontNode.Attributes.Append(fontEffect); } fontNode.InnerText = HtmlUtil.RemoveHtmlTags(txt.ToString()); html.Append(fontNode.OuterXml); txt = new StringBuilder(); } fontNo--; i += 6; } else { txt.Append(line[i]); } i++; } if (fontNo > 0) { if (txt.Length > 0) { XmlNode fontNode = xml.CreateElement("Font"); XmlAttribute fontColor = xml.CreateAttribute("Color"); fontColor.InnerText = fontColors.Peek(); fontNode.Attributes.Append(fontColor); if (isItalic) { XmlAttribute italic = xml.CreateAttribute("Italic"); italic.InnerText = "yes"; fontNode.Attributes.Append(italic); } if (!string.IsNullOrEmpty(ss.CurrentDCinemaFontEffect)) { XmlAttribute fontEffect = xml.CreateAttribute("Effect"); fontEffect.InnerText = ss.CurrentDCinemaFontEffect; fontNode.Attributes.Append(fontEffect); } fontNode.InnerText = HtmlUtil.RemoveHtmlTags(txt.ToString()); html.Append(fontNode.OuterXml); } else if (html.Length > 0 && html.ToString().StartsWith("<Font ")) { XmlDocument temp = new XmlDocument(); temp.LoadXml("<root>" + html + "</root>"); XmlNode fontNode = xml.CreateElement("Font"); fontNode.InnerXml = temp.DocumentElement.SelectSingleNode("Font").InnerXml; foreach (XmlAttribute a in temp.DocumentElement.SelectSingleNode("Font").Attributes) { XmlAttribute newA = xml.CreateAttribute(a.Name); newA.InnerText = a.InnerText; fontNode.Attributes.Append(newA); } XmlAttribute fontColor = xml.CreateAttribute("Color"); fontColor.InnerText = fontColors.Peek(); fontNode.Attributes.Append(fontColor); if (!string.IsNullOrEmpty(ss.CurrentDCinemaFontEffect)) { XmlAttribute fontEffect = xml.CreateAttribute("Effect"); fontEffect.InnerText = ss.CurrentDCinemaFontEffect; fontNode.Attributes.Append(fontEffect); } html = new StringBuilder(); html.Append(fontNode.OuterXml); } } else if (isItalic) { if (txt.Length > 0) { XmlNode fontNode = xml.CreateElement("Font"); XmlAttribute italic = xml.CreateAttribute("Italic"); italic.InnerText = "yes"; fontNode.Attributes.Append(italic); if (!string.IsNullOrEmpty(ss.CurrentDCinemaFontEffect)) { XmlAttribute fontEffect = xml.CreateAttribute("Effect"); fontEffect.InnerText = ss.CurrentDCinemaFontEffect; fontNode.Attributes.Append(fontEffect); } fontNode.InnerText = HtmlUtil.RemoveHtmlTags(line); html.Append(fontNode.OuterXml); } } else { if (txt.Length > 0) { nodeTemp.InnerText = txt.ToString(); html.Append(nodeTemp.InnerXml); } } textNode.InnerXml = html.ToString(); subNode.AppendChild(textNode); if (alignVTop) { vPos += vPosFactor; } else { vPos -= vPosFactor; } } mainListFont.AppendChild(subNode); no++; } } string s = ToUtf8XmlString(xml).Replace("encoding=\"utf-8\"", "encoding=\"UTF-8\""); while (s.Contains("</Font> ") || s.Contains(" <Font ") || s.Contains(Environment.NewLine + "<Font ") || s.Contains("</Font>" + Environment.NewLine)) { while (s.Contains(" Font")) { s = s.Replace(" <Font ", " <Font "); } while (s.Contains("\tFont")) { s = s.Replace("\t<Font ", " <Font "); } s = s.Replace("</Font> ", "</Font> "); s = s.Replace(" <Font ", " <Font "); s = s.Replace(Environment.NewLine + "<Font ", "<Font "); s = s.Replace(Environment.NewLine + " <Font ", "<Font "); s = s.Replace("</Font>" + Environment.NewLine, "</Font>"); s = s.Replace("><", "> <"); } return(s); }
public Subtitle MergeShortLinesInSubtitle(Subtitle subtitle, List <int> mergedIndexes, out int numberOfMerges, double maxMillisecondsBetweenLines, int maxCharacters, bool clearFixes) { listViewFixes.ItemChecked -= listViewFixes_ItemChecked; if (clearFixes) { listViewFixes.Items.Clear(); } numberOfMerges = 0; string language = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); var mergedSubtitle = new Subtitle(); bool lastMerged = false; Paragraph p = null; var lineNumbers = new StringBuilder(); bool onlyContinuousLines = checkBoxOnlyContinuationLines.Checked; for (int i = 1; i < subtitle.Paragraphs.Count; i++) { if (!lastMerged) { p = new Paragraph(subtitle.GetParagraphOrDefault(i - 1)); mergedSubtitle.Paragraphs.Add(p); } Paragraph next = subtitle.GetParagraphOrDefault(i); if (next != null) { if (Utilities.QualifiesForMerge(p, next, maxMillisecondsBetweenLines, maxCharacters, onlyContinuousLines) && IsFixAllowed(p)) { if (MergeShortLinesUtils.GetStartTag(p.Text) == MergeShortLinesUtils.GetStartTag(next.Text) && MergeShortLinesUtils.GetEndTag(p.Text) == MergeShortLinesUtils.GetEndTag(next.Text)) { string s1 = p.Text.Trim(); s1 = s1.Substring(0, s1.Length - MergeShortLinesUtils.GetEndTag(s1).Length); string s2 = next.Text.Trim(); s2 = s2.Substring(MergeShortLinesUtils.GetStartTag(s2).Length); p.Text = Utilities.AutoBreakLine(s1 + Environment.NewLine + s2, language); } else { p.Text = Utilities.AutoBreakLine(p.Text + Environment.NewLine + next.Text, language); } p.EndTime = next.EndTime; if (lastMerged) { lineNumbers.Append(next.Number); lineNumbers.Append(','); } else { lineNumbers.Append(p.Number); lineNumbers.Append(','); lineNumbers.Append(next.Number); lineNumbers.Append(','); } lastMerged = true; numberOfMerges++; if (!mergedIndexes.Contains(i)) { mergedIndexes.Add(i); } if (!mergedIndexes.Contains(i - 1)) { mergedIndexes.Add(i - 1); } } else { lastMerged = false; } } else { lastMerged = false; } if (!lastMerged && lineNumbers.Length > 0 && clearFixes) { AddToListView(p, lineNumbers.ToString(), p.Text); lineNumbers.Clear(); } } if (!lastMerged) { mergedSubtitle.Paragraphs.Add(new Paragraph(subtitle.GetParagraphOrDefault(subtitle.Paragraphs.Count - 1))); } listViewFixes.ItemChecked += listViewFixes_ItemChecked; return(mergedSubtitle); }
internal static bool BatchConvertSave(string toFormat, string offset, Encoding targetEncoding, string outputFolder, int count, ref int converted, ref int errors, IList <SubtitleFormat> formats, string fileName, Subtitle sub, SubtitleFormat format, bool overwrite, string pacCodePage, double?targetFrameRate, bool removeTextForHi, bool fixCommonErrors, bool redoCasing) { double oldFrameRate = Configuration.Settings.General.CurrentFrameRate; try { // adjust offset if (!string.IsNullOrEmpty(offset) && (offset.StartsWith("/offset:", StringComparison.Ordinal) || offset.StartsWith("offset:", StringComparison.Ordinal))) { string[] parts = offset.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 5) { try { var ts = new TimeSpan(0, int.Parse(parts[1].TrimStart('-')), int.Parse(parts[2]), int.Parse(parts[3]), int.Parse(parts[4])); if (parts[1].StartsWith('-')) { sub.AddTimeToAllParagraphs(ts.Negate()); } else { sub.AddTimeToAllParagraphs(ts); } } catch { Console.Write(" (unable to read offset " + offset + ")"); } } } // adjust frame rate if (targetFrameRate.HasValue) { sub.ChangeFrameRate(Configuration.Settings.General.CurrentFrameRate, targetFrameRate.Value); Configuration.Settings.General.CurrentFrameRate = targetFrameRate.Value; } if (removeTextForHi) { var hiSettings = new Core.Forms.RemoveTextForHISettings(); var hiLib = new Core.Forms.RemoveTextForHI(hiSettings); foreach (var p in sub.Paragraphs) { p.Text = hiLib.RemoveTextFromHearImpaired(p.Text); } } if (fixCommonErrors) { using (var fce = new FixCommonErrors { BatchMode = true }) { for (int i = 0; i < 3; i++) { fce.RunBatch(sub, format, targetEncoding, Configuration.Settings.Tools.BatchConvertLanguage); sub = fce.FixedSubtitle; } } } if (redoCasing) { using (var changeCasing = new ChangeCasing()) { changeCasing.FixCasing(sub, LanguageAutoDetect.AutoDetectGoogleLanguage(sub)); } using (var changeCasingNames = new ChangeCasingNames()) { changeCasingNames.Initialize(sub); changeCasingNames.FixCasing(); } } bool targetFormatFound = false; string outputFileName; foreach (SubtitleFormat sf in formats) { if (sf.IsTextBased && (sf.Name.Replace(" ", string.Empty).Equals(toFormat, StringComparison.OrdinalIgnoreCase) || sf.Name.Replace(" ", string.Empty).Equals(toFormat.Replace(" ", string.Empty), StringComparison.OrdinalIgnoreCase))) { targetFormatFound = true; sf.BatchMode = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, sf.Extension, outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); if (sf.IsFrameBased && !sub.WasLoadedWithFrameNumbers) { sub.CalculateFrameNumbersFromTimeCodesNoCheck(Configuration.Settings.General.CurrentFrameRate); } else if (sf.IsTimeBased && sub.WasLoadedWithFrameNumbers) { sub.CalculateTimeCodesFromFrameNumbers(Configuration.Settings.General.CurrentFrameRate); } if ((sf.GetType() == typeof(WebVTT) || sf.GetType() == typeof(WebVTTFileWithLineNumber))) { targetEncoding = Encoding.UTF8; } if (sf.GetType() == typeof(ItunesTimedText) || sf.GetType() == typeof(ScenaristClosedCaptions) || sf.GetType() == typeof(ScenaristClosedCaptionsDropFrame)) { Encoding outputEnc = new UTF8Encoding(false); // create encoding with no BOM using (var file = new StreamWriter(outputFileName, false, outputEnc)) // open file with encoding { file.Write(sub.ToText(sf)); } // save and close it } else if (targetEncoding == Encoding.UTF8 && (format.GetType() == typeof(TmpegEncAW5) || format.GetType() == typeof(TmpegEncXml))) { Encoding outputEnc = new UTF8Encoding(false); // create encoding with no BOM using (var file = new StreamWriter(outputFileName, false, outputEnc)) // open file with encoding { file.Write(sub.ToText(sf)); } // save and close it } else { try { File.WriteAllText(outputFileName, sub.ToText(sf), targetEncoding); } catch (Exception ex) { Console.WriteLine(ex.Message); errors++; return(false); } } if (format.GetType() == typeof(Sami) || format.GetType() == typeof(SamiModern)) { var sami = (Sami)format; foreach (string className in Sami.GetStylesFromHeader(sub.Header)) { var newSub = new Subtitle(); foreach (Paragraph p in sub.Paragraphs) { if (p.Extra != null && p.Extra.Trim().Equals(className.Trim(), StringComparison.OrdinalIgnoreCase)) { newSub.Paragraphs.Add(p); } } if (newSub.Paragraphs.Count > 0 && newSub.Paragraphs.Count < sub.Paragraphs.Count) { string s = fileName; if (s.LastIndexOf('.') > 0) { s = s.Insert(s.LastIndexOf('.'), "_" + className); } else { s += "_" + className + format.Extension; } outputFileName = FormatOutputFileNameForBatchConvert(s, sf.Extension, outputFolder, overwrite); File.WriteAllText(outputFileName, newSub.ToText(sf), targetEncoding); } } } Console.WriteLine(" done."); break; } } if (!targetFormatFound) { var ebu = new Ebu(); if (ebu.Name.Replace(" ", string.Empty).Equals(toFormat.Replace(" ", string.Empty), StringComparison.OrdinalIgnoreCase)) { targetFormatFound = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, ebu.Extension, outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); Ebu.Save(outputFileName, sub, true); Console.WriteLine(" done."); } } if (!targetFormatFound) { var pac = new Pac(); if (pac.Name.Replace(" ", string.Empty).Equals(toFormat, StringComparison.OrdinalIgnoreCase) || toFormat.Equals("pac", StringComparison.OrdinalIgnoreCase) || toFormat.Equals(".pac", StringComparison.OrdinalIgnoreCase)) { pac.BatchMode = true; int codePage; if (!string.IsNullOrEmpty(pacCodePage) && int.TryParse(pacCodePage, out codePage)) { pac.CodePage = codePage; } targetFormatFound = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, pac.Extension, outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); pac.Save(outputFileName, sub); Console.WriteLine(" done."); } } if (!targetFormatFound) { var cavena890 = new Cavena890(); if (cavena890.Name.Replace(" ", string.Empty).Equals(toFormat, StringComparison.OrdinalIgnoreCase)) { targetFormatFound = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, cavena890.Extension, outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); cavena890.Save(outputFileName, sub); Console.WriteLine(" done."); } } if (!targetFormatFound) { var cheetahCaption = new CheetahCaption(); if (cheetahCaption.Name.Replace(" ", string.Empty).Equals(toFormat, StringComparison.OrdinalIgnoreCase)) { targetFormatFound = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, cheetahCaption.Extension, outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); CheetahCaption.Save(outputFileName, sub); Console.WriteLine(" done."); } } if (!targetFormatFound) { var ayato = new Ayato(); if (ayato.Name.Replace(" ", string.Empty).Equals(toFormat, StringComparison.OrdinalIgnoreCase)) { targetFormatFound = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, ayato.Extension, outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); ayato.Save(outputFileName, null, sub); Console.WriteLine(" done."); } } if (!targetFormatFound) { var capMakerPlus = new CapMakerPlus(); if (capMakerPlus.Name.Replace(" ", string.Empty).Equals(toFormat, StringComparison.OrdinalIgnoreCase)) { targetFormatFound = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, capMakerPlus.Extension, outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); CapMakerPlus.Save(outputFileName, sub); Console.WriteLine(" done."); } } if (!targetFormatFound) { if (Configuration.Settings.Language.BatchConvert.PlainText == toFormat || Configuration.Settings.Language.BatchConvert.PlainText.Replace(" ", string.Empty).Equals(toFormat.Replace(" ", string.Empty), StringComparison.OrdinalIgnoreCase)) { targetFormatFound = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, ".txt", outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); File.WriteAllText(outputFileName, ExportText.GeneratePlainText(sub, false, false, false, false, false, false, string.Empty, true, false, true, true, false), targetEncoding); Console.WriteLine(" done."); } } if (!targetFormatFound) { if (string.Compare(BatchConvert.BluRaySubtitle, toFormat, StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(BatchConvert.BluRaySubtitle.Replace(" ", string.Empty), toFormat, StringComparison.OrdinalIgnoreCase) == 0) { targetFormatFound = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, ".sup", outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); using (var form = new ExportPngXml()) { form.Initialize(sub, format, "BLURAYSUP", fileName, null, null); var binarySubtitleFile = new FileStream(outputFileName, FileMode.Create); int width = 1920; int height = 1080; var parts = Configuration.Settings.Tools.ExportBluRayVideoResolution.Split('x'); if (parts.Length == 2 && Utilities.IsInteger(parts[0]) && Utilities.IsInteger(parts[1])) { width = int.Parse(parts[0]); height = int.Parse(parts[1]); } for (int index = 0; index < sub.Paragraphs.Count; index++) { var mp = form.MakeMakeBitmapParameter(index, width, height); mp.LineJoin = Configuration.Settings.Tools.ExportPenLineJoin; mp.Bitmap = ExportPngXml.GenerateImageFromTextWithStyle(mp); ExportPngXml.MakeBluRaySupImage(mp); binarySubtitleFile.Write(mp.Buffer, 0, mp.Buffer.Length); } binarySubtitleFile.Close(); } Console.WriteLine(" done."); } else if (string.Compare(BatchConvert.VobSubSubtitle, toFormat, StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(BatchConvert.VobSubSubtitle.Replace(" ", string.Empty), toFormat, StringComparison.OrdinalIgnoreCase) == 0) { targetFormatFound = true; outputFileName = FormatOutputFileNameForBatchConvert(fileName, ".sub", outputFolder, overwrite); Console.Write("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName); using (var form = new ExportPngXml()) { form.Initialize(sub, format, "VOBSUB", fileName, null, null); int width = 720; int height = 576; var parts = Configuration.Settings.Tools.ExportVobSubVideoResolution.Split('x'); if (parts.Length == 2 && Utilities.IsInteger(parts[0]) && Utilities.IsInteger(parts[1])) { width = int.Parse(parts[0]); height = int.Parse(parts[1]); } var cfg = Configuration.Settings.Tools; var languageIndex = IfoParser.LanguageCodes.IndexOf(LanguageAutoDetect.AutoDetectGoogleLanguageOrNull(sub)); if (languageIndex < 0) { languageIndex = IfoParser.LanguageCodes.IndexOf("en"); } using (var vobSubWriter = new VobSubWriter(outputFileName, width, height, cfg.ExportBottomMargin, cfg.ExportBottomMargin, 32, cfg.ExportFontColor, cfg.ExportBorderColor, !cfg.ExportVobAntiAliasingWithTransparency, IfoParser.LanguageNames[languageIndex], IfoParser.LanguageCodes[languageIndex])) { for (int index = 0; index < sub.Paragraphs.Count; index++) { var mp = form.MakeMakeBitmapParameter(index, width, height); mp.LineJoin = Configuration.Settings.Tools.ExportPenLineJoin; mp.Bitmap = ExportPngXml.GenerateImageFromTextWithStyle(mp); vobSubWriter.WriteParagraph(mp.P, mp.Bitmap, mp.Alignment); } vobSubWriter.WriteIdxFile(); } } Console.WriteLine(" done."); } } if (!targetFormatFound) { Console.WriteLine("{0}: {1} - target format '{2}' not found!", count, fileName, toFormat); errors++; return(false); } converted++; return(true); } finally { Configuration.Settings.General.CurrentFrameRate = oldFrameRate; } }
public static Subtitle SplitLongLinesInSubtitle(Subtitle subtitle, int totalLineMaxCharacters, int singleLineMaxCharacters) { var splittedIndexes = new List <int>(); var autoBreakedIndexes = new List <int>(); var splittedSubtitle = new Subtitle(); string language = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); for (int i = 0; i < subtitle.Paragraphs.Count; i++) { bool added = false; var p = subtitle.GetParagraphOrDefault(i); if (p != null && p.Text != null) { if (QualifiesForSplit(p.Text, singleLineMaxCharacters, totalLineMaxCharacters)) { var text = Utilities.AutoBreakLine(p.Text, language); if (!QualifiesForSplit(text, singleLineMaxCharacters, totalLineMaxCharacters)) { var newParagraph = new Paragraph(p) { Text = text }; autoBreakedIndexes.Add(splittedSubtitle.Paragraphs.Count); splittedSubtitle.Paragraphs.Add(newParagraph); added = true; } else { if (text.Contains(Environment.NewLine)) { var arr = text.SplitToLines(); if (arr.Length == 2) { var minMsBtwnLnBy2 = Configuration.Settings.General.MinimumMillisecondsBetweenLines / 2; int spacing1 = minMsBtwnLnBy2; int spacing2 = minMsBtwnLnBy2; if (Configuration.Settings.General.MinimumMillisecondsBetweenLines % 2 == 1) { spacing2++; } double duration = p.Duration.TotalMilliseconds / 2.0; var newParagraph1 = new Paragraph(p); var newParagraph2 = new Paragraph(p); newParagraph1.Text = Utilities.AutoBreakLine(arr[0], language); newParagraph1.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + duration - spacing1; newParagraph2.Text = Utilities.AutoBreakLine(arr[1], language); newParagraph2.StartTime.TotalMilliseconds = newParagraph1.EndTime.TotalMilliseconds + spacing2; splittedIndexes.Add(splittedSubtitle.Paragraphs.Count); splittedIndexes.Add(splittedSubtitle.Paragraphs.Count + 1); string p1 = HtmlUtil.RemoveHtmlTags(newParagraph1.Text); var len = p1.Length - 1; if (p1.Length > 0 && (p1[len] == '.' || p1[len] == '!' || p1[len] == '?' || p1[len] == ':' || p1[len] == ')' || p1[len] == ']' || p1[len] == '♪')) { if (newParagraph1.Text.StartsWith('-') && newParagraph2.Text.StartsWith('-')) { newParagraph1.Text = newParagraph1.Text.Remove(0, 1).Trim(); newParagraph2.Text = newParagraph2.Text.Remove(0, 1).Trim(); } else if (newParagraph1.Text.StartsWith("<i>-", StringComparison.Ordinal) && newParagraph2.Text.StartsWith('-')) { newParagraph1.Text = newParagraph1.Text.Remove(3, 1).Trim(); if (newParagraph1.Text.StartsWith("<i> ", StringComparison.Ordinal)) { newParagraph1.Text = newParagraph1.Text.Remove(3, 1).Trim(); } newParagraph2.Text = newParagraph2.Text.Remove(0, 1).Trim(); } } else { if (newParagraph1.Text.EndsWith("</i>", StringComparison.Ordinal)) { const string post = "</i>"; newParagraph1.Text = newParagraph1.Text.Remove(newParagraph1.Text.Length - post.Length); } //newParagraph1.Text += comboBoxLineContinuationEnd.Text.TrimEnd() + post; if (newParagraph2.Text.StartsWith("<i>", StringComparison.Ordinal)) { const string pre = "<i>"; newParagraph2.Text = newParagraph2.Text.Remove(0, pre.Length); } //newParagraph2.Text = pre + comboBoxLineContinuationBegin.Text + newParagraph2.Text; } var indexOfItalicOpen1 = newParagraph1.Text.IndexOf("<i>", StringComparison.Ordinal); if (indexOfItalicOpen1 >= 0 && indexOfItalicOpen1 < 10 && newParagraph1.Text.IndexOf("</i>", StringComparison.Ordinal) < 0 && newParagraph2.Text.Contains("</i>") && newParagraph2.Text.IndexOf("<i>", StringComparison.Ordinal) < 0) { newParagraph1.Text += "</i>"; newParagraph2.Text = "<i>" + newParagraph2.Text; } splittedSubtitle.Paragraphs.Add(newParagraph1); splittedSubtitle.Paragraphs.Add(newParagraph2); added = true; } } } } } if (!added) { splittedSubtitle.Paragraphs.Add(new Paragraph(p)); } } splittedSubtitle.Renumber(); return(splittedSubtitle); }
public override string ToText(Subtitle subtitle, string title) { var xml = new XmlDocument { XmlResolver = null }; var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); nsmgr.AddNamespace("ttp", "http://www.w3.org/ns/10/ttml#parameter"); nsmgr.AddNamespace("tts", "http://www.w3.org/ns/10/ttml#style"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); string xmlStructure = @"<?xml version='1.0' encoding='utf-8'?> <tt xml:lang='en' xmlns:tts='http://www.w3.org/ns/ttml#styling' xmlns:ttm='http://www.w3.org/ns/ttml#metadata' xmlns='http://www.w3.org/ns/ttml'> <head> <metadata> <ttm:title>untitled.dfxp</ttm:title> </metadata> <styling> <style xml:id='basic' tts:textAlign='center' /> </styling> </head> <body style='basic'> <div> </div> </body> </tt>".Replace("'", "\""); var languageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); xmlStructure = xmlStructure.Replace("\"en\"", "\"" + languageCode + "\""); xml.LoadXml(xmlStructure); if (!string.IsNullOrWhiteSpace(title)) { var headNode = xml.DocumentElement.SelectSingleNode("//ttml:head", nsmgr); var metadataNode = headNode?.SelectSingleNode("ttml:metadata", nsmgr); var titleNode = metadataNode?.FirstChild; if (titleNode != null) { titleNode.InnerText = title + ".dfxp"; } } var div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr); foreach (var p in subtitle.Paragraphs) { XmlNode paragraph = xml.CreateElement("p", "http://www.w3.org/ns/ttml"); string text = p.Text; XmlAttribute start = xml.CreateAttribute("begin"); start.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}.{3:000}", p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, p.StartTime.Milliseconds); paragraph.Attributes.Append(start); XmlAttribute end = xml.CreateAttribute("end"); end.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}.{3:000}", p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, p.EndTime.Milliseconds); paragraph.Attributes.Append(end); bool first = true; bool italicOn = false; foreach (string line in text.SplitToLines()) { if (!first) { XmlNode br = xml.CreateElement("br", "http://www.w3.org/ns/ttml"); paragraph.AppendChild(br); } var styles = new Stack <XmlNode>(); XmlNode currentStyle = xml.CreateTextNode(string.Empty); paragraph.AppendChild(currentStyle); int skipCount = 0; for (int i = 0; i < line.Length; i++) { if (skipCount > 0) { skipCount--; } else if (line.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase)) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); skipCount = 2; italicOn = true; } else if (line.Substring(i).StartsWith("<b>", StringComparison.OrdinalIgnoreCase)) { currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontWeight", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "bold"; currentStyle.Attributes.Append(attr); skipCount = 2; } else if (line.Substring(i).StartsWith("<font ", StringComparison.OrdinalIgnoreCase)) { int endIndex = line.Substring(i + 1).IndexOf('>'); if (endIndex > 0) { skipCount = endIndex + 1; string fontContent = line.Substring(i, skipCount); if (fontContent.Contains(" color=", StringComparison.OrdinalIgnoreCase)) { var arr = fontContent.Substring(fontContent.IndexOf(" color=", StringComparison.Ordinal) + 7).Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string fontColor = arr[0].Trim('\'').Trim('"').Trim('\''); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:color", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = fontColor; currentStyle.Attributes.Append(attr); } } } else { skipCount = line.Length; } } else if (line.Substring(i).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) || line.Substring(i).StartsWith("</b>", StringComparison.OrdinalIgnoreCase) || line.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase)) { currentStyle = xml.CreateTextNode(string.Empty); if (styles.Count > 0) { currentStyle = styles.Pop().CloneNode(true); currentStyle.InnerText = string.Empty; } paragraph.AppendChild(currentStyle); if (line.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase)) { skipCount = 6; } else { skipCount = 3; } italicOn = false; } else { if (i == 0 && italicOn && !line.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase)) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); } currentStyle.InnerText = currentStyle.InnerText + line[i]; } } first = false; } div.AppendChild(paragraph); } string xmlString = ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty).Replace(" xmlns:tts=\"http://www.w3.org/ns/10/ttml#style\">", ">").Replace("<br />", "<br/>"); if (subtitle.Header == null) { subtitle.Header = xmlString; } return(xmlString); }
public override string ToText(Subtitle subtitle, string title) { var languageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); string xmlStructure = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine + "<tt xmlns=\"http://www.w3.org/2006/04/ttaf1\" xmlns:tts=\"http://www.w3.org/2006/04/ttaf1#styling\" xmlns:ttm=\"https://www.w3.org/2006/04/ttaf1#metadata\">" + Environment.NewLine + "<head>" + Environment.NewLine + " <styling>" + Environment.NewLine + " <style xml:id=\"basic\" tts:textAlign=\"center\" />" + Environment.NewLine + " <style xml:id=\"italic\" tts:fontStyle=\"italic\" />" + Environment.NewLine + " </styling>" + Environment.NewLine + " </head>" + Environment.NewLine + " <ttm:metadata>" + Environment.NewLine + " <ttm:title>" + WebUtility.HtmlEncode(title) + "</ttm:title>" + Environment.NewLine + " </ttm:metadata>" + Environment.NewLine + " <body id=\"thebody\" style=\"basic\">" + Environment.NewLine + " <div xml:lang=\"" + languageCode + "\"/>" + Environment.NewLine + " </body>" + Environment.NewLine + "</tt>"; var xml = new XmlDocument(); xml.LoadXml(xmlStructure); var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("ttaf1", "http://www.w3.org/2006/04/ttaf1"); nsmgr.AddNamespace("tts", "http://www.w3.org/2006/04/ttaf1#styling"); XmlNode titleNode = xml.DocumentElement.SelectSingleNode("//ttaf1:head", nsmgr).FirstChild.FirstChild; titleNode.InnerText = title; XmlNode div = xml.DocumentElement.SelectSingleNode("//ttaf1:body", nsmgr).SelectSingleNode("ttaf1:div", nsmgr); if (div == null) { div = xml.DocumentElement.SelectSingleNode("//ttaf1:body", nsmgr).FirstChild; } int no = 0; foreach (Paragraph p in subtitle.Paragraphs) { XmlNode paragraph = xml.CreateElement("p", "http://www.w3.org/2006/04/ttaf1"); if (UseCDataForParagraphText) { XmlCDataSection cData = xml.CreateCDataSection(p.Text); paragraph.AppendChild(cData); } else { string text = HtmlUtil.RemoveHtmlTags(p.Text); bool first = true; foreach (string line in text.SplitToLines()) { if (!first) { XmlNode br = xml.CreateElement("br", "http://www.w3.org/2006/04/ttaf1"); paragraph.AppendChild(br); } XmlNode textNode = xml.CreateTextNode(line); paragraph.AppendChild(textNode); first = false; } } XmlAttribute start = xml.CreateAttribute("begin"); start.InnerText = ConvertToTimeString(p.StartTime); paragraph.Attributes.Append(start); XmlAttribute id = xml.CreateAttribute("id"); id.InnerText = "p" + no; paragraph.Attributes.Append(id); XmlAttribute end = xml.CreateAttribute("end"); end.InnerText = ConvertToTimeString(p.EndTime); paragraph.Attributes.Append(end); div.AppendChild(paragraph); no++; } return(ToUtf8XmlString(xml)); }