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);
}