Esempio n. 1
0
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (ConsoleOutput.Data == null)
                {
                    return;
                }

                if (!String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    StdOut = ConsoleOutput.Data;

                    // % calculation is a based on rough estimates of number of file to parse and number of segments
                    if (StdOut.Contains("Segment no."))
                    {
                        int start = StdOut.IndexOf("Segment no.") + "Segment no.".Length;
                        int end   = StdOut.IndexOf(":", start);

                        int.TryParse(StdOut.Substring(start, end - start), out _segmentCount); // Get the segment count, this will keep updating upto max)
                    }

                    if (StdOut.Contains("Writing output file")) // Final stage, now look for the 100%
                    {
                        _finalStage = true;
                    }

                    if (StdOut.Contains("0-100%:") && StdOut.Contains("...100"))
                    {
                        if (_finalStage)     // look for success in final stage
                        {
                            _success = true; // we actually have success
                        }
                        else // Percentage status hack, until we are at final stage (not 100% reliable)
                        {
                            _noOf100++; // we actually have success
                            _jobStatus.PercentageComplete = _noOf100 / _segmentCount * 100;
                            UpdateETAByPercentageComplete();
                        }
                    }

                    // Always check in the end
                    if (StdOut.Contains("PROCESSING FAILED!")) // look for  failure criteria
                    {
                        _success = false;
                    }
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (ConsoleOutput.Data == null)
                {
                    return;
                }

                if (!String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    StdOut = ConsoleOutput.Data;

                    // Check for percentage complete - First part is done via Streams (0% - 50%)
                    if (StdOut.Contains("Percentage complete :") && StdOut.Contains("%"))
                    {
                        int StartPos = StdOut.IndexOf("Percentage complete :") + "Percentage complete :".Length;
                        int EndPos   = StdOut.IndexOf("%");

                        // Parse the % complete directly
                        float perc;
                        float.TryParse(StdOut.Substring(StartPos, EndPos - StartPos).Trim(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out perc);

                        // Backup, if the % is not reported and we have a duration
                        _jobStatus.PercentageComplete = perc / 2; // 0 to 50%
                        UpdateETAByPercentageComplete();
                    }

                    // Check for percentage complete - Second part done via TsMuxer (50% - 100%)
                    if (StdOut.Contains("% complete"))
                    {
                        int   StartPos = StdOut.IndexOf("TSMuxer -->") + "TSMuxer -->".Length;
                        int   EndPos   = StdOut.IndexOf("%");
                        float Perc;
                        float.TryParse(StdOut.Substring(StartPos, EndPos - StartPos).Trim(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out Perc);
                        _jobStatus.PercentageComplete = 50 + Perc / 2; // 50 to 100%
                        UpdateETAByPercentageComplete();
                    }

                    // Always check in the end
                    if (StdOut.Contains("RemuxTiVOStreams Successful!!")) // look for success criteria
                    {
                        _success = true;
                    }
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }
Esempio n. 3
0
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut;
                int    StartPos, EndPos;
                float  perc;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (ConsoleOutput.Data == null)
                {
                    return;
                }

                if (!String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    StdOut = ConsoleOutput.Data;
                    if (StdOut.Contains("/100"))
                    {
                        EndPos = StdOut.IndexOf("/100");
                        for (StartPos = EndPos - 1; StartPos > -1; StartPos--)
                        {
                            if ((!char.IsNumber(StdOut[StartPos])) && (StdOut[StartPos] != '.') && (StdOut[StartPos] != ' '))
                            {
                                StartPos++;
                                break;
                            }
                        }
                        float.TryParse(StdOut.Substring(StartPos, EndPos - StartPos).Trim(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out perc);
                        _jobStatus.PercentageComplete = perc;
                        UpdateETAByPercentageComplete();
                    }

                    if (StdOut.Contains("Error importing"))
                    {
                        _success = false;
                    }

                    if (StdOut.Contains("Error writing data (Invalid argument): -1 blocks to write but 0 blocks written"))
                    {
                        _success            = false;
                        _unrecoverableError = true; // This is just going to hang forever in this loop, terminate the process
                    }
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }
Esempio n. 4
0
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut;
                int    StartPos, EndPos;
                float  Perc;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (ConsoleOutput.Data == null)
                {
                    return;
                }

                if (!String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    StdOut = ConsoleOutput.Data;
                    if (StdOut.Contains("Progress:") && StdOut.Contains("%"))
                    {
                        EndPos = StdOut.IndexOf("%");
                        for (StartPos = EndPos - 1; StartPos > -1; StartPos--)
                        {
                            if (!char.IsNumber(StdOut[StartPos]))
                            {
                                StartPos++;
                                break;
                            }
                        }
                        float.TryParse(StdOut.Substring(StartPos, EndPos - StartPos).Trim(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out Perc);
                        _jobStatus.PercentageComplete = Perc;
                    }

                    if (StdOut.Contains("Finished writing") || StdOut.Contains("completed")) // new ones say finished wirting, updating says completed
                    {
                        _success = true;
                    }
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }
Esempio n. 5
0
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut;
                int    StartPos, EndPos;
                float  perc;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (ConsoleOutput.Data == null)
                {
                    return;
                }

                if (!String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    StdOut = ConsoleOutput.Data;

                    if (StdOut.Contains("Progress:") && StdOut.Contains("%")) // look for progress
                    {
                        EndPos   = StdOut.IndexOf("%");
                        StartPos = StdOut.IndexOf("Progress:") + "Progress:".Length;
                        float.TryParse(StdOut.Substring(StartPos, EndPos - StartPos).Trim(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out perc);
                        _jobStatus.PercentageComplete = perc;
                        UpdateETAByPercentageComplete();
                    }

                    if (StdOut.Contains("Muxing took")) // look for  success criteria
                    {
                        _success = true;
                    }
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }
Esempio n. 6
0
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut;
                int    StartPos, EndPos;
                float  Perc;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (ConsoleOutput.Data == null)
                {
                    return;
                }

                if (!String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    StdOut = ConsoleOutput.Data;
                    if (StdOut.Contains("Encoding:") && StdOut.Contains(",") && StdOut.Contains("%"))
                    {
                        EndPos = StdOut.IndexOf("%");
                        for (StartPos = EndPos - 1; StartPos > -1; StartPos--)
                        {
                            if ((!char.IsNumber(StdOut[StartPos])) && (StdOut[StartPos] != '.') && (StdOut[StartPos] != ' '))
                            {
                                StartPos++;
                                break;
                            }
                        }
                        float.TryParse(StdOut.Substring(StartPos, EndPos - StartPos).Trim(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out Perc);
                        _jobStatus.PercentageComplete = Perc;

                        if (StdOut.Contains("ETA ") && StdOut.Contains(")"))
                        {
                            string ETAStr = "";
                            for (int idx = StdOut.IndexOf("ETA "); idx < StdOut.IndexOf(")"); idx++)
                            {
                                if (char.IsNumber(StdOut[idx]))
                                {
                                    ETAStr += StdOut[idx];
                                }
                            }
                            int ETAVal = 0;
                            int.TryParse(ETAStr, out ETAVal);
                            int Hours   = ETAVal / 10000;
                            int Minutes = (ETAVal - (Hours * 10000)) / 100;
                            int Seconds = ETAVal - (Hours * 10000) - (Minutes * 100);
                            UpdateETA(Hours, Minutes, Seconds);
                        }
                    }

                    if (StdOut.Contains("task 1 of 2"))
                    {
                        _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file - Pass 1");
                    }
                    else if (StdOut.Contains("task 2 of 2"))
                    {
                        _jobStatus.CurrentAction = Localise.GetPhrase("Converting video file - Pass 2");
                    }

                    if (StdOut.Contains("Rip done!") || StdOut.Contains("Encode done!"))
                    {
                        _success = true;
                    }

                    if (StdOut.Contains("HandBrake has exited"))
                    {
                        parseCompleted = true;
                    }

                    if (StdOut.Contains("Intel Quick Sync Video support:")) // Check for hardware drivers enabled (quick sync)
                    {
                        string answer = StdOut.Substring(StdOut.LastIndexOf(':') + 1).ToLower().Trim();
                        if (answer == "yes")
                        {
                            quickSyncEnabled = true;
                        }
                    }

                    // TODO: Need a reliable way to check for OpenCL version since the formats are not consistent and sometimes the numbers are missing
                    // - OpenCL version: 1.2 AMD-APP (1445.5)
                    // - OpenCL version: 1.2
                    // - OpenCL version: 1.1
                    // - OpenCL device type: GPU
                    // - OpenCL version: 1.1 CUDA
                    // OpenCL: library not available

                    // TODO: Intel QuickSync hardware hang detection hack. Is there a better way to do this?
                    if (quickSyncEnabled) // Sometimes hardware quicksync intel drivers are unstable and hang, detect hang condition
                    {
                        if (_lastPercentage != _jobStatus.PercentageComplete)
                        {
                            _lastPercentage = _jobStatus.PercentageComplete;
                            _lastUpdate     = DateTime.Now;
                        }
                        else if (_lastUpdate.AddSeconds(GlobalDefs.HANDBRAKE_HARDWARE_HANG_PERIOD_DETECT) < DateTime.Now)  // Check for no progress
                        {
                            _jobLog.WriteEntry(this, "Hardware encoding appears to have hung, no progress in the last " + GlobalDefs.HANDBRAKE_HARDWARE_HANG_PERIOD_DETECT.ToString() + " seconds.\r\nThis is likely due to an unstable Intel Display Driver. Try updating or using a stable Intel Display Driver.\r\nTerminating process.", Log.LogEntryType.Error);
                            _unrecoverableError = true; // We are hung terminate the process
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut, CropRes;
                int    StartPos, EndPos;
                float  perc;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (ConsoleOutput.Data == null)
                {
                    return;
                }

                if (!String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    StdOut = ConsoleOutput.Data;
                    if ((StdOut.Contains("-vf crop=")) && (StdOut.Contains(")")))
                    {
                        StartPos = StdOut.IndexOf("-vf crop=") + 9;
                        EndPos   = StdOut.IndexOf(")", StartPos);
                        if (EndPos > 0)
                        {
                            CropRes = StdOut.Substring(StartPos, EndPos - StartPos);
                            if (_CropResults.ContainsKey(CropRes))
                            {
                                _CropResults[CropRes]++;
                            }
                            else
                            {
                                _CropResults.Add(CropRes, 1);
                            }
                        }
                    }

                    //Update % complete
                    if ((StdOut.Contains("%)")) && (StdOut.Contains("(")))
                    {
                        EndPos = StdOut.IndexOf("%)");
                        for (StartPos = EndPos - 1; StartPos > -1; StartPos--)
                        {
                            if (StdOut[StartPos] == '(')
                            {
                                StartPos++;
                                break;
                            }
                        }
                        if (float.TryParse(StdOut.Substring(StartPos, EndPos - StartPos).Trim(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out perc))
                        {
                            _jobStatus.PercentageComplete = perc;
                            UpdateETAByPercentageComplete();
                        }
                    }

                    //Update ETA -- always 0

                    /*if ((StdOut.Contains("Trem:")) && (StdOut.Contains("min")))
                     * {
                     *  string ETAStr = "";
                     *  for (int idx = StdOut.IndexOf("Trem:") + "Trem".Length + 1; idx < StdOut.Length - 1; idx++)
                     *  {
                     *      if (char.IsNumber(StdOut[idx]))
                     *      {
                     *          ETAStr += StdOut[idx];
                     *      }
                     *      else if (char.IsWhiteSpace(StdOut[idx]))
                     *      {
                     *      }
                     *      else
                     *      {
                     *          break;
                     *      }
                     *  }
                     *  int ETAVal = 0;
                     *  int.TryParse(ETAStr, out ETAVal);
                     *  int Hours = ETAVal / 60;
                     *  int Minutes = ETAVal - (Hours * 60);
                     *  UpdateETA(Hours, Minutes, 0);
                     * }*/
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }
Esempio n. 8
0
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut;
                int    StartPos, EndPos;
                float  perc;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (ConsoleOutput.Data == null)
                {
                    return;
                }

                if (!String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    StdOut = ConsoleOutput.Data;
                    if ((StdOut.Contains("%)")) && (StdOut.Contains("(")))
                    {
                        EndPos = StdOut.IndexOf("%)");
                        for (StartPos = EndPos - 1; StartPos > -1; StartPos--)
                        {
                            if (StdOut[StartPos] == '(')
                            {
                                StartPos++;
                                break;
                            }
                        }
                        if (float.TryParse(StdOut.Substring(StartPos, EndPos - StartPos).Trim(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out perc))
                        {
                            if (perc > _jobStatus.PercentageComplete) // Sometimes Mencoder keeps jumping % complete, this to prevent it
                            {
                                _jobStatus.PercentageComplete = perc;
                            }
                        }
                    }

                    if ((StdOut.Contains("Trem:")) && (StdOut.Contains("min")))
                    {
                        string ETAStr = "";
                        for (int idx = StdOut.IndexOf("Trem:") + "Trem".Length + 1; idx < StdOut.Length - 1; idx++)
                        {
                            if (char.IsNumber(StdOut[idx]))
                            {
                                ETAStr += StdOut[idx];
                            }
                            else if (char.IsWhiteSpace(StdOut[idx]))
                            {
                            }
                            else
                            {
                                break;
                            }
                        }
                        int ETAVal = 0;
                        int.TryParse(ETAStr, out ETAVal);

                        if (ETAVal > 0) // sometimes it's zero in which case use by % instead
                        {
                            int Hours   = ETAVal / 60;
                            int Minutes = ETAVal - (Hours * 60);
                            UpdateETA(Hours, Minutes, 0);
                        }
                        else
                        {
                            UpdateETAByPercentageComplete();
                        }
                    }

                    if (_oldVersion) // Old Version of Mencoder uses a different output for success
                    {
                        if ((StdOut.Contains("Writing AVI index")) || (StdOut.Contains("Flushing video frames")))
                        {
                            _success = true;
                        }
                    }
                    else if ((StdOut.Contains("Writing index")) || (StdOut.Contains("Flushing video frames")))
                    {
                        _success = true;
                    }
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }
Esempio n. 9
0
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut;
                int    StartPos, EndPos;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (ConsoleOutput.Data == null)
                {
                    return;
                }

                if (!String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    StdOut = ConsoleOutput.Data;
                    if (StdOut.Contains("Duration:") && StdOut.Contains(",") && (_Duration < 1))
                    {
                        StartPos  = StdOut.IndexOf("Duration:") + "Duration:".Length;
                        EndPos    = StdOut.IndexOf(",", StartPos);
                        _Duration = TimeStringToSecs(StdOut.Substring(StartPos, EndPos - StartPos));
                        _jobLog.WriteEntry("Video duration=" + _Duration, Log.LogEntryType.Debug);
                    }
                    else if (StdOut.Contains("frame=") && StdOut.Contains("time="))
                    {
                        StartPos = StdOut.IndexOf("time=") + "time=".Length;
                        EndPos   = StdOut.IndexOf(" ", StartPos);
                        float timeCoded = TimeStringToSecs(StdOut.Substring(StartPos, EndPos - StartPos));
                        if (timeCoded > 0)
                        {
                            _jobStatus.PercentageComplete = (float)(timeCoded / _Duration * 100);
                            UpdateETAByPercentageComplete();
                        }
                    }

                    // Capture average rate of change in duplicate frames
                    if (StdOut.Contains("dup="))
                    {
                        StartPos = StdOut.IndexOf("dup=") + "dup=".Length;
                        EndPos   = StdOut.IndexOf(" ", StartPos);

                        Array.Resize(ref _dupArray, _dupArray.Length + 1); // increase the array size by 1 to store new value
                        double dup = 0;
                        double.TryParse(StdOut.Substring(StartPos, EndPos - StartPos), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out dup);

                        _dupArray[_dupArray.Length - 1] = dup - _lastDup; // We are storing the change in dup value to calcuate the average rate of change in duplicate packets
                        _lastDup = dup;
                    }

                    // Capture average rate of change in dropped frames
                    if (StdOut.Contains("drop="))
                    {
                        StartPos = StdOut.IndexOf("drop=") + "drop=".Length;
                        EndPos   = StdOut.IndexOf(" ", StartPos);

                        Array.Resize(ref _dropArray, _dropArray.Length + 1); // increase the array size by 1 to store new value
                        double drop = 0;
                        double.TryParse(StdOut.Substring(StartPos, EndPos - StartPos), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out drop);

                        _dropArray[_dropArray.Length - 1] = drop - _lastDrop; // We are storing the change in dup value to calcuate the average rate of change in duplicate packets
                        _lastDrop = drop;
                    }

                    // TODO: We need to track down more errors from av_interleaved_write_frame() and ffmpeg and put them here, newer builds report global headers even if 1 frame is encoded. The only other option is to look at the return value of ffmpeg for an error, but then wtv files are often cut and this may not work with them.
                    // av_interleaved_write_frame(): Invalid argument
                    // av_interleaved_write_frame(): Invalid data found when processing input
                    if (StdOut.Contains(@"av_interleaved_write_frame(): Invalid"))
                    {
                        _encodeError = true;
                    }

                    // use audio bitstream filter 'aac_adtstoasc' to fix it
                    if (StdOut.Contains("use") && StdOut.Contains("bitstream filter") && StdOut.Contains("aac_adtstoasc"))
                    {
                        _aacadtstoascError = true;
                    }

                    // [wtv @ 0000000003ffab20] H.264 bitstream malformed, no startcode found, use the h264_mp4toannexb bitstream filter (-bsf h264_mp4toannexb)
                    // [mpegts @ 02bdd680] H.264 bitstream malformed, no startcode found, use the video bitstream filter 'h264_mp4toannexb' to fix it ('-bsf:v h264_mp4toannexb' option with ffmpeg)
                    if (StdOut.Contains("use") && StdOut.Contains("bitstream filter") && StdOut.Contains("h264_mp4toannexb"))
                    {
                        _h264mp4toannexbError = true;
                    }

                    if (StdOut.Contains("non monotonically increasing"))
                    {
                        _muxError = true;
                    }

                    if ((StdOut.Contains("global headers")) && (StdOut.Contains("muxing overhead"))) // This is always the last line printed, so any errors happen before this is printed
                    {
                        _success = true && !FatalError;
                    }
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }
Esempio n. 10
0
        protected override void OutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs ConsoleOutput)
        {
            try
            {
                string StdOut;
                int    StartPos, EndPos;
                float  perc;

                base.OutputHandler(sendingProcess, ConsoleOutput);
                if (String.IsNullOrEmpty(ConsoleOutput.Data))
                {
                    return;
                }

                StdOut = ConsoleOutput.Data;

                try
                {
                    //Parse the Duration details if we can get it
                    if (StdOut.Contains("Duration:") && StdOut.Contains(",") && (duration <= 0))
                    {
                        StartPos = StdOut.IndexOf("Duration:") + "Duration:".Length;
                        EndPos   = StdOut.IndexOf(",", StartPos);
                        duration = TimeStringToSecs(StdOut.Substring(StartPos, EndPos - StartPos));
                        _jobLog.WriteEntry(this, "Comskip detected video duration = " + duration.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                    }
                }
                catch (Exception ex)
                {
                    _jobLog.WriteEntry(this, "Comskip error parsing Duration. String:" + StdOut + "\n" + ex.ToString(), Log.LogEntryType.Warning);
                }

                if (StdOut.Contains("Donator")) // Is this a donator version?
                {
                    donator = true;
                }

                if (StdOut.Contains("%")) // Old version of Comskip and new version sometimes doesn't report %, we need to calculate it by other methods
                {
                    EndPos = StdOut.IndexOf("%");
                    for (StartPos = EndPos - 1; StartPos > -1; StartPos--)
                    {
                        if (!char.IsNumber(StdOut[StartPos]))
                        {
                            StartPos++;
                            break;
                        }
                    }

                    // Parse the % complete directly
                    float.TryParse(StdOut.Substring(StartPos, EndPos - StartPos).Trim(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out perc);

                    // Backup, if the % is not reported and we have a duration
                    if ((perc <= 0) && duration > 0)
                    {
                        // Calculate the % based on time processed vs total duration
                        StartPos = 0;
                        EndPos   = StdOut.IndexOf("-") - 1;
                        TimeSpan time;
                        TimeSpan.TryParse(StdOut.Substring(StartPos, EndPos - StartPos), out time);
                        float timeProcessed = (float)time.TotalSeconds;
                        perc = timeProcessed / duration * 100;
                    }

                    if (perc > 0 && perc <= 100) // old version sometimes reports time duration which can lead to > 100%
                    {
                        if (firstRun)            //sometime Comskip makes 2 passes, but sometimes only 1
                        {
                            _jobStatus.CurrentAction = Localise.GetPhrase("Comskip advertisement scan - Pass 1");
                            if (perc < lastPerc)
                            {
                                firstRun = false;
                            }
                            else
                            {
                                lastPerc = perc;
                                _jobStatus.PercentageComplete = perc;
                                UpdateETAByPercentageComplete();
                            }
                        }
                        else
                        {
                            _jobStatus.CurrentAction      = Localise.GetPhrase("Comskip advertisement scan - Pass 2");
                            _jobStatus.PercentageComplete = perc;
                            UpdateETAByPercentageComplete();
                        }
                    }
                    else
                    {
                        _jobStatus.CurrentAction      = Localise.GetPhrase("Comskip advertisement scan - Pass 1");
                        _jobStatus.PercentageComplete = 0;
                    }
                }
            }
            catch (Exception e)
            {
                _jobLog.WriteEntry(this, "ERROR Processing Console Output.\n" + e.ToString(), Log.LogEntryType.Error);
            }
        }