private static void ProcessJson(ProgressReporter progressReporter, List <DiskTitle> diskTitles, ref StringBuilder json, ref HandBrakeJsonType jsonType, ref ProcessingState processingState, Stopwatch stopwatch, string line) { Match match = Regex.Match(line, "^(\\S.+):\\s*{"); if (match.Success) { // check the old version if (json != null) { processingState = ProcessJsonString(progressReporter, diskTitles, json, jsonType, processingState, stopwatch); } // start of json json = new StringBuilder(); json.Append("{ "); string type = match.Groups[1].Value; switch (type) { case "Version": jsonType = HandBrakeJsonType.Version; break; case "Progress": jsonType = HandBrakeJsonType.Progress; break; case "JSON Title Set": jsonType = HandBrakeJsonType.TitleSet; break; } } else if (json != null) { json.Append(line); } }
private static void ProcessProgress(ProgressReporter progressReporter, ref int lastProgress, ref long progressStarted, string line, bool suppressRemaining) { long progressNow = DateTimeOffset.Now.ToUnixTimeMilliseconds(); String[] progItems = Regex.Split(line, "^.{4}:|,"); int currentProgress = int.Parse(progItems[2]); if (lastProgress > currentProgress) { // need to reset progressStarted = progressNow; } lastProgress = currentProgress; // calc progress double pmsec = currentProgress / (double)(progressNow - progressStarted); int total = int.Parse(progItems[3]); int remain = total - currentProgress; int msToGo = (int)(remain / pmsec); progressReporter.MaxProgress = total; progressReporter.CurrentProgress = currentProgress; if (!suppressRemaining) { progressReporter.Remaining = Utils.GetDuration(msToGo / 1000); } }
/* -- Methods -- */ public PreferencesPage() { _encoderService = ((App)Application.Current).EncoderService; ProgressReporter = ((App)Application.Current).ProgressReporter; DataContext = this; InitializeComponent(); ProgressReporter.PropertyChanged += ProgressReporter_PropertyChanged; }
public ProgressPage() { ProgressReporter = ((App)Application.Current).ProgressReporter; ProgressReporter.PropertyChanged += PropertyReporter_PropertyChanged; stopwatch.Start(); InitializeComponent(); DataContext = ProgressReporter; JobListBox.ItemsSource = ProgressReporter.JobQueue.GetJobs(); LogRichTextBox.Document = ProgressReporter.LogDocument; }
internal static void CopyFile(string sourcePath, string destPath, ProgressReporter progressReporter) { byte[] buffer = new byte[1024 * 1024]; // 1MB buffer progressReporter.CurrentTask = $"Copying '{sourcePath}' to '{destPath}'"; progressReporter.MaxProgress = 100.0; progressReporter.CurrentProgress = 0.0; if (Directory.Exists(sourcePath)) { throw new Exception("SourcePath is a directory"); } if (Directory.Exists(destPath)) { throw new Exception("DestPath is a directory"); } bool canceled = false; using (FileStream source = new FileStream(sourcePath, FileMode.Open, FileAccess.Read)) { long fileLength = source.Length; using (FileStream dest = new FileStream(destPath, FileMode.Create, FileAccess.Write)) { long totalBytes = 0; int currentBlockSize = 0; while ((currentBlockSize = source.Read(buffer, 0, buffer.Length)) > 0) { totalBytes += currentBlockSize; double percentage = totalBytes * 100.0 / fileLength; dest.Write(buffer, 0, currentBlockSize); progressReporter.CurrentProgress = percentage; if (progressReporter.Shutdown) { canceled = true; break; } } } } if (canceled) { File.Delete(destPath); } }
private void Application_Startup(object sender, StartupEventArgs e) { ProgressReporter = new ProgressReporter(); EncoderService.SetProgressReporter(this.ProgressReporter); bool aIsNewInstance = false; myMutex = new Mutex(true, "MovieEncoderApplication", out aIsNewInstance); if (!aIsNewInstance) { // Bring main window to front Process proc = Process.GetCurrentProcess(); Process[] processes = Process.GetProcessesByName(proc.ProcessName); foreach (Process appProcess in processes) { if (appProcess.MainWindowHandle != proc.MainWindowHandle) { SetForegroundWindow(appProcess.MainWindowHandle); break; } } App.Current.Shutdown(); } }
private static ProcessingState ProcessJsonString(ProgressReporter progressReporter, List <DiskTitle> diskTitles, StringBuilder json, HandBrakeJsonType jsonType, ProcessingState processingState, Stopwatch stopwatch) { if (json == null) { return(processingState); } switch (jsonType) { case HandBrakeJsonType.Version: HBVersion jVersion = JsonSerializer.Deserialize <HBVersion>(json.ToString()); //JToken jVersion = JToken.Parse(json.ToString()); progressReporter.AppendLog($"Using {jVersion.Name} {jVersion.VersionString} {jVersion.Arch}", LogEntryType.Debug); break; case HandBrakeJsonType.Progress: // process HBProgress jProgress = JsonSerializer.Deserialize <HBProgress>(json.ToString()); if (jProgress.State == "WORKING") { if (processingState != ProcessingState.Encoding) { progressReporter.CurrentTask = "Encoding"; processingState = ProcessingState.Encoding; } } else if (jProgress.State == "SCANNING") { if (processingState != ProcessingState.Scanning) { progressReporter.CurrentTask = "Scanning"; processingState = ProcessingState.Scanning; } } else if (jProgress.State == "MUXING") { if (processingState != ProcessingState.Muxing) { progressReporter.CurrentTask = "Muxing"; processingState = ProcessingState.Muxing; } // TODO Remove Debug.WriteLine(json.ToString()); } else { // TODO Remove Debug.WriteLine(json.ToString()); } if (stopwatch.ElapsedMilliseconds > 1000) { progressReporter.CurrentProgress = (jProgress.GetCurrentProgress() * 100); progressReporter.Remaining = jProgress.GetETAString(); stopwatch.Restart(); } break; case HandBrakeJsonType.TitleSet: HBTitleSet jTitleSet = JsonSerializer.Deserialize <HBTitleSet>(json.ToString()); int mainFeature = jTitleSet.MainFeature; foreach (HBTitleSet.TitleListData jTitle in jTitleSet.TitleList) { DiskTitle diskTitle = new DiskTitle { TitleName = jTitle.Name, FullMKVPath = jTitle.Path }; diskTitle.FileName = Path.GetFileName(diskTitle.FullMKVPath); diskTitle.TitleIndex = jTitle.Index; if (mainFeature == -1 || diskTitle.TitleIndex == mainFeature) { diskTitle.MainMovie = true; } diskTitle.HorizontalResolution = jTitle.Geometry.Height; diskTitle.VerticalResolution = jTitle.Geometry.Width; diskTitle.VideoCodec = jTitle.VideoCodec; diskTitle.Seconds = (jTitle.Duration.Hours * 60 * 60) + (jTitle.Duration.Minutes * 60) + jTitle.Duration.Seconds; diskTitle.Chapters = jTitle.ChapterList.Length; diskTitles.Add(diskTitle); } break; } return(processingState); }
internal bool Encode(string inputFile, int titleIndex, string outputFile, ProgressReporter progressReporter) { bool success = false; StopRunningProcess(); wasKilled = false; string outputFormat = MovieOutputType == OutputType.MP4 ? "av_mp4" : "av_mkv"; string subtitles = ForceSubtitles == true ? "--subtitle scan --subtitle-forced" : ""; string cmdParams = $"--preset-import-file \"{HandBrakeProfileFile}\" -i \"{inputFile}\" -o \"{outputFile}\" --format {outputFormat} {subtitles} --json"; if (titleIndex != 0) { cmdParams += $" --title {titleIndex}"; } handBrakeProcess = new Process { StartInfo = new ProcessStartInfo(HandBrakeCliExePath, cmdParams) { CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardInput = true, RedirectStandardError = true, UseShellExecute = false }, EnableRaisingEvents = true }; StringBuilder error = new StringBuilder(); List <DiskTitle> diskTitles = new List <DiskTitle>(); StringBuilder json = null; HandBrakeJsonType jsonType = HandBrakeJsonType.Version; ProcessingState processingState = ProcessingState.None; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); handBrakeProcess.OutputDataReceived += new DataReceivedEventHandler( delegate(object sender, DataReceivedEventArgs e) { // append the new data to the data already read-in string line = e.Data; if (line == null) { return; } ProcessJson(progressReporter, diskTitles, ref json, ref jsonType, ref processingState, stopwatch, line); } ); handBrakeProcess.ErrorDataReceived += new DataReceivedEventHandler( delegate(object sender, DataReceivedEventArgs e) { error.Append(e.Data); error.Append("\r\n"); progressReporter.AppendLog(e.Data, LogEntryType.Trace); } ); handBrakeProcess.Start(); handBrakeProcess.BeginOutputReadLine(); handBrakeProcess.BeginErrorReadLine(); handBrakeProcess.WaitForExit(); if (handBrakeProcess != null) { handBrakeProcess.CancelOutputRead(); handBrakeProcess.CancelErrorRead(); success = handBrakeProcess.ExitCode == 0; } ProcessJsonString(progressReporter, diskTitles, json, jsonType, processingState, stopwatch); if (!success) { if (!wasKilled) { progressReporter.AppendLog($"Output from Handbrake\r\n{error}", LogEntryType.Debug); } File.Delete(outputFile); } return(success); }
internal List <DiskTitle> Scan(string file, int titleIndex, bool allTitles, ProgressReporter progressReporter) { List <DiskTitle> diskTitles = new List <DiskTitle>(); StopRunningProcess(); wasKilled = false; string cmdParams = $"-i \"{file}\" --scan --no-dvdnav --json"; if (!allTitles) { cmdParams += " --main-feature"; } else { cmdParams += $" --title {titleIndex}"; } handBrakeProcess = new Process { StartInfo = new ProcessStartInfo(HandBrakeCliExePath, cmdParams) { CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false }, EnableRaisingEvents = true }; bool success = false; StringBuilder json = null; HandBrakeJsonType jsonType = HandBrakeJsonType.Version; ProcessingState processingState = ProcessingState.None; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); handBrakeProcess.OutputDataReceived += new DataReceivedEventHandler( delegate(object sender, DataReceivedEventArgs e) { string line = e.Data; if (line == null) { return; } ProcessJson(progressReporter, diskTitles, ref json, ref jsonType, ref processingState, stopwatch, line); } ); StringBuilder error = new StringBuilder(); handBrakeProcess.ErrorDataReceived += new DataReceivedEventHandler( delegate(object sender, DataReceivedEventArgs e) { error.Append(e.Data); error.Append("\r\n"); progressReporter.AppendLog(e.Data, LogEntryType.Trace); } ); handBrakeProcess.Start(); handBrakeProcess.BeginOutputReadLine(); handBrakeProcess.BeginErrorReadLine(); handBrakeProcess.WaitForExit(); if (handBrakeProcess != null) { handBrakeProcess.CancelOutputRead(); handBrakeProcess.CancelErrorRead(); success = handBrakeProcess.ExitCode == 0; } ProcessJsonString(progressReporter, diskTitles, json, jsonType, processingState, stopwatch); if (!success && !wasKilled) { progressReporter.AppendLog($"Output from Handbrake\r\n{error}", LogEntryType.Debug); } return(diskTitles); }
public void SetReporter(ProgressReporter progressReporter) { this.progressReporter = progressReporter; }
internal List <DiskTitle> GetDiskTitles(string drive, ProgressReporter progressReporter) { StopRunningProcess(); makeMKVProcess = new Process { StartInfo = new ProcessStartInfo(MakeMKVConExePath, "-r --cache=1 --progress=-stdout info dev:" + drive) }; makeMKVProcess.StartInfo.CreateNoWindow = true; makeMKVProcess.StartInfo.RedirectStandardOutput = true; makeMKVProcess.StartInfo.RedirectStandardInput = true; makeMKVProcess.StartInfo.UseShellExecute = false; makeMKVProcess.EnableRaisingEvents = true; StringBuilder output = new StringBuilder(); string line = null; string title = null; string lastError = null; int titleCount = 0; DiskTitle[] diskTitles = null; int lastProgress = -1; long progressStarted = 0; makeMKVProcess.OutputDataReceived += new DataReceivedEventHandler( delegate(object sender, DataReceivedEventArgs e) { Debug.WriteLine(e.Data); line = e.Data; if (line == null) { return; } if (line.StartsWith("TCOUNT:")) { titleCount = int.Parse(Regex.Split(line, ":")[1]); diskTitles = new DiskTitle[titleCount]; } else if (line.StartsWith("CINFO:")) { String[] cInfo = Regex.Split(line, "^.{3,5}:|,"); if (cInfo[1].Equals("2")) { title = cInfo[3].Replace("\"", ""); } } else if (line.StartsWith("TINFO:")) { String[] tInfo = Regex.Split(line.Replace("\"", ""), "^.{3,5}:|,"); int titleIdx = int.Parse(tInfo[1]); DiskTitle diskTitle = diskTitles[titleIdx]; if (diskTitle == null) { diskTitle = new DiskTitle(); diskTitles[titleIdx] = diskTitle; diskTitle.Drive = drive; diskTitle.TitleIndex = titleIdx; diskTitle.TitleName = title; } switch (tInfo[2]) { case "2": diskTitle.TitleName = tInfo[4].Replace("\"", ""); break; case "8": diskTitle.Chapters = int.Parse(tInfo[4].Replace("\"", "")); break; case "9": String[] timeParts = Regex.Split(tInfo[4].Replace("\"", ""), ":"); int seconds = int.Parse(timeParts[timeParts.Length - 1]); if (timeParts.Length >= 2) { int minutes = int.Parse(timeParts[timeParts.Length - 2]); seconds += minutes * 60; } if (timeParts.Length >= 3) { int hours = int.Parse(timeParts[timeParts.Length - 3]); seconds += hours * 60 * 60; } diskTitle.Seconds = seconds; break; case "19": String resolution = tInfo[4]; MatchCollection mRes = Regex.Matches(resolution, "(\\d+)x(\\d+).*"); if (mRes.Count >= 3) { diskTitle.HorizontalResolution = int.Parse(mRes[1].Value); diskTitle.VerticalResolution = int.Parse(mRes[2].Value); } break; case "11": diskTitle.Bytes = long.Parse(tInfo[4].Replace("\"", "")); break; case "24": diskTitle.TitleIndex = int.Parse(tInfo[4].Replace("\"", "")); break; case "27": diskTitle.FileName = tInfo[4].Replace("\"", ""); break; } } else if (line.StartsWith("SINFO:")) { String[] sInfo = Regex.Split(line.Replace("\"", ""), "^.{3,5}:|,"); int titleIdx = int.Parse(sInfo[1]); DiskTitle diskTitle = diskTitles[titleIdx]; switch (sInfo[3]) { case "19": String resolution = sInfo[5]; MatchCollection mRes = Regex.Matches(resolution, "(\\d+)x(\\d+).*"); if (mRes.Count >= 3) { diskTitle.HorizontalResolution = int.Parse(mRes[1].Value); diskTitle.VerticalResolution = int.Parse(mRes[2].Value); } break; } } else if (line.StartsWith("MSG:")) { String[] msg = Regex.Split(line.Replace("\"", ""), "^.{3,5}:|,"); int errorCode = int.Parse(msg[1]); if (errorCode >= 2000 && errorCode < 3000) // == "2024") { lastError = msg[4]; progressReporter.AppendLog(lastError, LogEntryType.Error); } else { progressReporter.AppendLog(msg[4].Replace("\"", ""), LogEntryType.Debug); } } else if (line.StartsWith("PRGT:")) { String[] progItems = Regex.Split(line, "^.{4}:|,"); progressReporter.CurrentTask = progItems[3].Replace("\"", ""); } else if (line.StartsWith("PRGC:")) { String[] progItems = Regex.Split(line, "^.{4}:|,"); progressReporter.Remaining = progItems[3].Replace("\"", ""); } else if (line.StartsWith("PRGV:")) { // update progess but not time to go ProcessProgress(progressReporter, ref lastProgress, ref progressStarted, line, true); } } ); makeMKVProcess.Start(); makeMKVProcess.BeginOutputReadLine(); makeMKVProcess.WaitForExit(); if (makeMKVProcess != null) { makeMKVProcess.CancelOutputRead(); } if (lastError != null) { throw new JobException(lastError); } List <DiskTitle> titles = new List <DiskTitle>(); if (diskTitles != null) { foreach (DiskTitle diskTitle in diskTitles) { if (diskTitle != null) { titles.Add(diskTitle); } } } return(titles); }
internal bool Backup(DiskTitle diskTitle, ProgressReporter progressReporter) { string dirName = DirectoryName(diskTitle.TitleName); string outDir = Path.Combine(MakeMKVOutPath, Path.GetFileNameWithoutExtension(dirName)); string finalOutFile = Path.Combine(outDir, diskTitle.FileName); diskTitle.FullMKVPath = finalOutFile; // test this hasn't been done before if (File.Exists(finalOutFile)) { throw new Exception("Looks like MakeMKV was already run. Found file \"" + finalOutFile + "\". Will not create a backup."); } Directory.CreateDirectory(outDir); StopRunningProcess(); string cmd = "-r --decrypt --noscan --progress=-stdout --progress=-stdout --cache=1024 mkv dev:" + diskTitle.Drive + " " + diskTitle.TitleIndex + " \"" + outDir + "\""; makeMKVProcess = new Process { StartInfo = new ProcessStartInfo(MakeMKVConExePath, cmd) }; makeMKVProcess.StartInfo.CreateNoWindow = true; makeMKVProcess.StartInfo.RedirectStandardOutput = true; makeMKVProcess.StartInfo.RedirectStandardInput = true; makeMKVProcess.StartInfo.UseShellExecute = false; makeMKVProcess.EnableRaisingEvents = true; StringBuilder output = new StringBuilder(); int lastProgress = -1; long progressStarted = 0; makeMKVProcess.OutputDataReceived += new DataReceivedEventHandler( delegate(object sender, DataReceivedEventArgs e) { string line = e.Data; if (line == null) { return; } //Debug.WriteLine(line); if (line.StartsWith("PRGV:")) { ProcessProgress(progressReporter, ref lastProgress, ref progressStarted, line, false); } else if (line.StartsWith("MSG:")) { string[] msg = Regex.Split(line, ","); int msgCode = int.Parse(msg[2]); //if (msgParts[4].Contains("\"Saving %1 titles into directory %2\"")) if (msgCode == 5014) { progressReporter.CurrentTask = msg[3].Replace("\"", ""); } else { if (msgCode >= 2000 && msgCode < 3000) { progressReporter.AppendLog(msg[3].Replace("\"", ""), LogEntryType.Error); } else { progressReporter.AppendLog(msg[3].Replace("\"", ""), LogEntryType.Debug); } //progressReporter.AppendLog(msg[3].Replace("\"", ""), LogEntryType.Info); } } else if (line.StartsWith("PRGT:")) { String[] progItems = Regex.Split(line, "^.{4}:|,"); progressReporter.CurrentTask = progItems[3].Replace("\"", ""); } else if (line.StartsWith("PRGC:")) { String[] progItems = Regex.Split(line, "^.{4}:|,"); progressReporter.Remaining = progItems[3].Replace("\"", ""); } } ); makeMKVProcess.Start(); makeMKVProcess.BeginOutputReadLine(); makeMKVProcess.WaitForExit(); if (makeMKVProcess != null) { makeMKVProcess.CancelOutputRead(); } return(true); }
// TODO public void SetProgressReporter(ProgressReporter progress) { this.progressReporter = progress; this.jobQueue = this.progressReporter.JobQueue; }