Golang 调用 FFMpeg

在写视频相关的业务逻辑,发几个代码出来备用。

  1. goav 好像不维护了
  2. 目前在使用 u2takey/ffmpeg-go 这个包。虽然 star 数量不高……

按 FPS 抽帧

ffCmd := ffmpeg.Input(inputFile)
ffCmd = ffCmd.Filter("fps", nil, ffmpeg.KwArgs{
    "fps": "1",  // 1 FPS
})
ffCmd = ffCmd.Output(filepath.Join(tmpFolder, "/%08d.png"),
    ffmpeg.KwArgs{
        "format":   "image2", // https://ffmpeg.org/ffmpeg-formats.html#image2-1
        "qscale:v": 2,        // Fixed quality scale to assure quality
        "vsync":    "vfr",    // https://ffmpeg.org/ffmpeg.html#Advanced-options
    })

if err := ffCmd.Run(); nil != err {
    return nil, err
}

大致分为三部分:输入,Filter,输出。

输出部分 vsyncqscale:v 好像没啥用。qscale 好像会让画面变大一点。

不过我还是没研究出来如何按照帧号或时间来命名。

按场景变换抽帧

将 Filter 部分改成这样:

ffCmd = ffCmd.Filter("fps", nil, ffmpeg.KwArgs{"fps": "2"}).
    Filter("select", ffmpeg.Args{"gt(scene,0.08)"})

大致是,先按照 FPS 抽,然后再在结果中过滤出来场景变换比较大的帧。

抽音频

ffCmd := ffmpeg.Input(inputFile)
ffCmd =  ffCmd.Output("output/audio.pcm", ffmpeg.KwArgs{
	"vn": "", // No video
	// "acodec": "pcm_s16le", // Codec
	"f":  "u8", // Unsigned, 8 bit
	"ac": "1",  // Only one sound track
})

if err := ffCmd.Run(); nil != err {
	return nil, err
}

这里是抽成了单声道 pcm 格式。如果需要其他格式,那么去看 ffmpeg 的文档就好

如何看文档

  1. 参数名称里面有写「这个参数可用于哪里」,比如可用于 Input 或者 Input/Output 都可用
  2. 根据例子,写代码。如果是只有 key 没 value 的情况,写到 ffmpeg.Args 里,或者写到 ffmpeg.KwArgs 里,value 为空字符串;如果有 key 有 value,那么写到 ffmpeg.KwArgs 里。
  3. 可以用 Compile() 看看生成出来的命令行和网上找的命令行是否一致。

Posted

in

,

by

Tags:

Comments

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注