这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记
背景
青训营抖音大项目当中,需要对上传上来的视频进行处理来得到视频的封面,本来以为有库可以直接对视频流进行一个处理得到帧,但是查找过后好像发现并没有。
在网上查找过后发现有两种方式: 1. gocv,使用golang的库去调用OpenCV对视频进行一个处理,来获取封面,但是感觉有点杀鸡用牛刀的感觉,所以这个方法放弃。 2. FFMPEG,通过go命令行操作FFMPEG,对视频进行处理,获取封面,FFMPEG感觉比较轻便,可行性也高,所以采用此方法。
FFMPEG
简介
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、MaxOS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。FFmpeg编码库可以使用GPU加速。
安装
Ubuntu下
Ubuntu下比较简单,我这里是Ubuntu20.04,直接用apt就能安装好
sudo apt update
sudo apt install ffmpeg
验证安装,使用ffmpeg -version命令查看是否有打印版本信息
ffmpeg -version
Windows下
-
到官网中下载,最好下载full版本,链接:ffmpeg.org/download.ht…
-
下载完文件之后解压,并且将文件目录下bin文件夹的路径添加进系统环境变量当中
-
打开cmd使用ffmpeg命令查看使用安装和环境配置是否成功,成功打印如下
项目中的使用
获取某一帧
本来项目当中使用的是七牛云去存储视频文件,可以通过七牛云的开发者api直接将前端传来的视频直接上传至七牛云存储空间,但是现在需要截取一个封面,发现FFMPEG不能直接对文件流进行操作,所以就先本地暂存视频,截取封面后再一起上传至云存储空间,上传完毕后删除本地视频和封面截图。
//{...}先将视频暂存到本地,获取视频路径,创建预设的存放截图的路径
cmd := exec.Command("ffmpeg", "-i", videoPath, "-y", "-f", "mjpeg", "-ss", "0.1", "-t", "0.001", coverPath)
//{...}对视频和封面进行处理
如果需要设置截图的大小的话可以加上 -s xxx*xxx (xxx表示高度或宽度的值)
降低码率
由于项目原本未对视频进行压缩,如果上传的视频太大的话,会导致用户等待时间过长,也会占用更多的服务器资源,所以也是用FFMPEG对视频进行一个压缩,这里采取的是降低码率。试验效果为可将150M左右的视频压缩成10M,所提升的效率还是蛮大的。
func compressedVideo(oldVideoPath, videoPath string) {
defer os.Remove(oldVideoPath)
//压缩视频(减小码率)
cmd := exec.Command("ffmpeg", "-i", oldVideoPath, "-b:v", "1.5M", videoPath)
if err := cmd.Run(); err != nil {
log.Println("执行ffmpeg压缩视频失败:", err)
return
}
}
总结
FFMPEG是一个功能很强大的工具,可以进行视频的格式转换,精确到帧数的截取,但是本项目当中只使用了抽取第一帧和降低码率的功能,以后还是可以多了解多学习这个工具的使用,以实现更多的功能。