隐藏

C#使用FFmpeg 将视频格式转换成MP4示例

发布:2021/3/20 18:12:05作者:管理员 来源:本站 浏览次数:1016

一、常用视频格式分辨率

  • 640x480p
  • 720p格式,分辨率为1280×720p / 60Hz,行频为45kHz
  • 1080p格式,分辨率为1920×1080逐行扫描,专业格式

二、FFmpeg部分参数说明:


  1. //参数说明
  2. /*
  3. * -i filename(input) 源文件目录
  4. * -y 输出新文件,是否强制覆盖已有文件
  5. * -c 指定编码器
  6. * -fs limit_size(outinput) 设置文件大小的限制,以字节表示的。没有进一步的字节块被写入后,超过极限。输出文件的大小略大于所请求的文件大小。
  7. * -s 视频比例 4:3 320x240/640x480/800x600 16:9 1280x720 ,默认值 'wxh',和原视频大小相同
  8. * -vframes number(output) 将视频帧的数量设置为输出。别名:-frames:v
  9. * -dframes number (output) 将数据帧的数量设置为输出.别名:-frames:d
  10. * -frames[:stream_specifier] framecount (output,per-stream) 停止写入流之后帧数帧。
  11. * -bsf[:stream_specifier] bitstream_filters (output,per-stream) 指定输出文件流格式,
  12. 例如输出h264编码的MP4文件:ffmpeg -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264
  13. * -r 29.97 桢速率(可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)
  14. *
  15. */

三、使用实例代码:


  1. public class Demo2
  2. {
  3. public static string ffmpegtool = @"F:\SolutionSet\ABCSolution\VideoSolution\Demo1\bin\Debug\ffmpeg.exe";
  4. //public static string ffmpegtool = @"F:\ABCSolution\ffmpeg-20160808-ce2217b-win64-static\bin\ffplay.exe";
  5. public static string playFile = @"F:\SolutionSet\ABCSolution\VideoSolution\VideoSolution\Content\Video\my3.mp4";
  6. public static string imgFile = @"F:\SolutionSet\ABCSolution\VideoSolution\VideoSolution\Content\Video\my3.gif";
  7. public static string sourceFile = @"F:\SolutionSet\ABCSolution\VideoSolution\VideoSolution\Content\Video\COOLUI.mp4";
  8. //public static string sourceFile = @"F:\ABCSolution\VideoSolution\VideoSolution\Content\Video\theme.mp4";
  9. public void ConvertVideo()
  10. {
  11. Process p = new Process();//建立外部调用线程
  12. p.StartInfo.FileName = ffmpegtool;//要调用外部程序的绝对路径
  13. //参数(这里就是FFMPEG的参数了)
  14. //p.StartInfo.Arguments = @"-i "+sourceFile+ " -ab 56 -b a -ar 44100 -b 500 -r 29.97 -s 1280x720 -y " + playFile+"";
  15. // p.StartInfo.Arguments = "-y -i \""+sourceFile+"\" -b v -s 800x600 -r 29.97 -b 1500 -acodec aac -ac 2 -ar 24000 -ab 128 -vol 200 -f psp \""+playFile+"\" ";
  16. //string strArg = "-i " + sourceFile + " -y -s 640x480 " + playFile + " ";
  17. string strArg = "-i " + sourceFile + " -y -s 1280x720 " + playFile + " ";
  18. //获取图片
  19. //截取图片jpg
  20. //string strArg = "-i " + sourceFile + " -y -f image2 -t 1 " + imgFile;
  21. //string strArg = "-i " + sourceFile + " -y -s 1280x720 -f image2 -t 1 " + imgFile;
  22. //视频截取
  23. //string strArg = " -i " + sourceFile + " -y -ss 0:20 -frames 100 " + playFile;
  24. //转化gif动画
  25. //string strArg = "-i " + sourceFile + " -y -s 1280x720 -f gif -vframes 30 " + imgFile;
  26. //string strArg = " -i " + sourceFile + " -y -f gif -vframes 50 " + imgFile;
  27. // string strArg = " -i " + sourceFile + " -y -f gif -ss 0:20 -dframes 10 -frames 50 " + imgFile;
  28. //显示基本信息
  29. //string strArg = "-i " + sourceFile + " -n OUTPUT";
  30. //播放视频
  31. //string strArg = "-stats -i " + sourceFile + " ";
  32. p.StartInfo.Arguments = strArg;
  33. p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)
  34. p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...这是我耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)
  35. p.StartInfo.CreateNoWindow = false;//不创建进程窗口
  36. p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
  37. p.Start();//启动线程
  38. p.BeginErrorReadLine();//开始异步读取
  39. p.WaitForExit();//阻塞等待进程结束
  40. p.Close();//关闭进程
  41. p.Dispose();//释放资源
  42. }
  43. private void Output(object sendProcess, DataReceivedEventArgs output)
  44. {
  45. if (!String.IsNullOrEmpty(output.Data))
  46. {
  47. //处理方法...
  48. Console.WriteLine(output.Data);
  49. 去获取时长
  50. //string partitio1 = @"Duration: \d{2}:\d{2}:\d{2}.\d{2}";
  51. //if (RegexHelper.IsMatch(partitio1, output.Data))
  52. //{
  53. // string partition = @"(?<=Duration: )\d{2}:\d{2}:\d{2}.\d{2}";
  54. // string timespan = RegexHelper.Matchs(output.Data, partition).FirstOrDefault();
  55. // TimeSpan span;
  56. // if (TimeSpan.TryParse(timespan, out span))
  57. // {
  58. // Console.WriteLine(span.TotalMilliseconds);
  59. // }
  60. //}
  61. 获取时刻
  62. //string partitio2 = @"time=\d{2}:\d{2}:\d{2}.\d{2}";
  63. //if (RegexHelper.IsMatch(partitio2, output.Data))
  64. //{
  65. // string partition = @"(?<=time=)\d{2}:\d{2}:\d{2}.\d{2}";
  66. // string timespan = RegexHelper.Matchs(output.Data, partition).FirstOrDefault();
  67. // TimeSpan span;
  68. // if (TimeSpan.TryParse(timespan, out span))
  69. // {
  70. // Console.WriteLine(span.TotalMilliseconds);
  71. // }
  72. //}
  73. }
  74. }
  75. }