Пример #1
0
        protected override void FinalSanityCheck()
        {
            // Check if we don't have a video stream and remove the video mapping
            if (_videoFile.VideoStream == -1) // Check if we have a video stream
            {
                _jobLog.WriteEntry(this, "No Video stream detected, removing support for video stream", Log.LogEntryType.Warning);
                _cmdParams = _cmdParams.Replace("-map 0:v", ""); // Replace the map video command with nothing
            }
            else
            {
                _cmdParams = _cmdParams.Replace("-map 0:v", "-map 0:" + _videoFile.VideoStream.ToString(CultureInfo.InvariantCulture)); // Replace the map video command with the actual video stream (some TS files contain multiple video streams)
            }
            // Audio stream can be -1 if no language is selected do we don't check for it.
            if (_videoFile.FFMPEGStreamInfo.AudioTracks < 1)
            {
                _jobLog.WriteEntry(this, "No Audio stream detected, removing support for audio stream", Log.LogEntryType.Warning);
                _cmdParams = _cmdParams.Replace("-map 0:a", ""); // Replace the map audio command with nothing
            }

            // Check if we need to burn in subtitles, this is done in the VERY end because this filter cannot be replaced since it contains : that will break the MCEBuddy video manipulator functions (only works once)
            // Special characters \ : ' need to escaped for the filter (in that order)
            // Then you need to re-escapte the / ' characters for ffmpeg to parse it (in that order)
            // Refer to FFMPEG Ticket #3334, order if VERY important, first escape the \, then escape the :, then escape the ', then reescape the \ and finally reescape '

            /* Comment from Stefano Sabatini from ffmpeg users forum on "escaping hell" in ffmpeg filters
             *  the SRT filepath is
             *
             *  D:\MCEBuddy\MCEBuddy 2.x\MCEBuddy.ServiceCMD\bin\x86\Debug\working0\HD Small'.srt
             *
             *  So this string contains : which is special according to the filter
             *  description syntax, and the \ and ' special escaping characters.
             *
             *  So, first level escaping:
             *  D\:\\MCEBuddy\\MCEBuddy 2.x\\MCEBuddy.ServiceCMD\\bin\\x86\\Debug\\working0\\HD Small\'.srt
             *
             *  Now you embed the filter description string in the filtergraph
             *  description, so you add another escaping level, and you need to escape
             *  the special \ and ' characters. One way of doing this is as:
             *
             *  subtitles=D\\:\\\\MCEBuddy\\\\MCEBuddy 2.x\\\\MCEBuddy.ServiceCMD\\\\bin\\\\x86\\\\Debug\\\\working0\\\\HD Small\\\'.srt
             *
             *  Alternatively you use quoting:
             *  subtitles='D\:\\MCEBuddy\\MCEBuddy 2.x\\MCEBuddy.ServiceCMD\\bin\\x86\\Debug\\working0\\HD Small'\'.srt
             */

            if (!String.IsNullOrWhiteSpace(_srtFile) && File.Exists(_srtFile) && (ParameterValue("-vcodec") != "copy")) // does not work with copy codec
            {
                ParameterReplaceOrInsertVideoFilter("subtitles", "=" + FilePaths.FixSpaces(_srtFile.Replace(@"\", @"\\").Replace(@":", @"\:").Replace(@"'", @"\'").Replace(@"\", @"\\").Replace(@"'", @"\'")));
                _subtitleBurned = true;
            }
        }
Пример #2
0
        private bool MKVRemux()
        {
            _jobStatus.ErrorMsg           = "";
            _jobStatus.PercentageComplete = 100; //all good to start with
            _jobStatus.ETA = "";

            Util.FileIO.TryFileDelete(RemuxedTempFile);

            string   parameters = "--clusters-in-meta-seek -o " + FilePaths.FixSpaces(RemuxedTempFile) + " --compression -1:none " + FilePaths.FixSpaces(_originalFile);
            MKVMerge mkvMerge   = new MKVMerge(parameters, _jobStatus, _jobLog);

            mkvMerge.Run();
            if (!mkvMerge.Success)
            {
                _jobLog.WriteEntry(this, Localise.GetPhrase("MKVMerge failed"), Log.LogEntryType.Error);
                _jobStatus.ErrorMsg = Localise.GetPhrase("MKVMerge failed");
                return(false);
            }

            _jobLog.WriteEntry(this, Localise.GetPhrase("MKVMerge remux moving file"), Log.LogEntryType.Information);
            return(ReplaceTempRemuxed());
        }
Пример #3
0
        private bool MP4BoxRemux()
        {
            _jobStatus.ErrorMsg           = "";
            _jobStatus.PercentageComplete = 100; //all good to start with
            _jobStatus.ETA = "";

            Util.FileIO.TryFileDelete(RemuxedTempFile);
            string Parameters = " -keep-sys -keep-all";

            //Check for Null FPS (bug with MediaInfo for some .TS files)
            if (_fps <= 0)
            {
                _jobLog.WriteEntry(this, Localise.GetPhrase("Mp4BoxRemuxAVI FPS 0 reported by video file - non compliant video file, skipping adding to parameter"), Log.LogEntryType.Warning);
                Parameters += " -add " + FilePaths.FixSpaces(_originalFile) +
                              " -new " + FilePaths.FixSpaces(RemuxedTempFile);
            }
            else
            {
                Parameters += " -fps " + _fps.ToString(System.Globalization.CultureInfo.InvariantCulture) +
                              " -add " + FilePaths.FixSpaces(_originalFile) +
                              " -new " + FilePaths.FixSpaces(RemuxedTempFile);
            }

            MP4Box mp4Box = new MP4Box(Parameters, _jobStatus, _jobLog);

            mp4Box.Run();
            if (!mp4Box.Success || _jobStatus.PercentageComplete < GlobalDefs.ACCEPTABLE_COMPLETION)
            {
                _jobLog.WriteEntry(this, Localise.GetPhrase("MP4BoxRemux failed"), Log.LogEntryType.Error);
                _jobStatus.ErrorMsg = Localise.GetPhrase("MP4BoxRemux failed");
                return(false);
            }

            _jobLog.WriteEntry(this, Localise.GetPhrase("MP4Box remux moving file"), Log.LogEntryType.Information);
            return(ReplaceTempRemuxed());
        }
Пример #4
0
        /// <summary>
        /// Extracts subtitles from a video file into a SRT format (with same name) and cleans it up.
        /// It will overwrite any existing SRT files
        /// If there are multiple subtitles it extracts them into multiple files with incremental names.
        /// </summary>
        /// <param name="sourceFile">Path to video file</param>
        /// <param name="offset">Offset of the subtitles during extraction</param>
        /// <param name="overWrite">True to overwrite existing SRT files, false to create new ones with incremental names</param>
        /// <param name="languageExtractList">List of 3 digit language codes to extract (blank to extract all, unnamed languages will always be extracted)</param>
        /// <returns>True if successful</returns>
        public bool ExtractSubtitles(string sourceFile, string workingPath, int startTrim, int endTrim, double offset, bool overWrite, List <string> languageExtractList)
        {
            _jobLog.WriteEntry(this, ("Extracting Subtitles from " + sourceFile + " into SRT file"), Log.LogEntryType.Information);
            _jobLog.WriteEntry(this, "Source File : " + sourceFile, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Working Path " + workingPath, Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Start Trim : " + startTrim.ToString(CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Stop Trim : " + endTrim.ToString(CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
            _jobLog.WriteEntry(this, "Offset : " + offset.ToString(CultureInfo.InvariantCulture), Log.LogEntryType.Debug);

            if (String.IsNullOrEmpty(sourceFile))
            {
                return(true); // nothing to do
            }
            if (!File.Exists(sourceFile))
            {
                _jobLog.WriteEntry(this, ("File does not exist " + sourceFile), Log.LogEntryType.Warning);
                return(true); //nothing to process
            }

            FFmpegMediaInfo mediaInfo = new FFmpegMediaInfo(sourceFile, _jobStatus, _jobLog);

            if (!mediaInfo.Success || mediaInfo.ParseError)
            {
                _jobLog.WriteEntry(this, ("Error reading subtitle info from file"), Log.LogEntryType.Error);
                return(false);
            }

            _jobLog.WriteEntry(this, "Found " + mediaInfo.SubtitleTracks.ToString() + " Subtitle tracks, extract only the first matching track", Log.LogEntryType.Debug);

            bool extractedSubtitle = false;

            for (int i = 0; i < mediaInfo.SubtitleTracks; i++)
            {
                if (extractedSubtitle) // Only extract and use one subtitle (sometimes chapter tracks are misidentified as subtitle tracks)
                {
                    continue;
                }

                // Build the command line
                string parameters    = "";
                string outputSRTFile = ""; // Using Serviio subtitle filename format (filename.srt or filename_language.srt or filename_uniquenumber.srt)

                // Check for language comparison if required
                if (languageExtractList != null)
                {
                    if (languageExtractList.Count > 0) // If list is empty, we extract all
                    {
                        _jobLog.WriteEntry(this, "Subtitle language extraction list -> " + String.Join(",", languageExtractList.ToArray()), Log.LogEntryType.Debug);

                        if (!String.IsNullOrWhiteSpace(mediaInfo.MediaInfo.SubtitleInfo[i].Language))        // check if we have a language defined for this track
                        {
                            if (!languageExtractList.Contains(mediaInfo.MediaInfo.SubtitleInfo[i].Language)) // This language is not in the list of extraction
                            {
                                _jobLog.WriteEntry(this, "Skipping subtitle extraction since subtitle language >" + mediaInfo.MediaInfo.SubtitleInfo[i].Language + "< is NOT in the subtitle language list", Log.LogEntryType.Warning);
                                continue; // Skip this subtitle track
                            }
                        }
                        else
                        {
                            _jobLog.WriteEntry(this, "Extracting subtitle since there is no language defined for track", Log.LogEntryType.Debug);
                        }
                    }
                }

                // Check for existing SRT files
                if (overWrite)
                {
                    outputSRTFile = Path.Combine(workingPath, Path.GetFileNameWithoutExtension(sourceFile)) + (i > 0 ? (String.IsNullOrWhiteSpace(mediaInfo.MediaInfo.SubtitleInfo[i].Language) ? "_" + i.ToString() : "_" + mediaInfo.MediaInfo.SubtitleInfo[i].Language) : "") + ".srt"; // First file user default name, then try to name with language first, if not give a unique number
                    parameters   += " -y";
                }
                else // Create a unique SRT file name
                {
                    int existingSRTCount = 0;
                    outputSRTFile = Path.Combine(workingPath, Path.GetFileNameWithoutExtension(sourceFile)) + ".srt"; // Try default name
                    while (File.Exists(outputSRTFile))
                    {
                        _jobLog.WriteEntry(this, "Subtitle file " + outputSRTFile + " exists, creating a new unique SRT filename", Log.LogEntryType.Debug);
                        outputSRTFile = Path.Combine(workingPath, Path.GetFileNameWithoutExtension(sourceFile)) + (String.IsNullOrWhiteSpace(mediaInfo.MediaInfo.SubtitleInfo[i].Language) ? "_" + existingSRTCount.ToString() : "_" + mediaInfo.MediaInfo.SubtitleInfo[i].Language + (existingSRTCount > 0 ? existingSRTCount.ToString() : "")) + ".srt"; // Create a unique SRT filename, try with language first, if not give a unique identifier, avoid a loop
                        existingSRTCount++;
                    }
                }

                // Build ffmpeg command line
                parameters += " -i " + FilePaths.FixSpaces(sourceFile);
                parameters += " -an -vn";
                parameters += " -map 0:" + mediaInfo.MediaInfo.SubtitleInfo[i].Stream.ToString(); // Subtitle steam no
                parameters += " -scodec copy -copyinkf -f srt " + FilePaths.FixSpaces(outputSRTFile);

                // Now extract it
                _jobLog.WriteEntry(this, "Extracting Subtitle " + (i + 1).ToString() + " with language >" + mediaInfo.MediaInfo.SubtitleInfo[i].Language + "< to " + outputSRTFile, Log.LogEntryType.Debug);
                FFmpeg ffmpeg = new FFmpeg(parameters, _jobStatus, _jobLog);
                ffmpeg.Run();
                if (!ffmpeg.Success)
                {
                    FileIO.TryFileDelete(outputSRTFile); // Delete partial file

                    // Backup, try using MP4Box instead to extract it
                    _jobLog.WriteEntry(this, ("FFMPEG failed to extract subtitles into SRT file, retrying using MP4Box"), Log.LogEntryType.Warning);
                    parameters = "-srt " + (mediaInfo.MediaInfo.SubtitleInfo[i].Stream + 1).ToString() + " " + FilePaths.FixSpaces(sourceFile);
                    // MP4Box create an output file called <input>_<track>_text.srt
                    // Check if the output srt exists and then rename it if it does
                    string tempSrtOutput = FilePaths.GetFullPathWithoutExtension(sourceFile) + "_" + (mediaInfo.MediaInfo.SubtitleInfo[i].Stream + 1).ToString() + "_text.srt";
                    bool   tempSrtExists = false;
                    if (File.Exists(tempSrtOutput)) // Save the output srt filename if it exists
                    {
                        try
                        {
                            FileIO.MoveAndInheritPermissions(tempSrtOutput, tempSrtOutput + ".tmp");
                        }
                        catch (Exception e)
                        {
                            _jobLog.WriteEntry(this, ("Error extracting subtitles into SRT file.\r\n" + e.ToString()), Log.LogEntryType.Error);
                            return(false);
                        }
                        tempSrtExists = true;
                    }

                    // Extract the subtitle
                    MP4Box mp4Box = new MP4Box(parameters, _jobStatus, _jobLog);
                    mp4Box.Run();
                    if (!mp4Box.Success)
                    {
                        _jobLog.WriteEntry(this, ("Error extracting subtitles into SRT file"), Log.LogEntryType.Error);
                        FileIO.TryFileDelete(tempSrtOutput); // Delete partial file
                        if (tempSrtExists)
                        {
                            RestoreSavedSrt(tempSrtOutput);
                        }
                        return(false);
                    }

                    if (FileIO.FileSize(tempSrtOutput) <= 0) // MP4Box always return success even if nothing is extracted, so check if has been extracted
                    {
                        _jobLog.WriteEntry(this, "No or empty Subtitle file " + tempSrtOutput + " extracted by MP4Box, skipping", Log.LogEntryType.Debug);
                        FileIO.TryFileDelete(tempSrtOutput); // Delete empty file
                    }
                    else
                    {
                        // Rename the temp output SRT to the expected name
                        try
                        {
                            FileIO.MoveAndInheritPermissions(tempSrtOutput, outputSRTFile);
                        }
                        catch (Exception e)
                        {
                            _jobLog.WriteEntry(this, ("Error extracting subtitles into SRT file.\r\n" + e.ToString()), Log.LogEntryType.Error);
                            FileIO.TryFileDelete(tempSrtOutput); // Delete partial file
                            if (tempSrtExists)
                            {
                                RestoreSavedSrt(tempSrtOutput);
                            }
                            return(false);
                        }
                    }

                    // Restore temp SRT file if it exists
                    if (tempSrtExists)
                    {
                        RestoreSavedSrt(tempSrtOutput);
                    }
                }

                if (FileIO.FileSize(outputSRTFile) <= 0) // Check for empty files
                {
                    _jobLog.WriteEntry(this, "Empty Subtitle file " + outputSRTFile + " extracted, deleting it", Log.LogEntryType.Warning);
                    FileIO.TryFileDelete(outputSRTFile); // Delete empty file
                }
                else
                {
                    // Trim the SRT file if required
                    if (startTrim > 0 || endTrim > 0)
                    {
                        // Get the length of the video, needed to calculate end point
                        float Duration = 0;
                        Duration = VideoParams.VideoDuration(sourceFile);
                        if (Duration <= 0)
                        {
                            FFmpegMediaInfo ffmpegStreamInfo = new FFmpegMediaInfo(sourceFile, _jobStatus, _jobLog);
                            if (ffmpegStreamInfo.Success && !ffmpegStreamInfo.ParseError)
                            {
                                // Converted file should contain only 1 audio stream
                                Duration = ffmpegStreamInfo.MediaInfo.VideoInfo.Duration;
                                _jobLog.WriteEntry(this, ("Video duration") + " : " + Duration.ToString(CultureInfo.InvariantCulture), Log.LogEntryType.Information);

                                if (Duration == 0)
                                {
                                    _jobLog.WriteEntry(this, ("Video duration 0"), Log.LogEntryType.Error);
                                    return(false);
                                }
                            }
                            else
                            {
                                _jobLog.WriteEntry(this, ("Cannot read video duration"), Log.LogEntryType.Error);
                                return(false);
                            }
                        }

                        // Trim the subtitle
                        if (!TrimSubtitle(outputSRTFile, workingPath, startTrim, endTrim, Duration, 0))
                        {
                            _jobLog.WriteEntry(this, ("Error trimming SRT file"), Log.LogEntryType.Error);
                            return(false);
                        }
                    }

                    // Clean it up and offset the SRT if required
                    if (!SRTValidateAndClean(outputSRTFile, offset))
                    {
                        _jobLog.WriteEntry(this, ("Cannot clean and set offset for SRT file"), Log.LogEntryType.Error);
                        return(false);
                    }

                    // Check for empty file
                    if (Util.FileIO.FileSize(outputSRTFile) <= 0)
                    {
                        FileIO.TryFileDelete(outputSRTFile); // Delete the empty file
                        _jobLog.WriteEntry(this, ("No valid SRT file found"), Log.LogEntryType.Warning);
                        continue;                            // check for the next subtitle track
                    }

                    _extractedSRTFile = outputSRTFile; // Save it
                    _jobLog.WriteEntry(this, "Extracted Subtitle file " + outputSRTFile + ", size [KB] " + (FileIO.FileSize(outputSRTFile) / 1024).ToString("N", CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
                    extractedSubtitle = true;          // We have success
                }
            }

            return(true);
        }
Пример #5
0
        private bool MP4BoxRemuxAvi()
        {
            _jobStatus.ErrorMsg           = "";
            _jobStatus.PercentageComplete = 100; //all good to start with
            _jobStatus.ETA = "";

            string fileNameBase   = Path.Combine(_workingPath, Path.GetFileNameWithoutExtension(_originalFile));
            string audioStream    = fileNameBase + "_audio.raw";
            string newAudioStream = fileNameBase + "_audio.aac";
            string videoStream    = fileNameBase + "_video.h264";

            Util.FileIO.TryFileDelete(RemuxedTempFile);

            // Video
            string Parameters = " -keep-sys -aviraw video -out " + FilePaths.FixSpaces(videoStream) + " " + FilePaths.FixSpaces(_originalFile);

            _jobStatus.CurrentAction = Localise.GetPhrase("Remuxing to") + " " + _remuxTo.ToLower() + " " + Localise.GetPhrase("Part") + " 1";

            MP4Box mp4Box = new MP4Box(Parameters, _jobStatus, _jobLog);

            mp4Box.Run();
            if (!mp4Box.Success || _jobStatus.PercentageComplete < GlobalDefs.ACCEPTABLE_COMPLETION) // check for completion of job
            {
                _jobStatus.ErrorMsg = "MP4Box Remux Video AVI failed";
                _jobLog.WriteEntry(this, _jobStatus.ErrorMsg + " at " + _jobStatus.PercentageComplete.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Error);
                return(false);
            }

            // Audio
            Parameters = " -keep-all -keep-sys -aviraw audio -out " + FilePaths.FixSpaces(audioStream) + " " + FilePaths.FixSpaces(_originalFile);

            _jobStatus.CurrentAction = Localise.GetPhrase("Remuxing to") + " " + _remuxTo.ToLower() + " " + Localise.GetPhrase("Part") + " 2";

            mp4Box = new MP4Box(Parameters, _jobStatus, _jobLog);
            mp4Box.Run();
            if (!mp4Box.Success || _jobStatus.PercentageComplete < GlobalDefs.ACCEPTABLE_COMPLETION) //check for completion of job
            {
                _jobStatus.ErrorMsg = "MP4Box Remux Audio AVI failed";
                _jobLog.WriteEntry(this, _jobStatus.ErrorMsg + " at " + _jobStatus.PercentageComplete.ToString(System.Globalization.CultureInfo.InvariantCulture), Log.LogEntryType.Error);
                return(false);
            }

            // Check if streams are extracted
            if ((File.Exists(audioStream)) && (File.Exists(videoStream)))
            {
                _jobLog.WriteEntry(this, Localise.GetPhrase("MP4Box remux avi moving file"), Log.LogEntryType.Information);
                try
                {
                    Util.FileIO.TryFileDelete(newAudioStream);
                    FileIO.MoveAndInheritPermissions(audioStream, newAudioStream);
                }
                catch (Exception e)
                {
                    _jobLog.WriteEntry(this, Localise.GetPhrase("Unable to move remuxed stream") + " " + audioStream + " to " + newAudioStream + "\r\nError : " + e.ToString(), Log.LogEntryType.Error);
                    _jobStatus.PercentageComplete = 0;
                    _jobStatus.ErrorMsg           = "Unable to move muxed stream";
                    return(false);
                }

                string mergeParameters = " -keep-sys -keep-all";

                //Check for Null FPS (bug with MediaInfo for some .TS files)
                if (_fps <= 0)
                {
                    _jobLog.WriteEntry(this, Localise.GetPhrase("Mp4BoxRemuxAVI FPS 0 reported by video file - non compliant video file, skipping adding to parameter"), Log.LogEntryType.Warning);
                    mergeParameters += " -add " + FilePaths.FixSpaces(videoStream) +
                                       " -add " + FilePaths.FixSpaces(newAudioStream) +
                                       " -new " + FilePaths.FixSpaces(RemuxedTempFile);
                }
                else
                {
                    mergeParameters += " -fps " + _fps.ToString(System.Globalization.CultureInfo.InvariantCulture) +
                                       " -add " + FilePaths.FixSpaces(videoStream) +
                                       " -add " + FilePaths.FixSpaces(newAudioStream) +
                                       " -new " + FilePaths.FixSpaces(RemuxedTempFile);
                }


                _jobStatus.CurrentAction = Localise.GetPhrase("Remuxing to") + " " + _remuxTo.ToLower() + " " + Localise.GetPhrase("Part") + " 3";

                mp4Box = new MP4Box(mergeParameters, _jobStatus, _jobLog);
                mp4Box.Run();
                if (!mp4Box.Success || _jobStatus.PercentageComplete < GlobalDefs.ACCEPTABLE_COMPLETION) // check for completion
                {
                    _jobStatus.ErrorMsg = "Mp4Box Remux Merger AVI with FPS conversion failed";
                    _jobLog.WriteEntry(this, _jobStatus.ErrorMsg, Log.LogEntryType.Error);
                    return(false);
                }

                Util.FileIO.TryFileDelete(videoStream);
                Util.FileIO.TryFileDelete(newAudioStream);

                _jobLog.WriteEntry(this, Localise.GetPhrase("MP4Box remux AVI trying to move remuxed file"), Log.LogEntryType.Information);
                return(ReplaceTempRemuxed());
            }
            else
            {
                _jobLog.WriteEntry(this, Localise.GetPhrase("MP4Box Remux AVI of") + " " + _originalFile + " " + Localise.GetPhrase("failed.  Extracted video and audio streams not found."), Log.LogEntryType.Error);
                _jobStatus.PercentageComplete = 0;
                _jobStatus.ErrorMsg           = "Remux failed, extracted video streams not found";
                return(false);
            }
        }
Пример #6
0
        /// <summary>
        /// Remuxes the converted file to the specified extension/format using FFMPEG.
        /// (Optionally) If a new Audio Stream file is specified, the audio from the new file is taken and video from the original file
        /// </summary>
        /// <param name="newAudioStream">(Optional) New Audio stream to use</param>
        /// <returns>True is successful</returns>
        public bool FfmpegRemux(string newAudioStream = "")
        {
            _jobStatus.ErrorMsg           = "";
            _jobStatus.PercentageComplete = 100; //all good to start with
            _jobStatus.ETA = "";

            Util.FileIO.TryFileDelete(RemuxedTempFile);

            FFmpegMediaInfo ffmpegStreamInfo = new FFmpegMediaInfo(_originalFile, _jobStatus, _jobLog);

            if (!ffmpegStreamInfo.Success || ffmpegStreamInfo.ParseError)
            {
                _jobStatus.ErrorMsg = "Unable to read video information";
                _jobLog.WriteEntry(this, (_jobStatus.ErrorMsg), Log.LogEntryType.Error);
                _jobStatus.PercentageComplete = 0;
                return(false);
            }

            // Input original
            string ffmpegParams = "-y -i " + FilePaths.FixSpaces(_originalFile);

            // Add New Audio stream
            if (!String.IsNullOrEmpty(newAudioStream))
            {
                // Take audio stream from new audio file
                ffmpegParams += " -i " + FilePaths.FixSpaces(newAudioStream) + " -map 1:a -acodec copy";

                // Video from the original file
                if (ffmpegStreamInfo.MediaInfo.VideoInfo.Stream != -1)
                {
                    ffmpegParams += " -map 0:" + ffmpegStreamInfo.MediaInfo.VideoInfo.Stream.ToString() + " -vcodec copy"; // Fix for FFMPEG WTV MJPEG ticket #2227
                }
                else
                {
                    ffmpegParams += " -vn";
                }
            }
            else
            {
                // Check for audio tracks
                if (ffmpegStreamInfo.AudioTracks > 0)
                {
                    ffmpegParams += " -map 0:a -acodec copy";
                }
                else
                {
                    ffmpegParams += " -an";
                }

                // Check for video tracks
                if (ffmpegStreamInfo.MediaInfo.VideoInfo.Stream != -1)
                {
                    ffmpegParams += " -map 0:" + ffmpegStreamInfo.MediaInfo.VideoInfo.Stream.ToString() + " -vcodec copy"; // Fix for FFMPEG WTV MJPEG ticket #2227
                }
                else
                {
                    ffmpegParams += " -vn";
                }
            }

            ffmpegParams += " " + FilePaths.FixSpaces(RemuxedTempFile);

            if (!FFmpeg.FFMpegExecuteAndHandleErrors(ffmpegParams, _jobStatus, _jobLog, FilePaths.FixSpaces(RemuxedTempFile))) // Let this function handle error conditions since it's just a simple execute
            {
                _jobStatus.ErrorMsg = Localise.GetPhrase("ffmpeg remux failed");
                _jobLog.WriteEntry(this, (_jobStatus.ErrorMsg), Log.LogEntryType.Error);
                return(false);
            }

            _jobLog.WriteEntry(this, Localise.GetPhrase("FFMPEG ReMux moving file"), Log.LogEntryType.Information);
            return(ReplaceTempRemuxed());
        }