golang 使用 FFmpeg 截取视频第一帧实例 | 青训营笔记

2,316 阅读2分钟

使用 FFmpeg 截取视频第一帧并保存案例

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

运行准备

由于需要使用 FFmpeg 第三方工具来完成视频截取第一帧作为封面并存储到本机,

所以运行之前需要预先安装 FFmpeg 到本机并配置好环境变量。

我这里使用的是 ffmpeg version 5.0.1-full_build 版本。

参考链接:FFmpeg

项目结构

假设有这样一个案例:assets 文件夹中是专门存放视频的,现在的要求就是将该视频的第一帧截取为图片并保存。

 D:.
 │  go.mod
 │  go.sum
 │  
 ├─.idea
 │      .gitignore
 │      modules.xml
 │      testvideo.iml
 │      thriftCompiler.xml
 │      workspace.xml
 │
 ├─assets
 │      test.mp4
 │
 └─controller
         main.go

主要是调用 GetSnapshot() 函数

第一个参数是 视频的相对地址,第二个参数是截出来的图片的名称,返回值是图片的相对路径

func GetSnapshot(videoPath, snapshotPath string) (snapshotName string, err error)

main.go

 package main
 ​
 import (
     "bytes"
     "fmt"
     "log"
     "os"
     "strings"
     "github.com/disintegration/imaging"
     ffmpeg "github.com/u2takey/ffmpeg-go"
 )
 ​
 func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string, err error) {
     snapshotPath = "./assets/" + snapshotPath
     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)
         return "", err
     }
 ​
     img, err := imaging.Decode(buf)
     if err != nil {
         log.Fatal("生成缩略图失败:", err)
         return "", err
     }
 ​
     err = imaging.Save(img, snapshotPath+".png")
     if err != nil {
         log.Fatal("生成缩略图失败:", err)
         return "", err
     }
 ​
     fmt.Println("--snapshotPath--", snapshotPath)
     // --snapshotPath-- ./assets/testImage
 ​
     names := strings.Split(snapshotPath, "\")
     fmt.Println("----names----", names)
     // ----names---- [./assets/testImage]
     // 这里把 snapshotPath 的 string 类型转换成 []string
 ​
     snapshotName = names[len(names)-1] + ".png"
     fmt.Println("----snapshotName----", snapshotName)
     // ----snapshotName---- ./assets/testImage.png
 ​
     return snapshotName, nil
 }
 ​
 func main() {
     name, err := GetSnapshot("./assets/test.mp4", "testImage", 1)
     if err != nil {
         log.Fatal(err)
         return
     }
     fmt.Println("return:", name)
 }
 ​

完成之后发现项目的 assets 已经多了一个 testImage.png 文件,说明已经成功了!

 D:.
 │  go.mod
 │  go.sum
 │  
 ├─.idea
 │      .gitignore
 │      modules.xml
 │      testvideo.iml
 │      thriftCompiler.xml
 │      workspace.xml
 │
 ├─assets
 │      test.mp4
 │      testImage.png
 │
 └─controller
         main.go

解决方法

若生成失败,可能存在的问题:

1、安装 FFmpeg 之后,没有配置环境变量。可以使用 cmd 输入 ffmpeg -version 验证是否配置成功。

1.png

2、可以尝试以管理员身份运行 goland