微信公众号“CSharp编程大全”的文章《C#从视频提取图片?》介绍了基于Microsoft.DirectX.AudioVideoPlayback.Video类实现从视频提取图片的方式,本来是想学习并测试该类的用法,但实际测试过程中却没有测通。百度从视频提取图片,网上用的较多的是用ffmpeg,本文记录调用ffmpeg从视频提取图片的基本用法。
从官网文档来看(如下图所示),ffmpeg.exe支持通过不同的参数配置按多种模式提取图片,主要包括以下几种:
1)按视频流逐帧导出。下面的命令从视频中按一秒钟一帧的方式导出jpeg格式的图片,主要的参数包括:-i,指定源视频文件地址,-r,设置视频流的帧率,-s,设定视频的画面大小,-f,设置设定文件格式,如果是图片,则是image2,最后是设置导出文件的文件名;
ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg
2)将视频指定时间段内容导出为图片。下面的命令从视频中指定时间点提取指定时长内的所有帧的图片,主要参数包括:-i,指定源视频文件地址,-ss,从指定时间开始转换,以秒为单位,-t,指定输出文件的持续时间,以秒为单位,-f,设置设定文件格式,如果是图片,则是image2,最后是设置导出文件的文件名;
ffmpeg -i foo.avi -ss startseconds -t seconds -f image2 foo-%03d.jpeg
3)将视频指定帧数的内容导出为图片。下面的命令从视频中指定时间点开始提取指定帧数的图片,主要参数包括-i,指定源视频文件地址,-ss,从指定时间开始转换,以秒为单位,-vframes,等价于frames:v,指定输出的视频帧数目,-f,设置设定文件格式,如果是图片,则是image2,最后是设置导出文件的文件名。
ffmpeg -i foo.avi -ss startseconds -vframes seconds -f image2 foo-%03d.jpeg
根据上述说明,编写简单的测试程序,支持按时间段和按帧数导出图片,关键代码如下:
//按时间段导图片
process.StartInfo.FileName = "ffmpeg.exe";
process.StartInfo.Arguments = @$"-i {txtVideoFile.Text} -ss {Convert.ToInt32(nudStart.Value)} -t {Convert.ToInt32(nudEnd.Value - nudStart.Value)} -f image2 {txtImgDir.Text + "\\" + "foo-%03d.jpeg"}";
process.Start();
//按帧数导图片
process.StartInfo.FileName = "ffmpeg.exe";
process.StartInfo.Arguments = @$"-i {txtVideoFile.Text} -ss {Convert.ToInt32(nudStart.Value)} -vframes {Convert.ToInt32(nudEnd.Value - nudStart.Value)} -f image2 {txtImgDir.Text + "\\" + "foo-%03d.jpeg"}";
process.Start();
测试程序界面如下图所示:
参考文献:
[1]https://blog.csdn.net/weixin_68436326/article/details/134047021
[2]http://ffmpeg.org/ffmpeg.html#Video-Options
[3]https://blog.csdn.net/chinaherolts2008/article/details/122611791
[4]https://blog.csdn.net/angzhuo9931/article/details/101931713
[5]https://blog.csdn.net/weixin_44350205/article/details/105886069
[6]https://zhuanlan.zhihu.com/p/637199541