コード例 #1
1
ファイル: Job.cs プロジェクト: inSight-mk1/ExpertVideoToolbox
        private void runTask(videoTask t, Process process)
        {
            this.rsForm.setPercent("0.0");
            this.rsForm.setTime("");
            this.rsForm.setFps("");
            this.rsForm.setEta("");

            string fp = t.getFP();

            process = new System.Diagnostics.Process();

            process.StartInfo.FileName = "cmd";

            // 必须禁用操作系统外壳程序
            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.CreateNoWindow         = true;
            process.StartInfo.RedirectStandardError  = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardInput  = true;

            process.ErrorDataReceived  += new DataReceivedEventHandler(OutputHandler);
            process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);

            process.Start();

            this.PIDs[0]    = process.Id;
            this.rsForm.PID = process.Id;
            this.rsForm.setStopBtnState(true);

            // 找到预设存储的文件并提取到taskSetting中
            string      tsfp = System.Windows.Forms.Application.StartupPath + "\\taskSettings\\" + t.getSetting() + ".json";
            taskSetting ts   = JsonConvert.DeserializeObject <taskSetting>(File.ReadAllText(tsfp));

            // 将encoder信息传给信息显示界面
            this.rsForm.encodingProgram = ts.encoder;
            this.rsForm.HideVideoEncoderSetting();

            cmdCode c = new cmdCode(fp, ts, this.outputFolderPath);
            string  cmd;

            int type     = c.taskType();
            int checkNum = 0;

            int       beforeProcessCheckTime = 3500;
            int       processCheckInterval   = 1000;
            const int checkF = 20;

            // 定义一个内部(匿名)方法
            // 整个视频转换过程结束时
            InnerMethodDelagate afterSuccess = delegate()
            {
                this.finishedNum++;
                this.rsForm.setStatusBarFilesCountLabel(this.finishedNum, this.num);

                try
                {
                    process.CancelErrorRead();
                    process.CancelOutputRead();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                this.rsForm.setEta("");
                this.rsForm.setFps("");
                this.rsForm.setTime("");
                this.rsForm.setEstKbps("");
                this.rsForm.SetTaskStepsLabel(true);

                Process p = Process.GetProcessById(this.PIDs[0]);
                p.Kill();
                this.rsForm.setStopBtnState(false);
                this.rsForm.setPercent("-3");
                this.isfinished[0] = true;
                this.reportCount   = 0;
                this.log.Clear();

                miniLog += t.getFP() + Environment.NewLine + Environment.NewLine + Environment.NewLine;
                saveMiniLog2File();
            };

            // 运行失败时调用
            InnerMethodDelagate afterFailed = delegate()
            {
                this.isfailed = true;

                saveLog2File();

                this.rsForm.setPercent("-1");
                this.rsForm.setTime("发生错误");
                this.rsForm.setFps("日志保存在程序目录");

                int sleepTime = 5;  // 设置失败后继续下一个任务的时间
                this.rsForm.setEta(sleepTime.ToString() + "秒后继续运行");

                this.rsForm.setStatusBarLabelTextColorRED();
                this.finishedNum++;
                this.rsForm.setStatusBarFilesCountLabel(this.finishedNum, this.num);
                this.rsForm.HideVideoEncoderSetting();

                try
                {
                    process.CancelErrorRead();
                    process.CancelOutputRead();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                Thread.Sleep(sleepTime * 1000);

                Process p = Process.GetProcessById(this.PIDs[0]);
                p.Kill();
                this.rsForm.setStopBtnState(false);
                this.rsForm.setPercent("-3");
                this.isfinished[0] = true;
                this.reportCount   = 0;
                this.log.Clear();
            };

            // 视频编码前更新UI(显示视频总帧数)
            InnerMethodDelagate DispVideoFrames = delegate()
            {
                // MediaInfo读取视频帧数
                MediaInfo MI = new MediaInfo();
                string    duration;
                string    frameRate;
                string    frames;
                MI.Open(t.getFP());
                duration = MI.Get(StreamKind.Video, 0, "Duration");
                try
                {
                    double totalTime = Double.Parse(duration) / 1000.0;
                    frameRate = MI.Get(StreamKind.Video, 0, "FrameRate");
                    frames    = ((int)(totalTime * Double.Parse(frameRate))).ToString();

                    if (!String.IsNullOrWhiteSpace(frames))
                    {
                        this.rsForm.setTime("0/" + frames);
                    }
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }
            };

            InnerMethodDelagate VideoEncode = delegate()
            {
                // 视频编码
                this.encoding = true;
                this.rsForm.setPercent("0.0");

                string ext = this.getFileExtName(t.getFP());
                if (String.Equals(ext, "avs", StringComparison.CurrentCultureIgnoreCase))
                {
                    this.videoType = AVS;
                }
                else
                {
                    this.videoType = NORMAL;
                    DispVideoFrames();
                }

                cmd = c.cmdCodeGenerate(VIDEOENCODE, this.videoType);
                process.StandardInput.WriteLine(cmd);

                try
                {
                    process.BeginErrorReadLine();
                    process.BeginOutputReadLine();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                checkNum         = 0;
                this.reportCount = 0;
                int cpx2 = this.checkPattern + this.checkPattern;
                for (int i = 0; i < cpx2; i++)
                {
                    checkFrame[i] = 0;
                }
                for (int i = 0; i < cpx2; i++)
                {
                    this.fps[i] = 0;
                }

                Thread.Sleep(beforeProcessCheckTime);

                Process p;
                switch (videoType)
                {
                case NORMAL:
                    p = GetSubTaskProcess(ts.encoder);
                    if (p != null)
                    {
                        this.subTaskPID = p.Id;
                    }
                    else
                    {
                        this.subTaskPID = -1;
                    }
                    break;

                case AVS:
                    Process avsP  = GetSubTaskProcess("avs4x265.exe");
                    int     avsId = avsP.Id;
                    if (avsP != null)
                    {
                        bool hasFound = false;

                        // 等待视频编码进程启动,最长等待1小时
                        for (int i = 0; i < 7200; i++)
                        {
                            // 确认avs进程仍在运行
                            try
                            {
                                Process.GetProcessById(avsId);
                            }
                            catch (Exception e)
                            {
                                if (this.encoding == true || ConfirmFailed())
                                {
                                    afterFailed();
                                }
                                return;
                            }

                            // 每隔500ms寻找视频编码进程
                            p = GetSubTaskProcess(ts.encoder, avsId);
                            if (p != null)
                            {
                                this.subTaskPID = p.Id;
                                hasFound        = true;
                                break;
                            }
                            else
                            {
                                Thread.Sleep(500);
                            }
                        }

                        if (!hasFound)
                        {
                            this.subTaskPID = -1;
                        }
                    }
                    else
                    {
                        this.subTaskPID = -1;
                    }
                    break;

                default:
                    break;
                }

                this.rsForm.ShowVideoEncoderSetting();

                while (this.encoding == true || this.postProcessing == true)
                {
                    try
                    {
                        Process.GetProcessById(this.subTaskPID);
                    }
                    catch (Exception e)
                    {
                        if (this.encoding == true || ConfirmFailed())
                        {
                            afterFailed();
                        }
                        return;
                    }

                    Thread.Sleep(processCheckInterval);
                }
                try
                {
                    process.CancelErrorRead();
                    process.CancelOutputRead();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                this.rsForm.HideVideoEncoderSetting();
            };

            InnerMethodDelagate Mux = delegate()
            {
                // muxer
                this.muxing = true;
                int stepIdx = type == ONLYVIDEO ? 2 : 3;
                this.rsForm.SetTaskStepsLabel(false, stepIdx, stepIdx, MUXER);

                cmd = c.cmdCodeGenerate(MUXER);
                process.StandardInput.WriteLine(cmd);

                try
                {
                    process.BeginErrorReadLine();
                    process.BeginOutputReadLine();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                checkNum = 0;

                Thread.Sleep(beforeProcessCheckTime);  // 有些超短的视频(1-2M),如果不加这句就会直接判定为任务已失败,疑似原因:没等判断完进程就已经结束

                string muxerProcessName = "";
                if (String.Equals("mp4", ts.outputFormat))
                {
                    muxerProcessName = "mp4Box";
                }
                else if (String.Equals("mkv", ts.outputFormat))
                {
                    muxerProcessName = "mkvmerge";
                }

                Process p = GetSubTaskProcess(muxerProcessName);
                if (p != null)
                {
                    this.subTaskPID = p.Id;
                }
                else
                {
                    this.subTaskPID = -1;
                }

                while (this.muxing == true)
                {
                    try
                    {
                        Process.GetProcessById(this.subTaskPID);
                    }
                    catch (Exception e)
                    {
                        Thread.Sleep(1000);
                        if (this.muxing == true)
                        {
                            afterFailed();
                        }
                        return;
                    }

                    Thread.Sleep(processCheckInterval);
                    //checkNum = checkCmdRunning(checkNum, checkF);
                    //if (checkNum == -1)
                    //{
                    //    return;
                    //}
                }

                afterSuccess();

                string tempVideoFp = c.cmdCodeGenerate(DELETEVIDEOTEMP);
                string tempAudioFp = c.cmdCodeGenerate(DELETEAUDIOTEMP);
                try
                {
                    File.Delete(tempVideoFp);
                    File.Delete(tempAudioFp);
                }
                catch (System.IO.IOException ex)
                {
                    this.log.AppendLine("出现异常:" + ex);
                    saveLog2File();
                }
            };

            // 音频编码或复制开始前更新UI(显示音频总时长)
            InnerMethodDelagate DispAudioDuration = delegate()
            {
                // MediaInfo读取音频时长
                MediaInfo MI = new MediaInfo();
                string    duration;
                MI.Open(c.getAudioSource());
                duration = MI.Get(StreamKind.Audio, 0, 69);

                if (!String.IsNullOrWhiteSpace(duration))
                {
                    this.rsForm.setTime("0/" + duration);
                }

                this.rsForm.setPercent("0.0", AUDIOENCODE);
            };

            InnerMethodDelagate ClearUIAfterAudioProcessing = delegate()
            {
                this.rsForm.setPercent("0.0");
                this.rsForm.setTime("");
                this.rsForm.setFps("");
            };

            switch (type)
            {
            case ONLYVIDEO:

                this.rsForm.SetTaskStepsLabel(false, 1, 2, VIDEOENCODE);

                VideoEncode();

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                //afterSuccess();

                Mux();

                break;

            case COPYAUDIO:
                // 复制音频
                cmd = c.cmdCodeGenerate(AUDIOCOPY);
                process.StandardInput.WriteLine(cmd);
                process.BeginErrorReadLine();
                process.BeginOutputReadLine();
                this.audioProcessing = true;
                this.rsForm.SetTaskStepsLabel(false, 1, 3, AUDIOCOPY);
                DispAudioDuration();

                checkNum = 0;

                Thread.Sleep(beforeProcessCheckTime);

                Process p = GetSubTaskProcess("ffmpeg");
                if (p != null)
                {
                    this.subTaskPID = p.Id;
                }
                else
                {
                    this.subTaskPID = -1;
                }

                while (this.audioProcessing == true)
                {
                    try
                    {
                        Process.GetProcessById(this.subTaskPID);
                    }
                    catch (Exception e)
                    {
                        Thread.Sleep(1000);
                        if (this.audioProcessing == true)
                        {
                            afterFailed();
                        }
                        return;
                    }

                    Thread.Sleep(processCheckInterval);
                    //checkNum = checkCmdRunning(checkNum, checkF);
                    //if (checkNum == -1)
                    //{
                    //    return;
                    //}
                }
                ClearUIAfterAudioProcessing();

                process.CancelErrorRead();
                process.CancelOutputRead();

                this.rsForm.SetTaskStepsLabel(false, 2, 3, VIDEOENCODE);

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                VideoEncode();

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                Mux();

                break;

            case SUPPRESSAUDIO:
                // 音频编码
                cmd = c.cmdCodeGenerate(AUDIOENCODE);
                process.StandardInput.WriteLine(cmd);
                process.BeginErrorReadLine();
                process.BeginOutputReadLine();
                this.audioProcessing = true;
                this.rsForm.SetTaskStepsLabel(false, 1, 3, AUDIOENCODE);
                DispAudioDuration();

                checkNum = 0;

                Thread.Sleep(beforeProcessCheckTime);

                Process p2 = GetSubTaskProcess(ts.audioEncoder);
                if (p2 != null)
                {
                    this.subTaskPID = p2.Id;
                }
                else
                {
                    this.subTaskPID = -1;
                }

                while (this.audioProcessing == true)
                {
                    try
                    {
                        Process.GetProcessById(this.subTaskPID);
                    }
                    catch (Exception e)
                    {
                        Thread.Sleep(1000);
                        if (this.audioProcessing == true)
                        {
                            afterFailed();
                        }
                        return;
                    }

                    Thread.Sleep(processCheckInterval);
                    //checkNum = checkCmdRunning(checkNum, checkF);
                    //if (checkNum == -1)
                    //{
                    //    return;
                    //}
                }
                ClearUIAfterAudioProcessing();

                process.CancelErrorRead();
                process.CancelOutputRead();

                this.rsForm.SetTaskStepsLabel(false, 2, 3, VIDEOENCODE);

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                VideoEncode();

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                Mux();

                break;

            default:
                cmd = "";
                break;
            }

            //MessageBox.Show(cmd);
        }
コード例 #2
0
        private void saveSetting2File(string name)
        {
            taskSetting ts = new taskSetting(name, this.encoderCB.Text, this.fileFormatCB.Text, this.cmdCodeTB.Text,
                                             this.audioEncoderCB.Text, this.profileCB.Text, this.codecModeCB.Text, this.bitrateOrQualityCB.Text,
                                             this.bitrateOrQualityCB.Text);
            string fp = System.Windows.Forms.Application.StartupPath + "\\taskSettings\\" + name + ".json";

            File.WriteAllText(fp, JsonConvert.SerializeObject(ts));
        }
コード例 #3
0
        // 检查预设与UI显示的有无不同, 结果1和0分别表示真和假,-1表示预设不存在
        private int checkSettingChange()
        {
            string fp = System.Windows.Forms.Application.StartupPath + "\\taskSettings\\" + this.encodeSettingCB.Text + ".json";

            try
            {
                taskSetting ts = JsonConvert.DeserializeObject <taskSetting>(File.ReadAllText(fp));
                if (String.Equals(this.encoderCB.Text, ts.encoder) &&
                    String.Equals(this.fileFormatCB.Text, ts.outputFormat) &&
                    String.Equals(this.cmdCodeTB.Text, ts.encoderSetting) &&
                    String.Equals(this.audioEncoderCB.Text, ts.audioEncoder) &&
                    (String.Equals(this.profileCB.Text, ts.audioProfile) || this.profileCB.Enabled == false) &&
                    (String.Equals(this.codecModeCB.Text, ts.audioCodecMode) || this.codecModeCB.Enabled == false) &&
                    (String.Equals(this.bitrateOrQualityCB.Text, ts.audioQuality) || this.bitrateOrQualityCB.Enabled == false))
                {
                    return(0);  // false表示没有变化
                }
                return(1);
            }
            catch (System.IO.IOException)
            {
                return(-1);
            }
        }