Пример #1
0
        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);
            }
        }
Пример #2
0
        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}");
            }
        }
Пример #3
0
        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;
        }
Пример #4
0
        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;
        }
Пример #5
0
        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;
        }
Пример #6
0
 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);
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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");
            }
        }
Пример #11
0
        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);
        }
Пример #13
0
        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;
        }
Пример #14
0
        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");
            }
        }
Пример #15
0
        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;
            }
        }