希曼日记

ffmpeg 截取视频第一帧

package test

import (
	"bytes"
	"fmt"
	"github.com/disintegration/imaging"
	ffmpeg "github.com/u2takey/ffmpeg-go"
	"log"
	"os"
	"strings"
	"testing"
)

func TestV(t *testing.T) {
	// 参数 1: 根据主入口文件的相对路径的文件, 
	// 参数 2: 输出的 image文件的位置
	// 参数 3: 截取的帧数, 1 表示视频第一帧
	name, err := GetSnapshot("./assets/video/1.mp4", "1", 1)
	if err != nil {
		log.Fatal(err)
		return
	}
	fmt.Println("return:", name)
}

func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string, err error) {
	// 给快照路径加上前缀, 需要修改的地方, 根据实际需要
	snapshotPath = "./assets/video/fm/" + snapshotPath

	// 创建一个空的字节缓冲区
	buf := bytes.NewBuffer(nil)

	// 使用ffmpeg从视频中提取指定帧
	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
	}

	// 保存图片为PNG格式
	err = imaging.Save(img, snapshotPath+".jpg")
	if err != nil {
		log.Fatal("生成缩略图失败:", err)
		return "", err
	}

	// 打印快照路径
	fmt.Println("--snapshotPath--", snapshotPath)

	// 分割路径
	names := strings.Split(snapshotPath, "/")
	fmt.Println("----names----", names)

	// 获取图片的名称
	snapshotName = names[len(names)-1]
	fmt.Println("----snapshotName----", snapshotName)

	return snapshotName, nil
}

在宿主机安装ffmpeg并挂载到alpine容器: /home/ffmpeg-6.0-amd64-static:/usr/local/binffmpeg所在的目录挂载到alpine 的环境变量

alpine 的环境变量通过docker exec -it <容器> echo $PATH得到, 挂载到它返回的任意一个目录即可, 例如/usr/local/bin

示例输出:

docker exec -it tiktok echo $PATH

-> /root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
version: '3'

services:
  tiktok:
    image: docker.io/library/tiktok
    container_name: tiktok
    restart: always
    ports:
      - "8080:8080"
      - "4000:4000"
    volumes:
      - ./configs:/data/conf
      - /home/ffmpeg-6.0-amd64-static:/usr/local/bin
    environment:
      - TZ=Asia/Shanghai
    command: ["/app/tiktok", "-conf", "/data/conf/production.yaml", "sh", "-c", "export PATH=\"/ffmpeg:$PATH\" && source /etc/profile"]

参考

  1. https://github.com/u2takey/ffmpeg-go
  2. https://juejin.cn/post/7107959471355199495
  3. http://ffmpeg.org/