コード例 #1
0
        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);
            }
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        /* -- Methods -- */

        public PreferencesPage()
        {
            _encoderService  = ((App)Application.Current).EncoderService;
            ProgressReporter = ((App)Application.Current).ProgressReporter;

            DataContext = this;
            InitializeComponent();

            ProgressReporter.PropertyChanged += ProgressReporter_PropertyChanged;
        }
コード例 #4
0
        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;
        }
コード例 #5
0
ファイル: Utils.cs プロジェクト: ben-owen/media-encoder
        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);
            }
        }
コード例 #6
0
ファイル: App.xaml.cs プロジェクト: ben-owen/media-encoder
        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();
            }
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
ファイル: Job.cs プロジェクト: ben-owen/media-encoder
 public void SetReporter(ProgressReporter progressReporter)
 {
     this.progressReporter = progressReporter;
 }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
 // TODO
 public void SetProgressReporter(ProgressReporter progress)
 {
     this.progressReporter = progress;
     this.jobQueue         = this.progressReporter.JobQueue;
 }