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); }
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); } }
public void MatroskaTestValid() { string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_MKV_SRT.mkv"); using (var parser = new MatroskaFile(fileName)) { Assert.IsTrue(parser.IsValid); } }
public void MatroskaTestInvalid() { string fileName = Path.Combine(Directory.GetCurrentDirectory(), "sample_TS_with_graphics.ts"); using (var parser = new MatroskaFile(fileName)) { Assert.IsFalse(parser.IsValid); } }
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"); } }
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); } }
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"); } }
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); }
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"); } }
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 } }
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); }
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); }
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); } }
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); }
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); }
public void Close() { m_File = null; m_DataSource = null; }
public static bool IsMatroskaFile(string fileName) { var validator = new MatroskaFile(fileName); return(validator.IsValid); }
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; }
public void Open(string filename) { m_DataSource = new FileDataSource(filename, "r"); m_File = new MatroskaFile(m_DataSource); m_File.readFile(); }
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); }
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; }
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; }
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(); } }
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); } }
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); }