ffmpeg-go库的介绍

ffmpeg-go is a Go programming language wrapper for the FFmpeg multimedia framework. It allows developers to easily integrate FFmpeg functionalities into their Go applications, such as decoding and encoding audio and video files, converting media formats, and applying various filters and effects. FFmpeg-go provides a simple and intuitive API, making it easier for Go developers to utilize the powerful multimedia features of FFmpeg.

本质上ffmpeg-go是对命令行ffmpeg工具的封装,最终功能的实现都是通过在go里执行命令行工具来实现。

我们来看个例子。

在go代码中调用ffprobe命令行工具。

Go 复制代码
// 包装ffprobe工具
// Probe Run ffprobe on the specified file and return a JSON representation of the output.
func Probe(fileName string, kwargs ...KwArgs) (string, error) {
	return ProbeWithTimeout(fileName, 0, MergeKwArgs(kwargs))
}

// 为命令行执行ffprobe增加timeout
func ProbeWithTimeout(fileName string, timeOut time.Duration, kwargs KwArgs) (string, error) {
	args := KwArgs{
		"show_format":  "",
		"show_streams": "",
		"of":           "json",
	}

	return ProbeWithTimeoutExec(fileName, timeOut, MergeKwArgs([]KwArgs{args, kwargs}))
}


// 生成ffprobe命令行执行用到的参数
func ProbeWithTimeoutExec(fileName string, timeOut time.Duration, kwargs KwArgs) (string, error) {
	args := ConvertKwargsToCmdLineArgs(kwargs)
	args = append(args, fileName)
	ctx := context.Background()

    // 将超时转换为context控制
	if timeOut > 0 {
		var cancel func()
		ctx, cancel = context.WithTimeout(context.Background(), timeOut)
		defer cancel()
	}
	cmd := exec.CommandContext(ctx, "ffprobe", args...)
	buf := bytes.NewBuffer(nil)
	stdErrBuf := bytes.NewBuffer(nil)
	cmd.Stdout = buf
	cmd.Stderr = stdErrBuf
	for _, option := range GlobalCommandOptions {
		option(cmd)
	}

    // 运行命令行的命令
    // 实际运行的是: ffprobe -of json -show_format -show_streams ${fileName}
	err := cmd.Run()
	if err != nil {
		return "", fmt.Errorf("[%s] %w", string(stdErrBuf.Bytes()), err)
	}
	return string(buf.Bytes()), nil
}

输出示例:

Go 复制代码
 "streams": [
                {
                    "index": 0,
                    "codec_name": "h264",
                    "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
                    "profile": "Main",
                    "codec_type": "video",
                    "codec_tag_string": "avc1",
                    "codec_tag": "0x31637661",
                    "width": 320,
                    "height": 240,
                    "coded_width": 320,
                    "coded_height": 240,
                    "closed_captions": 0,
                    "film_grain": 0,
                    "has_b_frames": 0,
                    "sample_aspect_ratio": "1:1",
                    "display_aspect_ratio": "4:3",
                    "pix_fmt": "yuv420p",
                    "level": 13,
                    "chroma_location": "left",
                    "field_order": "progressive",
                    "refs": 1,
                    "is_avc": "true",
                    "nal_length_size": "4",
                    "id": "0x1",
                    "r_frame_rate": "30000/1001",
                    "avg_frame_rate": "30000/1001",
                    "time_base": "1/90000",
                    "start_pts": 0,
                    "start_time": "0.000000",
                    "duration_ts": 627627,
                    "duration": "6.973633",
                    "bit_rate": "251413",
                    "bits_per_raw_sample": "8",
                    "nb_frames": "209",
                    "extradata_size": 37,
                    "disposition": {
                        "default": 1,
                        "dub": 0,
                        "original": 0,
                        "comment": 0,
                        "lyrics": 0,
                        "karaoke": 0,
                        "forced": 0,
                        "hearing_impaired": 0,
                        "visual_impaired": 0,
                        "clean_effects": 0,
                        "attached_pic": 0,
                        "timed_thumbnails": 0,
                        "captions": 0,
                        "descriptions": 0,
                        "metadata": 0,
                        "dependent": 0,
                        "still_image": 0
                    },
                    "tags": {
                        "language": "und",
                        "handler_name": "VideoHandler",
                        "vendor_id": "[0][0][0][0]"
                    }
                },
                {
                    "index": 1,
                    "codec_name": "aac",
                    "codec_long_name": "AAC (Advanced Audio Coding)",
                    "profile": "LC",
                    "codec_type": "audio",
                    "codec_tag_string": "mp4a",
                    "codec_tag": "0x6134706d",
                    "sample_fmt": "fltp",
                    "sample_rate": "44100",
                    "channels": 2,
                    "channel_layout": "stereo",
                    "bits_per_sample": 0,
                    "initial_padding": 0,
                    "id": "0x2",
                    "r_frame_rate": "0/0",
                    "avg_frame_rate": "0/0",
                    "time_base": "1/44100",
                    "start_pts": 0,
                    "start_time": "0.000000",
                    "duration_ts": 310272,
                    "duration": "7.035646",
                    "bit_rate": "125587",
                    "nb_frames": "303",
                    "extradata_size": 2,
                    "disposition": {
                        "default": 1,
                        "dub": 0,
                        "original": 0,
                        "comment": 0,
                        "lyrics": 0,
                        "karaoke": 0,
                        "forced": 0,
                        "hearing_impaired": 0,
                        "visual_impaired": 0,
                        "clean_effects": 0,
                        "attached_pic": 0,
                        "timed_thumbnails": 0,
                        "captions": 0,
                        "descriptions": 0,
                        "metadata": 0,
                        "dependent": 0,
                        "still_image": 0
                    },
                    "tags": {
                        "language": "und",
                        "handler_name": "SoundHandler",
                        "vendor_id": "[0][0][0][0]"
                    }
                }
            ],
            "format": {
                "filename": "./examples/sample_data/in1.mp4",
                "nb_streams": 2,
                "nb_programs": 0,
                "format_name": "mov,mp4,m4a,3gp,3g2,mj2",
                "format_long_name": "QuickTime / MOV",
                "start_time": "0.000000",
                "duration": "7.035646",
                "size": "336833",
                "bit_rate": "383001",
                "probe_score": 100,
                "tags": {
                    "major_brand": "isom",
                    "minor_version": "512",
                    "compatible_brands": "isomiso2avc1mp41",
                    "encoder": "Lavf57.71.100"
                }
            }
        }
相关推荐
Aevget7 小时前
智能高效Go开发工具GoLand v2025.3全新上线——新增资源泄漏分析
开发语言·ide·后端·golang·go
haibindev8 小时前
【终极踩坑指南】Windows 10上MsQuic证书加载失败?坑不在证书,而在Schannel!
直播·http3·quic·流媒体
asdfg12589639 小时前
小程序开发中的JS和Go的对比及用途
开发语言·javascript·golang
2501_941881409 小时前
在墨西哥城复杂流量环境下构建高稳定性API网关的架构设计与实现实践分享
macos·golang·xcode
天远云服10 小时前
Go语言高并发实战:集成天远手机号码归属地核验API打造高性能风控中台
大数据·开发语言·后端·golang
源代码•宸12 小时前
Leetcode—1161. 最大层内元素和【中等】
经验分享·算法·leetcode·golang
七夜zippoe15 小时前
Spring Data JPA原理与实战 Repository接口的魔法揭秘
java·ffmpeg·事务·jpa·repository
Benny的老巢15 小时前
n8n工作流中FFmpeg 视频截取失败排查:文件路径和参数顺序错误解决方案
chrome·ffmpeg·音视频
Thetimezipsby1 天前
Go(GoLang)语言基础、知识速查
开发语言·后端·golang
we have a whole life1 天前
Golang(Handler入门)
开发语言·http·golang