/// <summary>
        /// tries to open the video source and gets the number of frames from it, or
        /// exits with an error
        /// </summary>
        /// <param name="videoSource">the AviSynth script</param>
        /// <param name="error">return parameter for all errors</param>
        /// <returns>true if the file could be opened, false if not</returns>
        protected void getInputProperties(VideoJob job)
        {
            //VapourSynthHelper vsHelper = new VapourSynthHelper();
            //vsHelper.LoadScriptFile(job.Input);
            VSPipeInfo vsHelper = new VSPipeInfo(job.Input, job.VspipeArgs);

            fps_n              = vsHelper.FpsNum;
            fps_d              = vsHelper.FpsDen;
            NumberOfFrames     = (ulong)vsHelper.TotalFreams;
            job.NumberOfFrames = NumberOfFrames;
            if (fps_n == job.FpsNum && fps_d == job.FpsDen)
            {
                return;
            }
            if (job.Vfr)
            {
                job.FpsNum = (uint)fps_n;
                job.FpsDen = (uint)fps_d;
                job.Fps    = (fps_n + 0.0) / fps_d;
                return;
            }
            OKETaskException ex = new OKETaskException(Constants.fpsMismatchSmr);

            ex.progress        = 0.0;
            ex.Data["SRC_FPS"] = ((double)job.FpsNum / job.FpsDen).ToString("F3");
            ex.Data["DST_FPS"] = ((double)fps_n / fps_d).ToString("F3");
            throw ex;
        }
        /// <summary>
        /// tries to open the video source and gets the number of frames from it, or
        /// exits with an error
        /// </summary>
        /// <param name="videoSource">the AviSynth script</param>
        /// <param name="error">return parameter for all errors</param>
        /// <returns>true if the file could be opened, false if not</returns>
        protected void getInputProperties(VideoJob job)
        {
            //VapourSynthHelper vsHelper = new VapourSynthHelper();
            //vsHelper.LoadScriptFile(job.Input);
            VSPipeInfo vsHelper = new VSPipeInfo(job.Input);

            fps_n          = vsHelper.FpsNum;
            fps_d          = vsHelper.FpsDen;
            numberOfFrames = (ulong)vsHelper.TotalFreams;
            // su.ClipLength = TimeSpan.FromSeconds((double)numberOfFrames / fps);
        }
Beispiel #3
0
 public RpcJob(string sourceFile, VideoJob videoJob)
 {
     Input      = sourceFile;
     Output     = Path.ChangeExtension(sourceFile, "rpc");
     RippedFile = videoJob.Output;
     TotalFrame = videoJob.NumberOfFrames;
     foreach (string arg in videoJob.VspipeArgs)
     {
         int    pos      = arg.IndexOf('=');
         string variable = arg.Substring(0, pos);
         string value    = arg.Substring(pos + 1);
         Args[variable] = value;
     }
 }
Beispiel #4
0
        public X264Encoder(VideoJob job) : base()
        {
            this.job = job;
            getInputProperties(job);

            executable = Path.Combine(Environment.SystemDirectory, "cmd.exe");

            if (File.Exists(job.EncoderPath))
            {
                this.X264Path = job.EncoderPath;
            }

            // 获取VSPipe路径
            this.VspipePath = Initializer.Config.vspipePath;

            commandLine = BuildCommandline(job.EncodeParam, job.NumaNode, job.VspipeArgs);
        }
        /// <summary>
        /// tries to open the video source and gets the number of frames from it, or
        /// exits with an error
        /// </summary>
        /// <param name="videoSource">the AviSynth script</param>
        /// <param name="error">return parameter for all errors</param>
        /// <returns>true if the file could be opened, false if not</returns>
        protected void getInputProperties(VideoJob job)
        {
            //VapourSynthHelper vsHelper = new VapourSynthHelper();
            //vsHelper.LoadScriptFile(job.Input);
            VSPipeInfo vsHelper = new VSPipeInfo(job.Input, job.VspipeArgs);

            fps_n          = vsHelper.FpsNum;
            fps_d          = vsHelper.FpsDen;
            NumberOfFrames = (ulong)vsHelper.TotalFreams;
            if (fps_n != job.FpsNum || fps_d != job.FpsDen)
            {
                OKETaskException ex = new OKETaskException(Constants.fpsMismatchSmr);
                ex.progress        = 0.0;
                ex.Data["SRC_FPS"] = ((double)job.FpsNum / job.FpsDen).ToString("F3");
                ex.Data["DST_FPS"] = ((double)fps_n / fps_d).ToString("F3");
                throw ex;
            }

            // su.ClipLength = TimeSpan.FromSeconds((double)numberOfFrames / fps);
        }
Beispiel #6
0
        public void Start()
        {
            // TODO: 只考虑完整的视频压制流程
            if (job.JobType != "video")
            {
                return;
            }

            VideoJob vjob = job as VideoJob;

            // 抽取音轨
            FileInfo eacInfo = new FileInfo(".\\tools\\eac3to\\eac3to.exe");

            if (!eacInfo.Exists)
            {
                throw new Exception("Eac3to 不存在");
            }
            EACDemuxer eac         = new EACDemuxer(eacInfo.FullName, vjob.config.InputFile);
            var        audioTracks = eac.Extract((double progress, EACProgressType type) => {
                switch (type)
                {
                case EACProgressType.Analyze:
                    vjob.config.Status        = "轨道分析中";
                    vjob.config.ProgressValue = progress;
                    break;

                case EACProgressType.Process:
                    vjob.config.Status        = "抽取音轨中";
                    vjob.config.ProgressValue = progress;
                    break;

                case EACProgressType.Completed:
                    vjob.config.Status        = "音轨抽取完毕";
                    vjob.config.ProgressValue = progress;
                    break;

                default:
                    return;
                }
            });

            // 默认列表是按照顺序来
            string audioTrack = audioTracks[0].OutFileName;

            // 音频转码
            List <string> audioFile = new List <string>();

            foreach (var track in vjob.config.AudioTracks)
            {
                var    audioOutput  = audioTracks[track.TrackId];
                string audioOutpath = audioOutput.OutFileName;

                if (track.Format.ToUpper() == "AAC")
                {
                    vjob.config.Status        = "音轨转码中";
                    vjob.config.ProgressValue = -1;

                    if (audioOutput.FileExtension == ".flac")
                    {
                        AudioJob aDecode = new AudioJob("WAV");
                        aDecode.Input  = audioOutput.OutFileName;
                        aDecode.Output = "-";
                        FLACDecoder flac = new FLACDecoder(".\\tools\\flac\\flac.exe", aDecode);

                        AudioJob aEncode = new AudioJob("AAC");
                        aEncode.Input  = "-";
                        aEncode.Output = Path.ChangeExtension(audioOutpath, ".aac");
                        QAACEncoder qaac = new QAACEncoder(".\\tools\\qaac\\qaac.exe", aEncode, track.Bitrate);

                        CMDPipeJobProcessor cmdpipe = CMDPipeJobProcessor.NewCMDPipeJobProcessor(flac, qaac);
                        cmdpipe.start();
                        cmdpipe.waitForFinish();

                        audioOutpath = aEncode.Output;
                    }
                }

                var audioFileInfo = new FileInfo(audioOutpath);
                if (audioFileInfo.Length < 1024)
                {
                    // 无效音轨
                    // TODO: 提示用户不能封装
                    File.Move(audioOutpath, Path.ChangeExtension(audioOutpath, ".bak") + audioFileInfo.Extension);
                    continue;
                }

                if (!track.SkipMuxing)
                {
                    audioFile.Add(audioOutpath);
                }
            }

            vjob.config.Status = "获取信息中";
            IJobProcessor processor = x265Encoder.init(vjob, vjob.config.EncoderParam);

            vjob.config.Status        = "压制中";
            vjob.config.ProgressValue = 0.0;
            processor.start();
            processor.waitForFinish();

            if (vjob.config.ContainerFormat != "")
            {
                // 封装
                vjob.config.Status = "封装中";
                FileInfo mkvInfo = new FileInfo(".\\tools\\mkvtoolnix\\mkvmerge.exe");
                if (!mkvInfo.Exists)
                {
                    throw new Exception("mkvmerge不存在");
                }

                FileInfo lsmash = new FileInfo(".\\tools\\l-smash\\muxer.exe");
                if (!lsmash.Exists)
                {
                    throw new Exception("l-smash 封装工具不存在");
                }

                AutoMuxer muxer = new AutoMuxer(mkvInfo.FullName, lsmash.FullName);
                muxer.ProgressChanged += progress => vjob.config.ProgressValue = progress;

                List <string> mergeList = new List <string> {
                    vjob.config.InputFile + ".hevc",
                    Path.ChangeExtension(vjob.config.InputFile, ".txt"),
                };
                mergeList.AddRange(audioFile);

                muxer.StartMerge(mergeList, vjob.Output);
            }

            vjob.config.Status        = "完成";
            vjob.config.ProgressValue = 100;
        }