Example #1
0
        private List <BluRaySupParser.PcsData> LoadMkv(string filename, int trackNumber)
        {
            List <BluRaySupParser.PcsData> result = null;

            using (var matroska = new MatroskaFile(filename))
            {
                if (matroska.IsValid)
                {
                    var pgsTracks = GetPgsSubtitleTracks(matroska);
                    var track     = (from t in pgsTracks where t.TrackNumber == trackNumber select t).FirstOrDefault();

                    if (track != null)
                    {
                        result = LoadSubtitles(matroska, track);
                    }
                    else
                    {
                        _logger.LogInformation($"Track {trackNumber} is not a PGS track.");
                        ShowPgsTracks(filename, pgsTracks);
                    }
                }
                else
                {
                    _logger.LogInformation($"Invalid matroska file '{filename}'");
                }
            }

            return(result);
        }
Example #2
0
        public MatroskaProvider(MatroskaFile mfi)
        {
            infos = new InfoCollection();
            MFI   = mfi;

            Add(EntryKey.Size, MFI.SectionSize.ToString(), "byte");
            Add(EntryKey.Date, MFI.Segment.SegmentInfo.ProductionDate.HasValue ? MFI.Segment.SegmentInfo.ProductionDate.Value.ToString("yyyy.MM.dd HH.mm.ss.ffff") : null, null);
            Add(EntryKey.Duration, MFI.Segment.SegmentInfo.Duration.HasValue ? (MFI.Segment.SegmentInfo.Duration.Value * (MFI.Segment.SegmentInfo.TimecodeScale / 1000000000d)).ToString("0.000", CultureInfo.InvariantCulture) : null, "s");
            Add(EntryKey.WritingApp, MFI.Segment.SegmentInfo.WritingApp, null);
            Add(EntryKey.MuxingApp, MFI.Segment.SegmentInfo.MuxingApp, null);


            int[] indeces = new int[3];
            bool  hasVideo, hasAudio, hasSubtitle, is3d;

            hasVideo = hasAudio = hasSubtitle = is3d = false;
            foreach (var track in MFI.Segment.Tracks.Items)
            {
                if (!track.TrackType.HasValue)
                {
                    throw new Exception("TrackType missing");
                }
                switch (track.TrackType.Value)
                {
                case TrackEntrySection.Types.Video:
                    AddStreamInfo(track, StreamType.Video, indeces[0]++);
                    hasVideo = true;
                    is3d     = track.Video.StereoMode != VideoSection.DisplayMode.Mono;
                    is3d    |= track.TrackOperation != null ? track.TrackOperation.Is3d : false;
                    break;

                case TrackEntrySection.Types.Audio: AddStreamInfo(track, StreamType.Audio, indeces[1]++); hasAudio = true; break;

                case TrackEntrySection.Types.Subtitle: AddStreamInfo(track, StreamType.Text, indeces[2]++); hasSubtitle = true; break;

                default: break;
                }
            }

            if (MFI.EbmlHeader.DocType.Equals("webm"))
            {
                Add(EntryKey.Extension, "webm", null);
            }
            else if (is3d)
            {
                Add(EntryKey.Extension, "mk3d", null);
            }
            else if (hasVideo)
            {
                Add(EntryKey.Extension, "mkv", null);
            }
            else if (hasAudio)
            {
                Add(EntryKey.Extension, "mka", null);
            }
            else if (hasSubtitle)
            {
                Add(EntryKey.Extension, "mks", null);
            }
        }
Example #3
0
        public void MatroskaTestValid()
        {
            string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_MKV_SRT.mkv");

            using (var parser = new MatroskaFile(fileName))
            {
                Assert.IsTrue(parser.IsValid);
            }
        }
Example #4
0
        public void MatroskaTestInvalid()
        {
            string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_TS_with_graphics.ts");

            using (var parser = new MatroskaFile(fileName))
            {
                Assert.IsFalse(parser.IsValid);
            }
        }
Example #5
0
        public void MatroskaTestIsSrt()
        {
            string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_MKV_SRT.mkv");

            using (var parser = new MatroskaFile(fileName))
            {
                var tracks = parser.GetTracks(true);
                Assert.IsTrue(tracks[0].CodecId == "S_TEXT/UTF8");
            }
        }
Example #6
0
        public void MatroskaTestDelayed500Ms()
        {
            string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_MKV_delayed.mkv");

            using (var parser = new MatroskaFile(fileName))
            {
                var delay = parser.GetTrackStartTime(parser.GetTracks()[0].TrackNumber);
                Assert.IsTrue(delay == 500);
            }
        }
Example #7
0
        public void MatroskaTestVobSubPgs()
        {
            string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_MKV_VobSub_PGS.mkv");

            using (var parser = new MatroskaFile(fileName))
            {
                var tracks = parser.GetTracks(true);
                Assert.IsTrue(tracks[0].CodecId == "S_VOBSUB");
                Assert.IsTrue(tracks[1].CodecId == "S_HDMV/PGS");
            }
        }
Example #8
0
        public List <BluRaySupParser.PcsData> LoadSubtitles(MatroskaFile matroska, MatroskaTrackInfo track)
        {
            List <BluRaySupParser.PcsData> result = null;

            if (matroska.IsValid)
            {
                result = LoadBluRaySubFromMatroska(track, matroska);
            }

            return(result);
        }
        public static List <SubtitleEvent> ReadMatroskaVobSub(string inputFile, int tracknumber)
        {
            var matroska             = new MatroskaFile(inputFile);
            var matroskaSubtitleInfo = matroska.GetTracks()[tracknumber];

            var subtitle = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, (p, t) => Console.WriteLine("Progress: {0} out of {1}", p, t));


            var mergedVobSubPacks = new List <VobSubMergedPack>();

            if (matroskaSubtitleInfo.ContentEncodingType == 1)
            {
                throw new ArgumentException("Track number is invalid.");
            }

            var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, null);
            var idx = new Idx(matroskaSubtitleInfo.GetCodecPrivate().SplitToLines());

            foreach (var p in sub)
            {
                mergedVobSubPacks.Add(new VobSubMergedPack(p.GetData(matroskaSubtitleInfo), TimeSpan.FromMilliseconds(p.Start), 32, null));
                if (mergedVobSubPacks.Count > 0)
                {
                    mergedVobSubPacks[mergedVobSubPacks.Count - 1].EndTime = TimeSpan.FromMilliseconds(p.End);
                }

                // fix overlapping (some versions of Handbrake makes overlapping time codes - thx Hawke)
                if (mergedVobSubPacks.Count > 1 && mergedVobSubPacks[mergedVobSubPacks.Count - 2].EndTime > mergedVobSubPacks[mergedVobSubPacks.Count - 1].StartTime)
                {
                    mergedVobSubPacks[mergedVobSubPacks.Count - 2].EndTime = TimeSpan.FromMilliseconds(mergedVobSubPacks[mergedVobSubPacks.Count - 1].StartTime.TotalMilliseconds - 1);
                }
            }


            List <SubtitleEvent> events = new List <SubtitleEvent>();
            StringBuilder        logger = new StringBuilder();
            var MergedVobSubPacks       = mergedVobSubPacks;
            int i = 0;

            foreach (var line in MergedVobSubPacks)
            {
                var bitmap = line.SubPicture.GetBitmap(idx.Palette, Color.Black, Color.White, Color.Gray, Color.White, false);

                var image_data = ImageUtil.ConvertToPngBytes(bitmap);
                events.Add(new SubtitleEvent()
                {
                    StartTime = line.StartTime, EndTime = line.EndTime, MimeType = "image/png", Image = image_data, Origin = line.SubPicture.ImageDisplayArea.Location
                });
                i++;
            }
            return(events);
        }
Example #10
0
        public void MatroskaTestSrtContent()
        {
            string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_MKV_SRT.mkv");

            using (var parser = new MatroskaFile(fileName))
            {
                var tracks    = parser.GetTracks(true);
                var subtitles = parser.GetSubtitle(Convert.ToInt32(tracks[0].TrackNumber), null);
                Assert.IsTrue(subtitles.Count == 2);
                Assert.IsTrue(subtitles[0].Text == "Line 1");
                Assert.IsTrue(subtitles[1].Text == "Line 2");
            }
        }
Example #11
0
        public void MatroskaTestVobSubPgsContent()
        {
            string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_MKV_VobSub_PGS.mkv");

            using (var parser = new MatroskaFile(fileName))
            {
                var tracks    = parser.GetTracks(true);
                var subtitles = parser.GetSubtitle(Convert.ToInt32(tracks[0].TrackNumber), null);
                Assert.IsTrue(subtitles.Count == 2);
                // TODO: Check bitmaps

                //subtitles = parser.GetSubtitle(Convert.ToInt32(tracks[1].TrackNumber), null);
                //Assert.IsTrue(subtitles.Count == 2);
                //check bitmaps
            }
        }
Example #12
0
        public static List <MatroskaTrackInfo> GetPgsSubtitleTracks(MatroskaFile matroska)
        {
            var result = new List <MatroskaTrackInfo>();

            if (matroska.IsValid)
            {
                var tracks   = matroska.GetTracks(true);
                var pgsTrack = (
                    from t in tracks
                    orderby t.TrackNumber
                    where string.Equals(_pgsTrackCodecId, t.CodecId)
                    select t);

                result.AddRange(pgsTrack);
            }

            return(result);
        }
Example #13
0
        public List <BluRaySupParser.PcsData> LoadSubtitles(string mkvFileName, int trackNumber)
        {
            List <BluRaySupParser.PcsData> result = null;

            using (var matroska = new MatroskaFile(mkvFileName))
            {
                if (matroska.IsValid)
                {
                    var tracks = matroska.GetTracks(true);
                    var track  = (from t in tracks where t.TrackNumber == trackNumber && string.Equals(_pgsTrackCodecId, t.CodecId) select t).FirstOrDefault();
                    if (track != null)
                    {
                        result = LoadBluRaySubFromMatroska(track, matroska);
                    }
                }
            }

            return(result);
        }
Example #14
0
        public MatroskaProvider(MatroskaFile mfi)
        {
            infos = new InfoCollection();
            MFI = mfi;

            Add(EntryKey.Size, MFI.SectionSize.ToString(), "byte");
            Add(EntryKey.Date, MFI.Segment.SegmentInfo.ProductionDate.HasValue ? MFI.Segment.SegmentInfo.ProductionDate.Value.ToString("yyyy.MM.dd HH.mm.ss.ffff") : null, null);
            Add(EntryKey.Duration, MFI.Segment.SegmentInfo.Duration.HasValue ? (MFI.Segment.SegmentInfo.Duration.Value * (MFI.Segment.SegmentInfo.TimecodeScale / 1000000000d)).ToString("0.000", CultureInfo.InvariantCulture) : null, "s");
            Add(EntryKey.WritingApp, MFI.Segment.SegmentInfo.WritingApp, null);
            Add(EntryKey.MuxingApp, MFI.Segment.SegmentInfo.MuxingApp, null);

            int[] indeces = new int[3];
            bool hasVideo, hasAudio, hasSubtitle, is3d;
            hasVideo = hasAudio = hasSubtitle = is3d = false;
            foreach(var track in MFI.Segment.Tracks.Items) {
                if(!track.TrackType.HasValue) throw new Exception("TrackType missing");
                switch(track.TrackType.Value) {
                    case TrackEntrySection.Types.Video:
                        AddStreamInfo(track, StreamType.Video, indeces[0]++);
                        hasVideo = true;
                        is3d = track.Video.StereoMode != VideoSection.DisplayMode.Mono;
                        is3d |= track.TrackOperation != null ? track.TrackOperation.Is3d : false;
                        break;
                    case TrackEntrySection.Types.Audio: AddStreamInfo(track, StreamType.Audio, indeces[1]++); hasAudio = true; break;
                    case TrackEntrySection.Types.Subtitle: AddStreamInfo(track, StreamType.Text, indeces[2]++); hasSubtitle = true; break;
                    default: break;
                }
            }

            if(MFI.EbmlHeader.DocType.Equals("webm")) {
                Add(EntryKey.Extension, "webm", null);
            } else if(is3d) {
                Add(EntryKey.Extension, "mk3d", null);
            } else if(hasVideo) {
                Add(EntryKey.Extension, "mkv", null);
            } else if(hasAudio) {
                Add(EntryKey.Extension, "mka", null);
            } else if(hasSubtitle) {
                Add(EntryKey.Extension, "mks", null);
            }
        }
Example #15
0
        public static VideoInfo TryReadVideoInfoViaMatroskaHeader(string fileName)
        {
            var info = new VideoInfo {
                Success = false
            };

            using (var matroska = new MatroskaFile(fileName))
            {
                if (matroska.IsValid)
                {
                    matroska.GetInfo(out var frameRate, out var width, out var height, out var milliseconds, out var videoCodec);

                    info.Width             = width;
                    info.Height            = height;
                    info.FramesPerSecond   = frameRate;
                    info.Success           = true;
                    info.TotalMilliseconds = milliseconds;
                    info.TotalSeconds      = milliseconds / TimeCode.BaseUnit;
                    info.TotalFrames       = info.TotalSeconds * frameRate;
                    info.VideoCodec        = videoCodec;
                }
            }
            return(info);
        }
Example #16
0
        internal static List <TrackOutputOption> GetTracksByLanguage(string filename, string trackLanguage, string output)
        {
            var result = new List <TrackOutputOption>();

            using (var matroska = new MatroskaFile(filename))
            {
                if (matroska.IsValid)
                {
                    var pgsTracks = GetPgsSubtitleTracks(matroska);
                    var tracks    = (from t in pgsTracks where string.Equals(trackLanguage, t.Language, StringComparison.OrdinalIgnoreCase) select t);

                    foreach (var track in tracks)
                    {
                        var defaultOutputFilename = GetDefaultOutputFilename(result, filename, track, output);
                        result.Add(new TrackOutputOption()
                        {
                            Track = track.TrackNumber, Output = defaultOutputFilename
                        });
                    }
                }
            }

            return(result);
        }
Example #17
0
 public void Close()
 {
     m_File = null;
       m_DataSource = null;
 }
Example #18
0
        public static bool IsMatroskaFile(string fileName)
        {
            var validator = new MatroskaFile(fileName);

            return(validator.IsValid);
        }
Example #19
0
        private void buttonRipWave_Click(object sender, EventArgs e)
        {
            if (listViewInputFiles.Items.Count == 0)
            {
                MessageBox.Show(Configuration.Settings.Language.BatchConvert.NothingToConvert);
                return;
            }
            _converting                = true;
            buttonRipWave.Enabled      = false;
            progressBar1.Style         = ProgressBarStyle.Blocks;
            progressBar1.Maximum       = listViewInputFiles.Items.Count;
            progressBar1.Value         = 0;
            progressBar1.Visible       = progressBar1.Maximum > 2;
            buttonInputBrowse.Enabled  = false;
            buttonSearchFolder.Enabled = false;
            _abort = false;
            listViewInputFiles.BeginUpdate();
            foreach (ListViewItem item in listViewInputFiles.Items)
            {
                item.SubItems[3].Text = "-";
            }
            listViewInputFiles.EndUpdate();
            Refresh();
            int index = 0;

            while (index < listViewInputFiles.Items.Count && _abort == false)
            {
                var item = listViewInputFiles.Items[index];
                item.SubItems[3].Text = Configuration.Settings.Language.AddWaveformBatch.ExtractingAudio;
                string fileName = item.Text;
                try
                {
                    string  targetFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".wav");
                    Process process;
                    try
                    {
                        string encoderName;
                        process        = AddWaveform.GetCommandLineProcess(fileName, -1, targetFile, Configuration.Settings.General.VlcWaveTranscodeSettings, out encoderName);
                        labelInfo.Text = encoderName;
                    }
                    catch (DllNotFoundException)
                    {
                        if (MessageBox.Show(Configuration.Settings.Language.AddWaveform.VlcMediaPlayerNotFound + Environment.NewLine +
                                            Environment.NewLine +
                                            Configuration.Settings.Language.AddWaveform.GoToVlcMediaPlayerHomePage,
                                            Configuration.Settings.Language.AddWaveform.VlcMediaPlayerNotFoundTitle, MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            Process.Start("http://www.videolan.org/");
                        }
                        buttonRipWave.Enabled = true;
                        return;
                    }

                    process.Start();
                    while (!process.HasExited && !_abort)
                    {
                        Application.DoEvents();
                    }


                    // check for delay in matroska files
                    var audioTrackNames      = new List <string>();
                    var mkvAudioTrackNumbers = new Dictionary <int, int>();
                    if (fileName.ToLower().EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                    {
                        MatroskaFile matroska = null;
                        try
                        {
                            matroska = new MatroskaFile(fileName);

                            if (matroska.IsValid)
                            {
                                foreach (var track in matroska.GetTracks())
                                {
                                    if (track.IsAudio)
                                    {
                                        if (track.CodecId != null && track.Language != null)
                                        {
                                            audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty));
                                        }
                                        else
                                        {
                                            audioTrackNames.Add("#" + track.TrackNumber);
                                        }
                                        mkvAudioTrackNumbers.Add(mkvAudioTrackNumbers.Count, track.TrackNumber);
                                    }
                                }
                                if (mkvAudioTrackNumbers.Count > 0)
                                {
                                    _delayInMilliseconds = (int)matroska.GetTrackStartTime(mkvAudioTrackNumbers[0]);
                                }
                            }
                        }
                        catch
                        {
                            _delayInMilliseconds = 0;
                        }
                        finally
                        {
                            if (matroska != null)
                            {
                                matroska.Dispose();
                            }
                        }
                    }

                    item.SubItems[3].Text = Configuration.Settings.Language.AddWaveformBatch.Calculating;
                    MakeWaveformAndSpectrogram(fileName, targetFile, _delayInMilliseconds);

                    // cleanup
                    try
                    {
                        File.Delete(targetFile);
                    }
                    catch
                    {
                        // don't show error about unsuccessful delete
                    }

                    IncrementAndShowProgress();

                    item.SubItems[3].Text = Configuration.Settings.Language.AddWaveformBatch.Done;
                }
                catch
                {
                    IncrementAndShowProgress();
                    item.SubItems[3].Text = "ERROR";
                }
                index++;
            }
            _converting          = false;
            labelProgress.Text   = string.Empty;
            labelInfo.Text       = string.Empty;
            progressBar1.Visible = false;
            TaskbarList.SetProgressState(Handle, TaskbarButtonProgressFlags.NoProgress);
            buttonRipWave.Enabled      = true;
            buttonInputBrowse.Enabled  = true;
            buttonSearchFolder.Enabled = true;
        }
Example #20
0
 public void Open(string filename)
 {
     m_DataSource = new FileDataSource(filename, "r");
       m_File = new MatroskaFile(m_DataSource);
       m_File.readFile();
 }
Example #21
0
        private static List <BluRaySupParser.PcsData> LoadBluRaySubFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska)
        {
            var sub           = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, null);
            var subtitles     = new List <BluRaySupParser.PcsData>();
            var log           = new StringBuilder();
            var clusterStream = new MemoryStream();
            var lastPalettes  = new Dictionary <int, List <PaletteInfo> >();

            foreach (var p in sub)
            {
                var buffer = p.GetData(matroskaSubtitleInfo);
                if (buffer != null && buffer.Length > 2)
                {
                    clusterStream.Write(buffer, 0, buffer.Length);
                    if (ContainsBluRayStartSegment(buffer))
                    {
                        if (subtitles.Count > 0 && subtitles[subtitles.Count - 1].StartTime == subtitles[subtitles.Count - 1].EndTime)
                        {
                            subtitles[subtitles.Count - 1].EndTime = (long)((p.Start - 1) * 90.0);
                        }
                        clusterStream.Position = 0;
                        var list = BluRaySupParser.ParseBluRaySup(clusterStream, log, true, lastPalettes);
                        foreach (var sup in list)
                        {
                            sup.StartTime = (long)((p.Start - 1) * 90.0);
                            sup.EndTime   = (long)((p.End - 1) * 90.0);
                            subtitles.Add(sup);

                            // fix overlapping
                            if (subtitles.Count > 1 && sub[subtitles.Count - 2].End > sub[subtitles.Count - 1].Start)
                            {
                                subtitles[subtitles.Count - 2].EndTime = subtitles[subtitles.Count - 1].StartTime - 1;
                            }
                        }
                        clusterStream = new MemoryStream();
                    }
                }
                else if (subtitles.Count > 0)
                {
                    var lastSub = subtitles[subtitles.Count - 1];
                    if (lastSub.StartTime == lastSub.EndTime)
                    {
                        lastSub.EndTime = (long)((p.Start - 1) * 90.0);
                        if (lastSub.EndTime - lastSub.StartTime > 1000000)
                        {
                            lastSub.EndTime = lastSub.StartTime;
                        }
                    }
                }
            }

            return(subtitles);
        }
Example #22
0
        private void AddWaveform_Shown(object sender, EventArgs e)
        {
            Refresh();
            _numberOfAudioTracks = 0;
            var audioTrackNames      = new List <string>();
            var mkvAudioTrackNumbers = new Dictionary <int, int>();

            if (labelVideoFileName.Text.Length > 1 && File.Exists(labelVideoFileName.Text))
            {
                if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                { // Choose for number of audio tracks in matroska files
                    MatroskaFile matroska = null;
                    try
                    {
                        matroska = new MatroskaFile(labelVideoFileName.Text);
                        if (matroska.IsValid)
                        {
                            foreach (var track in matroska.GetTracks())
                            {
                                if (track.IsAudio)
                                {
                                    _numberOfAudioTracks++;
                                    if (track.CodecId != null && track.Language != null)
                                    {
                                        audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty));
                                    }
                                    else
                                    {
                                        audioTrackNames.Add("#" + track.TrackNumber);
                                    }

                                    mkvAudioTrackNumbers.Add(mkvAudioTrackNumbers.Count, track.TrackNumber);
                                }
                            }
                        }
                    }
                    finally
                    {
                        matroska?.Dispose();
                    }
                }
                else if (labelVideoFileName.Text.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase) || labelVideoFileName.Text.EndsWith(".m4v", StringComparison.OrdinalIgnoreCase))
                { // Choose for number of audio tracks in mp4 files
                    try
                    {
                        var mp4    = new MP4Parser(labelVideoFileName.Text);
                        var tracks = mp4.GetAudioTracks();
                        int i      = 0;
                        foreach (var track in tracks)
                        {
                            i++;
                            if (track.Name != null && track.Mdia != null && track.Mdia.Mdhd != null && track.Mdia.Mdhd.LanguageString != null)
                            {
                                audioTrackNames.Add(i + ":  " + track.Name + " - " + track.Mdia.Mdhd.LanguageString);
                            }
                            else if (track.Name != null)
                            {
                                audioTrackNames.Add(i + ":  " + track.Name);
                            }
                            else
                            {
                                audioTrackNames.Add(i.ToString(CultureInfo.InvariantCulture));
                            }
                        }
                        _numberOfAudioTracks = tracks.Count;
                    }
                    catch
                    {
                        // ignored
                    }
                }

                // Choose audio track
                if (_numberOfAudioTracks > 1)
                {
                    using (var form = new ChooseAudioTrack(audioTrackNames, AudioTrackNumber))
                    {
                        if (form.ShowDialog(this) == DialogResult.OK)
                        {
                            if (AudioTrackNumber != form.SelectedTrack)
                            {
                                AudioTrackNumber = form.SelectedTrack;

                                var peakWaveFileName  = WavePeakGenerator.GetPeakWaveFileName(labelVideoFileName.Text, form.SelectedTrack);
                                var spectrogramFolder = WavePeakGenerator.SpectrogramDrawer.GetSpectrogramFolder(labelVideoFileName.Text, form.SelectedTrack);
                                if (File.Exists(peakWaveFileName))
                                {
                                    DialogResult = DialogResult.Cancel;
                                    return;
                                }

                                _peakWaveFileName     = peakWaveFileName;
                                _spectrogramDirectory = spectrogramFolder;
                            }
                        }
                        else
                        {
                            DialogResult = DialogResult.Cancel;
                            return;
                        }
                    }
                }

                // check for delay in matroska files
                if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                {
                    MatroskaFile matroska = null;
                    try
                    {
                        matroska = new MatroskaFile(labelVideoFileName.Text);
                        if (matroska.IsValid)
                        {
                            _delayInMilliseconds = (int)matroska.GetAudioTrackDelayMilliseconds(mkvAudioTrackNumbers[AudioTrackNumber]);
                        }
                    }
                    catch (Exception exception)
                    {
                        SeLogger.Error(exception, $"Error getting delay from mkv: {labelVideoFileName.Text}");
                        _delayInMilliseconds = 0;
                    }
                    finally
                    {
                        matroska?.Dispose();
                    }
                }

                buttonRipWave_Click(null, null);
            }
            else if (_wavFileName != null)
            {
                FixWaveOnly();
            }
        }
        // E.g.: /convert *.txt SubRip
        public static void Convert(string title, string[] args)
        {
            const int attachParentProcess = -1;
            if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux())
                NativeMethods.AttachConsole(attachParentProcess);

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine(title + " - Batch converter");
            Console.WriteLine();
            Console.WriteLine("- Syntax: SubtitleEdit /convert <pattern> <name-of-format-without-spaces> [/offset:hh:mm:ss:ms] [/encoding:<encoding name>] [/fps:<frame rate>] [/targetfps:<frame rate>] [/inputfolder:<input folder>] [/outputfolder:<output folder>] [/pac-codepage:<code page>]");
            Console.WriteLine();
            Console.WriteLine("    example: SubtitleEdit /convert *.srt sami");
            Console.WriteLine("    list available formats: SubtitleEdit /convert /list");
            Console.WriteLine();

            string currentDir = Directory.GetCurrentDirectory();

            if (args.Length < 4)
            {
                bool isCommandList =
                    args[2].Equals("/list", StringComparison.OrdinalIgnoreCase) ||
                    args[2].Equals("-list", StringComparison.OrdinalIgnoreCase);

                if (args.Length == 3 && isCommandList)
                {
                    Console.WriteLine("- Supported formats (input/output):");
                    foreach (SubtitleFormat format in SubtitleFormat.AllSubtitleFormats)
                    {
                        Console.WriteLine("    " + format.Name.Replace(" ", string.Empty));
                    }

                    Console.WriteLine();
                    Console.WriteLine("- Supported formats (input only):");
                    Console.WriteLine("    " + CapMakerPlus.NameOfFormat);
                    Console.WriteLine("    " + Captionate.NameOfFormat);
                    Console.WriteLine("    " + Cavena890.NameOfFormat);
                    Console.WriteLine("    " + CheetahCaption.NameOfFormat);
                    Console.WriteLine("    " + Chk.NameOfFormat);
                    Console.WriteLine("    Matroska (.mkv)");
                    Console.WriteLine("    Matroska subtitle (.mks)");
                    Console.WriteLine("    " + NciCaption.NameOfFormat);
                    Console.WriteLine("    " + AvidStl.NameOfFormat);
                    Console.WriteLine("    " + Pac.NameOfFormat);
                    Console.WriteLine("    " + Spt.NameOfFormat);
                    Console.WriteLine("    " + Ultech130.NameOfFormat);
                }

                Console.WriteLine();
                Console.Write(currentDir + ">");

                if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux())
                {
                    NativeMethods.FreeConsole();
                }

                Environment.Exit(1);
            }

            int count = 0;
            int converted = 0;
            int errors = 0;
            try
            {
                string pattern = args[2];
                string toFormat = args[3];
                string offset = GetArgument(args, "/offset:");
                double currentFrameRate;

                var fps = GetArgument(args, "/fps:");
                if (fps.Length > 6)
                {
                    fps = fps.Remove(0, 5).Replace(",", ".").Trim();
                    if (double.TryParse(fps, System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.CultureInfo.InvariantCulture, out currentFrameRate))
                    {
                        Configuration.Settings.General.CurrentFrameRate = currentFrameRate;
                    }
                }

                var targetFps = GetArgument(args, "/targetfps:");
                double? targetFrameRate = null;
                if (targetFps.Length > 12)
                {
                    targetFps = targetFps.Remove(0, 11).Replace(",", ".").Trim();
                    if (double.TryParse(targetFps, System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.CultureInfo.InvariantCulture, out currentFrameRate))
                    {
                        targetFrameRate = currentFrameRate;
                    }
                }

                var targetEncodingName = GetArgument(args, "/encoding:"); ;
                var targetEncoding = Encoding.UTF8;
                try
                {
                    if (!string.IsNullOrEmpty(targetEncodingName))
                    {
                        targetEncodingName = targetEncodingName.Substring(10);
                        if (!string.IsNullOrEmpty(targetEncodingName))
                        {
                            targetEncoding = Encoding.GetEncoding(targetEncodingName);
                        }
                    }
                }
                catch (ArgumentException exception)
                {
                    Console.WriteLine("Unable to set encoding (" + exception.Message + ") - using UTF-8");
                    targetEncoding = Encoding.UTF8;
                }

                var outputFolder = GetArgument(args, "/outputfolder:");
                if (outputFolder.Length > "/outputFolder:".Length)
                {
                    outputFolder = outputFolder.Remove(0, "/outputFolder:".Length);
                    if (!Directory.Exists(outputFolder))
                        outputFolder = string.Empty;
                }

                var inputFolder = GetArgument(args, "/inputFolder:", Directory.GetCurrentDirectory());
                if (inputFolder.Length > "/inputFolder:".Length)
                {
                    inputFolder = inputFolder.Remove(0, "/inputFolder:".Length);
                    if (!Directory.Exists(inputFolder))
                        inputFolder = Directory.GetCurrentDirectory();
                }

                var pacCodePage = GetArgument(args, "/pac-codepage:");
                if (pacCodePage.Length > "/pac-codepage:".Length)
                {
                    pacCodePage = pacCodePage.Remove(0, "/pac-codepage:".Length);
                    if (string.Compare("Latin", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "0";
                    }
                    else if (string.Compare("Greek", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "1";
                    }
                    else if (string.Compare("Czech", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "2";
                    }
                    else if (string.Compare("Arabic", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "3";
                    }
                    else if (string.Compare("Hebrew", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "4";
                    }
                    else if (string.Compare("Encoding", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "5";
                    }
                    else if (string.Compare("Cyrillic", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "6";
                    }
                }

                bool overwrite = GetArgument(args, "/overwrite", string.Empty).Equals("/overwrite");

                string[] files;
                string inputDirectory = Directory.GetCurrentDirectory();
                if (!string.IsNullOrEmpty(inputFolder))
                {
                    inputDirectory = inputFolder;
                }

                if (pattern.Contains(',') && !File.Exists(pattern))
                {
                    files = pattern.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    for (int k = 0; k < files.Length; k++)
                    {
                        files[k] = files[k].Trim();
                    }
                }
                else
                {
                    int indexOfDirectorySeparatorChar = pattern.LastIndexOf(Path.DirectorySeparatorChar);
                    if (indexOfDirectorySeparatorChar > 0 && indexOfDirectorySeparatorChar < pattern.Length)
                    {
                        pattern = pattern.Substring(indexOfDirectorySeparatorChar + 1);
                        inputDirectory = args[2].Substring(0, indexOfDirectorySeparatorChar);
                    }

                    files = Directory.GetFiles(inputDirectory, pattern);
                }

                var formats = SubtitleFormat.AllSubtitleFormats;
                foreach (string fName in files)
                {
                    string fileName = fName;
                    count++;

                    if (!string.IsNullOrEmpty(inputFolder) && File.Exists(Path.Combine(inputFolder, fileName)))
                    {
                        fileName = Path.Combine(inputFolder, fileName);
                    }

                    if (File.Exists(fileName))
                    {
                        var sub = new Subtitle();
                        SubtitleFormat format = null;
                        bool done = false;

                        if (Path.GetExtension(fileName).Equals(".mkv", StringComparison.OrdinalIgnoreCase) || Path.GetExtension(fileName).Equals(".mks", StringComparison.OrdinalIgnoreCase))
                        {
                            using (var matroska = new MatroskaFile(fileName))
                            {
                                if (matroska.IsValid)
                                {
                                    var tracks = matroska.GetTracks();
                                    if (tracks.Count > 0)
                                    {
                                        foreach (var track in tracks)
                                        {
                                            if (track.CodecId.Equals("S_VOBSUB", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Console.WriteLine("{0}: {1} - Cannot convert from VobSub image based format!", fileName, toFormat);
                                            }
                                            else if (track.CodecId.Equals("S_HDMV/PGS", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Console.WriteLine("{0}: {1} - Cannot convert from Blu-ray image based format!", fileName, toFormat);
                                            }
                                            else
                                            {
                                                format = ConvertToMatroska(matroska, track, format, sub, fileName, tracks, toFormat, formats, offset, targetEncoding, outputFolder, count, overwrite, pacCodePage, targetFrameRate, ref converted, ref errors, ref done);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (FileUtil.IsBluRaySup(fileName))
                        {
                            Console.WriteLine("Found Blu-Ray subtitle format");
                            ConvertBluRaySubtitle(fileName, toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate);
                            done = true;
                        }
                        if (!done && FileUtil.IsVobSub(fileName))
                        {
                            Console.WriteLine("Found VobSub subtitle format");
                            ConvertVobSubSubtitle(fileName, toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate);
                            done = true;
                        }

                        var fi = new FileInfo(fileName);
                        if (fi.Length < 10 * 1024 * 1024 && !done) // max 10 mb
                        {
                            Encoding encoding;
                            format = sub.LoadSubtitle(fileName, out encoding, null, true);

                            format = GetSubtitleFormat(format, fileName, sub, pacCodePage);
                        }

                        if (format == null)
                        {
                            if (fi.Length < 1024*1024) // max 1 mb
                            {
                                Console.WriteLine("{0}: {1} - input file format unknown!", fileName, toFormat);
                            }
                            else
                            {
                                Console.WriteLine("{0}: {1} - input file too large!", fileName, toFormat);
                            }
                        }
                        else if (!done)
                        {
                            BatchConvertSave(toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, fileName, sub, format, overwrite, pacCodePage, targetFrameRate);
                        }
                    }
                    else
                    {
                        Console.WriteLine("{0}: {1} - file not found!", count, fileName);
                        errors++;
                    }
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine();
                Console.WriteLine("Ups - an error occured: " + exception.Message);
                Console.WriteLine();
            }

            Console.WriteLine();
            Console.WriteLine("{0} file(s) converted", converted);
            Console.WriteLine();
            Console.Write(currentDir + ">");

            if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux())
            {
                NativeMethods.FreeConsole();
            }

            if (count == converted && errors == 0)
            {
                Environment.Exit(0);
            }
            else
            {
                Environment.Exit(1);
            }
        }
        private static SubtitleFormat ConvertToMatroska(MatroskaFile matroska, MatroskaTrackInfo track, SubtitleFormat format, Subtitle sub, string fileName, List<MatroskaTrackInfo> tracks, string toFormat, IList<SubtitleFormat> formats, string offset, Encoding targetEncoding, string outputFolder, int count, bool overwrite, string pacCodePage, double? targetFrameRate, ref int converted, ref int errors, ref bool done)
        {
            var ss = matroska.GetSubtitle(track.TrackNumber, null);
            format = Utilities.LoadMatroskaTextSubtitle(track, matroska, ss, sub);
            string newFileName = fileName;
            if (tracks.Count > 1)
            {
                newFileName = fileName
                    .Insert(fileName.Length - 4, "_" + track.TrackNumber + "_" + track.Language
                        .Replace("?", string.Empty)
                        .Replace("!", string.Empty)
                        .Replace("*", string.Empty)
                        .Replace(",", string.Empty)
                        .Replace("/", string.Empty)
                        .Trim());
            }

            bool isSubStationAlpha =
                format.GetType() == typeof(AdvancedSubStationAlpha) ||
                format.GetType() == typeof(SubStationAlpha);

            if (isSubStationAlpha)
            {
                if (toFormat.ToLower() != AdvancedSubStationAlpha.NameOfFormat.ToLower().Replace(" ", string.Empty) &&
                    toFormat.ToLower() != SubStationAlpha.NameOfFormat.ToLower().Replace(" ", string.Empty))
                {
                    foreach (SubtitleFormat subtitleFormat in formats)
                    {
                        if (subtitleFormat
                            .Name
                            .Replace(" ", string.Empty)
                            .Equals(toFormat, StringComparison.OrdinalIgnoreCase) ||
                            subtitleFormat
                                .Name
                                .Replace(" ", string.Empty)
                                .Equals(toFormat.Replace(" ", string.Empty), StringComparison.OrdinalIgnoreCase))
                        {
                            format.RemoveNativeFormatting(sub, subtitleFormat);
                            break;
                        }
                    }
                }
            }

            BatchConvertSave(toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, newFileName, sub, format, overwrite, pacCodePage, targetFrameRate);
            done = true;
            return format;
        }
        internal static SubtitleFormat LoadMatroskaTextSubtitle(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska, List<MatroskaSubtitle> sub, Subtitle subtitle)
        {
            if (subtitle == null)
            {
                throw new ArgumentNullException("subtitle");
            }

            subtitle.Paragraphs.Clear();

            var isSsa = false;
            SubtitleFormat format = new SubRip();
            if (matroskaSubtitleInfo.CodecPrivate.Contains("[script info]", StringComparison.OrdinalIgnoreCase))
            {
                if (matroskaSubtitleInfo.CodecPrivate.Contains("[V4 Styles]", StringComparison.OrdinalIgnoreCase))
                {
                    format = new SubStationAlpha();
                }
                else
                {
                    format = new AdvancedSubStationAlpha();
                }

                isSsa = true;
            }

            if (isSsa)
            {
                foreach (var p in LoadMatroskaSSA(matroskaSubtitleInfo, matroska.Path, format, sub).Paragraphs)
                {
                    subtitle.Paragraphs.Add(p);
                }

                if (!string.IsNullOrEmpty(matroskaSubtitleInfo.CodecPrivate))
                {
                    bool eventsStarted = false;
                    bool fontsStarted = false;
                    bool graphicsStarted = false;
                    var header = new StringBuilder();
                    foreach (string line in matroskaSubtitleInfo.CodecPrivate.Replace(Environment.NewLine, "\n").Split('\n'))
                    {
                        if (!eventsStarted && !fontsStarted && !graphicsStarted)
                        {
                            header.AppendLine(line);
                        }

                        if (line.TrimStart().StartsWith("dialog:", StringComparison.OrdinalIgnoreCase))
                        {
                            eventsStarted = true;
                            fontsStarted = false;
                            graphicsStarted = false;
                        }
                        else if (line.Trim().Equals("[events]", StringComparison.OrdinalIgnoreCase))
                        {
                            eventsStarted = true;
                            fontsStarted = false;
                            graphicsStarted = false;
                        }
                        else if (line.Trim().Equals("[fonts]", StringComparison.OrdinalIgnoreCase))
                        {
                            eventsStarted = false;
                            fontsStarted = true;
                            graphicsStarted = false;
                        }
                        else if (line.Trim().Equals("[graphics]", StringComparison.OrdinalIgnoreCase))
                        {
                            eventsStarted = false;
                            fontsStarted = false;
                            graphicsStarted = true;
                        }
                    }

                    subtitle.Header = header.ToString().TrimEnd();
                    if (!subtitle.Header.Contains("[events]", StringComparison.OrdinalIgnoreCase))
                    {
                        subtitle.Header += Environment.NewLine + Environment.NewLine + "[Events]" + Environment.NewLine;
                    }
                }
            }
            else
            {
                foreach (var p in sub)
                {
                    subtitle.Paragraphs.Add(new Paragraph(p.Text, p.Start, p.End));
                }
            }

            subtitle.Renumber();
            return format;
        }
        private static VideoInfo TryReadVideoInfoViaMatroskaHeader(string fileName)
        {
            var info = new VideoInfo { Success = false };

            MatroskaFile matroska = null;
            try
            {
                matroska = new MatroskaFile(fileName);
                if (matroska.IsValid)
                {
                    double frameRate;
                    int width;
                    int height;
                    double milliseconds;
                    string videoCodec;
                    matroska.GetInfo(out frameRate, out width, out height, out milliseconds, out videoCodec);

                    info.Width = width;
                    info.Height = height;
                    info.FramesPerSecond = frameRate;
                    info.Success = true;
                    info.TotalMilliseconds = milliseconds;
                    info.TotalSeconds = milliseconds / TimeCode.BaseUnit;
                    info.TotalFrames = info.TotalSeconds * frameRate;
                    info.VideoCodec = videoCodec;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (matroska != null)
                {
                    matroska.Dispose();
                }
            }

            return info;
        }
Example #27
0
        private void ExtractAudio()
        {
            try
            {
                _waveFileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".wav");
                Process process;
                try
                {
                    process = GetCommandLineProcess(_videoFileName, -1, _waveFileName, Configuration.Settings.General.VlcWaveTranscodeSettings, out var waveExtractor);
                    _backgroundWorker.ReportProgress(0, string.Format(Configuration.Settings.Language.AudioToText.ExtractingAudioUsingX, waveExtractor));
                }
                catch (DllNotFoundException)
                {
                    if (MessageBox.Show(Configuration.Settings.Language.AddWaveform.VlcMediaPlayerNotFound + Environment.NewLine +
                                        Environment.NewLine + Configuration.Settings.Language.AddWaveform.GoToVlcMediaPlayerHomePage,
                                        Configuration.Settings.Language.AddWaveform.VlcMediaPlayerNotFoundTitle,
                                        MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        UiUtil.OpenURL("http://www.videolan.org/");
                    }
                    return;
                }

                process.Start();
                while (!process.HasExited && !_abort)
                {
                    Application.DoEvents();
                }

                // check for delay in matroska files
                var mkvAudioTrackNumbers = new Dictionary <int, int>();
                if (_videoFileName.ToLowerInvariant().EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                {
                    MatroskaFile matroska = null;
                    try
                    {
                        matroska = new MatroskaFile(_videoFileName);

                        if (matroska.IsValid)
                        {
                            foreach (var track in matroska.GetTracks())
                            {
                                if (track.IsAudio)
                                {
                                    var audioTrackNames = new List <string>();
                                    if (track.CodecId != null && track.Language != null)
                                    {
                                        audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty));
                                    }
                                    else
                                    {
                                        audioTrackNames.Add("#" + track.TrackNumber);
                                    }

                                    mkvAudioTrackNumbers.Add(mkvAudioTrackNumbers.Count, track.TrackNumber);
                                }
                            }
                            if (mkvAudioTrackNumbers.Count > 0)
                            {
                                _delayInMilliseconds = (int)matroska.GetTrackStartTime(mkvAudioTrackNumbers[0]);
                            }
                        }
                    }
                    catch
                    {
                        _delayInMilliseconds = 0;
                    }
                    finally
                    {
                        matroska?.Dispose();
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }
        private void buttonRipWave_Click(object sender, EventArgs e)
        {
            if (listViewInputFiles.Items.Count == 0)
            {
                MessageBox.Show(Configuration.Settings.Language.BatchConvert.NothingToConvert);
                return;
            }
            _converting = true;
            buttonRipWave.Enabled = false;
            progressBar1.Style = ProgressBarStyle.Blocks;
            progressBar1.Maximum = listViewInputFiles.Items.Count;
            progressBar1.Value = 0;
            progressBar1.Visible = progressBar1.Maximum > 2;
            buttonInputBrowse.Enabled = false;
            buttonSearchFolder.Enabled = false;
            _abort = false;
            listViewInputFiles.BeginUpdate();
            foreach (ListViewItem item in listViewInputFiles.Items)
                item.SubItems[3].Text = "-";
            listViewInputFiles.EndUpdate();
            Refresh();
            int index = 0;
            while (index < listViewInputFiles.Items.Count && _abort == false)
            {
                var item = listViewInputFiles.Items[index];
                item.SubItems[3].Text = Configuration.Settings.Language.AddWaveformBatch.ExtractingAudio;
                string fileName = item.Text;
                try
                {
                    string targetFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".wav");
                    Process process;
                    try
                    {
                        string encoderName;
                        process = AddWaveform.GetCommandLineProcess(fileName, -1, targetFile, Configuration.Settings.General.VlcWaveTranscodeSettings, out encoderName);
                        labelInfo.Text = encoderName;
                    }
                    catch (DllNotFoundException)
                    {
                        if (MessageBox.Show(Configuration.Settings.Language.AddWaveform.VlcMediaPlayerNotFound + Environment.NewLine +
                                            Environment.NewLine + Configuration.Settings.Language.AddWaveform.GoToVlcMediaPlayerHomePage,
                                            Configuration.Settings.Language.AddWaveform.VlcMediaPlayerNotFoundTitle,
                                            MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            Process.Start("http://www.videolan.org/");
                        }
                        buttonRipWave.Enabled = true;
                        return;
                    }

                    process.Start();
                    while (!process.HasExited && !_abort)
                    {
                        Application.DoEvents();
                    }

                    // check for delay in matroska files
                    var audioTrackNames = new List<string>();
                    var mkvAudioTrackNumbers = new Dictionary<int, int>();
                    if (fileName.ToLower().EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                    {
                        MatroskaFile matroska = null;
                        try
                        {
                            matroska = new MatroskaFile(fileName);

                            if (matroska.IsValid)
                            {
                                foreach (var track in matroska.GetTracks())
                                {
                                    if (track.IsAudio)
                                    {
                                        if (track.CodecId != null && track.Language != null)
                                            audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty));
                                        else
                                            audioTrackNames.Add("#" + track.TrackNumber);
                                        mkvAudioTrackNumbers.Add(mkvAudioTrackNumbers.Count, track.TrackNumber);
                                    }
                                }
                                if (mkvAudioTrackNumbers.Count > 0)
                                {
                                    _delayInMilliseconds = (int)matroska.GetTrackStartTime(mkvAudioTrackNumbers[0]);
                                }
                            }
                        }
                        catch
                        {
                            _delayInMilliseconds = 0;
                        }
                        finally
                        {
                            if (matroska != null)
                            {
                                matroska.Dispose();
                            }
                        }
                    }

                    item.SubItems[3].Text = Configuration.Settings.Language.AddWaveformBatch.Calculating;
                    MakeWaveformAndSpectrogram(fileName, targetFile, _delayInMilliseconds);

                    // cleanup
                    try
                    {
                        File.Delete(targetFile);
                    }
                    catch
                    {
                        // don't show error about unsuccessful delete
                    }

                    IncrementAndShowProgress();

                    item.SubItems[3].Text = Configuration.Settings.Language.AddWaveformBatch.Done;
                }
                catch
                {
                    IncrementAndShowProgress();

                    item.SubItems[3].Text = Configuration.Settings.Language.AddWaveformBatch.Error;
                }
                index++;
            }
            _converting = false;
            labelProgress.Text = string.Empty;
            labelInfo.Text = string.Empty;
            progressBar1.Visible = false;
            TaskbarList.SetProgressState(Handle, TaskbarButtonProgressFlags.NoProgress);
            buttonRipWave.Enabled = true;
            buttonInputBrowse.Enabled = true;
            buttonSearchFolder.Enabled = true;
        }
Example #29
0
        private void buttonRipWave_Click(object sender, EventArgs e)
        {
            if (listViewInputFiles.Items.Count == 0)
            {
                MessageBox.Show(LanguageSettings.Current.BatchConvert.NothingToConvert);
                return;
            }

            _converting                = true;
            buttonRipWave.Enabled      = false;
            progressBar1.Style         = ProgressBarStyle.Blocks;
            progressBar1.Maximum       = listViewInputFiles.Items.Count;
            progressBar1.Value         = 0;
            progressBar1.Visible       = progressBar1.Maximum > 2;
            buttonInputBrowse.Enabled  = false;
            buttonSearchFolder.Enabled = false;
            _abort = false;
            listViewInputFiles.BeginUpdate();
            foreach (ListViewItem item in listViewInputFiles.Items)
            {
                item.SubItems[3].Text = "-";
            }

            listViewInputFiles.EndUpdate();
            Refresh();
            var index = 0;

            while (index < listViewInputFiles.Items.Count && _abort == false)
            {
                var item = listViewInputFiles.Items[index];

                void UpdateStatus(string status)
                {
                    item.SubItems[3].Text = status;
                    Refresh();
                }

                UpdateStatus(LanguageSettings.Current.AddWaveformBatch.ExtractingAudio);
                var fileName = item.Text;
                try
                {
                    var     targetFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".wav");
                    Process process;
                    try
                    {
                        process        = AddWaveform.GetCommandLineProcess(fileName, -1, targetFile, Configuration.Settings.General.VlcWaveTranscodeSettings, out var encoderName);
                        labelInfo.Text = encoderName;
                    }
                    catch (DllNotFoundException)
                    {
                        var isFfmpegAvailable = !string.IsNullOrEmpty(Configuration.Settings.General.FFmpegLocation) && File.Exists(Configuration.Settings.General.FFmpegLocation);
                        if (isFfmpegAvailable)
                        {
                            Configuration.Settings.General.UseFFmpegForWaveExtraction = true;
                            process        = AddWaveform.GetCommandLineProcess(fileName, -1, targetFile, Configuration.Settings.General.VlcWaveTranscodeSettings, out var encoderName);
                            labelInfo.Text = encoderName;
                        }
                        else
                        {
                            if (MessageBox.Show(LanguageSettings.Current.AddWaveform.FfmpegNotFound, "Subtitle Edit", MessageBoxButtons.YesNoCancel) != DialogResult.Yes)
                            {
                                buttonRipWave.Enabled = true;
                                return;
                            }

                            using (var form = new DownloadFfmpeg())
                            {
                                if (form.ShowDialog(this) == DialogResult.OK && !string.IsNullOrEmpty(form.FFmpegPath))
                                {
                                    Configuration.Settings.General.FFmpegLocation             = form.FFmpegPath;
                                    Configuration.Settings.General.UseFFmpegForWaveExtraction = true;
                                    process        = AddWaveform.GetCommandLineProcess(fileName, -1, targetFile, Configuration.Settings.General.VlcWaveTranscodeSettings, out var encoderName);
                                    labelInfo.Text = encoderName;
                                }
                                else
                                {
                                    buttonRipWave.Enabled = true;
                                    return;
                                }
                            }
                        }
                    }

                    process.Start();
                    while (!process.HasExited && !_abort)
                    {
                        Application.DoEvents();
                    }

                    // check for delay in matroska files
                    var audioTrackNames      = new List <string>();
                    var mkvAudioTrackNumbers = new Dictionary <int, int>();
                    if (fileName.ToLowerInvariant().EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                    {
                        try
                        {
                            using (var matroska = new MatroskaFile(fileName))
                            {
                                if (matroska.IsValid)
                                {
                                    foreach (var track in matroska.GetTracks())
                                    {
                                        if (track.IsAudio)
                                        {
                                            if (track.CodecId != null && track.Language != null)
                                            {
                                                audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty));
                                            }
                                            else
                                            {
                                                audioTrackNames.Add("#" + track.TrackNumber);
                                            }

                                            mkvAudioTrackNumbers.Add(mkvAudioTrackNumbers.Count, track.TrackNumber);
                                        }
                                    }
                                    if (mkvAudioTrackNumbers.Count > 0)
                                    {
                                        _delayInMilliseconds = (int)matroska.GetAudioTrackDelayMilliseconds(mkvAudioTrackNumbers[0]);
                                    }
                                }
                            }
                        }
                        catch (Exception exception)
                        {
                            SeLogger.Error(exception, $"Error getting delay from mkv: {fileName}");
                            _delayInMilliseconds = 0;
                        }
                    }

                    UpdateStatus(LanguageSettings.Current.AddWaveformBatch.Calculating);
                    MakeWaveformAndSpectrogram(fileName, targetFile, _delayInMilliseconds);

                    if (checkBoxGenerateSceneChanges.Visible && checkBoxGenerateSceneChanges.Checked)
                    {
                        GenerateSceneChanges(fileName);
                    }

                    // cleanup
                    try
                    {
                        File.Delete(targetFile);
                    }
                    catch
                    {
                        // don't show error about unsuccessful delete
                    }

                    IncrementAndShowProgress();

                    UpdateStatus(LanguageSettings.Current.AddWaveformBatch.Done);
                }
                catch
                {
                    IncrementAndShowProgress();

                    UpdateStatus(LanguageSettings.Current.AddWaveformBatch.Error);
                }
                index++;
            }
            _converting          = false;
            labelProgress.Text   = string.Empty;
            labelInfo.Text       = string.Empty;
            progressBar1.Visible = false;
            TaskbarList.SetProgressState(Owner.Handle, TaskbarButtonProgressFlags.NoProgress);
            buttonRipWave.Enabled      = true;
            buttonInputBrowse.Enabled  = true;
            buttonSearchFolder.Enabled = true;
        }
        private void AddWareForm_Shown(object sender, EventArgs e)
        {
            Refresh();
            var audioTrackNames = new List<string>();
            var mkvAudioTrackNumbers = new Dictionary<int, int>();
            int numberOfAudioTracks = 0;
            if (labelVideoFileName.Text.Length > 1 && File.Exists(labelVideoFileName.Text))
            {
                if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                { // Choose for number of audio tracks in matroska files
                    MatroskaFile matroska = null;
                    try
                    {
                        matroska = new MatroskaFile(labelVideoFileName.Text);
                        if (matroska.IsValid)
                        {
                            foreach (var track in matroska.GetTracks())
                            {
                                if (track.IsAudio)
                                {
                                    numberOfAudioTracks++;
                                    if (track.CodecId != null && track.Language != null)
                                        audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty));
                                    else
                                        audioTrackNames.Add("#" + track.TrackNumber);
                                    mkvAudioTrackNumbers.Add(mkvAudioTrackNumbers.Count, track.TrackNumber);
                                }
                            }
                        }
                    }
                    finally
                    {
                        if (matroska != null)
                        {
                            matroska.Dispose();
                        }
                    }
                }
                else if (labelVideoFileName.Text.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase) || labelVideoFileName.Text.EndsWith(".m4v", StringComparison.OrdinalIgnoreCase))
                { // Choose for number of audio tracks in mp4 files
                    try
                    {
                        var mp4 = new MP4Parser(labelVideoFileName.Text);
                        var tracks = mp4.GetAudioTracks();
                        int i = 0;
                        foreach (var track in tracks)
                        {
                            i++;
                            if (track.Name != null && track.Mdia != null && track.Mdia.Mdhd != null && track.Mdia.Mdhd.LanguageString != null)
                                audioTrackNames.Add(i + ":  " + track.Name + " - " + track.Mdia.Mdhd.LanguageString);
                            else if (track.Name != null)
                                audioTrackNames.Add(i + ":  " + track.Name);
                            else
                                audioTrackNames.Add(i.ToString(CultureInfo.InvariantCulture));
                        }
                        numberOfAudioTracks = tracks.Count;
                    }
                    catch
                    {
                    }
                }

                if (Configuration.Settings.General.UseFFmpegForWaveExtraction)
                { // don't know how to extract audio number x via FFmpeg...
                    numberOfAudioTracks = 1;
                    _audioTrackNumber = 0;
                }

                // Choose audio track
                if (numberOfAudioTracks > 1)
                {
                    using (var form = new ChooseAudioTrack(audioTrackNames, _audioTrackNumber))
                    {
                        if (form.ShowDialog(this) == DialogResult.OK)
                        {
                            _audioTrackNumber = form.SelectedTrack;
                        }
                        else
                        {
                            DialogResult = DialogResult.Cancel;
                            return;
                        }
                    }
                }

                // check for delay in matroska files
                if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                {
                    MatroskaFile matroska = null;
                    try
                    {
                        matroska = new MatroskaFile(labelVideoFileName.Text);
                        if (matroska.IsValid)
                        {
                            _delayInMilliseconds = (int)matroska.GetTrackStartTime(mkvAudioTrackNumbers[_audioTrackNumber]);
                        }
                    }
                    catch
                    {
                        _delayInMilliseconds = 0;
                    }
                    finally
                    {
                        if (matroska != null)
                        {
                            matroska.Dispose();
                        }
                    }
                }

                buttonRipWave_Click(null, null);
            }
            else if (_wavFileName != null)
            {
                FixWaveOnly();
            }
        }
Example #31
0
        public static void Convert(string title, string[] args) // E.g.: /convert *.txt SubRip
        {
            const int ATTACH_PARENT_PROCESS = -1;

            if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux())
            {
                NativeMethods.AttachConsole(ATTACH_PARENT_PROCESS);
            }

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine(title + " - Batch converter");
            Console.WriteLine();
            Console.WriteLine("- Syntax: SubtitleEdit /convert <pattern> <name-of-format-without-spaces> [/offset:hh:mm:ss:ms] [/encoding:<encoding name>] [/fps:<frame rate>] [/targetfps:<frame rate>] [/inputfolder:<input folder>] [/outputfolder:<output folder>] [/removetextforhi] [/fixcommonerrors] [/pac-codepage:<code page>]");
            Console.WriteLine();
            Console.WriteLine("    example: SubtitleEdit /convert *.srt sami");
            Console.WriteLine("    list available formats: SubtitleEdit /convert /list");
            Console.WriteLine();

            string currentDir = Directory.GetCurrentDirectory();

            if (args.Length < 4)
            {
                if (args.Length == 3 && (args[2].Equals("/list", StringComparison.OrdinalIgnoreCase) || args[2].Equals("-list", StringComparison.OrdinalIgnoreCase)))
                {
                    Console.WriteLine("- Supported formats (input/output):");
                    foreach (SubtitleFormat format in SubtitleFormat.AllSubtitleFormats)
                    {
                        Console.WriteLine("    " + format.Name.Replace(" ", string.Empty));
                    }
                    Console.WriteLine();
                    Console.WriteLine("- Supported formats (input only):");
                    Console.WriteLine("    " + CapMakerPlus.NameOfFormat);
                    Console.WriteLine("    " + Captionate.NameOfFormat);
                    Console.WriteLine("    " + Cavena890.NameOfFormat);
                    Console.WriteLine("    " + CheetahCaption.NameOfFormat);
                    Console.WriteLine("    " + Chk.NameOfFormat);
                    Console.WriteLine("    Matroska (.mkv)");
                    Console.WriteLine("    Matroska subtitle (.mks)");
                    Console.WriteLine("    " + NciCaption.NameOfFormat);
                    Console.WriteLine("    " + AvidStl.NameOfFormat);
                    Console.WriteLine("    " + Pac.NameOfFormat);
                    Console.WriteLine("    " + Spt.NameOfFormat);
                    Console.WriteLine("    " + Ultech130.NameOfFormat);
                    Console.WriteLine("- For Blu-ray .sup output use: '" + BatchConvert.BluRaySubtitle.Replace(" ", string.Empty) + "'");
                    Console.WriteLine("- For VobSub .sub output use: '" + BatchConvert.VobSubSubtitle.Replace(" ", string.Empty) + "'");
                }

                Console.WriteLine();
                Console.Write(currentDir + ">");
                if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux())
                {
                    NativeMethods.FreeConsole();
                }
                Environment.Exit(1);
            }

            int count     = 0;
            int converted = 0;
            int errors    = 0;

            try
            {
                string pattern  = args[2];
                string toFormat = args[3];
                string offset   = GetArgument(args, "/offset:");

                var fps = GetArgument(args, "/fps:");
                if (fps.Length > 6)
                {
                    fps = fps.Remove(0, 5).Replace(',', '.').Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, ".").Trim();
                    double d;
                    if (double.TryParse(fps, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out d))
                    {
                        Configuration.Settings.General.CurrentFrameRate = d;
                    }
                }

                var    targetFps       = GetArgument(args, "/targetfps:");
                double?targetFrameRate = null;
                if (targetFps.Length > 12)
                {
                    targetFps = targetFps.Remove(0, 11).Replace(',', '.').Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, ".").Trim();
                    double d;
                    if (double.TryParse(targetFps, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out d))
                    {
                        targetFrameRate = d;
                    }
                }

                var targetEncodingName = GetArgument(args, "/encoding:");;
                var targetEncoding     = Encoding.UTF8;
                try
                {
                    if (!string.IsNullOrEmpty(targetEncodingName))
                    {
                        targetEncodingName = targetEncodingName.Substring(10);
                        if (!string.IsNullOrEmpty(targetEncodingName))
                        {
                            targetEncoding = Encoding.GetEncoding(targetEncodingName);
                        }
                    }
                }
                catch (Exception exception)
                {
                    Console.WriteLine("Unable to set encoding (" + exception.Message + ") - using UTF-8");
                    targetEncoding = Encoding.UTF8;
                }

                var outputFolder = GetArgument(args, "/outputfolder:");;
                if (outputFolder.Length > "/outputFolder:".Length)
                {
                    outputFolder = outputFolder.Remove(0, "/outputFolder:".Length);
                    if (!Directory.Exists(outputFolder))
                    {
                        outputFolder = string.Empty;
                    }
                }

                var inputFolder = GetArgument(args, "/inputFolder:", Directory.GetCurrentDirectory());
                if (inputFolder.Length > "/inputFolder:".Length)
                {
                    inputFolder = inputFolder.Remove(0, "/inputFolder:".Length);
                    if (!Directory.Exists(inputFolder))
                    {
                        inputFolder = Directory.GetCurrentDirectory();
                    }
                }

                var pacCodePage = GetArgument(args, "/pac-codepage:");
                if (pacCodePage.Length > "/pac-codepage:".Length)
                {
                    pacCodePage = pacCodePage.Remove(0, "/pac-codepage:".Length);
                    if (string.Compare("Latin", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "0";
                    }
                    else if (string.Compare("Greek", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "1";
                    }
                    else if (string.Compare("Czech", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "2";
                    }
                    else if (string.Compare("Arabic", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "3";
                    }
                    else if (string.Compare("Hebrew", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "4";
                    }
                    else if (string.Compare("Encoding", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "5";
                    }
                    else if (string.Compare("Cyrillic", pacCodePage, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        pacCodePage = "6";
                    }
                }

                bool overwrite       = GetArgument(args, "/overwrite", string.Empty).Equals("/overwrite");
                bool removeTextForHi = GetArgument(args, "/removetextforhi", string.Empty).Equals("/removetextforhi");
                bool fixCommonErrors = GetArgument(args, "/fixcommonerrors", string.Empty).Equals("/fixcommonerrors");
                bool redoCasing      = GetArgument(args, "/redocasing", string.Empty).Equals("/redocasing");

                string[] files;
                string   inputDirectory = Directory.GetCurrentDirectory();
                if (!string.IsNullOrEmpty(inputFolder))
                {
                    inputDirectory = inputFolder;
                }

                if (pattern.Contains(',') && !File.Exists(pattern))
                {
                    files = pattern.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int k = 0; k < files.Length; k++)
                    {
                        files[k] = files[k].Trim();
                    }
                }
                else
                {
                    int indexOfDirectorySeparatorChar = pattern.LastIndexOf(Path.DirectorySeparatorChar);
                    if (indexOfDirectorySeparatorChar > 0 && indexOfDirectorySeparatorChar < pattern.Length)
                    {
                        pattern        = pattern.Substring(indexOfDirectorySeparatorChar + 1);
                        inputDirectory = args[2].Substring(0, indexOfDirectorySeparatorChar);
                    }
                    files = Directory.GetFiles(inputDirectory, pattern);
                }

                var formats = SubtitleFormat.AllSubtitleFormats;
                foreach (string fName in files)
                {
                    string fileName = fName;
                    count++;

                    if (!string.IsNullOrEmpty(inputFolder) && File.Exists(Path.Combine(inputFolder, fileName)))
                    {
                        fileName = Path.Combine(inputFolder, fileName);
                    }

                    if (File.Exists(fileName))
                    {
                        var            sub    = new Subtitle();
                        SubtitleFormat format = null;
                        bool           done   = false;

                        if (Path.GetExtension(fileName).Equals(".mkv", StringComparison.OrdinalIgnoreCase) || Path.GetExtension(fileName).Equals(".mks", StringComparison.OrdinalIgnoreCase))
                        {
                            using (var matroska = new MatroskaFile(fileName))
                            {
                                if (matroska.IsValid)
                                {
                                    var tracks = matroska.GetTracks();
                                    if (tracks.Count > 0)
                                    {
                                        foreach (var track in tracks)
                                        {
                                            if (track.CodecId.Equals("S_VOBSUB", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Console.WriteLine("{0}: {1} - Cannot convert from VobSub image based format!", fileName, toFormat);
                                            }
                                            else if (track.CodecId.Equals("S_HDMV/PGS", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Console.WriteLine("{0}: {1} - Cannot convert from Blu-ray image based format!", fileName, toFormat);
                                            }
                                            else
                                            {
                                                var ss = matroska.GetSubtitle(track.TrackNumber, null);
                                                format = Utilities.LoadMatroskaTextSubtitle(track, matroska, ss, sub);
                                                string newFileName = fileName;
                                                if (tracks.Count > 1)
                                                {
                                                    newFileName = fileName.Insert(fileName.Length - 4, "_" + track.TrackNumber + "_" + track.Language.Replace("?", string.Empty).Replace("!", string.Empty).Replace("*", string.Empty).Replace(",", string.Empty).Replace("/", string.Empty).Trim());
                                                }

                                                if (format.GetType() == typeof(AdvancedSubStationAlpha) || format.GetType() == typeof(SubStationAlpha))
                                                {
                                                    if (toFormat.ToLower() != AdvancedSubStationAlpha.NameOfFormat.ToLower().Replace(" ", string.Empty) &&
                                                        toFormat.ToLower() != SubStationAlpha.NameOfFormat.ToLower().Replace(" ", string.Empty))
                                                    {
                                                        foreach (SubtitleFormat sf in formats)
                                                        {
                                                            if (sf.Name.Replace(" ", string.Empty).Equals(toFormat, StringComparison.OrdinalIgnoreCase) || sf.Name.Replace(" ", string.Empty).Equals(toFormat.Replace(" ", string.Empty), StringComparison.OrdinalIgnoreCase))
                                                            {
                                                                format.RemoveNativeFormatting(sub, sf);
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }

                                                BatchConvertSave(toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, newFileName, sub, format, overwrite, pacCodePage, targetFrameRate, removeTextForHi, fixCommonErrors, redoCasing);
                                                done = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (FileUtil.IsBluRaySup(fileName))
                        {
                            Console.WriteLine("Found Blu-Ray subtitle format");
                            ConvertBluRaySubtitle(fileName, toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate, removeTextForHi, fixCommonErrors, redoCasing);
                            done = true;
                        }
                        if (!done && FileUtil.IsVobSub(fileName))
                        {
                            Console.WriteLine("Found VobSub subtitle format");
                            ConvertVobSubSubtitle(fileName, toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate, removeTextForHi, fixCommonErrors, redoCasing);
                            done = true;
                        }

                        var fi = new FileInfo(fileName);
                        if (fi.Length < 10 * 1024 * 1024 && !done) // max 10 mb
                        {
                            Encoding encoding;
                            format = sub.LoadSubtitle(fileName, out encoding, null, true);

                            if (format == null || format.GetType() == typeof(Ebu))
                            {
                                var ebu = new Ebu();
                                if (ebu.IsMine(null, fileName))
                                {
                                    ebu.LoadSubtitle(sub, null, fileName);
                                    format = ebu;
                                }
                            }
                            if (format == null)
                            {
                                var pac = new Pac();
                                if (pac.IsMine(null, fileName))
                                {
                                    pac.BatchMode = true;

                                    if (!string.IsNullOrEmpty(pacCodePage) && Utilities.IsInteger(pacCodePage))
                                    {
                                        pac.CodePage = int.Parse(pacCodePage);
                                    }
                                    else
                                    {
                                        pac.CodePage = -1;
                                    }

                                    pac.LoadSubtitle(sub, null, fileName);
                                    format = pac;
                                }
                            }
                            if (format == null)
                            {
                                var cavena890 = new Cavena890();
                                if (cavena890.IsMine(null, fileName))
                                {
                                    cavena890.LoadSubtitle(sub, null, fileName);
                                    format = cavena890;
                                }
                            }
                            if (format == null)
                            {
                                var spt = new Spt();
                                if (spt.IsMine(null, fileName))
                                {
                                    spt.LoadSubtitle(sub, null, fileName);
                                    format = spt;
                                }
                            }
                            if (format == null)
                            {
                                var cheetahCaption = new CheetahCaption();
                                if (cheetahCaption.IsMine(null, fileName))
                                {
                                    cheetahCaption.LoadSubtitle(sub, null, fileName);
                                    format = cheetahCaption;
                                }
                            }
                            if (format == null)
                            {
                                var chk = new Chk();
                                if (chk.IsMine(null, fileName))
                                {
                                    chk.LoadSubtitle(sub, null, fileName);
                                    format = chk;
                                }
                            }
                            if (format == null)
                            {
                                var ayato = new Ayato();
                                if (ayato.IsMine(null, fileName))
                                {
                                    ayato.LoadSubtitle(sub, null, fileName);
                                    format = ayato;
                                }
                            }
                            if (format == null)
                            {
                                var capMakerPlus = new CapMakerPlus();
                                if (capMakerPlus.IsMine(null, fileName))
                                {
                                    capMakerPlus.LoadSubtitle(sub, null, fileName);
                                    format = capMakerPlus;
                                }
                            }
                            if (format == null)
                            {
                                var captionate = new Captionate();
                                if (captionate.IsMine(null, fileName))
                                {
                                    captionate.LoadSubtitle(sub, null, fileName);
                                    format = captionate;
                                }
                            }
                            if (format == null)
                            {
                                var ultech130 = new Ultech130();
                                if (ultech130.IsMine(null, fileName))
                                {
                                    ultech130.LoadSubtitle(sub, null, fileName);
                                    format = ultech130;
                                }
                            }
                            if (format == null)
                            {
                                var nciCaption = new NciCaption();
                                if (nciCaption.IsMine(null, fileName))
                                {
                                    nciCaption.LoadSubtitle(sub, null, fileName);
                                    format = nciCaption;
                                }
                            }
                            if (format == null)
                            {
                                var tsb4 = new TSB4();
                                if (tsb4.IsMine(null, fileName))
                                {
                                    tsb4.LoadSubtitle(sub, null, fileName);
                                    format = tsb4;
                                }
                            }
                            if (format == null)
                            {
                                var avidStl = new AvidStl();
                                if (avidStl.IsMine(null, fileName))
                                {
                                    avidStl.LoadSubtitle(sub, null, fileName);
                                    format = avidStl;
                                }
                            }
                            if (format == null)
                            {
                                var elr = new ELRStudioClosedCaption();
                                if (elr.IsMine(null, fileName))
                                {
                                    elr.LoadSubtitle(sub, null, fileName);
                                    format = elr;
                                }
                            }
                        }

                        if (format == null)
                        {
                            if (fi.Length < 1024 * 1024) // max 1 mb
                            {
                                Console.WriteLine("{0}: {1} - input file format unknown!", fileName, toFormat);
                            }
                            else
                            {
                                Console.WriteLine("{0}: {1} - input file too large!", fileName, toFormat);
                            }
                        }
                        else if (!done)
                        {
                            BatchConvertSave(toFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, fileName, sub, format, overwrite, pacCodePage, targetFrameRate, removeTextForHi, fixCommonErrors, redoCasing);
                        }
                    }
                    else
                    {
                        Console.WriteLine("{0}: {1} - file not found!", count, fileName);
                        errors++;
                    }
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine();
                Console.WriteLine("Ups - an error occured: " + exception.Message);
                Console.WriteLine();
            }

            Console.WriteLine();
            Console.WriteLine("{0} file(s) converted", converted);
            Console.WriteLine();
            Console.Write(currentDir + ">");

            if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux())
            {
                NativeMethods.FreeConsole();
            }

            if (count == converted && errors == 0)
            {
                Environment.Exit(0);
            }
            else
            {
                Environment.Exit(1);
            }
        }
        public static void Convert(string title, string[] args) // E.g.: /convert *.txt SubRip
        {
            const int ATTACH_PARENT_PROCESS = -1;

            if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux())
            {
                NativeMethods.AttachConsole(ATTACH_PARENT_PROCESS);
            }

            var currentFolder = Directory.GetCurrentDirectory();

            Console.WriteLine();
            Console.WriteLine(title + " - Batch converter");
            Console.WriteLine();

            if (args.Length < 4)
            {
                if (args.Length == 3 && (args[2].Equals("/list", StringComparison.OrdinalIgnoreCase) || args[2].Equals("-list", StringComparison.OrdinalIgnoreCase)))
                {
                    Console.WriteLine("- Supported formats (input/output):");
                    foreach (SubtitleFormat format in SubtitleFormat.AllSubtitleFormats)
                    {
                        Console.WriteLine("    " + format.Name.Replace(" ", string.Empty));
                    }
                    Console.WriteLine();
                    Console.WriteLine("- Supported formats (input only):");
                    Console.WriteLine("    " + CapMakerPlus.NameOfFormat);
                    Console.WriteLine("    " + Captionate.NameOfFormat);
                    Console.WriteLine("    " + Cavena890.NameOfFormat);
                    Console.WriteLine("    " + CheetahCaption.NameOfFormat);
                    Console.WriteLine("    " + Chk.NameOfFormat);
                    Console.WriteLine("    Matroska (.mkv)");
                    Console.WriteLine("    Matroska subtitle (.mks)");
                    Console.WriteLine("    " + NciCaption.NameOfFormat);
                    Console.WriteLine("    " + AvidStl.NameOfFormat);
                    Console.WriteLine("    " + Pac.NameOfFormat);
                    Console.WriteLine("    " + Spt.NameOfFormat);
                    Console.WriteLine("    " + Ultech130.NameOfFormat);
                    Console.WriteLine("- For Blu-ray .sup output use: '" + BatchConvert.BluRaySubtitle.Replace(" ", string.Empty) + "'");
                    Console.WriteLine("- For VobSub .sub output use: '" + BatchConvert.VobSubSubtitle.Replace(" ", string.Empty) + "'");
                }
                else
                {
                    Console.WriteLine("- Usage: SubtitleEdit /convert <pattern> <name-of-format-without-spaces> [<optional-parameters>]");
                    Console.WriteLine();
                    Console.WriteLine("    pattern:");
                    Console.WriteLine("        one or more file name patterns separated by commas");
                    Console.WriteLine("        relative patterns are relative to /inputfolder if specified");
                    Console.WriteLine("    optional-parameters:");
                    Console.WriteLine("        /offset:hh:mm:ss:ms");
                    Console.WriteLine("        /fps:<frame rate>");
                    Console.WriteLine("        /targetfps:<frame rate>");
                    Console.WriteLine("        /encoding:<encoding name>");
                    Console.WriteLine("        /pac-codepage:<code page>");
                    Console.WriteLine("        /inputfolder:<folder name>");
                    Console.WriteLine("        /outputfolder:<folder name>");
                    Console.WriteLine("        /removetextforhi");
                    Console.WriteLine("        /fixcommonerrors");
                    Console.WriteLine("        /redocasing");
                    Console.WriteLine("        /multiplereplace");
                    Console.WriteLine();
                    Console.WriteLine("    example: SubtitleEdit /convert *.srt sami");
                    Console.WriteLine("    list available formats: SubtitleEdit /convert /list");
                }
                Console.WriteLine();

                if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux())
                {
                    Console.Write(currentFolder + ">");
                    NativeMethods.FreeConsole();
                }
                Environment.Exit(1);
            }

            int count     = 0;
            int converted = 0;
            int errors    = 0;

            try
            {
                var pattern      = args[2].Trim();
                var targetFormat = args[3].Trim().Replace(" ", string.Empty);
                var offset       = GetArgument(args, "offset:");

                double?targetFrameRate = null;
                {
                    var fps = GetArgument(args, "targetfps:");
                    if (fps.Length > 1)
                    {
                        fps = fps.Replace(',', '.').Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, ".");
                        double d;
                        if (double.TryParse(fps, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out d))
                        {
                            targetFrameRate = d;
                        }
                    }

                    fps = GetArgument(args, "fps:");
                    if (fps.Length > 1)
                    {
                        fps = fps.Replace(',', '.').Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, ".");
                        double d;
                        if (double.TryParse(fps, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out d))
                        {
                            Configuration.Settings.General.CurrentFrameRate = d;
                        }
                    }
                }

                var targetEncoding = Encoding.UTF8;
                try
                {
                    var encodingName = GetArgument(args, "encoding:");
                    if (encodingName.Length > 0)
                    {
                        targetEncoding = Encoding.GetEncoding(encodingName);
                    }
                }
                catch (Exception exception)
                {
                    Console.WriteLine("Unable to set encoding (" + exception.Message + ") - using UTF-8");
                }

                var outputFolder = string.Empty;
                {
                    var folder = GetArgument(args, "outputfolder:");
                    if (folder.Length > 0 && Directory.Exists(folder))
                    {
                        outputFolder = folder;
                    }
                }

                var inputFolder = currentFolder;
                {
                    var folder = GetArgument(args, "inputFolder:");
                    if (folder.Length > 0 && Directory.Exists(folder))
                    {
                        inputFolder = folder;
                    }
                }

                int pacCodePage = -1;
                {
                    var pcp = GetArgument(args, "pac-codepage:");
                    if (pcp.Length > 0)
                    {
                        if (pcp.Equals("Latin", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageLatin;
                        }
                        else if (pcp.Equals("Greek", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageGreek;
                        }
                        else if (pcp.Equals("Czech", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageLatinCzech;
                        }
                        else if (pcp.Equals("Arabic", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageArabic;
                        }
                        else if (pcp.Equals("Hebrew", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageHebrew;
                        }
                        else if (pcp.Equals("Thai", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageThai;
                        }
                        else if (pcp.Equals("Cyrillic", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageCyrillic;
                        }
                        else if (pcp.Equals("CHT", StringComparison.OrdinalIgnoreCase) || pcp.Replace(" ", string.Empty).Equals("TraditionalChinese", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageChineseTraditional;
                        }
                        else if (pcp.Equals("CHS", StringComparison.OrdinalIgnoreCase) || pcp.Replace(" ", string.Empty).Equals("SimplifiedChinese", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageChineseSimplified;
                        }
                        else if (pcp.Equals("Korean", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageKorean;
                        }
                        else if (pcp.Equals("Japanese", StringComparison.OrdinalIgnoreCase))
                        {
                            pacCodePage = Pac.CodePageJapanese;
                        }
                        else if (!int.TryParse(pcp, out pacCodePage) || !Pac.IsValidCodePage(pacCodePage))
                        {
                            Console.WriteLine("Unknown pac code page '" + pcp + "' - using default code page");
                            pacCodePage = -1;
                        }
                    }
                }

                bool overwrite       = GetArgument(args, "overwrite").Equals("overwrite");
                bool removeTextForHi = GetArgument(args, "removetextforhi").Equals("removetextforhi");
                bool fixCommonErrors = GetArgument(args, "fixcommonerrors").Equals("fixcommonerrors");
                bool redoCasing      = GetArgument(args, "redocasing").Equals("redocasing");
                bool multipleReplace = GetArgument(args, "multiplereplace").Equals("multiplereplace");

                var patterns = Enumerable.Empty <string>();

                if (pattern.Contains(',') && !File.Exists(pattern))
                {
                    patterns = pattern.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(fn => fn.Trim()).Where(fn => fn.Length > 0);
                }
                else
                {
                    patterns = patterns.DefaultIfEmpty(pattern);
                }

                var files = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

                foreach (var p in patterns)
                {
                    var folderName = Path.GetDirectoryName(p);
                    var fileName   = Path.GetFileName(p);
                    if (string.IsNullOrEmpty(folderName) || string.IsNullOrEmpty(fileName))
                    {
                        folderName = inputFolder;
                        fileName   = p;
                    }
                    else if (!Path.IsPathRooted(folderName))
                    {
                        folderName = Path.Combine(inputFolder, folderName);
                    }
                    foreach (var fn in Directory.EnumerateFiles(folderName, fileName))
                    {
                        files.Add(fn); // silently ignore duplicates
                    }
                }

                var formats = SubtitleFormat.AllSubtitleFormats;
                foreach (var fileName in files)
                {
                    count++;

                    var fileInfo = new FileInfo(fileName);
                    if (fileInfo.Exists)
                    {
                        var            sub    = new Subtitle();
                        SubtitleFormat format = null;
                        bool           done   = false;

                        if (fileInfo.Extension.Equals(".mkv", StringComparison.OrdinalIgnoreCase) || fileInfo.Extension.Equals(".mks", StringComparison.OrdinalIgnoreCase))
                        {
                            using (var matroska = new MatroskaFile(fileName))
                            {
                                if (matroska.IsValid)
                                {
                                    var tracks = matroska.GetTracks();
                                    if (tracks.Count > 0)
                                    {
                                        foreach (var track in tracks)
                                        {
                                            if (track.CodecId.Equals("S_VOBSUB", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Console.WriteLine("{0}: {1} - Cannot convert from VobSub image based format!", fileName, targetFormat);
                                            }
                                            else if (track.CodecId.Equals("S_HDMV/PGS", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Console.WriteLine("{0}: {1} - Cannot convert from Blu-ray image based format!", fileName, targetFormat);
                                            }
                                            else
                                            {
                                                var ss = matroska.GetSubtitle(track.TrackNumber, null);
                                                format = Utilities.LoadMatroskaTextSubtitle(track, matroska, ss, sub);
                                                string newFileName = fileName;
                                                if (tracks.Count > 1)
                                                {
                                                    newFileName = fileName.Insert(fileName.Length - 4, "_" + track.TrackNumber + "_" + track.Language.Replace("?", string.Empty).Replace("!", string.Empty).Replace("*", string.Empty).Replace(",", string.Empty).Replace("/", string.Empty).Trim());
                                                }

                                                if (format.GetType() == typeof(AdvancedSubStationAlpha) || format.GetType() == typeof(SubStationAlpha))
                                                {
                                                    if (!AdvancedSubStationAlpha.NameOfFormat.Replace(" ", string.Empty).Equals(targetFormat, StringComparison.OrdinalIgnoreCase) &&
                                                        !SubStationAlpha.NameOfFormat.Replace(" ", string.Empty).Equals(targetFormat, StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        foreach (SubtitleFormat sf in formats)
                                                        {
                                                            if (sf.Name.Replace(" ", string.Empty).Equals(targetFormat, StringComparison.OrdinalIgnoreCase))
                                                            {
                                                                format.RemoveNativeFormatting(sub, sf);
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }

                                                BatchConvertSave(targetFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, newFileName, sub, format, overwrite, pacCodePage, targetFrameRate, removeTextForHi, fixCommonErrors, redoCasing, multipleReplace);
                                                done = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (!done && FileUtil.IsBluRaySup(fileName))
                        {
                            Console.WriteLine("Found Blu-Ray subtitle format");
                            ConvertBluRaySubtitle(fileName, targetFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate, removeTextForHi, fixCommonErrors, redoCasing, multipleReplace);
                            done = true;
                        }
                        if (!done && FileUtil.IsVobSub(fileName))
                        {
                            Console.WriteLine("Found VobSub subtitle format");
                            ConvertVobSubSubtitle(fileName, targetFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, overwrite, pacCodePage, targetFrameRate, removeTextForHi, fixCommonErrors, redoCasing, multipleReplace);
                            done = true;
                        }

                        if (!done && fileInfo.Length < 10 * 1024 * 1024) // max 10 mb
                        {
                            Encoding encoding;
                            format = sub.LoadSubtitle(fileName, out encoding, null, true);

                            if (format == null || format.GetType() == typeof(Ebu))
                            {
                                var ebu = new Ebu();
                                if (ebu.IsMine(null, fileName))
                                {
                                    ebu.LoadSubtitle(sub, null, fileName);
                                    format = ebu;
                                }
                            }
                            if (format == null)
                            {
                                var pac = new Pac();
                                if (pac.IsMine(null, fileName))
                                {
                                    pac.BatchMode = true;
                                    pac.CodePage  = pacCodePage;
                                    pac.LoadSubtitle(sub, null, fileName);
                                    format = pac;
                                }
                            }
                            if (format == null)
                            {
                                var cavena890 = new Cavena890();
                                if (cavena890.IsMine(null, fileName))
                                {
                                    cavena890.LoadSubtitle(sub, null, fileName);
                                    format = cavena890;
                                }
                            }
                            if (format == null)
                            {
                                var spt = new Spt();
                                if (spt.IsMine(null, fileName))
                                {
                                    spt.LoadSubtitle(sub, null, fileName);
                                    format = spt;
                                }
                            }
                            if (format == null)
                            {
                                var cheetahCaption = new CheetahCaption();
                                if (cheetahCaption.IsMine(null, fileName))
                                {
                                    cheetahCaption.LoadSubtitle(sub, null, fileName);
                                    format = cheetahCaption;
                                }
                            }
                            if (format == null)
                            {
                                var chk = new Chk();
                                if (chk.IsMine(null, fileName))
                                {
                                    chk.LoadSubtitle(sub, null, fileName);
                                    format = chk;
                                }
                            }
                            if (format == null)
                            {
                                var ayato = new Ayato();
                                if (ayato.IsMine(null, fileName))
                                {
                                    ayato.LoadSubtitle(sub, null, fileName);
                                    format = ayato;
                                }
                            }
                            if (format == null)
                            {
                                var capMakerPlus = new CapMakerPlus();
                                if (capMakerPlus.IsMine(null, fileName))
                                {
                                    capMakerPlus.LoadSubtitle(sub, null, fileName);
                                    format = capMakerPlus;
                                }
                            }
                            if (format == null)
                            {
                                var captionate = new Captionate();
                                if (captionate.IsMine(null, fileName))
                                {
                                    captionate.LoadSubtitle(sub, null, fileName);
                                    format = captionate;
                                }
                            }
                            if (format == null)
                            {
                                var ultech130 = new Ultech130();
                                if (ultech130.IsMine(null, fileName))
                                {
                                    ultech130.LoadSubtitle(sub, null, fileName);
                                    format = ultech130;
                                }
                            }
                            if (format == null)
                            {
                                var nciCaption = new NciCaption();
                                if (nciCaption.IsMine(null, fileName))
                                {
                                    nciCaption.LoadSubtitle(sub, null, fileName);
                                    format = nciCaption;
                                }
                            }
                            if (format == null)
                            {
                                var tsb4 = new TSB4();
                                if (tsb4.IsMine(null, fileName))
                                {
                                    tsb4.LoadSubtitle(sub, null, fileName);
                                    format = tsb4;
                                }
                            }
                            if (format == null)
                            {
                                var avidStl = new AvidStl();
                                if (avidStl.IsMine(null, fileName))
                                {
                                    avidStl.LoadSubtitle(sub, null, fileName);
                                    format = avidStl;
                                }
                            }
                            if (format == null)
                            {
                                var elr = new ELRStudioClosedCaption();
                                if (elr.IsMine(null, fileName))
                                {
                                    elr.LoadSubtitle(sub, null, fileName);
                                    format = elr;
                                }
                            }
                        }

                        if (format == null)
                        {
                            if (fileInfo.Length < 1024 * 1024) // max 1 mb
                            {
                                Console.WriteLine("{0}: {1} - input file format unknown!", fileName, targetFormat);
                            }
                            else
                            {
                                Console.WriteLine("{0}: {1} - input file too large!", fileName, targetFormat);
                            }
                        }
                        else if (!done)
                        {
                            BatchConvertSave(targetFormat, offset, targetEncoding, outputFolder, count, ref converted, ref errors, formats, fileName, sub, format, overwrite, pacCodePage, targetFrameRate, removeTextForHi, fixCommonErrors, redoCasing, multipleReplace);
                        }
                    }
                    else
                    {
                        Console.WriteLine("{0}: {1} - file not found!", count, fileName);
                        errors++;
                    }
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine();
                Console.WriteLine("Oops - an error occured: " + exception.Message);
                Console.WriteLine();
            }

            Console.WriteLine();
            Console.WriteLine("{0} file(s) converted", converted);
            Console.WriteLine();

            if (!Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux())
            {
                Console.Write(currentFolder + ">");
                NativeMethods.FreeConsole();
            }

            if (count == converted && errors == 0)
            {
                Environment.Exit(0);
            }
            else
            {
                Environment.Exit(1);
            }
        }
Example #33
0
        private void AddWaveform_Shown(object sender, EventArgs e)
        {
            Refresh();
            var audioTrackNames      = new List <string>();
            var mkvAudioTrackNumbers = new Dictionary <int, int>();
            int numberOfAudioTracks  = 0;

            if (labelVideoFileName.Text.Length > 1 && File.Exists(labelVideoFileName.Text))
            {
                if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                { // Choose for number of audio tracks in matroska files
                    MatroskaFile matroska = null;
                    try
                    {
                        matroska = new MatroskaFile(labelVideoFileName.Text);
                        if (matroska.IsValid)
                        {
                            foreach (var track in matroska.GetTracks())
                            {
                                if (track.IsAudio)
                                {
                                    numberOfAudioTracks++;
                                    if (track.CodecId != null && track.Language != null)
                                    {
                                        audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty));
                                    }
                                    else
                                    {
                                        audioTrackNames.Add("#" + track.TrackNumber);
                                    }

                                    mkvAudioTrackNumbers.Add(mkvAudioTrackNumbers.Count, track.TrackNumber);
                                }
                            }
                        }
                    }
                    finally
                    {
                        matroska?.Dispose();
                    }
                }
                else if (labelVideoFileName.Text.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase) || labelVideoFileName.Text.EndsWith(".m4v", StringComparison.OrdinalIgnoreCase))
                { // Choose for number of audio tracks in mp4 files
                    try
                    {
                        var mp4    = new MP4Parser(labelVideoFileName.Text);
                        var tracks = mp4.GetAudioTracks();
                        int i      = 0;
                        foreach (var track in tracks)
                        {
                            i++;
                            if (track.Name != null && track.Mdia != null && track.Mdia.Mdhd != null && track.Mdia.Mdhd.LanguageString != null)
                            {
                                audioTrackNames.Add(i + ":  " + track.Name + " - " + track.Mdia.Mdhd.LanguageString);
                            }
                            else if (track.Name != null)
                            {
                                audioTrackNames.Add(i + ":  " + track.Name);
                            }
                            else
                            {
                                audioTrackNames.Add(i.ToString(CultureInfo.InvariantCulture));
                            }
                        }
                        numberOfAudioTracks = tracks.Count;
                    }
                    catch
                    {
                        // ignored
                    }
                }

                // Choose audio track
                if (numberOfAudioTracks > 1)
                {
                    using (var form = new ChooseAudioTrack(audioTrackNames, _audioTrackNumber))
                    {
                        if (form.ShowDialog(this) == DialogResult.OK)
                        {
                            _audioTrackNumber = form.SelectedTrack;
                        }
                        else
                        {
                            DialogResult = DialogResult.Cancel;
                            return;
                        }
                    }
                }

                // check for delay in matroska files
                if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
                {
                    MatroskaFile matroska = null;
                    try
                    {
                        matroska = new MatroskaFile(labelVideoFileName.Text);
                        if (matroska.IsValid)
                        {
                            _delayInMilliseconds = (int)matroska.GetTrackStartTime(mkvAudioTrackNumbers[_audioTrackNumber]);
                        }
                    }
                    catch
                    {
                        _delayInMilliseconds = 0;
                    }
                    finally
                    {
                        matroska?.Dispose();
                    }
                }

                buttonRipWave_Click(null, null);
            }
            else if (_wavFileName != null)
            {
                FixWaveOnly();
            }
        }
        public static List <SubtitleEvent> ReadMatroskaBluraySup(string inputFile, int tracknumber)
        {
            List <SubtitleEvent> events = new List <SubtitleEvent>();
            var matroska             = new MatroskaFile(inputFile);
            var matroskaSubtitleInfo = matroska.GetTracks()[tracknumber];

            var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, (p, t) => Console.WriteLine("Progress: {0} out of {1}", p, t));

            var subtitles         = new List <BluRaySupParser.PcsData>();
            var log               = new StringBuilder();
            var clusterStream     = new MemoryStream();
            var lastPalettes      = new Dictionary <int, List <PaletteInfo> >();
            var lastBitmapObjects = new Dictionary <int, List <BluRaySupParser.OdsData> >();

            foreach (var p in sub)
            {
                byte[] buffer = p.GetData(matroskaSubtitleInfo);
                if (buffer != null && buffer.Length > 2)
                {
                    clusterStream.Write(buffer, 0, buffer.Length);
                    if (ContainsBluRayStartSegment(buffer))
                    {
                        if (subtitles.Count > 0 && subtitles[subtitles.Count - 1].StartTime == subtitles[subtitles.Count - 1].EndTime)
                        {
                            subtitles[subtitles.Count - 1].EndTime = (long)((p.Start - 1) * 90.0);
                        }
                        clusterStream.Position = 0;
                        var list = BluRaySupParser.ParseBluRaySup(clusterStream, log, true, lastPalettes, lastBitmapObjects);
                        foreach (var sup in list)
                        {
                            sup.StartTime = (long)((p.Start - 1) * 90.0);
                            sup.EndTime   = (long)((p.End - 1) * 90.0);
                            subtitles.Add(sup);

                            // fix overlapping
                            if (subtitles.Count > 1 && sub[subtitles.Count - 2].End > sub[subtitles.Count - 1].Start)
                            {
                                subtitles[subtitles.Count - 2].EndTime = subtitles[subtitles.Count - 1].StartTime - 1;
                            }
                        }
                        clusterStream = new MemoryStream();
                    }
                }
                else if (subtitles.Count > 0)
                {
                    var lastSub = subtitles[subtitles.Count - 1];
                    if (lastSub.StartTime == lastSub.EndTime)
                    {
                        lastSub.EndTime = (long)((p.Start - 1) * 90.0);
                        if (lastSub.EndTime - lastSub.StartTime > 1000000)
                        {
                            lastSub.EndTime = lastSub.StartTime;
                        }
                    }
                }
            }

            clusterStream.Dispose();

            int i = 0;

            foreach (var line in subtitles)
            {
                var bitmap = BluRaySupParser.SupDecoder.DecodeImage(line.PcsObjects[0], line.BitmapObjects[0], line.PaletteInfos);

                var image_data = ImageUtil.ConvertToPngBytes(bitmap);
                events.Add(new SubtitleEvent()
                {
                    StartTime = TimeSpan.FromMilliseconds(line.StartTime / 90.0), EndTime = TimeSpan.FromMilliseconds(line.EndTime / 90.0), MimeType = "image/png", Image = image_data, Origin = line.PcsObjects[0].Origin
                });
                i++;
            }
            return(events);
        }