GoLang 项目实战:通过视频生成缩略图作为封面|青训营笔记

1,548 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第 2 篇笔记

前言
在完成青训营的考核项目时,涉及到为用户投稿的视频生成缩略图的问题
我一想这肯定不是我能写出来的(好像也确实,不是因为懒 T.T)
通过一顿找资料,最后锁定了 FFmpeg 这个工具,并顺利生成了缩略图,在这里和大家分享一下~

——IceClean

1. 配置 FFmpeg 环境

1) 简介
官方介绍:FFmpeg 是一个开放源代码的自由软件,可以执行音频和视频多种格式的录影、转换、串流功能 官网源代码:ffmpeg.org/download.ht… (虽然最后没用到但还是放出来)

2) 下载
真正发挥作用的是这个 go 版本的仓库:github.com/u2takey/ffm…
go get -u github.com/u2takey/ffmpeg-go 将依赖拉到本地就可以直接使用了

但在看了官方的例子之后,发现还需要再装一个 imaging 依赖,如下:
go get -u github.com/disintegration/imaging
这个看名字,应该是用来解析生成的图片的,项目中最后保存图片的动作也是由它来完成

真正运行的时候,发现又又又有一个问题:"ffmpeg": executable file not found in %PATH%
原因是环境变量中找不到 ffmpeg 这个程序,需要手动配置进去
我是在这里下载的:ffbinaries.com/downloads image.png

下载完会得到一个 .exe 文件,放置到 GOPATH 下的 bin 目录即可 (更正)
默认路径为 C:\Users\xxx\go\bin

到这里,所有需要的环境都已经配置完成了,接下来进入实操

2. 生成缩略图

自己写了一个工具类,用来通过视频文件生成缩略图(也是通过 github 官方示例更改的):

// GetSnapshot 生成视频缩略图并保存(作为封面)
func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string) {
   buf := bytes.NewBuffer(nil)
   err := ffmpeg.Input(videoPath).
      Filter("select", ffmpeg.Args{fmt.Sprintf("gte(n,%d)", frameNum)}).
      Output("pipe:", ffmpeg.KwArgs{"vframes": 1, "format": "image2", "vcodec": "mjpeg"}).
      WithOutput(buf, os.Stdout).
      Run()
   if err != nil {
      log.Fatal("生成缩略图失败:", err)
   }

   img, err := imaging.Decode(buf)
   if err != nil {
      log.Fatal("生成缩略图失败:", err)
   }

   err = imaging.Save(img, snapshotPath+".jpeg")
   if err != nil {
      log.Fatal("生成缩略图失败:", err)
   }

   // 成功则返回生成的缩略图名
   names := strings.Split(snapshotPath, "\")
   snapshotName = names[len(names)-1] + ".jpeg"
   return
}

传入的参数分别是:
视频的路径 videoPath
生成的缩略图保存的路径 snapshotPath
以及缩略图所属的帧数 frameNum
返回值则是缩略图的文件名称: snapshotName

其中 frameNum 可以指定要截取视频的哪一帧作为封面,一般情况下第一帧就可以,但有的视频第一帧并不是视频的主体内容,而是一些其他的东西,所以为了获得一个比较好的封面,就可以通过调整帧数截取稍微靠后的几秒作为封面


520,我在发博客 i^i

——IceClean