1

C#调用ffmpeg

已有 172 人阅读此文 --本站

8. C#调用FFMPEG,并异步读取输出信息的代码...

public void ConvertVideo()

{

       Process p = new Process();//建立外部调用线程

       p.StartInfo.FileName = @"c:/ffmpeg.exe";//要调用外部程序的绝对路径

       p.StartInfo.Arguments = "-i XXXXXXXXXXXXXX";//参数(这里就是FFMPEG的参数了)

       p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)

       p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...这是我耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)

       p.StartInfo.CreateNoWindow = false;//不创建进程窗口

       p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN

       p.Start();//启动线程

       p.BeginErrorReadLine();//开始异步读取

       p.WaitForExit();//阻塞等待进程结束

       p.Close();//关闭进程

       p.Dispose();//释放资源

}

private void Output(object sendProcess, DataReceivedEventArgs output)

{

 if (!String.IsNullOrEmpty(output.Data))

 {

          //处理方法...

     }

}

9.最近完成了这个小Demo,来分享一下!

这里讲一下重要的:

1.用到两个工具,一个是ffmpeg.exe,另一个是mencoder.exe

ffmpeg最新版本的下载地址:http://ffdshow.faireal.net/mirror/ffmpeg/

Mencoder新版本的下载地址:http://www5.mplayerhq.hu/MPlayer/releases/win32/

这里有一个重点,网上的文章都没讲到,所以造成有些人运行后没反应,原因是上面路径的下载,有很多版本,不同的版本可能个别参数不同,而网上的文章所用的参数都是用很早的版本写的,所以会造成运行后因参数错误而没有效果

简单处理是:把网上参数在cmd命令行执行一下,这时命令行会报哪个参数错误,把它删了即可!

2.判断处理成功与失败或是进度是否完成,从异步获取的输出信息判断[包括获取原视频的宽与高]

这里重点在两个委托事件中,详情见以下几行代码

private void StartProcess(string tool)

3         {

4             StartProcess(tool, false);

5         }

6        private void StartProcess(string tool,bool onlyCheckInfo)

7         {

8             System.Diagnostics.Process p = new System.Diagnostics.Process();

9             p.StartInfo.FileName = tool;

10             p.StartInfo.Arguments = commandPara;

11             p.StartInfo.UseShellExecute = false;

12             p.StartInfo.RedirectStandardInput = true;

13             p.StartInfo.RedirectStandardOutput = true;

14             p.StartInfo.RedirectStandardError = true;

15             p.StartInfo.CreateNoWindow = false;

16             p.OutputDataReceived += newSystem.Diagnostics.DataReceivedEventHandler(p_OutputDataReceived);

17            if (onlyCheckInfo)//只检测文件是否可转换与获到内部宽与高

18             {

19                 p.ErrorDataReceived += newSystem.Diagnostics.DataReceivedEventHandler(p_CheckInfoDataReceived);

20             }

21            else

22             {

23                 p.ErrorDataReceived += newSystem.Diagnostics.DataReceivedEventHandler(p_ErrorDataReceived);

24             }

25            //开始执行

26            try

27             {

28                 p.Start();

29                 p.BeginOutputReadLine();

30                 p.BeginErrorReadLine();

31                 p.WaitForExit();

32             }

33            catch (Exception err)

34             {

35                 Console.WriteLine(err.Message);

36             }

37            finally

38             {

39                 p.Close();

40             }

41         }

42        void p_CheckInfoDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)

43         {

44            if (!string.IsNullOrEmpty(e.Data))

45             {

46                if (e.Data.Contains("Stream") && e.Data.Contains("Video:"))//设置原视频窗口大小作为flv视频的宽与高

47                 {

48                     Match match = Regex.Match(e.Data, @", (/d+)x(/d+)");

49                    if (match != null)

50                     {

51                         videoWidth = match.Groups[1].Value;

52                         videoHeight = match.Groups[2].Value;

53                     }

54                 }

55                else if (e.Data.Contains("could not find codec parameters"))//ffmpeg转换失败

56                 {

57                     isCanChangeToFlv = false;

58                     Program.SetDataBase(id, 1, count + 1);

59                 }

60             }

61

62         }

63

64         void p_ErrorDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)

65         {

66            if (!string.IsNullOrEmpty(e.Data))

67             {

68                if (e.Data.Contains("video:") && e.Data.Contains("muxing overhead"))//ffmpeg转换完成

69                 {

70                     Program.SetDataBase(id, 2, count + 1);

71                     Console.WriteLine("转换完成");

72                 }

73                 Console.WriteLine(e.Data);

74             }

75            

76         }

77

78         void p_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)

79         {

80            if (!string.IsNullOrEmpty(e.Data))

81             {

82                if (e.Data.Contains("Writing index"))//mencoder转换完成

83                 {

84                     Program.SetDataBase(id, 2, count + 1);

85                     Console.WriteLine("转换完成");

86                 }

87                //else if (e.Data.Contains("Exiting"))//mencoder转换失败

88                //{

89                //    Console.WriteLine("转换失败");

90                //}

91                 Console.WriteLine(e.Data);

92             }

93         }

3:Youtube的成功,使得国内的视频网站如雨后春笋般的冒出来,前不久朋友叫我帮他写一个将各种视频格式转换成flv的程序,这里就将编写程序遇到困难和获得的经验拿出来和大家分享一下。

1、使用引擎:ffmpeg + Mencoder

2、ffmpeg最新版本的下载地址:http://ffdshow.faireal.net/mirror/ffmpeg/

Mencoder新版本的下载地址:http://www5.mplayerhq.hu/MPlayer/releases/win32/

3、转换速度比较:总体上ffmpeg转换的速度快于Mencoder

4、转换格式要求:rm、rmvb、rt格式的文件只能用Mencoder转换,出于速度考虑我基本上都用ffmpeg转换,所以Mencoder能转换的格式我没有详细测试(哪个朋友知道,麻烦你告诉我下,我补充上去)。

5、纯音频格式只能用Mencoder进行转换。如何判断是否是纯音频格式可以通过使用命令 FFmpeg -i "文件的完整路径" 获得输出后就可以分析出来。

6、.mov格式的用ffmpeg转换出来的效果比较差,建议用Mencoder进行转换,wmv8用ffmpeg经常会有花屏产生建议用Mencoder。

7、视频按比率输出的问题:必须先获取源视频文件的宽度和高度(也是通过 FFmpeg -i "文件的完整路径" 获得输出后就可以分析出来)根据这个高度和宽度的比率来设定输出文件的尺寸。

8、可能的难点:因为这ffmpeg 和 Mencoder都是命令行工具(当然你也可以下载源代码自己修改成com之类的),在C#只能用Process调用,

前面我提过要获得输出信息(获取视频相关信息、获取当前的转换进度、获取什么时候完成转换),

必须设置process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true;

然后必须通过异步编程的方式获取Process.StandardOutput和Process.StandardError的值,

相关说明可以见(ms-help://MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfSystemDiagnosticsProcessClassStandardOutputTopic.htm)(必须安装了msdn的才能看)。

0
相关评论
0 / 500
发表
暂无相关评论...