FFMPEG获取帧和降低码率|青训营笔记

473 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第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命令查看使用安装和环境配置是否成功,成功打印如下

    image.png

项目中的使用

获取某一帧

本来项目当中使用的是七牛云去存储视频文件,可以通过七牛云的开发者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是一个功能很强大的工具,可以进行视频的格式转换,精确到帧数的截取,但是本项目当中只使用了抽取第一帧和降低码率的功能,以后还是可以多了解多学习这个工具的使用,以实现更多的功能。