这个是我今天整理项目的时候无意发现的,当时主要是用它来转换flv文件在手机上使用,后来买了psp之后就没有用了,记录一下,以后写这种类似的程序可以参考。
class VideoConverter : IDisposable
{
public string InputFile { get; private set; }
public string OutPutFile { get; private set; }
public int Progress { get; private set; }
public object Tag { get; set; }
double totalTime;
public VideoConverter(string input, string output)
{
InputFile = input;
OutPutFile = output;
}
~VideoConverter()
{
Dispose();
}
const string ffmpeg_exe = "ffmpeg.exe";
/// <summary>
/// 这个是个阻塞调用,切勿在ui线程上调用
/// </summary>
public void Process()
{
var sb = new StringBuilder();
ExcuteProcess(ffmpeg_exe, string.Format(" -i \"{0}\"", InputFile), (s, e) => sb.AppendLine(e.Data));
var totalT = SimpleMatch(sb.ToString(), @"Duration:\s+(\S+?)[,\s]");
var totalTs = TimeSpan.Parse(totalT);
totalTime = totalTs.TotalSeconds;
ExcuteProcess(ffmpeg_exe, string.Format(" -i \"{0}\" \"{1}\" ", InputFile, OutPutFile), (s, e) => ProcessOutPut(e.Data));
Progress = 100;
Console.WriteLine("-----------{0}---------", Progress);
}
string SimpleMatch(string data, string patten)
{
Console.WriteLine(data);
var m = System.Text.RegularExpressions.Regex.Match(data, patten);
return m.Groups[1].Value;
}
void ExcuteProcess(string exe, string arg, DataReceivedEventHandler output)
{
Console.WriteLine(exe + " " + arg);
using (var p = new Process())
{
killHanlder = p.Kill;
p.StartInfo.FileName = exe;
p.StartInfo.Arguments = arg;
p.StartInfo.UseShellExecute = false; //输出信息重定向
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.OutputDataReceived += output;
p.ErrorDataReceived += output;
p.Start(); //启动线程
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit(); //等待进程结束
}
killHanlder = null;
}
void ProcessOutPut(string output)
{
Console.WriteLine(output);
if (string.IsNullOrEmpty(output))
return;
if (!output.Contains("time="))
return;
var current = SimpleMatch(output, @"time=(\S+)");
var currentTime = double.Parse(current);
Progress = (int)(currentTime * 100 / totalTime);
if (Progress > 100)
Progress = 100;
Console.WriteLine("-----------{0}---------", Progress);
}
#region IDisposable 成员
Action killHanlder;
public void Dispose()
{
if (killHanlder == null)
return;
killHanlder();
killHanlder = null;
}
#endregion
}