private string GetMovieTitle(DiskTitle diskTitle) { // strip any non ASCII chars char[] title = diskTitle.TitleName.ToCharArray(); char[] newTitle = new char[title.Length]; int n = 0; for (int c = 0; c < title.Length; c++) { char ch = title[c]; if (ch < 128) { if (ch == ':' || ch == '\\') { newTitle[n++] = '-'; } else { newTitle[n++] = ch; } } } string sNewTitle = new string(newTitle, 0, n); return(sNewTitle.Replace(" - Blu-ray", "")); }
public override bool RunJob(JobQueue jobRunner) { List <DiskTitle> diskTitles = handBrakeService.Scan(driveName, 0, true, progressReporter); if (diskTitles.Count > 0) { // order them diskTitles.Sort((o1, o2) => { if (o1.Seconds > o2.Seconds) { return(-1); } else if (o1.Seconds == o2.Seconds) { return(0); } else { return(1); } }); DiskTitle mainTitle = diskTitles.Find((o) => o.MainMovie == true); if (mainTitle != null) { diskTitles.Remove(mainTitle); if (!backupAll) { diskTitles.Clear(); diskTitles.Add(mainTitle); } else { diskTitles.Insert(0, mainTitle); } } else if (!backupAll) { // pick the 1st mainTitle = diskTitles[0]; diskTitles.Clear(); diskTitles.Add(mainTitle); } int n = 0; foreach (DiskTitle title in diskTitles) { if (title.Seconds >= minMovieLen) { string cleanTitle = GetMovieTitle(title); jobRunner.AddJob(new EncodeMovieJob(handBrakeService, driveName, cleanTitle, title.TitleIndex, n++, false)); } } return(true); } return(false); }
private static int ComparDiskTitleByDuration(DiskTitle x, DiskTitle y) { if (x == null) { if (y == null) { return(0); } else { return(-1); } } else { if (y == null) { return(1); } else { if (x.Seconds < y.Seconds) { return(-1); } else if (x.Seconds == y.Seconds) { return(0); } else { return(1); } } } }
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 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); }