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); }
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)); }
// 检查预设与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); } }