public void Process(MediaConversionOptions aOptions) { Directory.CreateDirectory(IntermediateEpisodeFolder); Directory.CreateDirectory(ReadyToEditEpisodeFolder); List <Task> tasks = new List <Task>(); if (!aOptions.disableSubtitles) { foreach (var subtitleTrack in mSubtitleInfos) { tasks.Add(Task.Run(() => ProcessTrack(subtitleTrack, aOptions))); } } if (!aOptions.disableAudio) { foreach (var audioTrack in mAudioInfos) { tasks.Add(Task.Run(() => ProcessTrack(audioTrack, aOptions))); } } if (!aOptions.disableVideo) { foreach (var videoTrack in mVideoInfos) { tasks.Add(Task.Run(() => ProcessTrack(videoTrack, aOptions))); } } Task.WaitAll(tasks.ToArray()); }
public MkvInfo(string aFile, List <string> aTracks, MediaConversionOptions aOptions) { mVideoInfos = new List <VideoInfo>(); mAudioInfos = new List <AudioInfo>(); mSubtitleInfos = new List <SubtitleInfo>(); FileName = aFile; EpisodeName = Path.GetFileNameWithoutExtension(aFile); IntermediateEpisodeFolder = Path.Combine(aOptions.rootPath, "2_Intermediate", EpisodeName); ReadyToEditEpisodeFolder = Path.Combine(aOptions.rootPath, "3_ReadyToEdit", EpisodeName); IntermediateFilePath = Path.Combine(IntermediateEpisodeFolder, Path.GetFileNameWithoutExtension(aFile)); FinalFilePath = Path.Combine(ReadyToEditEpisodeFolder, Path.GetFileNameWithoutExtension(aFile)); foreach (var track in aTracks) { // Get Track properties var properties = track.Split("| + ").ToList(); properties.RemoveAt(0); //Empty Line if (properties[2].StartsWith("Track type: video")) { mVideoInfos.Add(new VideoInfo(properties)); } else if (properties[2].StartsWith("Track type: audio")) { mAudioInfos.Add(new AudioInfo(properties)); } else if (properties[2].StartsWith("Track type: subtitles")) { mSubtitleInfos.Add(new SubtitleInfo(properties)); } } }
//////////////////////////////////////////////////////////////// // Subtitles void ProcessTrack(SubtitleInfo aTrack, MediaConversionOptions aOptions) { //////////////////////////////////////////////////////////////// // Extract sup files var supPath = $"{IntermediateFilePath}_Track_{aTrack.mMediaInfo.TrackNumber}.sup"; RunProcess("mkvextract", $"\"{FileName}\" tracks {aTrack.mMediaInfo.TrackNumber}:{supPath}").WaitAndCheck(); //////////////////////////////////////////////////////////////// // Convert sup files to SRT if (!aOptions.disableSubtitleConversion) { string pgsApp = "\"C:\\Program Files\\PgsToSrt\\PgsToSrt.dll\""; string srtFile = Path.ChangeExtension(supPath, ".srt").Replace("2_Intermediate", "3_ReadyToEdit"); RunProcess("dotnet", $"{pgsApp} --input {supPath} --output {srtFile} --tesseractlanguage eng").WaitAndCheck(); } }
//////////////////////////////////////////////////////////////// // Video void ProcessTrack(VideoInfo aTrack, MediaConversionOptions aOptions) { var codecSanitized = $"({aTrack.mMediaInfo.TrackCodec.Replace('\\', '/').Split('/').Join('_')})"; var langSanitized = $"({aTrack.mMediaInfo.Language.Replace('\\', '/').Split('/').Join('_')})"; //////////////////////////////////////////////////////////////// // Extract our video track (id: 0 all files) var mkvPath = $"{IntermediateFilePath}_Lang_{langSanitized}_Codec_{codecSanitized}_Track_{aTrack.mMediaInfo.TrackNumber}.mkv"; RunProcess("mkvmerge", $"-o {mkvPath} --no-audio --no-subtitles {FileName}").WaitAndCheck(); //////////////////////////////////////////////////////////////// // Convert MKV to MP4 if (!aOptions.disableVideoConversion) { var mp4Path = $"{FinalFilePath}_Lang_{aTrack.mMediaInfo.Language}_Codec_{codecSanitized}_Track_{aTrack.mMediaInfo.TrackNumber}.mp4"; RunProcess("ffmpeg", $"-i {mkvPath} -c copy {mp4Path}").WaitAndCheck(); } }
//////////////////////////////////////////////////////////////// // Audio void ProcessTrack(AudioInfo aTrack, MediaConversionOptions aOptions) { var codecSanitized = $"({aTrack.mMediaInfo.TrackCodec.Replace('\\', '/').Split('/').Join('_')})"; var langSanitized = $"({aTrack.mMediaInfo.Language.Replace('\\', '/').Split('/').Join('_')})"; var codec = cBlurayCodecToOutputCodec[aTrack.mMediaInfo.TrackCodec]; //////////////////////////////////////////////////////////////// // Extract out Bluray track var blurayAudioPath = $"{IntermediateFilePath}_Lang_{langSanitized}_Codec_{codecSanitized}_Track_{aTrack.mMediaInfo.TrackNumber}.truehd"; RunProcess("mkvextract", $"\"{FileName}\" tracks {aTrack.mMediaInfo.TrackNumber}:{blurayAudioPath}").WaitAndCheck(); //////////////////////////////////////////////////////////////// // Convert Bluray audio tracks to FLAC if (!aOptions.disableAudioConversion) { var flacPath = Path.ChangeExtension(blurayAudioPath, ".flac").Replace("2_Intermediate", "3_ReadyToEdit"); RunProcess("ffmpeg", $"-analyzeduration 30000000 -acodec {codec} -i {blurayAudioPath} -vn -sn -acodec flac {flacPath}").WaitAndCheck(); } }
static MkvInfo GetMkvInfo(string aFile, MediaConversionOptions aOptions) { var builder = new StringBuilder(); var process = MkvInfo.RunProcess("mkvinfo", aFile, builder); process.WaitForExit(); var tracks = builder .ToString() .Split("\r\n") .ToList() .RemoveAllOf(line => line.StartsWith("| + EBML void: ")) .Join() .Split("|+ ") .First(line => line.StartsWith("Tracks")) .Split("| + Track\r\n") .ToList(); // First one is just the beginning of the track section. tracks.RemoveAt(0); return(new MkvInfo(aFile, tracks, aOptions)); }
static void Main(string[] args) { //var files = GetFileList(); // //Console.WriteLine($"File Count: {files.Count}"); //Console.WriteLine($"Files"); // //var changedNames = new List<string>(); // //foreach (var episode in Enumerable.Range(1, files.Count())) // changedNames.Add(files[episode - 1].Replace(Path.GetFileName(files[episode - 1]), cNameRemapper[episode])); // //var filesToProcess = new List<string>(); // //foreach (var episode in Enumerable.Range(0, files.Count())) //{ // var normalizedFileName = Path.GetFileName(changedNames[episode]).Replace(" - ", "-").Replace(' ', '_'); // filesToProcess.Add(Path.Combine("D:\\BlackCloverFanEdit\\1_ToBeProcessed\\", normalizedFileName)); // // var copyingTo = Path.Combine("D:\\Kodi\\TV\\Black Clover", Path.GetFileName(changedNames[episode])); // Console.WriteLine($" Processing: {files[episode]}"); // Console.WriteLine($" Copying file from {files[episode]} to {copyingTo}"); // Directory.CreateDirectory(Path.GetDirectoryName(copyingTo)); // Directory.CreateDirectory(Path.GetDirectoryName(filesToProcess.Back())); // File.Copy(files[episode], copyingTo); // // Console.WriteLine($" Moving file from {files[episode]} to {filesToProcess.Back()}"); // File.Move(files[episode], filesToProcess.Back()); //} // these are the available options, note that they set the variables var mediaOptions = new MediaConversionOptions(); var optionsSet = new OptionSet { { "r|root=", "Root path that contains the folders we'll be processing.", r => mediaOptions.rootPath = r }, { "dv|no-video", "Don't do video processing", h => mediaOptions.disableVideo = h != null }, { "dvc|no-video-conversion", "Don't do video conversion", h => mediaOptions.disableVideoConversion = h != null }, { "da|no-audio", "Don't do audio processing", h => mediaOptions.disableAudio = h != null }, { "dac|no-audio-conversion", "Don't do video conversion", h => mediaOptions.disableAudioConversion = h != null }, { "ds|no-subtitle", "Don't do subtitle processing", h => mediaOptions.disableSubtitles = h != null }, { "dsc|no-subtitle-conversion", "Don't do subtitle conversion", h => mediaOptions.disableSubtitleConversion = h != null }, }; try { // parse the command line var extra = optionsSet.Parse(args); } catch (OptionException e) { // output some error message Console.Write("greet: "); Console.WriteLine(e.Message); Console.WriteLine("Try `greet --help' for more information."); return; } var codecSet = new SortedSet <string>(); foreach (var file in GetFileListToProcess(mediaOptions)) { var mkvInfo = GetMkvInfo(file, mediaOptions); foreach (var videoTrack in mkvInfo.mVideoInfos) { codecSet.Add(videoTrack.mMediaInfo.TrackCodec); } foreach (var audioTrack in mkvInfo.mAudioInfos) { codecSet.Add(audioTrack.mMediaInfo.TrackCodec); } foreach (var subtitleTrack in mkvInfo.mSubtitleInfos) { codecSet.Add(subtitleTrack.mMediaInfo.TrackCodec); } mkvInfo.Process(mediaOptions); } }
static List <string> GetFileListToProcess(MediaConversionOptions aOptions) { return(Directory.GetFiles(Path.Combine(aOptions.rootPath, "1_ToBeProcessed")).OrderBy(file => file).ToList()); }