var origFilePath = "C:/MyOriginalFile.webm";
var processedFilePath = "C:/MyProcessedFile.webm";
RunFfmpeg($"-i \"{origFilePath}\" -af \"silenceremove=1:0.1:0.001, areverse, silenceremove=1:0.1:0.001, areverse\" \"{processedFilePath}\" -y");
// fails with IOException as the file presumably not been released by FFmpeg
System.IO.File.Delete(origFilePath);
当文件被删除时,以下异常经常(可能是80%的时间)抛出:
IOException:进程无法访问文件&C; \ MyOriginalFile.webm'因为它正被另一个进程使用。
创建和运行FFmpeg进程的调用如下:
private List<string> RunFfmpeg(string arguments)
{
using (var process = new Process())
{
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.FileName = _hostingEnvironment.ContentRootPath + _settings.FfmpegPath;
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
// ffmpeg only uses strerr for its output
var output = new List<string>();
process.ErrorDataReceived += new DataReceivedEventHandler((s, e) => {
if (e.Data != null)
output.Add(e.Data);
});
process.Start();
process.BeginErrorReadLine();
process.WaitForExit();
return output;
}
}
即使删除文件时进程已完成,但FFmpeg仍处理或未发布。
预计会出现这种情况吗?在继续之前,如何确保FFmpeg已完成文件处理?
答案 0 :(得分:0)
如果是我,我会在后台线程上运行它并点击process.Exited
事件并尝试删除那里的文件。
MSDN Documentation for the Process Exit Event使用此策略并轮询30秒,直到Exited事件触发并检查ExitCode。根据ExitCode,您可以给它更多时间,检查文件是否仍然被锁定或执行另一个操作,直到process.ExitCode == 0
private Process myProcess = new Process();
private int elapsedTime;
private bool eventHandled;
public void RunFfmpeg(string arguments)
{
elapsedTime = 0;
eventHandled = false;
try
{
myProcess.StartInfo.FileName = _hostingEnvironment.ContentRootPath + _settings.FfmpegPath;
myProcess.StartInfo.Arguments = arguments;
myProcess.StartInfo.CreateNoWindow = true;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(myProcess_Exited);
myProcess.Start();
}
catch (Exception ex)
{
Console.WriteLine("An error occurred trying to print \"{0}\":" + "\n" + ex.Message, fileName);
return;
}
// Wait for Exited event, but not more than 30 seconds.
const int SLEEP_AMOUNT = 100;
while (!eventHandled)
{
elapsedTime += SLEEP_AMOUNT;
if (elapsedTime > 30000)
{
break;
}
Thread.Sleep(SLEEP_AMOUNT);
}
}
private void myProcess_Exited(object sender, System.EventArgs e)
{
eventHandled = true;
Console.WriteLine("Exit time: {0}\r\n" +
"Exit code: {1}\r\nElapsed time: {2}", myProcess.ExitTime, myProcess.ExitCode, elapsedTime);
}