private async void _btnConvert_Click(object sender, EventArgs e) { try { string outputFilePath; if (Path.GetExtension(_txtInputFile.Text).Equals(".ass", StringComparison.InvariantCultureIgnoreCase)) { AssDocument inputDoc = new AssDocument(_txtInputFile.Text, (List <AssStyleOptions>)_lstStyles.DataSource); YttDocument outputDoc = new YttDocument(inputDoc); outputFilePath = Path.ChangeExtension(_txtInputFile.Text, ".ytt"); outputDoc.Save(outputFilePath); } else { SubtitleDocument inputDoc = SubtitleDocument.Load(_txtInputFile.Text); SrtDocument outputDoc = new SrtDocument(inputDoc); outputFilePath = Path.ChangeExtension(_txtInputFile.Text, ".srt"); outputDoc.Save(outputFilePath); } _lblConversionSuccess.Text = string.Format(Resources.SuccessfullyCreated0, Path.GetFileName(outputFilePath)); _lblConversionSuccess.Visible = true; await Task.Delay(4000); _lblConversionSuccess.Visible = false; } catch (Exception ex) { MessageBox.Show(ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
private static void RunCommandLine(string[] args) { if (args.Length != 1) { Console.WriteLine("Too many arguments specified"); return; } string filePath = args[0]; if (!File.Exists(filePath)) { Console.WriteLine("Specified file not found"); return; } try { if (Path.GetExtension(filePath).Equals(".ass", StringComparison.InvariantCultureIgnoreCase)) { SubtitleDocument doc = new AssDocument(filePath, AssStyleOptionsList.Load()); new YttDocument(doc).Save(Path.ChangeExtension(filePath, ".ytt")); } else { SubtitleDocument doc = SubtitleDocument.Load(filePath); new SrtDocument(doc).Save(Path.ChangeExtension(filePath, ".srt")); } } catch (Exception ex) { Console.WriteLine($"Error occurred: {ex}"); } }
private void PopulateUi(string filePath, SubtitleDocument doc) { _txtInputFile.Text = filePath; AssDocument assDoc = doc as AssDocument; if (assDoc != null) { _grpStyleOptions.Enabled = true; _styles = assDoc.Styles.ToDictionary(s => s.Name); foreach (AssStyle style in assDoc.Styles) { if (!_styleOptions.ContainsKey(style.Name)) { _styleOptions.Add(style.Name, new AssStyleOptions(style)); } } _lstStyles.DataSource = assDoc.Styles.Select(s => _styleOptions[s.Name]).ToList(); if (_lstStyles.Items.Count > 0) { _lstStyles.SelectedIndex = 0; } } _chkAutoConvert.Enabled = true; _chkAutoConvert.Checked = false; _subtitleWatcher.Path = Path.GetDirectoryName(filePath); _subtitleWatcher.Filter = Path.GetFileName(filePath); _btnConvert.Enabled = true; }
private void PopulateUi(string filePath, SubtitleDocument document) { _txtInputFile.Text = filePath; AssDocument assDoc = document as AssDocument; if (assDoc != null) { _grpStyleOptions.Enabled = true; RefreshStyleList(assDoc); } _chkAutoConvert.Enabled = true; _chkAutoConvert.Checked = false; _subtitleModifyWatcher.EnableRaisingEvents = false; _subtitleModifyWatcher.Path = Path.GetDirectoryName(filePath); _subtitleModifyWatcher.Filter = Path.GetFileName(filePath); // Aegisub doesn't write straight to the .ass file, but instead creates a separate <name>_tmp_<number>.ass // and renames that to the original name. _subtitleRenameWatcher.EnableRaisingEvents = false; _subtitleRenameWatcher.Path = Path.GetDirectoryName(filePath); _subtitleRenameWatcher.Filter = Path.GetFileNameWithoutExtension(filePath) + "_tmp_*" + Path.GetExtension(filePath); _btnConvert.Enabled = true; }
public static IEnumerable<AssLine> Expand(AssDocument document, AssLine originalLine) { List<AnimationWithSectionIndex> anims = GetAnimationsWithSectionIndex(originalLine); if (anims.Count == 0) { yield return originalLine; yield break; } SortedList<TimeRange, List<AnimationWithSectionIndex>> animClusters = ClusterAnimations(originalLine, anims); AssLine lastLine = CreateInitialLine(originalLine, anims); if (animClusters.Count == 0 || animClusters.Keys[0].Start > lastLine.Start) yield return lastLine; for (int i = 0; i < animClusters.Count; i++) { TimeRange clusterRange = animClusters.Keys[i]; List<AnimationWithSectionIndex> clusterAnims = animClusters.Values[i]; foreach (AssLine frameLine in CreateFrameLines(document, lastLine, clusterRange, clusterAnims)) { lastLine.End = frameLine.Start; yield return lastLine = frameLine; } DateTime interAnimStart = clusterRange.End; DateTime interAnimEnd = i < animClusters.Count - 1 ? animClusters.Keys[i + 1].Start : originalLine.End; if (interAnimEnd > interAnimStart) yield return lastLine = CreatePostAnimationClusterLine(originalLine, lastLine, interAnimStart, interAnimEnd, clusterAnims); } lastLine.End = originalLine.End; }
public override void Handle(AssTagContext context, string arg) { context.Style = context.Document.GetStyle(arg) ?? context.InitialStyle; context.StyleOptions = context.Document.GetStyleOptions(arg) ?? context.InitialStyleOptions; AssDocument.ApplyStyle(context.Section, context.Style, context.StyleOptions); context.Section.Scale = 1; context.Section.Offset = OffsetType.Regular; }
public override void Handle(AssTagContext context, string arg) { int alignment = ParseInt(arg); if (alignment >= 1 && alignment <= 9) { context.Line.AnchorPoint = AssDocument.GetAnchorPoint(alignment); } }
public override void Handle(AssTagContext context, string arg) { if (!int.TryParse(arg, out int alignment)) { return; } context.Line.AnchorPoint = AssDocument.GetAnchorPointFromAlignment(alignment); }
private async void _btnConvert_Click(object sender, EventArgs e) { try { string inputExtension = Path.GetExtension(_txtInputFile.Text).ToLower(); SubtitleDocument outputDoc; string outputExtension; switch (inputExtension) { case ".ass": { AssDocument inputDoc = new AssDocument(_txtInputFile.Text, (List <AssStyleOptions>)_lstStyles.DataSource); outputDoc = new YttDocument(inputDoc); outputExtension = ".ytt"; RefreshStyleList(inputDoc); break; } case ".ytt": case ".srv3": { YttDocument inputDoc = new YttDocument(_txtInputFile.Text); outputDoc = new AssDocument(inputDoc); outputExtension = inputExtension == ".ytt" ? ".reverse.ass" : ".ass"; break; } default: { SubtitleDocument inputDoc = SubtitleDocument.Load(_txtInputFile.Text); outputDoc = new SrtDocument(inputDoc); outputExtension = ".srt"; break; } } string outputFilePath = Path.ChangeExtension(_txtInputFile.Text, outputExtension); outputDoc.Save(outputFilePath); _lblConversionSuccess.Text = string.Format(Resources.SuccessfullyCreated0, Path.GetFileName(outputFilePath)); _lblConversionSuccess.Visible = true; await Task.Delay(4000); _lblConversionSuccess.Visible = false; } catch (Exception ex) { MessageBox.Show(ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
public void TestForwardConversion(string assFilePath, List <AssStyleOptions> styleOptions, string expectedYttFilePath) { SubtitleDocument assDoc = new AssDocument(assFilePath, styleOptions); SubtitleDocument yttDoc = new YttDocument(assDoc); try { yttDoc.Save("actual.ytt"); string actual = File.ReadAllText("actual.ytt"); string expected = File.ReadAllText(expectedYttFilePath); Assert.That(actual, Is.EqualTo(expected)); } finally { File.Delete("actual.ytt"); } }
private static IEnumerable <AssLine> CreateFrameLines(AssDocument document, AssLine originalLine, TimeRange timeRange, List <AnimationWithSectionIndex> animations) { int rangeStartFrame = TimeUtil.StartTimeToFrame(timeRange.Start); int rangeEndFrame = TimeUtil.EndTimeToFrame(timeRange.End); const int frameStepSize = 2; int subStepFrames = (rangeEndFrame + 1 - rangeStartFrame) % frameStepSize; int lastIterationFrame = rangeEndFrame + 1 - subStepFrames - frameStepSize; bool needTextReset = animations.Any(a => a.Animation.AffectsText); AssLine frameLine = originalLine; for (int frame = rangeStartFrame; frame <= lastIterationFrame; frame += frameStepSize) { frameLine = (AssLine)frameLine.Clone(); frameLine.Start = TimeUtil.FrameToStartTime(frame); frameLine.End = frame < lastIterationFrame?TimeUtil.FrameToEndTime(frame + frameStepSize - 1) : timeRange.End; frameLine.Position = originalLine.Position ?? document.GetDefaultPosition(originalLine.AnchorPoint); if (needTextReset) { ResetText(frameLine, originalLine); } float interpFrame = frame + (frameStepSize - 1) / 2.0f; foreach (AnimationWithSectionIndex animWithSection in animations) { int animStartFrame = TimeUtil.StartTimeToFrame(animWithSection.Animation.StartTime); int animEndFrame = TimeUtil.EndTimeToFrame(animWithSection.Animation.EndTime); if (interpFrame >= animStartFrame && interpFrame < animEndFrame) { float t = (interpFrame - animStartFrame) / (animEndFrame - animStartFrame); ApplyAnimation(frameLine, animWithSection, t); } else if (interpFrame >= animEndFrame && interpFrame < animEndFrame + frameStepSize) { ApplyAnimation(frameLine, animWithSection, 1); } } yield return(frameLine); } }
private List <Section> GenerateCursor(AssDocument doc, AssSection initialFormatting, string cursor) { AssSection section = (AssSection)initialFormatting.Clone(); section.Text = string.Empty; AssLine line = new AssLine(SubtitleDocument.TimeBase, SubtitleDocument.TimeBase); AssTagContext context = new AssTagContext { Document = doc, Line = line, Section = section }; doc.CreateTagSections(line, cursor, context); return(line.Sections); }
private void PopulateUi(string filePath, SubtitleDocument doc) { _txtInputFile.Text = filePath; AssDocument assDoc = doc as AssDocument; if (assDoc != null) { _grpStyleOptions.Enabled = true; _styles = assDoc.Styles.ToDictionary(s => s.Name); _defaultFontSize = assDoc.DefaultFontSize; foreach (AssStyle style in assDoc.Styles) { if (!_styleOptions.ContainsKey(style.Name)) { _styleOptions.Add(style.Name, new AssStyleOptions(style)); } } _lstStyles.DataSource = assDoc.Styles.Select(s => _styleOptions[s.Name]).ToList(); if (_lstStyles.Items.Count > 0) { _lstStyles.SelectedIndex = 0; } } _chkAutoConvert.Enabled = true; _chkAutoConvert.Checked = false; _subtitleModifyWatcher.EnableRaisingEvents = false; _subtitleModifyWatcher.Path = Path.GetDirectoryName(filePath); _subtitleModifyWatcher.Filter = Path.GetFileName(filePath); // Aegisub doesn't write straight to the .ass file, but instead creates a separate <name>_tmp_<number>.ass // and renames that to the original name. _subtitleRenameWatcher.EnableRaisingEvents = false; _subtitleRenameWatcher.Path = Path.GetDirectoryName(filePath); _subtitleRenameWatcher.Filter = Path.GetFileNameWithoutExtension(filePath) + "_tmp_*" + Path.GetExtension(filePath); _btnConvert.Enabled = true; }
public void TestReverseConversion(string inputYttFilePath) { SubtitleDocument yttDoc = new YttDocument(inputYttFilePath); SubtitleDocument assDoc = new AssDocument(yttDoc); try { assDoc.Save("actual.ass"); assDoc = new AssDocument("actual.ass", AssStyleOptionsList.LoadFromString(Resources.DefaultStyleOptions)); yttDoc = new YttDocument(assDoc); yttDoc.Save("actual.ytt"); string actual = File.ReadAllText("actual.ytt"); string expected = RoundYttTimestamps(File.ReadAllText(inputYttFilePath)); Assert.That(actual, Is.EqualTo(expected)); } finally { File.Delete("actual.ass"); File.Delete("actual.ytt"); } }
private void RefreshStyleList(AssDocument document) { _styles = document.Styles.ToDictionary(s => s.Name); _defaultFontSize = document.DefaultFontSize; foreach (AssStyle style in document.Styles) { if (!_styleOptions.ContainsKey(style.Name)) { _styleOptions.Add(style.Name, new AssStyleOptions(style)); } } int selectedIndex = _lstStyles.SelectedIndex; _lstStyles.DataSource = document.Styles.Select(s => _styleOptions[s.Name]).ToList(); if (_lstStyles.Items.Count > selectedIndex) { _lstStyles.SelectedIndex = selectedIndex; } else if (_lstStyles.Items.Count > 0) { _lstStyles.SelectedIndex = 0; } }