Пример #1
0
        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)
        {
            // adjust offset
            if (!string.IsNullOrEmpty(offset) && (offset.StartsWith("/offset:") || offset.StartsWith("offset:")))
            {
                string[] parts = offset.Split(":".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length == 5)
                {
                    try
                    {
                        TimeSpan 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 + ")");
                    }
                }
            }

            bool targetFormatFound = false;
            string outputFileName;
            foreach (SubtitleFormat sf in formats)
            {
                if (sf.Name.ToLower().Replace(" ", string.Empty) == toFormat.ToLower() || sf.Name.ToLower().Replace(" ", string.Empty) == toFormat.Replace(" ", string.Empty).ToLower())
                {
                    targetFormatFound = true;
                    sf.BatchMode = true;
                    outputFileName = FormatOutputFileNameForBatchConvert(fileName, sf.Extension, outputFolder, overwrite);
                    Console.Write(string.Format("{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);
                    File.WriteAllText(outputFileName, sub.ToText(sf), targetEncoding);
                    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.ToLower().Trim() == className.ToLower().Trim())
                                    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.");
                }
            }
            if (!targetFormatFound)
            {
                var ebu = new Ebu();
                if (ebu.Name.ToLower().Replace(" ", string.Empty) == toFormat.ToLower())
                {
                    targetFormatFound = true;
                    outputFileName = FormatOutputFileNameForBatchConvert(fileName, ebu.Extension, outputFolder, overwrite);
                    Console.Write(string.Format("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName));
                    ebu.Save(outputFileName, sub);
                    Console.WriteLine(" done.");
                }
            }
            if (!targetFormatFound)
            {
                var pac = new Pac();
                if (pac.Name.ToLower().Replace(" ", string.Empty) == toFormat.ToLower() || toFormat.ToLower() == "pac" || toFormat.ToLower() == ".pac")
                {
                    pac.BatchMode = true;
                    if (!string.IsNullOrEmpty(pacCodePage) && Utilities.IsInteger(pacCodePage))
                        pac.CodePage = Convert.ToInt32(pacCodePage);
                    targetFormatFound = true;
                    outputFileName = FormatOutputFileNameForBatchConvert(fileName, pac.Extension, outputFolder, overwrite);
                    Console.Write(string.Format("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName));
                    pac.Save(outputFileName, sub);
                    Console.WriteLine(" done.");
                }
            }
            if (!targetFormatFound)
            {
                var cavena890 = new Cavena890();
                if (cavena890.Name.ToLower().Replace(" ", string.Empty) == toFormat.ToLower())
                {
                    targetFormatFound = true;
                    outputFileName = FormatOutputFileNameForBatchConvert(fileName, cavena890.Extension, outputFolder, overwrite);
                    Console.Write(string.Format("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName));
                    cavena890.Save(outputFileName, sub);
                    Console.WriteLine(" done.");
                }
            }
            if (!targetFormatFound)
            {
                var cheetahCaption = new CheetahCaption();
                if (cheetahCaption.Name.ToLower().Replace(" ", string.Empty) == toFormat.ToLower())
                {
                    targetFormatFound = true;
                    outputFileName = FormatOutputFileNameForBatchConvert(fileName, cheetahCaption.Extension, outputFolder, overwrite);
                    Console.Write(string.Format("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName));
                    cheetahCaption.Save(outputFileName, sub);
                    Console.WriteLine(" done.");
                }
            }
            if (!targetFormatFound)
            {
                var capMakerPlus = new CapMakerPlus();
                if (capMakerPlus.Name.ToLower().Replace(" ", string.Empty) == toFormat.ToLower())
                {
                    targetFormatFound = true;
                    outputFileName = FormatOutputFileNameForBatchConvert(fileName, capMakerPlus.Extension, outputFolder, overwrite);
                    Console.Write(string.Format("{0}: {1} -> {2}...", count, Path.GetFileName(fileName), outputFileName));
                    capMakerPlus.Save(outputFileName, sub);
                    Console.WriteLine(" done.");
                }
            }
            if (!targetFormatFound)
            {
                Console.WriteLine(string.Format("{0}: {1} - target format '{2}' not found!", count, fileName, toFormat));
                errors++;
                return false;
            }
            else
            {
                converted++;
                return true;
            }
        }
        /// <summary>
        /// The get alignment from paragraph.
        /// </summary>
        /// <param name="p">
        /// The p.
        /// </param>
        /// <param name="format">
        /// The format.
        /// </param>
        /// <param name="subtitle">
        /// The subtitle.
        /// </param>
        /// <returns>
        /// The <see cref="ContentAlignment"/>.
        /// </returns>
        private static ContentAlignment GetAlignmentFromParagraph(MakeBitmapParameter p, SubtitleFormat format, Subtitle subtitle)
        {
            var alignment = ContentAlignment.BottomCenter;
            if (p.AlignLeft)
            {
                alignment = ContentAlignment.BottomLeft;
            }
            else if (p.AlignRight)
            {
                alignment = ContentAlignment.BottomRight;
            }

            if (format.HasStyleSupport && !string.IsNullOrEmpty(p.P.Extra))
            {
                if (format.GetType() == typeof(SubStationAlpha))
                {
                    var style = AdvancedSubStationAlpha.GetSsaStyle(p.P.Extra, subtitle.Header);
                    alignment = GetSsaAlignment("{\\a" + style.Alignment + "}", alignment);
                }
                else if (format.GetType() == typeof(AdvancedSubStationAlpha))
                {
                    var style = AdvancedSubStationAlpha.GetSsaStyle(p.P.Extra, subtitle.Header);
                    alignment = GetAssAlignment("{\\an" + style.Alignment + "}", alignment);
                }
            }

            string text = p.P.Text;
            if (format.GetType() == typeof(SubStationAlpha) && text.Length > 5)
            {
                text = p.P.Text.Substring(0, 6);
                alignment = GetSsaAlignment(text, alignment);
            }
            else if (text.Length > 6)
            {
                text = p.P.Text.Substring(0, 6);
                alignment = GetAssAlignment(text, alignment);
            }

            return alignment;
        }
Пример #3
0
        private DialogResult SaveSubtitle(SubtitleFormat format)
        {
            if (string.IsNullOrEmpty(_fileName) || _converted)
                return FileSaveAs(false);

            try
            {
                string allText = _subtitle.ToText(format);

                // Seungki begin
                if (_splitDualSami && _subtitleAlternate != null)
                {
                    var s = new Subtitle(_subtitle);
                    foreach (Paragraph p in _subtitleAlternate.Paragraphs)
                        s.Paragraphs.Add(p);
                    allText = s.ToText(format);
                }
                // Seungki end

                var currentEncoding = GetCurrentEncoding();
                if (currentEncoding == Encoding.Default && (allText.Contains("♪") || allText.Contains("♫") || allText.Contains("♥") || allText.Contains("—") || allText.Contains("…"))) // ANSI & music/unicode symbols
                {
                    if (MessageBox.Show(string.Format(_language.UnicodeMusicSymbolsAnsiWarning), Title, MessageBoxButtons.YesNo) == DialogResult.No)
                        return DialogResult.No;
                }


                bool containsNegativeTime = false;
                foreach (var p in _subtitle.Paragraphs)
                {
                    if (p.StartTime.TotalMilliseconds < 0 || p.EndTime.TotalMilliseconds < 0)
                    {
                        containsNegativeTime = true;
                        break;
                    }
                }
                if (containsNegativeTime && !string.IsNullOrEmpty(_language.NegativeTimeWarning))
                {
                    if (MessageBox.Show(_language.NegativeTimeWarning, Title, MessageBoxButtons.YesNo) == DialogResult.No)
                        return DialogResult.No;
                }

                if (File.Exists(_fileName))
                {
                    DateTime fileOnDisk = File.GetLastWriteTime(_fileName);
                    if (_fileDateTime != fileOnDisk && _fileDateTime != new DateTime())
                    {
                        if (MessageBox.Show(string.Format(_language.OverwriteModifiedFile,
                                                          _fileName, fileOnDisk.ToShortDateString(), fileOnDisk.ToString("HH:mm:ss"),
                                                          Environment.NewLine, _fileDateTime.ToShortDateString(), _fileDateTime.ToString("HH:mm:ss")),
                                             Title + " - " + _language.FileOnDiskModified, MessageBoxButtons.YesNo) == DialogResult.No)
                            return DialogResult.No;
                    }
                    File.Delete(_fileName);
                }

                if (Control.ModifierKeys == (Keys.Control | Keys.Shift))
                    allText = allText.Replace("\r\n", "\n");

                if (format.GetType() == typeof(ItunesTimedText))
                {
                    Encoding outputEnc = new UTF8Encoding(false); // create encoding with no BOM
                    TextWriter file = new StreamWriter(_fileName, false, outputEnc); // open file with encoding
                    file.Write(allText);
                    file.Close(); // save and close it
                }
                else if (currentEncoding == Encoding.UTF8 && (format.GetType() == typeof(TmpegEncAW5) || format.GetType() == typeof(TmpegEncXml)))
                {
                    Encoding outputEnc = new UTF8Encoding(false); // create encoding with no BOM
                    TextWriter file = new StreamWriter(_fileName, false, outputEnc); // open file with encoding
                    file.Write(allText);
                    file.Close(); // save and close it
                }
                else
                {
                    if (allText.Trim().Length == 0)
                    {
                        MessageBox.Show(string.Format(_language.UnableToSaveSubtitleX, _fileName) + Environment.NewLine + Environment.NewLine + "Subtitle seems to be empty - try to re-save if you're working on a valid subtitle!");
                        return DialogResult.Cancel;
                    }
                    File.WriteAllText(_fileName, allText, currentEncoding);
                }

                _fileDateTime = File.GetLastWriteTime(_fileName);
                ShowStatus(string.Format(_language.SavedSubtitleX, _fileName));
                _changeSubtitleToString = SerializeSubtitle(_subtitle);
                return DialogResult.OK;
            }
            catch (Exception exception)
            {
                MessageBox.Show(string.Format(_language.UnableToSaveSubtitleX, _fileName));
                System.Diagnostics.Debug.Write(exception.Message);
                return DialogResult.Cancel;
            }
        }
Пример #4
0
        private DialogResult SaveSubtitle(SubtitleFormat format)
        {
            if (string.IsNullOrEmpty(this._fileName) || this._converted)
            {
                return this.FileSaveAs(false);
            }

            try
            {
                if (format != null && !format.IsTextBased)
                {
                    if (format.GetType() == typeof(Ebu))
                    {
                        Ebu.Save(this._fileName, this._subtitle);
                    }

                    return DialogResult.OK;
                }

                string allText = this._subtitle.ToText(format);

                // Seungki begin
                if (this._splitDualSami && this._subtitleAlternate != null)
                {
                    var s = new Subtitle(this._subtitle);
                    foreach (var p in this._subtitleAlternate.Paragraphs)
                    {
                        s.Paragraphs.Add(p);
                    }

                    allText = s.ToText(format);
                }

                // Seungki end
                var currentEncoding = this.GetCurrentEncoding();
                bool isUnicode = currentEncoding == Encoding.Unicode || currentEncoding == Encoding.UTF32 || currentEncoding == Encoding.UTF7 || currentEncoding == Encoding.UTF8;
                if (!isUnicode && allText.Contains(new[] { '♪', '♫', '♥', '—', '―', '…' }))
                {
                    // ANSI & music/unicode symbols
                    if (MessageBox.Show(string.Format(this._language.UnicodeMusicSymbolsAnsiWarning), this.Title, MessageBoxButtons.YesNo) == DialogResult.No)
                    {
                        return DialogResult.No;
                    }
                }

                if (!isUnicode)
                {
                    allText = this.NormalizeUnicode(allText);
                }

                bool containsNegativeTime = false;
                foreach (var p in this._subtitle.Paragraphs)
                {
                    if (p.StartTime.TotalMilliseconds < 0 || p.EndTime.TotalMilliseconds < 0)
                    {
                        containsNegativeTime = true;
                        break;
                    }
                }

                if (containsNegativeTime)
                {
                    if (MessageBox.Show(this._language.NegativeTimeWarning, this.Title, MessageBoxButtons.YesNo) == DialogResult.No)
                    {
                        return DialogResult.No;
                    }
                }

                if (File.Exists(this._fileName))
                {
                    var fileInfo = new FileInfo(this._fileName);
                    var fileOnDisk = fileInfo.LastWriteTime;
                    if (this._fileDateTime != fileOnDisk && this._fileDateTime != new DateTime())
                    {
                        if (MessageBox.Show(string.Format(this._language.OverwriteModifiedFile, this._fileName, fileOnDisk.ToShortDateString(), fileOnDisk.ToString("HH:mm:ss"), Environment.NewLine, this._fileDateTime.ToShortDateString(), this._fileDateTime.ToString("HH:mm:ss")), this.Title + " - " + this._language.FileOnDiskModified, MessageBoxButtons.YesNo) == DialogResult.No)
                        {
                            return DialogResult.No;
                        }
                    }

                    if (fileInfo.IsReadOnly)
                    {
                        MessageBox.Show(string.Format(this._language.FileXIsReadOnly, this._fileName));
                        return DialogResult.No;
                    }
                }

                if (format.GetType() == typeof(WebVTT) || format.GetType() == typeof(WebVTTFileWithLineNumber))
                {
                    this.SetEncoding(Encoding.UTF8);
                    currentEncoding = Encoding.UTF8;
                }

                if (ModifierKeys == (Keys.Control | Keys.Shift))
                {
                    allText = allText.Replace("\r\n", "\n");
                }

                if (format.GetType() == typeof(ItunesTimedText) || format.GetType() == typeof(ScenaristClosedCaptions) || format.GetType() == typeof(ScenaristClosedCaptionsDropFrame))
                {
                    var outputEnc = new UTF8Encoding(false); // create encoding with no BOM
                    using (var file = new StreamWriter(this._fileName, false, outputEnc))
                    {
                        // open file with encoding
                        file.Write(allText);
                    }
                }
                else if (currentEncoding == Encoding.UTF8 && (format.GetType() == typeof(TmpegEncAW5) || format.GetType() == typeof(TmpegEncXml)))
                {
                    var outputEnc = new UTF8Encoding(false); // create encoding with no BOM
                    using (var file = new StreamWriter(this._fileName, false, outputEnc))
                    {
                        // open file with encoding
                        file.Write(allText);
                    }
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(allText))
                    {
                        MessageBox.Show(string.Format(this._language.UnableToSaveSubtitleX, this._fileName), string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Stop);
                        return DialogResult.Cancel;
                    }

                    using (var fs = File.Open(this._fileName, FileMode.Create, FileAccess.Write, FileShare.Read))
                    using (var sw = new StreamWriter(fs, currentEncoding))
                    {
                        sw.Write(allText);
                    }
                }

                this._fileDateTime = File.GetLastWriteTime(this._fileName);
                this.ShowStatus(string.Format(this._language.SavedSubtitleX, this._fileName));
                this._changeSubtitleToString = SerializeSubtitle(this._subtitle);
                return DialogResult.OK;
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
                return DialogResult.Cancel;
            }
        }
Пример #5
0
        private DialogResult SaveSubtitle(SubtitleFormat format)
        {
            if (string.IsNullOrEmpty(_fileName) || _converted)
                return FileSaveAs(false);

            try
            {
                if (format != null && !format.IsTextBased)
                {
                    if (format.GetType() == typeof(Ebu))
                    {
                        Ebu.Save(_fileName, _subtitle);
                    }
                    return DialogResult.OK;
                }

                string allText = _subtitle.ToText(format);

                // Seungki begin
                if (_splitDualSami && _subtitleAlternate != null)
                {
                    var s = new Subtitle(_subtitle);
                    foreach (Paragraph p in _subtitleAlternate.Paragraphs)
                        s.Paragraphs.Add(p);
                    allText = s.ToText(format);
                }
                // Seungki end

                var currentEncoding = GetCurrentEncoding();
                bool isUnicode = currentEncoding == Encoding.Unicode || currentEncoding == Encoding.UTF32 || currentEncoding == Encoding.UTF7 || currentEncoding == Encoding.UTF8;
                if (!isUnicode && (allText.Contains('♪') || allText.Contains('♫') || allText.Contains('♥') || allText.Contains('—') || allText.Contains('―') || allText.Contains('…'))) // ANSI & music/unicode symbols
                {
                    if (MessageBox.Show(string.Format(_language.UnicodeMusicSymbolsAnsiWarning), Title, MessageBoxButtons.YesNo) == DialogResult.No)
                        return DialogResult.No;
                }

                if (!isUnicode)
                {
                    allText = allText.Replace("—", "-"); // mdash, code 8212
                    allText = allText.Replace("―", "-"); // mdash, code 8213
                    allText = allText.Replace("…", "...");
                    allText = allText.Replace("♪", "#");
                    allText = allText.Replace("♫", "#");
                }

                bool containsNegativeTime = false;
                foreach (var p in _subtitle.Paragraphs)
                {
                    if (p.StartTime.TotalMilliseconds < 0 || p.EndTime.TotalMilliseconds < 0)
                    {
                        containsNegativeTime = true;
                        break;
                    }
                }
                if (containsNegativeTime && !string.IsNullOrEmpty(_language.NegativeTimeWarning))
                {
                    if (MessageBox.Show(_language.NegativeTimeWarning, Title, MessageBoxButtons.YesNo) == DialogResult.No)
                        return DialogResult.No;
                }

                if (File.Exists(_fileName))
                {
                    FileInfo fileInfo = new FileInfo(_fileName);
                    DateTime fileOnDisk = fileInfo.LastWriteTime;
                    if (_fileDateTime != fileOnDisk && _fileDateTime != new DateTime())
                    {
                        if (MessageBox.Show(string.Format(_language.OverwriteModifiedFile,
                                                          _fileName, fileOnDisk.ToShortDateString(), fileOnDisk.ToString("HH:mm:ss"),
                                                          Environment.NewLine, _fileDateTime.ToShortDateString(), _fileDateTime.ToString("HH:mm:ss")),
                                             Title + " - " + _language.FileOnDiskModified, MessageBoxButtons.YesNo) == DialogResult.No)
                            return DialogResult.No;
                    }
                    if (fileInfo.IsReadOnly)
                    {
                        if (string.IsNullOrEmpty(_language.FileXIsReadOnly))
                            MessageBox.Show("Cannot save " + _fileName + Environment.NewLine + "File is read-only!");
                        else
                            MessageBox.Show(string.Format(_language.FileXIsReadOnly, _fileName));
                        return DialogResult.No;
                    }
                }

                if (Control.ModifierKeys == (Keys.Control | Keys.Shift))
                    allText = allText.Replace("\r\n", "\n");

                if (format.GetType() == typeof(ItunesTimedText) || format.GetType() == typeof(ScenaristClosedCaptions) || format.GetType() == typeof(ScenaristClosedCaptionsDropFrame))
                {
                    Encoding outputEnc = new UTF8Encoding(false); // create encoding with no BOM
                    TextWriter file = new StreamWriter(_fileName, false, outputEnc); // open file with encoding
                    file.Write(allText);
                    file.Close(); // save and close it
                }
                else if (currentEncoding == Encoding.UTF8 && (format.GetType() == typeof(TmpegEncAW5) || format.GetType() == typeof(TmpegEncXml)))
                {
                    Encoding outputEnc = new UTF8Encoding(false); // create encoding with no BOM
                    TextWriter file = new StreamWriter(_fileName, false, outputEnc); // open file with encoding
                    file.Write(allText);
                    file.Close(); // save and close it
                }
                else
                {
                    if (allText.Trim().Length == 0)
                    {
                        MessageBox.Show(string.Format(_language.UnableToSaveSubtitleX, _fileName), String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Stop);
                        return DialogResult.Cancel;
                    }

                    FileStream fs = null;
                    try
                    {
                        fs = File.Open(_fileName, FileMode.Create, FileAccess.Write, FileShare.Read);
                        using (StreamWriter sw = new StreamWriter(fs, currentEncoding))
                        {
                            fs = null;
                            sw.Write(allText);
                        }
                    }
                    finally
                    {
                        if (fs != null)
                            fs.Dispose();
                    }
                }

                _fileDateTime = File.GetLastWriteTime(_fileName);
                ShowStatus(string.Format(_language.SavedSubtitleX, _fileName));
                _changeSubtitleToString = SerializeSubtitle(_subtitle);
                return DialogResult.OK;
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
                return DialogResult.Cancel;
            }
        }
 private bool CheckSkipFilter(string fileName, SubtitleFormat format, Subtitle sub)
 {
     bool skip = false;
     if (comboBoxFilter.SelectedIndex == 1)
     {
         if (format != null && format.GetType() == typeof(SubRip) && FileUtil.HasUtf8Bom(fileName))
             skip = true;
     }
     else if (comboBoxFilter.SelectedIndex == 2)
     {
         foreach (Paragraph p in sub.Paragraphs)
         {
             if (p.Text != null && Utilities.GetNumberOfLines(p.Text) > 2)
             {
                 skip = true;
                 break;
             }
         }
     }
     else if (comboBoxFilter.SelectedIndex == 3 && !string.IsNullOrWhiteSpace(textBoxFilter.Text))
     {
         skip = true;
         foreach (Paragraph p in sub.Paragraphs)
         {
             if (p.Text != null && p.Text.Contains(textBoxFilter.Text, StringComparison.Ordinal))
             {
                 skip = false;
                 break;
             }
         }
     }
     return skip;
 }
        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)
        {
            double oldFrameRate = Configuration.Settings.General.CurrentFrameRate;
            try
            {
                // adjust offset
                if (!string.IsNullOrEmpty(offset) && (offset.StartsWith("/offset:") || offset.StartsWith("offset:")))
                {
                    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;
                }

                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 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)
                {
                    Console.WriteLine("{0}: {1} - target format '{2}' not found!", count, fileName, toFormat);
                    errors++;
                    return false;
                }
                converted++;
                return true;
            }
            finally
            {
                Configuration.Settings.General.CurrentFrameRate = oldFrameRate;
            }
        }