示例#1
0
        /// <summary>
        /// Handle eac3 conversions for mencoder
        /// TODO: This function is redundant and incorrectly written, handbrake, ffmpeg and mencoder are able to handle eac3 audio why do we need this?
        /// </summary>
        private bool ConvertMencoderEAC3()
        {
            string audioStream = "";

            _jobStatus.PercentageComplete = 100; //all good by default
            _jobStatus.ETA = "";

            if ((_videoFile.AudioCodec != "e-ac-3") && (_videoFile.AudioCodec != "eac3"))
                return true;
            
            // Only supports MP4, MKV and AVI
            if ((_extension != ".mp4") && (_extension != ".mkv") && (_extension != ".avi"))
                return true;

            _jobStatus.CurrentAction = Localise.GetPhrase("Converting E-AC3");
            _jobLog.WriteEntry(this, ("Converting E-AC3"), Log.LogEntryType.Information);

            // Convert EAC3 file
            string eac3toParams;
            string audiop = _audioParams.Trim();
            if (audiop.Contains("faac") || audiop.Contains("libfaac") || audiop.Contains("aac"))
            {
                audioStream = Path.Combine(_workingPath, Path.GetFileNameWithoutExtension(SourceVideo) + "_AUDIO.mp4");
                eac3toParams = Util.FilePaths.FixSpaces(SourceVideo) + " " + Util.FilePaths.FixSpaces(audioStream) + " -384";
            }
            else // TODO: what about other audio formats?
            {
                audioStream = Path.Combine(_workingPath, Path.GetFileNameWithoutExtension(SourceVideo) + "_AUDIO.ac3");
                eac3toParams = Util.FilePaths.FixSpaces(SourceVideo) + " " + Util.FilePaths.FixSpaces(audioStream) + " -384";
            }

            FileIO.TryFileDelete(audioStream); // Clean before starting
            Eac3To eac3to = new AppWrapper.Eac3To(eac3toParams, _jobStatus, _jobLog);
            eac3to.Run();
            if (!eac3to.Success)
            {
                FileIO.TryFileDelete(audioStream); // Clean
                _jobLog.WriteEntry(this, ("E-AC3 conversion unsuccessful"), Log.LogEntryType.Error);
                _jobStatus.ErrorMsg = "E-AC3 conversion unsuccessful";
                _jobStatus.PercentageComplete = 0;
                return false; // something went wrong
            }

            // Mux into destination 
            if ((_extension == ".mp4") || (_extension == ".m4v"))
            {
                _jobLog.WriteEntry(this, ("Muxing E-AC3 using MP4Box"), Log.LogEntryType.Information);
                string mp4boxParams = " -keep-sys -keep-all -add " + FilePaths.FixSpaces(audioStream) + " " + FilePaths.FixSpaces(_convertedFile);
                _jobStatus.PercentageComplete = 0; //reset
                _jobStatus.ETA = "";
                MP4Box mp4box = new MP4Box(mp4boxParams, _jobStatus, _jobLog);
                mp4box.Run();
                if (!mp4box.Success || _jobStatus.PercentageComplete < GlobalDefs.ACCEPTABLE_COMPLETION) // check for incomplete output or process issues
                {
                    FileIO.TryFileDelete(audioStream);
                    _jobLog.WriteEntry(this, ("E-AC3 muxing using MP4Box failed at") + " " + _jobStatus.PercentageComplete.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Error);
                    _jobStatus.ErrorMsg = "E-AC3 muxing using MP4Box failed";
                    _jobStatus.PercentageComplete = 0; // something went wrong with the process
                    return false;
                }
            }
            else if (_extension == ".mkv")
            {
                _jobLog.WriteEntry(this, ("Muxing E-AC3 using MKVMerge"), Log.LogEntryType.Information);
                string remuxedFile = Path.Combine(_workingPath, Path.GetFileNameWithoutExtension(_convertedFile) + "_REMUX.mkv");
                FileIO.TryFileDelete(remuxedFile);
                string mkvmergeParams = "--clusters-in-meta-seek --compression -1:none " + FilePaths.FixSpaces(_convertedFile) + " --compression -1:none " + FilePaths.FixSpaces(audioStream) + " -o " + FilePaths.FixSpaces(remuxedFile);
                _jobStatus.PercentageComplete = 0; //reset
                _jobStatus.ETA = "";
                MKVMerge mkvmerge = new MKVMerge(mkvmergeParams, _jobStatus, _jobLog);
                mkvmerge.Run();
                if (!mkvmerge.Success)
                {
                    FileIO.TryFileDelete(audioStream);
                    FileIO.TryFileDelete(remuxedFile);
                    _jobLog.WriteEntry(this, ("Muxing E-AC3 using MKVMerge failed"), Log.LogEntryType.Error);
                    _jobStatus.ErrorMsg = "Muxing E-AC3 using MKVMerge failed";
                    _jobStatus.PercentageComplete = 0; // something went wrong with the process
                    return false;
                }

                try
                {
                    _jobLog.WriteEntry(this, ("Moving MKVMerge muxed E-AC3"), Log.LogEntryType.Information);
                    FileIO.TryFileDelete(_convertedFile);
                    File.Move(remuxedFile, _convertedFile);
                    _jobStatus.PercentageComplete = 100; //proxy for job done since mkvmerge doesn't report
                    _jobStatus.ETA = "";
                }
                catch (Exception e)
                {
                    FileIO.TryFileDelete(audioStream);
                    FileIO.TryFileDelete(remuxedFile);
                    _jobLog.WriteEntry(this, ("Unable to move MKVMerge remuxed E-AC3 file") + " " + remuxedFile + "\r\nError : " + e.ToString(), Log.LogEntryType.Error);
                    _jobStatus.PercentageComplete = 0;
                    _jobStatus.ErrorMsg = "Unable to move MKVMerge remuxed E-AC3 file";
                    return false;
                }
            }
            else
            {
                _jobStatus.PercentageComplete = 0; //reset
                _jobStatus.ETA = "";
                _jobLog.WriteEntry(this, ("Muxing E-AC3 using FFMPEGRemux"), Log.LogEntryType.Information);
                double fps = 0;
                double.TryParse(_fps, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out fps);
                RemuxExt remuxFile = new RemuxExt(_convertedFile, _workingPath, (fps <= 0 ? _videoFile.Fps : fps), _jobStatus, _jobLog, _remuxTo); // Use output FPS if it exists otherwise the source file FPS (since it has not changed)
                if (remuxFile.FfmpegRemux(audioStream))
                {
                    _convertedFile = remuxFile.RemuxedFile;
                }
                else
                {
                    FileIO.TryFileDelete(audioStream);
                    _jobLog.WriteEntry(this, ("Error Muxing E-AC3 using FFMPEGRemux"), Log.LogEntryType.Error);
                    _jobStatus.PercentageComplete = 0;
                    _jobStatus.ErrorMsg = "Error Muxing E-AC3 using FFMPEGRemux";
                    return false;
                }
            }

            FileIO.TryFileDelete(audioStream); // Clean up
            _jobLog.WriteEntry(this, ("Finished EAC3 conversion, file size [KB]") + " " + (FileIO.FileSize(_convertedFile) / 1024).ToString("N", System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);

            return true;
        }
示例#2
0
        public bool Convert() // THE MAIN CONVERSION ROUTINE
        {
            if (_unsupported) return false;

            _jobLog.WriteEntry(this, "Main conversion routine DEBUG", Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Source Video File : " + _videoFile.SourceVideo, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Extension : " + _extension, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Remux To : " + _remuxTo, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Auto Enable Hardware Encoding : " + _preferHardwareEncoding.ToString(), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "2 Pass : "******"Fixed Resolution : " + _fixedResolution.ToString(), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Skip Cropping (profile + conversion option) : " + _skipCropping.ToString(), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Video Audio Delay : " + _videoFile.AudioDelay.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Manual Audio Delay : " + _toolAudioDelay.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Skip Audio Delay : " + _audioDelay, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Max Width : " + _maxWidth.ToString(), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "User Quality : " + _userQuality.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Audio Track : " + _videoFile.AudioTrack.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Start Trim : " + _startTrim.ToString(), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Stop Trim : " + _endTrim.ToString(), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Output FPS : " + _fps, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Auto DeInterlacing (profile + conversion option): " + _autoDeInterlacing.ToString(), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Working Path : " + _workingPath, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Temp Converted File : " + _convertedFile, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Final Converted File : " + _renameConvertedFileWithOriginalName, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, ("Source video file, file size [KB]") + " " + (FileIO.FileSize(SourceVideo) / 1024).ToString("N", System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);

            // WAY TO BUILD THE COMMAND LINE
            // GeneralParameters + InputFile + VideoOptions + AudioOptions + OutputFile

            // GENERAL PARAMETERS
            _jobLog.WriteEntry(this, ("Setting up General conversion parameters :") + " " + _generalParams, Log.LogEntryType.Information);
            AppendParameters(_generalParams); // General Parameters

            // Set the DRC before the input file for some encoders like ffmpeg
            if (_drc)
            {
                if ((_videoFile.AudioCodec == "ac-3") || (_videoFile.AudioCodec == "ac3") || (_videoFile.AudioCodec != "e-ac-3") || (_videoFile.AudioCodec != "eac3")) // DRC only applies to AC3 audio
                {
                    _jobLog.WriteEntry(this, ("Setting up PreDRC"), Log.LogEntryType.Information);

                    if (_audioParams.ToLower().Contains("copy"))
                        _jobLog.WriteEntry(this, ("Copy Audio stream detected, skipping DRC settings"), Log.LogEntryType.Warning);
                    else
                        SetAudioPreDRC(); // do this before we BEFORE setting the input filename
                }
                else
                    _jobLog.WriteEntry(this, ("Non AC3 Source Audio, DRC not applicable"), Log.LogEntryType.Information);
            }

            // INPUT FILE
            _jobLog.WriteEntry(this, ("Setting up input file name parameters"), Log.LogEntryType.Information);
            SetInputFileName(); // Input Filename

            // VIDEO PARAMETERS
            _jobLog.WriteEntry(this, ("Setting up video conversion parameters :") + " " + _videoParams, Log.LogEntryType.Information);
            AppendParameters(_videoParams); // Video Parameters

            // Get the value of the preset width before we start modifying
            _isPresetVideoWidth = IsPresetVideoWidth();
            _jobLog.WriteEntry(this, "Is preset video size -> " + _isPresetVideoWidth.ToString(), Log.LogEntryType.Information);

            // Set the start and end trim parameters (after the video parameters) if trimming is not already done
            if ((_startTrim != 0) || (_endTrim != 0))
            {
                bool trimFile = false;
                _jobLog.WriteEntry(this, "Setting up trim parameters", Log.LogEntryType.Information);
                
                //Sanity checking if we need to trim
                if (_startTrim != 0)
                {
                    if (_startTrim < _videoFile.Duration)
                        trimFile = true;
                    else
                    {
                        _jobLog.WriteEntry(this, "Start trim (" + _startTrim.ToString() + ") greater than file duration (" + _videoFile.Duration.ToString(System.Globalization.CultureInfo.InvariantCulture) + "). Skipping start trimming.", Log.LogEntryType.Warning);
                        _startTrim = 0;
                    }
                }

                if (_endTrim != 0)
                {
                    int encDuration = (((int)_videoFile.Duration) - _endTrim) - (_startTrim); // by default _startTrim is 0
                    if (encDuration > 0)
                        trimFile = true;
                    else
                    {
                        _jobLog.WriteEntry(this, "End trim (" + _endTrim.ToString() + ") + Start trim (" + _startTrim.ToString() + ") greater than file duration (" + _videoFile.Duration.ToString(System.Globalization.CultureInfo.InvariantCulture) + "). Skipping end trimming.", Log.LogEntryType.Warning);
                        _endTrim = 0;
                    }
                }

                if (trimFile)
                    SetVideoTrim(); // Set Trim Parameters
                else
                    _jobLog.WriteEntry(this, "Start trim and end trim skipped. Skipping trimming.", Log.LogEntryType.Warning);
            }

            // Set the interlacing filters as the first filter in the chain, before processing anything
            SetVideoDeInterlacing();

            // Set the pre cropping BEFORE scaling, filter chain rule
            _jobLog.WriteEntry(this, "Setting up crop parameters", Log.LogEntryType.Information);
            SetVideoCropping();

            //Set the scaling
            if (!_fixedResolution && !_isPresetVideoWidth)
            {
                int VideoWidth = _videoFile.Width;

                _jobLog.WriteEntry(this, ("Checking if video resizing required"), Log.LogEntryType.Information);
                if ((_videoFile.CropWidth > 0) && (_videoFile.CropWidth < _videoFile.Width))
                {
                    VideoWidth = _videoFile.CropWidth;
                }
                // If we do not need to scale, don't
                if (VideoWidth > _maxWidth)
                {
                    _jobLog.WriteEntry(this, ("Setting up video resize parameters"), Log.LogEntryType.Information);
                    SetVideoResize(); // Set Resize parameters
                }
            }
            else
                _jobLog.WriteEntry(this, ("Fixed resolution video, no resizing"), Log.LogEntryType.Information);

            // Sometimes we need to set the Aspect Ratio as the last parameter in the video filter chain (e.g. with libxvid)
            _jobLog.WriteEntry(this, ("Setting up aspect ratio if required"), Log.LogEntryType.Information);
            SetVideoAspectRatio();

            // Adjust the bitrate to compensate for resizing and cropping
            _jobLog.WriteEntry(this, ("Setting up bitrate and quality parameters"), Log.LogEntryType.Information);
            AdjustResizeCropBitrateQuality();
            if (_userQuality <= 0.1)
                _userQuality = 0.1;

            // If we using quality instead of bitrate
            if (ConstantVideoQuality && (_userQuality > 2))
                _userQuality = 2;
            
            // Update the BitRate/Quality parameters
            SetVideoBitrateAndQuality();

            // Set the output framerate if required
            SetVideoOutputFrameRate();

            // AUDIO PARAMETERS
            _jobLog.WriteEntry(this, ("Setting up audio conversion parameters :") + " " + _audioParams, Log.LogEntryType.Information);
            AppendParameters(_audioParams); // Audio Parameters

            // Select the audio language specified by the user if multiple audio languages exist
            if ((!String.IsNullOrEmpty(_videoFile.RequestedAudioLanguage) || _encoderChooseBestAudioTrack) && (_videoFile.FFMPEGStreamInfo.AudioTracks > 1)) // check if we were requested to isolate a language manually and if there is more than one audio track
            {
                _jobLog.WriteEntry(this, ("Selecting Audio Track :") + " " + _videoFile.AudioTrack.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Information);
                SetAudioLanguage(); // Select the right Audio Track if required, do this before we AFTER setting the audio parameters
            }
            else
                _jobLog.WriteEntry(this, ("Skipping over Audio Track selection, no language request or only one Audio Track found"), Log.LogEntryType.Information);

            // Set the volume
            if (_volume != 0) // volume is in dB (0dB is no change)
            {
                _jobLog.WriteEntry(this, ("Setting up volume adjustment :") + " " + _volume.ToString("#0.0", System.Globalization.CultureInfo.InvariantCulture) + "dB", Log.LogEntryType.Information);

                if (_audioParams.ToLower().Contains("copy"))
                    _jobLog.WriteEntry(this, ("Copy Audio stream detected, skipping volume settings"), Log.LogEntryType.Warning);
                else
                    SetAudioVolume(); // do this before we AFTER setting the audio parameters
            }

            // Set the DRC with the remaining audio options for most encoders (except ffmpeg)
            if (_drc)
            {
                if ((_videoFile.AudioCodec == "ac-3") || (_videoFile.AudioCodec == "ac3") || (_videoFile.AudioCodec != "e-ac-3") || (_videoFile.AudioCodec != "eac3")) // DRC only applies to AC3 audio
                {
                    _jobLog.WriteEntry(this, ("Setting up PostDRC"), Log.LogEntryType.Information);

                    if (_audioParams.ToLower().Contains("copy"))
                        _jobLog.WriteEntry(this, ("Copy Audio stream detected, skipping DRC settings"), Log.LogEntryType.Warning);
                    else
                        SetAudioPostDRC(); // do this before we BEFORE setting the input filename
                }
                else
                    _jobLog.WriteEntry(this, ("Non AC3 Source Audio, DRC not applicable"), Log.LogEntryType.Information);
            }

            //Set audio channels
            _jobLog.WriteEntry(this, ("Setting up Audio channels"), Log.LogEntryType.Information);
            SetAudioChannels(); // Multi channel Audio

            // OUTPUT FILE
            //Set the output file names
            _jobLog.WriteEntry(this, ("Setting up Output filename"), Log.LogEntryType.Information);
            SetOutputFileName();

            // Replace user specific parameters in the final command line
            _jobLog.WriteEntry(this, "Replacing user specified parameters", Log.LogEntryType.Information);
            ReplaceUserParameters();

            // One final santiy check on the parameters before calling the convert function
            FinalSanityCheck();

            //Convert the video - MAIN ONE
            if (!_jobStatus.Cancelled)
            {
                _jobLog.WriteEntry(this, ("Converting the video - Main conversion"), Log.LogEntryType.Information);
                bool ret = ConvertWithTool();
                _jobLog.WriteEntry(this, ("Conversion: Percentage Complete") + " " + _jobStatus.PercentageComplete.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                _jobLog.WriteEntry(this, ("Original file size [KB]") + " " + (FileIO.FileSize(SourceVideo) / 1024).ToString("N", System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                _jobLog.WriteEntry(this, ("Finished video conversion, file size [KB]") + " " + (FileIO.FileSize(_convertedFile) / 1024).ToString("N", System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                // TODO: Handbrake sometime fails with a small file conversion and puts out encode done even on a failure, so check filesize. Is there a more reliable way to do this?
                if (!ret || (FileIO.FileSize(_convertedFile) <= (GlobalDefs.MINIMUM_CONVERTED_FILE_THRESHOLD * (double)FileIO.FileSize(SourceVideo)))) // with unsuccessful or incomplete or if the filesize if less than 1% of the original file
                {
                    _jobStatus.ErrorMsg = ("Conversion of video failed");
                    _jobLog.WriteEntry(this, (_jobStatus.ErrorMsg), Log.LogEntryType.Error);
                    return false;
                }
            }

            // EAC3 exception handling - redundant, not required as encoders can handle eac3 audio and function is incorrectly written
            /*
            if (!_jobStatus.Cancelled)
            {
                _jobLog.WriteEntry(this, ("Checking EAC3 Audio conversion"), Log.LogEntryType.Information);
                bool ret = ConvertEAC3();
                _jobLog.WriteEntry(this, ("EAC3 conversion: Percentage Complete") + " " + _jobStatus.PercentageComplete.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                _jobLog.WriteEntry(this, ("Finished EAC3 conversion, file size [KB]") + " " + (FileIO.FileSize(_convertedFile) / 1024).ToString("N", System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                if (!ret || _jobStatus.PercentageComplete == 0 || (FileIO.FileSize(_convertedFile) <= 0)) // Check for total failure as some component like FFMPEG dont' return a correct %
                {
                    _jobStatus.ErrorMsg = ("Conversion of EAC3 failed");
                    _jobLog.WriteEntry(this, (_jobStatus.ErrorMsg), Log.LogEntryType.Error);
                    return false;
                }
            }*/

            // Set the audio delay post conversion
            if (!_jobStatus.Cancelled)
            {
                _jobLog.WriteEntry(this, ("Correcting Audio Delay if required"), Log.LogEntryType.Information);
                bool ret = FixAudioDelay();
                _jobLog.WriteEntry(this, ("Fix Audio Delay: Percentage Complete") + " " + _jobStatus.PercentageComplete.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                _jobLog.WriteEntry(this, ("Finished fixing audio delay, file size [KB]") + " " + (FileIO.FileSize(_convertedFile) / 1024).ToString("N", System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                if (!ret || (FileIO.FileSize(_convertedFile) <= 0))
                {
                    _jobStatus.ErrorMsg = ("Fix AudioSync failed");
                    _jobLog.WriteEntry(this, (_jobStatus.ErrorMsg), Log.LogEntryType.Error);
                    return false;
                }
            }

            // Fix the converted filename conflict before remuxing
            if (!String.IsNullOrEmpty(_renameConvertedFileWithOriginalName))
            {
                try
                {
                    FileIO.TryFileDelete(_renameConvertedFileWithOriginalName); // Delete if the file with the replacement name exists (sometime with .TS file and TS profiles this happens)
                    File.Move(_convertedFile, _renameConvertedFileWithOriginalName);
                    _convertedFile = _renameConvertedFileWithOriginalName;
                }
                catch (Exception e)
                {
                    _jobStatus.ErrorMsg = ("Unable to rename file after conversion");
                    _jobLog.WriteEntry(this, ("Unable to rename file after conversion"), Log.LogEntryType.Error);
                    _jobLog.WriteEntry(this, "Error -> " + e.ToString(), Log.LogEntryType.Error);
                    return false;
                }
            }

            // Remux to new Extension if required
            if (!_jobStatus.Cancelled)
            {
                _jobLog.WriteEntry(this, ("Remuxing video if required"), Log.LogEntryType.Information);

                double fps = 0;
                double.TryParse(_fps, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out fps);
                RemuxExt remuxVideo = new RemuxExt(_convertedFile, _workingPath, (fps <= 0 ? _videoFile.Fps : fps), _jobStatus, _jobLog, _remuxTo); // Use output FPS if it exists otherwise the source file FPS (since it has not changed)
                bool ret = remuxVideo.RemuxFile();
                _convertedFile = remuxVideo.RemuxedFile;
                _jobLog.WriteEntry(this, ("Conversion Remux: Percentage Complete") + " " + _jobStatus.PercentageComplete.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                _jobLog.WriteEntry(this, ("Finished conversion remuxing video, file size [KB]") + " " + (FileIO.FileSize(_convertedFile) / 1024).ToString("N", System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                if (!ret || (FileIO.FileSize(_convertedFile) <= 0)) // Check for total failure as some component like FFMPEG dont' return a correct %
                {
                    _jobStatus.ErrorMsg = ("Remux failed");
                    _jobLog.WriteEntry(this, (_jobStatus.ErrorMsg), Log.LogEntryType.Error);
                    return false;
                }
            }

            if (!_jobStatus.Cancelled)
            {
                if (_removedAds) // We have successfully removed ad's
                    _videoFile.AdsRemoved = true;
                return true;
            }
            else
            {
                _jobStatus.ErrorMsg = ("Job cancelled, Aborting conversion");
                _jobLog.WriteEntry(this, ("Job cancelled, Aborting conversion"), Log.LogEntryType.Error);
                return false;
            }
        }