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"
                }
            }
        }
相关推荐
2501_941982054 小时前
深度对比:Java、Go、Python 实现企微外部群推送,哪个效率更高?
java·golang·企业微信
参.商.11 小时前
【Day 27】121.买卖股票的最佳时机 122.买卖股票的最佳时机II
leetcode·golang
牛奔11 小时前
如何理解 Go 的调度模型,以及 G / M / P 各自的职责
开发语言·后端·golang
牛奔12 小时前
Go 是如何做抢占式调度的?
开发语言·后端·golang
炼金术13 小时前
SkyPlayer v1.2.0 : AI 字幕-端侧 Whisper 实时语音识别实践
ffmpeg·openai
清云随笔14 小时前
Golang基础
golang
硫酸锌0115 小时前
使用ffmpeg合并文件夹内的所有*.mp4格式视频
ffmpeg·音视频
源文雨15 小时前
shell调用ffmpeg递归转换所有wav至flac的脚本
ffmpeg·bash·音视频·音频·unix·shell·音频编码
西部秋虫15 小时前
迷你视频会议系统(FlashMeeting)
opencv·ffmpeg·视频会议·回声抑制
牛奔18 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang