Exemple #1
0
        /// <summary>
        /// Check if audio stream is Blu-Ray compatible
        /// </summary>
        /// <param name="aud"><see cref="AudioInfo"/></param>
        /// <returns>true if stream is Blu-Ray compatible, false otherwise</returns>
        public bool CheckAudioBluRayCompatible(AudioInfo aud)
        {
            var ext = StreamFormat.GetFormatExtension(aud.Format, aud.FormatProfile, false);

            var compat = !(ext != "ac3" &&
                           ext != "eac3" &&
                           ext != "dts" &&
                           ext != "dtshd" &&
                           ext != "mp2" &&
                           ext != "truehd");

            return(compat);
        }
Exemple #2
0
        /// <summary>
        /// Check if audio stream is DVD compatible
        /// </summary>
        /// <param name="aud"><see cref="AudioInfo"/></param>
        /// <returns>true if stream is DVD compatible, false otherwise</returns>
        public bool CheckAudioDvdCompatible(AudioInfo aud)
        {
            var ext = StreamFormat.GetFormatExtension(aud.Format, aud.FormatProfile, false);

            var compat = true;

            Log.Info("Check if audio is compatible with DVD Spec");
            Log.Info($"Format: {aud.Format}, Profile: {aud.FormatProfile}");
            Log.Info($"Bitrate: {aud.Bitrate:0}, Samplerate: {aud.SampleRate:0}, Channel Count: {aud.ChannelCount:0}");

            if (ext != "ac3")
            {
                Log.Info("Format is not AC3");
                compat = false;
            }

            if (compat)
            {
                if (ext == "ac3")
                {
                    if (aud.Bitrate > 448000)
                    {
                        Log.Info("Bitrate is higher than 448kbit/s");
                        compat = false;
                    }
                }
            }

            if (compat)
            {
                if (aud.ChannelCount > 6)
                {
                    Log.Info("This channel configuration is not supported");
                    compat = false;
                }
            }

            if (!compat)
            {
                return(false);
            }
            if (aud.SampleRate == 48000)
            {
                return(true);
            }

            Log.Info("Samplerate != 48000Hz");

            return(false);
        }
Exemple #3
0
        /// <summary>
        /// check if audio stream is dvd compatible
        /// </summary>
        /// <param name="aud"></param>
        /// <returns>true if stream is dvd compatible, false otherwise</returns>
        public static bool CheckAudioDvdCompatible(AudioInfo aud)
        {
            string ext = StreamFormat.GetFormatExtension(aud.Format, aud.FormatProfile, false);

            bool compat = true;

            Log.Info("Check if audio is compatible with DVD Spec");
            Log.InfoFormat("Format: {0:s}, Profile: {1:s}", aud.Format, aud.FormatProfile);
            Log.InfoFormat("Bitrate: {0:g}, Samplerate: {1:g}, Channel Count: {2:g}", aud.Bitrate, aud.SampleRate,
                           aud.ChannelCount);

            if (ext != "ac3")
            {
                Log.Info("Format is not AC3");
                compat = false;
            }

            if (compat)
            {
                if (ext == "ac3")
                {
                    if (aud.Bitrate > 448000)
                    {
                        Log.InfoFormat("Bitrate is higher than 448kbit/s");
                        compat = false;
                    }
                }
            }

            if (compat)
            {
                if (aud.ChannelCount > 6)
                {
                    Log.InfoFormat("This channel configuration is not supported");
                    compat = false;
                }
            }

            if (compat)
            {
                if (aud.SampleRate != 48000)
                {
                    Log.InfoFormat("Samplerate != 48000Hz");
                    compat = false;
                }
            }

            return(compat);
        }
        private string GenerateCommandLine()
        {
            var sb = new StringBuilder();

            sb.Append(DefaultParams);

            _subtitle  = _currentTask.SubtitleStreams[_currentTask.StreamId];
            _inputFile = _subtitle.TempFile;
            var    ext          = StreamFormat.GetFormatExtension(_subtitle.Format, "", true);
            string formattedExt = $"raw.{ext}";

            _outputFile = FileSystemHelper.CreateTempFile(_appConfig.TempPath, _inputFile, formattedExt);

            sb.Append($"tracks \"{_inputFile}\" 0:\"{_outputFile}\" ");

            return(sb.ToString());
        }
Exemple #5
0
        public void DemuxSubtitle(object sender, DoWorkEventArgs e)
        {
            _bw = (BackgroundWorker)sender;

            string localExecutable = Path.Combine(AppSettings.ToolsPath, "mkvextract.exe");
            string status          = Processing.GetResourceString("mkvmerge_demuxing_status");

            _bw.ReportProgress(-10, status);
            _bw.ReportProgress(0, status);

            SubtitleInfo sub          = _jobInfo.SubtitleStreams[_jobInfo.StreamId];
            string       input        = sub.TempFile;
            string       ext          = StreamFormat.GetFormatExtension(sub.Format, "", true);
            string       formattedExt = string.Format("raw.{0}", ext);

            sub.TempFile = Processing.CreateTempFile(sub.TempFile, formattedExt);

            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("{0} tracks \"{1}\" 0:\"{2}\" ", Defaultparams, input, sub.TempFile);

            using (Process encoder = new Process())
            {
                ProcessStartInfo parameter = new ProcessStartInfo(localExecutable)
                {
                    WorkingDirectory       = AppSettings.DemuxLocation,
                    Arguments              = sb.ToString(),
                    CreateNoWindow         = true,
                    UseShellExecute        = false,
                    RedirectStandardOutput = true
                };

                encoder.StartInfo = parameter;

                encoder.OutputDataReceived += OnDemuxDataReceived;

                Log.InfoFormat("mkvextract {0:s}", parameter.Arguments);

                bool started;
                try
                {
                    started = encoder.Start();
                }
                catch (Exception ex)
                {
                    started = false;
                    Log.ErrorFormat("mkvmerge exception: {0}", ex);
                    _jobInfo.ExitCode = -1;
                }

                if (started)
                {
                    encoder.PriorityClass = AppSettings.GetProcessPriority();
                    encoder.BeginOutputReadLine();

                    while (!encoder.HasExited)
                    {
                        if (_bw.CancellationPending)
                        {
                            encoder.Kill();
                        }
                        Thread.Sleep(200);
                    }
                    encoder.WaitForExit(10000);
                    encoder.CancelOutputRead();

                    _jobInfo.ExitCode = encoder.ExitCode;
                    Log.InfoFormat("Exit Code: {0:g}", _jobInfo.ExitCode);
                    if (_jobInfo.ExitCode < 2)
                    {
                        if (_jobInfo.ExitCode == 1)
                        {
                            string warningStr = Processing.GetResourceString("process_finish_warnings");
                            _bw.ReportProgress(-10, warningStr);
                            _jobInfo.ExitCode = 0;
                        }

                        _jobInfo.TempFiles.Add(input);
                        sub.RawStream = true;
                        if (sub.Format == "VobSub")
                        {
                            _jobInfo.TempFiles.Add(sub.TempFile);
                            sub.TempFile = Path.ChangeExtension(sub.TempFile, "idx");
                        }
                    }
                }
            }

            _bw.ReportProgress(100);
            _jobInfo.CompletedStep = _jobInfo.NextStep;

            e.Result = _jobInfo;
        }
        /// <summary>
        /// Generates commandline for the eac3to executable
        /// </summary>
        /// <param name="jobInfo">Job entry to process</param>
        /// <returns>commandline arguments</returns>
        public static string GenerateDemuxLine(ref EncodeInfo jobInfo)
        {
            StringBuilder sb = new StringBuilder();

            string inputFile;
            int    startstream = 0;
            string ext;
            string formattedExt;

            // generate output filename depending input file given
            if (jobInfo.Input == InputType.InputDvd)
            {
                inputFile = jobInfo.DumpOutput;
                jobInfo.VideoStream.TempFile = Path.ChangeExtension(jobInfo.DumpOutput, "demuxed.mkv");
            }
            else
            {
                inputFile = string.IsNullOrEmpty(jobInfo.TempInput) ? jobInfo.InputFile : jobInfo.TempInput;

                jobInfo.VideoStream.TempFile = string.IsNullOrEmpty(jobInfo.TempInput)
                                                   ? Processing.CreateTempFile(
                    string.IsNullOrEmpty(jobInfo.TempOutput)
                                                           ? jobInfo.BaseName
                                                           : jobInfo.TempOutput, "demuxed.video.mkv")
                                                   : Processing.CreateTempFile(jobInfo.TempInput, "demuxed.video.mkv");
            }

            sb.AppendFormat("\"{0}\" {1:g}:\"{2}\" ", inputFile, jobInfo.VideoStream.StreamId + startstream,
                            jobInfo.VideoStream.TempFile);

            // on stereo sources, decide if stream for right eye should be extracted
            if (jobInfo.StereoVideoStream.RightStreamId > 0 && jobInfo.EncodingProfile.StereoType != StereoEncoding.None)
            {
                jobInfo.StereoVideoStream.RightTempFile = Processing.CreateTempFile(jobInfo.VideoStream.TempFile,
                                                                                    "right.h264");
                jobInfo.StereoVideoStream.LeftTempFile = Processing.CreateTempFile(jobInfo.VideoStream.TempFile,
                                                                                   "left.h264");
                sb.AppendFormat("{0:g}:\"{1}\" {2:g}:\"{3}\" ", jobInfo.StereoVideoStream.LeftStreamId,
                                jobInfo.StereoVideoStream.LeftTempFile, jobInfo.StereoVideoStream.RightStreamId,
                                jobInfo.StereoVideoStream.RightTempFile);
            }

            // if input source is dvd, increment stream id to match eac2to stream counting
            if (jobInfo.Input == InputType.InputDvd)
            {
                startstream++;
            }

            // process all audio streams
            foreach (AudioInfo item in jobInfo.AudioStreams)
            {
                // get file extension for selected stream based on format and format profile
                ext = StreamFormat.GetFormatExtension(item.Format, item.FormatProfile, false);
                string core = string.Empty;

                // extract only core audio data for dvd output
                if (jobInfo.EncodingProfile.OutFormat == OutputType.OutputDvd && jobInfo.AudioProfile.Type == ProfileType.Copy)
                {
                    if (string.CompareOrdinal(ext, "dtshd") == 0)
                    {
                        core = "-core";
                        ext  = "dts";
                    }
                    else if (string.CompareOrdinal(ext, "truehd") == 0)
                    {
                        core = "-core";
                        ext  = "ac3";
                    }
                }
                formattedExt = string.Format("demuxed.audio.{0:g}.{1}.{2}", item.StreamId, item.LangCode, ext);

                switch (jobInfo.Input)
                {
                case InputType.InputDvd:
                    item.TempFile = Processing.CreateTempFile(jobInfo.DumpOutput, formattedExt);
                    break;

                default:
                    item.TempFile = string.IsNullOrEmpty(jobInfo.TempInput)
                            ? Processing.CreateTempFile(
                        string.IsNullOrEmpty(jobInfo.TempOutput)
                                    ? jobInfo.BaseName
                                    : jobInfo.TempOutput, formattedExt)
                            : Processing.CreateTempFile(jobInfo.TempInput, formattedExt);
                    break;
                }

                sb.AppendFormat("{0:g}:\"{1}\" {2} ", item.Id + startstream, item.TempFile, core);
            }

            // process all subtitle streams
            foreach (SubtitleInfo item in jobInfo.SubtitleStreams)
            {
                ext          = StreamFormat.GetFormatExtension(item.Format, String.Empty, false);
                formattedExt = string.Format("demuxed.subtitle.{0:g}.{1}.{2}", item.StreamId, item.LangCode, ext);

                switch (jobInfo.Input)
                {
                case InputType.InputDvd:
                    item.TempFile = Processing.CreateTempFile(jobInfo.DumpOutput, formattedExt);
                    break;

                default:
                    item.TempFile = string.IsNullOrEmpty(jobInfo.TempInput)
                            ? Processing.CreateTempFile(
                        string.IsNullOrEmpty(jobInfo.TempOutput)
                                    ? jobInfo.BaseName
                                    : jobInfo.TempOutput, formattedExt)
                            : Processing.CreateTempFile(jobInfo.TempInput, formattedExt);
                    break;
                }

                sb.AppendFormat("{0:g}:\"{1}\" ", item.Id + startstream, item.TempFile);
                item.RawStream = true;
            }

            // add logfile to tempfiles list for deletion
            jobInfo.TempFiles.Add(
                jobInfo.VideoStream.TempFile.Substring(0, jobInfo.VideoStream.TempFile.LastIndexOf('.')) + " - Log.txt");

            if (jobInfo.Input == InputType.InputDvd)
            {
                jobInfo.TempFiles.Add(jobInfo.DumpOutput);
            }

            sb.Append("-progressNumbers -no2ndpass ");

            return(sb.ToString());
        }
        private string GenerateCommandLine()
        {
            var sb = new StringBuilder();

            if (_currentTask.Input == InputType.InputDvd)
            {
                sb.Append("-probesize 2147483647 -analyzeduration 2147483647 -fflags genpts ");
            }

            sb.Append($"-i \"{_inputFile}\" ");

            string baseName;
            string ext;

            var formattedExt = "demuxed.video.mkv";

            if (string.IsNullOrEmpty(_currentTask.TempInput))
            {
                baseName = string.IsNullOrEmpty(_currentTask.TempOutput)
                           ? _currentTask.BaseName
                           : _currentTask.TempOutput;
            }
            else
            {
                baseName = _currentTask.TempInput;
            }

            _currentTask.VideoStream.TempFile = FileSystemHelper.CreateTempFile(_appConfig.DemuxLocation,
                                                                                baseName,
                                                                                formattedExt);

            var streamID = _currentTask.Input == InputType.InputDvd
                              ? $"#0x{_currentTask.VideoStream.StreamId + 479:X}"
                              : $"0:v:{_currentTask.VideoStream.StreamKindID:0}";

            sb.Append($"-map {streamID} -c:v copy -y \"{_currentTask.VideoStream.TempFile}\" ");

            foreach (var item in _currentTask.AudioStreams)
            {
                ext = StreamFormat.GetFormatExtension(item.Format, item.FormatProfile, false);

                string acodec;
                switch (ext)
                {
                case "flac":
                    acodec = "flac";
                    break;

                case "wav":
                    acodec = "pcm_s16le";
                    break;

                default:
                    acodec = "copy";
                    break;
                }

                formattedExt = $"demuxed.audio.{item.StreamId:g}.{item.LangCode}.{ext}";

                item.TempFile =
                    FileSystemHelper.CreateTempFile(_appConfig.DemuxLocation, baseName, formattedExt);

                if (_currentTask.Input == InputType.InputDvd)
                {
                    var dvdStreamId = item.StreamId;
                    if (string.CompareOrdinal(item.Format.ToLowerInvariant(), "mpeg1") == 0 ||
                        string.CompareOrdinal(item.Format.ToLowerInvariant(), "mpeg2") == 0)
                    {
                        dvdStreamId += 256;
                    }
                    streamID = $"#0x{dvdStreamId:X}";
                }
                else
                {
                    streamID = $"0:a:{item.StreamKindId:0}";
                }

                sb.Append($"-map {streamID} -c:a {acodec} -y \"{item.TempFile}\" ");
            }

            foreach (var item in _currentTask.SubtitleStreams)
            {
                ext = "mkv";

                formattedExt = $"demuxed.subtitle.{item.StreamId:g}.{item.LangCode}.{ext}";

                item.TempFile = FileSystemHelper.CreateTempFile(_appConfig.DemuxLocation, baseName, formattedExt);

                item.RawStream = false;

                streamID = _currentTask.Input == InputType.InputDvd
                    ? $"#0x{item.StreamId:X}"
                    : $"0:s:{item.StreamKindId:0}";

                var codec = "copy";

                if (item.Format == "VobSub")
                {
                    codec = "dvd_subtitle";
                }

                sb.Append($"-map {streamID} -c:s {codec} -y \"{item.TempFile}\" ");
            }

            return(sb.ToString());
        }
        /// <summary>
        /// Generates AviSynth script used for audio encoding
        /// </summary>
        /// <param name="inputFile">Path to input file</param>
        /// <param name="inFormat">Format of input file</param>
        /// <param name="inFormatProfile">Format profile of input file</param>
        /// <param name="inChannels">Channel count of input file</param>
        /// <param name="outChannels">Target channel count</param>
        /// <param name="inSampleRate">Samplerate of input file</param>
        /// <param name="outSampleRate">Target samplerate</param>
        /// <returns>Path to AviSynth script</returns>
        public string GenerateAudioScript(string inputFile, string inFormat, string inFormatProfile,
                                          int inChannels, int outChannels, int inSampleRate,
                                          int outSampleRate)
        {
            var sb = new StringBuilder();

            var ext = StreamFormat.GetFormatExtension(inFormat, inFormatProfile, false);

            sb.AppendLine($"LoadPlugin(\"{Path.Combine(_appConfig.AvsPluginsPath, "ffms2.dll")}\")");
            sb.AppendLine($"FFAudioSource(\"{inputFile}\")");

            if (inChannels > outChannels && outChannels > 0)
            {
                sb.AppendLine($"Import(\"{Path.Combine(_appConfig.AvsPluginsPath, "audio", "ChannelDownMix.avsi")}\")");

                switch (inChannels)
                {
                case 3:
                    switch (outChannels)
                    {
                    case 2:
                        sb.AppendLine("Dmix3Stereo()");
                        break;

                    case 4:
                    case 3:
                        sb.AppendLine("Dmix3Dpl()");
                        break;

                    case 1:
                        sb.AppendLine("ConvertToMono()");
                        break;
                    }
                    break;

                case 4:
                    switch (outChannels)
                    {
                    case 2:
                        sb.AppendLine("Dmix4qStereo()");
                        break;

                    case 3:
                        sb.AppendLine("Dmix4qDpl()");
                        break;

                    case 4:
                        sb.AppendLine("Dmix4qDpl2()");
                        break;

                    case 1:
                        sb.AppendLine("ConvertToMono()");
                        break;
                    }
                    break;

                case 5:
                    switch (outChannels)
                    {
                    case 2:
                        sb.AppendLine("Dmix5Stereo()");
                        break;

                    case 3:
                        sb.AppendLine("Dmix5Dpl()");
                        break;

                    case 4:
                        sb.AppendLine("Dmix5Dpl2()");
                        break;

                    case 1:
                        sb.AppendLine("ConvertToMono()");
                        break;
                    }
                    break;

                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                    switch (outChannels)
                    {
                    case 2:
                        sb.AppendLine("Dmix6StereoLfe()");
                        break;

                    case 3:
                        sb.AppendLine("Dmix6DplLfe()");
                        break;

                    case 4:
                        sb.AppendLine("Dmix6Dpl2Lfe()");
                        break;

                    case 1:
                        sb.AppendLine("ConvertToMono()");
                        break;

                    case 6:
                        sb.AppendLine("GetChannel(1,2,3,4,5,6)");
                        break;
                    }
                    break;
                }
            }

            if (inSampleRate != outSampleRate && outSampleRate > 0)
            {
                sb.Append($"SSRC({outSampleRate},fast=False)");
                sb.AppendLine();
            }

            sb.AppendLine("return last");

            return(WriteScript(sb.ToString()));
        }
        private string GenerateCommandLine()
        {
            var sb = new StringBuilder();

            string baseFileName;

            _inputFile = string.IsNullOrEmpty(_currentTask.TempInput)
                            ? _currentTask.InputFile
                            : _currentTask.TempInput;

            if (string.IsNullOrEmpty(_currentTask.TempInput))
            {
                baseFileName = Path.Combine(_appConfig.DemuxLocation,
                                            string.IsNullOrEmpty(_currentTask.TempOutput)
                        ? _currentTask.BaseName
                        : Path.GetFileNameWithoutExtension(_currentTask.TempOutput));

                _currentTask.VideoStream.TempFile =
                    FileSystemHelper.CreateTempFile(_appConfig.DemuxLocation,
                                                    baseFileName, "demuxed.video.mkv");
            }
            else
            {
                baseFileName = Path.Combine(_appConfig.DemuxLocation,
                                            Path.GetFileNameWithoutExtension(_currentTask.TempInput));
                _currentTask.VideoStream.TempFile =
                    FileSystemHelper.CreateTempFile(_appConfig.DemuxLocation, baseFileName,
                                                    "demuxed.video.mkv");
            }

            sb.Append($"\"{_inputFile}\" {_currentTask.VideoStream.StreamId:0}:\"{_currentTask.VideoStream.TempFile}\" ");

            // on stereo sources, decide if stream for right eye should be extracted
            if (_currentTask.StereoVideoStream.RightStreamId > 0 &&
                _currentTask.EncodingProfile.StereoType != StereoEncoding.None)
            {
                _currentTask.StereoVideoStream.RightTempFile =
                    FileSystemHelper.CreateTempFile(_appConfig.DemuxLocation,
                                                    _currentTask.VideoStream.TempFile,
                                                    "right.h264");
                _currentTask.StereoVideoStream.LeftTempFile =
                    FileSystemHelper.CreateTempFile(_appConfig.DemuxLocation,
                                                    _currentTask.VideoStream.TempFile,
                                                    "left.h264");
                sb.Append($"{_currentTask.StereoVideoStream.LeftStreamId:0}:\"{_currentTask.StereoVideoStream.LeftTempFile}\" ");
                sb.Append($"{_currentTask.StereoVideoStream.RightStreamId:0}:\"{_currentTask.StereoVideoStream.RightTempFile}\" ");
            }

            string ext;
            string formattedExt;

            // process all audio streams
            foreach (var item in _currentTask.AudioStreams)
            {
                // get file extension for selected stream based on format and format profile
                ext = StreamFormat.GetFormatExtension(item.Format, item.FormatProfile, false);

                formattedExt = $"demuxed.audio.{item.StreamId:g}.{item.LangCode}.{ext}";

                item.TempFile = FileSystemHelper.CreateTempFile(_appConfig.DemuxLocation,
                                                                baseFileName,
                                                                formattedExt);

                sb.Append($"{item.Id:0}:\"{item.TempFile}\" ");
            }

            // process all subtitle streams
            foreach (var item in _currentTask.SubtitleStreams)
            {
                ext          = StreamFormat.GetFormatExtension(item.Format, string.Empty, false);
                formattedExt = $"demuxed.subtitle.{item.StreamId:g}.{item.LangCode}.{ext}";

                item.TempFile = FileSystemHelper.CreateTempFile(_appConfig.DemuxLocation,
                                                                _currentTask.TempInput,
                                                                formattedExt);

                sb.Append($"{item.Id:0}:\"{item.TempFile}\" ");
                item.RawStream = true;
            }

            // add logfile to tempfiles list for deletion
            _currentTask.TempFiles.Add(_currentTask.VideoStream.TempFile.Substring(0,
                                                                                   _currentTask.VideoStream.TempFile.LastIndexOf('.')) + " - Log.txt");

            sb.Append("-progressNumbers ");

            return(sb.ToString());
        }
        /// <summary>
        /// Generates AviSynth script used for audio encoding
        /// </summary>
        /// <param name="inputFile">Path to input file</param>
        /// <param name="inFormat">Format of input file</param>
        /// <param name="inFormatProfile">Format profile of input file</param>
        /// <param name="inChannels">Channel count of input file</param>
        /// <param name="outChannels">Target channel count</param>
        /// <param name="inSampleRate">Samplerate of input file</param>
        /// <param name="outSampleRate">Target samplerate</param>
        /// <returns>Path to AviSynth script</returns>
        public static string GenerateAudioScript(string inputFile, string inFormat, string inFormatProfile,
                                                 int inChannels, int outChannels, int inSampleRate,
                                                 int outSampleRate)
        {
            StringBuilder sb = new StringBuilder();

            string ext = StreamFormat.GetFormatExtension(inFormat, inFormatProfile, false);

            switch (ext)
            {
            case "ac3":
                sb.AppendLine(ImportNicAudio());
                sb.AppendFormat(AppSettings.CInfo, "NicAC3Source(\"{0}\")", inputFile);
                break;

            case "dts":
            case "dtshd":
                sb.AppendLine(ImportNicAudio());
                sb.AppendFormat(AppSettings.CInfo, "NicDTSSource(\"{0}\")", inputFile);
                break;

            case "mp2":
            case "mp3":
            case "mpa":
                sb.AppendLine(ImportNicAudio());
                sb.AppendFormat(AppSettings.CInfo, "NicMPG123Source(\"{0}\")", inputFile);
                break;

            default:
                sb.AppendLine(ImportFFMPEGSource());
                sb.AppendFormat(AppSettings.CInfo, "FFAudioSource(\"{0}\")", inputFile);
                break;
            }
            sb.AppendLine();

            if (inChannels > outChannels && outChannels > 0)
            {
                sb.AppendLine(string.Format(AppSettings.CInfo, "Import(\"{0:s}\")",
                                            Path.Combine(AppSettings.AppPath, "AvsPlugins", "audio",
                                                         "ChannelDownMix.avsi")));

                switch (inChannels)
                {
                case 3:
                    switch (outChannels)
                    {
                    case 2:
                        sb.AppendLine("Dmix3Stereo()");
                        break;

                    case 4:
                    case 3:
                        sb.AppendLine("Dmix3Dpl()");
                        break;

                    case 1:
                        sb.AppendLine("ConvertToMono()");
                        break;
                    }
                    break;

                case 4:
                    switch (outChannels)
                    {
                    case 2:
                        sb.AppendLine("Dmix4qStereo()");
                        break;

                    case 3:
                        sb.AppendLine("Dmix4qDpl()");
                        break;

                    case 4:
                        sb.AppendLine("Dmix4qDpl2()");
                        break;

                    case 1:
                        sb.AppendLine("ConvertToMono()");
                        break;
                    }
                    break;

                case 5:
                    switch (outChannels)
                    {
                    case 2:
                        sb.AppendLine("Dmix5Stereo()");
                        break;

                    case 3:
                        sb.AppendLine("Dmix5Dpl()");
                        break;

                    case 4:
                        sb.AppendLine("Dmix5Dpl2()");
                        break;

                    case 1:
                        sb.AppendLine("ConvertToMono()");
                        break;
                    }
                    break;

                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                    switch (outChannels)
                    {
                    case 2:
                        sb.AppendLine("Dmix6StereoLfe()");
                        break;

                    case 3:
                        sb.AppendLine("Dmix6DplLfe()");
                        break;

                    case 4:
                        sb.AppendLine("Dmix6Dpl2Lfe()");
                        break;

                    case 1:
                        sb.AppendLine("ConvertToMono()");
                        break;

                    case 6:
                        sb.AppendLine("GetChannel(1,2,3,4,5,6)");
                        break;
                    }
                    break;
                }
            }

            if (inSampleRate != outSampleRate && outSampleRate > 0)
            {
                sb.AppendFormat(AppSettings.CInfo, "SSRC({0},fast=False)", outSampleRate);
                sb.AppendLine();
            }

            sb.AppendLine("return last");

            return(WriteScript(sb.ToString()));
        }
Exemple #11
0
        /// <summary>
        /// Demux processing function, called by BackgroundWorker thread
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void DoDemux(object sender, DoWorkEventArgs e)
        {
            _bw = (BackgroundWorker)sender;

            bool use64BitEncoder = AppSettings.Use64BitEncoders &&
                                   AppSettings.Ffmpeg64Installed &&
                                   Environment.Is64BitOperatingSystem;

            string status = Processing.GetResourceString("ffmpeg_demuxing_status");

            _bw.ReportProgress(-10, status);
            _bw.ReportProgress(0, status);

            string inputFile;

            if (_jobInfo.Input == InputType.InputDvd)
            {
                inputFile = _jobInfo.DumpOutput;
            }
            else
            {
                inputFile = string.IsNullOrEmpty(_jobInfo.TempInput) ? _jobInfo.InputFile : _jobInfo.TempInput;
            }
            _jobInfo.VideoStream.TempFile = inputFile;
            try
            {
                _jobInfo.MediaInfo = Processing.GetMediaInfo(inputFile);
                if (_jobInfo.Input == InputType.InputDvd)
                {
                    _jobInfo.VideoStream = VideoHelper.GetStreamInfo(_jobInfo.MediaInfo, _jobInfo.VideoStream, false);
                }
            }
            catch (TimeoutException ex)
            {
                Log.Error(ex);
            }

            StringBuilder sb = new StringBuilder();

            if (_jobInfo.Input == InputType.InputDvd)
            {
                sb.Append("-probesize 2147483647 -analyzeduration 2147483647 -fflags genpts ");
            }

            sb.AppendFormat("-i \"{0}\" ", inputFile);

            string baseName;
            string ext;

            string formattedExt = "demuxed.video.mkv";

            if (string.IsNullOrEmpty(_jobInfo.TempInput))
            {
                baseName = string.IsNullOrEmpty(_jobInfo.TempOutput) ? _jobInfo.BaseName : _jobInfo.TempOutput;
            }
            else
            {
                baseName = _jobInfo.TempInput;
            }

            _jobInfo.VideoStream.TempFile =
                Processing.CreateTempFile(baseName, formattedExt);

            string streamID = _jobInfo.Input == InputType.InputDvd
                ? string.Format("#0x{0:X}", _jobInfo.VideoStream.StreamId + 479)
                : string.Format("0:v:{0:0}", _jobInfo.VideoStream.StreamKindID);

            sb.AppendFormat("-map {0} -c:v copy -y \"{1}\" ", streamID, _jobInfo.VideoStream.TempFile);

            foreach (AudioInfo item in _jobInfo.AudioStreams)
            {
                ext = StreamFormat.GetFormatExtension(item.Format, item.FormatProfile, false);

                string acodec;

                switch (ext)
                {
                case "flac":
                    acodec = "flac";
                    break;

                case "wav":
                    acodec = "pcm_s16le";
                    break;

                default:
                    acodec = "copy";
                    break;
                }

                formattedExt = string.Format("demuxed.audio.{0:g}.{1}.{2}", item.StreamId, item.LangCode, ext);

                if (string.IsNullOrEmpty(_jobInfo.TempInput))
                {
                    baseName = string.IsNullOrEmpty(_jobInfo.TempOutput) ? _jobInfo.BaseName : _jobInfo.TempOutput;
                }
                else
                {
                    baseName = _jobInfo.TempInput;
                }
                item.TempFile =
                    Processing.CreateTempFile(baseName, formattedExt);

                if (_jobInfo.Input == InputType.InputDvd)
                {
                    int dvdStreamId = item.StreamId;
                    if (String.CompareOrdinal(item.Format.ToLowerInvariant(), "mpeg1") == 0 ||
                        String.CompareOrdinal(item.Format.ToLowerInvariant(), "mpeg2") == 0)
                    {
                        dvdStreamId += 256;
                    }
                    streamID = string.Format("#0x{0:X}", dvdStreamId);
                }
                else
                {
                    streamID = string.Format("0:a:{0:0}", item.StreamKindId);
                }

                sb.AppendFormat("-map {0} -c:a {1} -y \"{2}\" ", streamID, acodec, item.TempFile);
            }

            foreach (SubtitleInfo item in _jobInfo.SubtitleStreams)
            {
                ext = "mkv";

                formattedExt = string.Format("demuxed.subtitle.{0:g}.{1}.{2}", item.StreamId, item.LangCode, ext);

                if (string.IsNullOrEmpty(_jobInfo.TempInput))
                {
                    baseName = string.IsNullOrEmpty(_jobInfo.TempOutput) ? _jobInfo.BaseName : _jobInfo.TempOutput;
                }
                else
                {
                    baseName = _jobInfo.TempInput;
                }

                item.TempFile = Processing.CreateTempFile(baseName, formattedExt);

                item.RawStream = false;

                streamID = _jobInfo.Input == InputType.InputDvd
                    ? string.Format("#0x{0:X}", item.StreamId)
                    : string.Format("0:s:{0:0}", item.StreamKindId);

                string codec = "copy";
                if (item.Format == "VobSub")
                {
                    codec = "dvd_subtitle";
                }

                sb.AppendFormat("-map {0} -c:s {1} -y \"{2}\" ", streamID, codec, item.TempFile);
            }

            string localExecutable = Path.Combine(AppSettings.ToolsPath, use64BitEncoder ? Executable64 : Executable);

            using (Process encoder = new Process())
            {
                ProcessStartInfo parameter = new ProcessStartInfo(localExecutable)
                {
                    WorkingDirectory      = AppSettings.DemuxLocation,
                    Arguments             = sb.ToString(),
                    CreateNoWindow        = true,
                    UseShellExecute       = false,
                    RedirectStandardError = true
                };
                encoder.StartInfo          = parameter;
                encoder.ErrorDataReceived += DemuxOnErrorDataReceived;

                Log.InfoFormat("ffmpeg {0:s}", parameter.Arguments);

                bool started;
                try
                {
                    started = encoder.Start();
                }
                catch (Exception ex)
                {
                    started = false;
                    Log.ErrorFormat("ffmpeg exception: {0}", ex);
                    _jobInfo.ExitCode = -1;
                }

                if (started)
                {
                    encoder.PriorityClass = AppSettings.GetProcessPriority();
                    encoder.BeginErrorReadLine();

                    _bw.ReportProgress(-1, status);

                    while (!encoder.HasExited)
                    {
                        if (_bw.CancellationPending)
                        {
                            encoder.Kill();
                        }
                        Thread.Sleep(200);
                    }

                    encoder.WaitForExit(10000);
                    encoder.CancelErrorRead();

                    _jobInfo.ExitCode = encoder.ExitCode;

                    if (_jobInfo.ExitCode == 0)
                    {
                        if (_jobInfo.Input == InputType.InputDvd)
                        {
                            _jobInfo.TempFiles.Add(inputFile);
                        }
                    }
                    Log.InfoFormat("Exit Code: {0:g}", _jobInfo.ExitCode);
                }
            }

            _bw.ReportProgress(100);
            _jobInfo.CompletedStep = _jobInfo.NextStep;
            e.Result = _jobInfo;
        }