这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天
在青训营大项目的开发中,有一个需求需要将上传后的视频,进行抽帧获取封面给的操作。显然手动编写这个功能是非常麻烦的事情,不仅需要对视频进行解码操作,还有涉及到很多麻烦的问题。
经过搜索,发现可以使用ffmpeg的工具来处理多媒体信息,比如视频处理,编码解码,转码操作。我们的这个视频中抽取封面帧的操作也是可以直接使用ffmpeg工具来操作的。
安装
要使用ffmpeg工具,首先需要在计算机上安装这个程序。可以在官网上直接下载符合自己系统的对应版本。
完成安装后,需要在命令行输入ffmpeg来确认ffmpeg是否安装成功。
go拓展安装
如果要使用ffmpeg,如果使用go调用命令行工具会相对来说比较麻烦,因此我们可以站在巨人的肩膀上——使用现成的封装好的框架调用ffmpeg。
ffmpeg-go
使用命令go get github.com/u2takey/ffmpeg-go进行安装。
截取帧
ffmpeg-go主要使用了链式结构的api,因此我们可以链式调用接口。
要想使用ffmpeg截取第一帧,首先我们就需要输入文件。
filePath = "./xxx.mp4"
ffmpeg.Input(filePath)
上方的代码调用了ffmpeg下的Input方法,用于从给定的路径中读取视频文件。但是在文件上传后,视频文件是在内存中传递进来的,我们首先就需要将视频文件保存到硬盘中,才能使用ffmpeg进行操作。
要临时保存文件,我们可以使用临时文件夹的功能,将视频文件临时保存到某个目录中,然后进行ffmpeg的处理,处理完成后再进行删除。
我们的需求是截取这个视频的第一帧,通过查阅文档,发现可以使用Filter函数来进行。
buf := bytes.NewBuffer(nil)
err := ffmpeg.Input(filePath).
Filter("select", ffmpeg.Args{fmt.Sprintf("gte(n,%03d)", 1)}).
Output("pipe:", ffmpeg.KwArgs{"vframes": 1, "format": "image2", "vcodec": "mjpeg", "pattern_type": "none"}).
WithOutput(buf, os.Stdout).
Run()
阅读代码 可以发现主要是调用了Filter的select功能,然后传入参数"gte(n,1)"。代表截取第一帧。
完成截取后可以使用Output函数来输出,参数中主要指定了一些输出的格式,帧数等等。
最后将输出结果拷贝到buf中,完成整个截取第一帧的过程。最后就是简单的对照片进行编解码,存储到硬盘中的操作。