这是我参与「第三届青训营 -后端场」笔记创作活动的第二篇笔记
在项目开发过程中,我们小组遇到了一些比较不知道如何下手,花了比较长时间的问题,这里整理几个问题。
截取视频封面
我们小组使用ffmpeg截取视频封面,这个用起来方便又有效,可以自己更改输入的参数,来确定截取的封面是视频第几帧的,通常截取视频第一帧。ffmpeg除了截取视频某帧图片外,还可以执行音频和视频多种格式的录影、转换、串流等许多功能。
ffmpeg环境配置
首先需要下载ffmpeg这个程序,下载地址:FFbinaries - Download binaries for ffmpeg, ffprobe, ffserver and ffplay (cross-platform: Windows, Mac, Linux)
根据电脑系统选择下载的,下载完后得到一个exe文件,把他放置到环境变量的GOPATH下的bin文件夹里即可。
然后是在项目中从GitHub拉取两个依赖
首先是 go get -u github.com/u2takey/ffmpeg-go,这个是ffmpeg的仓库
然后是 go get -u github.com/disintegration/imaging,imaging依赖,用于对图片的操作,保存图片等。
到这里就可以用了,有个要注意的点是,先写代码然后再用go mod tidy的话不能拉取所有需要的依赖,因此还是得手动拉取一下,接下来就是代码部分。
代码部分
首先可以看看以下GitHub库: u2takey/ffmpeg-go: golang binding for ffmpeg (github.com)
从视频里截取封面图片需要用到的是源码里的以下部分
稍微改了一下,以下是改动后的代码
引用部分,有些是不需要的,因为函数写在publish里面,所有有许多多余的,主要是ffmpeg "..."这个需要手动添加,不然不会自动识别到并添加,会爆红
import (
"bytes"
"fmt"
"github.com/disintegration/imaging"
"github.com/gin-gonic/gin"
ffmpeg "github.com/u2takey/ffmpeg-go"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"time"
)
函数部分
// 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。
这里需要注意一点,就是names := ...这一行第二个参数"/"可能会由于系统不同而有不同,我用的win10是/,可能其他系统会是\,这个根据本地文件路径来定。frameNum可以指定是截取视频的哪一帧,通常用第一帧。
以上便是抖音(极简版)项目截取视频封面的问题整理。