跳转到主内容
极星编程网:以代码为星,赴技术山海!

解析Golang中的简单视频信息提取工具 Go语言FFmpeg指令调用

ffmpeg卡住主因是stderr未读取致管道阻塞;提取元数据应优先用ffprobe而非ffmpeg -i;解析JSON需处理字段缺失与类型漂移;Windows下需确保架构匹配且路径正确。 为什么
os/exec.Command
调用
ffmpeg
常卡住或没输出 根本原因是
ffmpeg
默认把进度信息(如帧数、码率、时间戳)写到
stderr
,而很多 Go 代码只等
stdout
或直接忽略错误流,导致进程看似“卡死”——其实它在持续往
stderr
打印。更糟的是,如果没显式读取
stderr
,管道缓冲区满后
ffmpeg
就会阻塞。 实操建议: 立即学习 “ go语言免费学习笔记(深入) ”; 必须同时启动
stdout
和
stderr
的读取 goroutine,哪怕你只关心其中一部分 用
cmd.StdoutPipe()
和
cmd.StderrPipe()
分别获取,别用
cmd.CombinedOutput()
——它会吞掉关键的进度流,且无法实时解析 对
stderr
建议用
bufio.Scanner
行读取,避免因某行超长导致阻塞 加上
-v quiet -print_format json
这类静默+结构化输出参数,比自己 parse 文本行更稳 提取时长/分辨率/编码格式,该用
ffprobe
还是
ffmpeg -i
ffprobe
是专为元数据设计的工具,输出稳定、字段明确、无副作用;
ffmpeg -i
只是把输入信息当日志打出来,格式随版本浮动,还可能触发解码(比如遇到损坏帧就卡住)。除非你顺带想验证文件可播性,否则别用
ffmpeg -i
提取基本信息。 实操建议: 立即学习 “ go语言免费学习笔记(深入) ”; 优先调用
ffprobe -v quiet -show_entries format=duration:stream=width,height,codec_name -of default=nw=1
若需 JSON 输出便于 Go 解析,加
-of json
,但注意:Go 的
json.Unmarshal
对
ffprobe
的数组字段(如多路 stream)默认映射为
[]interface{}
,需提前定义 struct 别漏掉
-v quiet
——否则
ffprobe
会在开头打印一堆版本和编译信息,污染结构化输出 对 MP4/MKV 等容器,
format.duration
可能为空(依赖 moov 位置),此时得 fallback 到
stream_tags.DURATION
或靠
ffprobe -show_entries packet=duration_ts
算总时长 Go 中解析
ffprobe
JSON 输出容易崩在哪几个点 常见崩法不是语法错,而是字段缺失或类型漂移:
ffprobe
对不同格式返回的字段不一致(比如 GIF 没
duration
,WebP 可能没有
codec_name
),且同一字段在不同版本里可能从 string 变成 number(如
bit_rate
)。 go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载 实操建议: 立即学习 “ go语言免费学习笔记(深入) ”; 定义 struct 时所有字段用指针或
interface{}
,例如
Duration *float64
,避免 Unmarshal 失败 用
json.RawMessage
先接整个 stream 数组,再按需解析每项,防止某路流字段异常拖垮全部 对数值型字段(如
width
,
height
),先用
json.Number
解,再转
int
,避免 float64 精度误差 永远检查
err != nil
后再访问字段,别信 “这个视频肯定有宽高” Windows 下找不到
ffprobe.exe
或提示 “不是有效的 Win32 应用程序” 前者多半是 PATH 没配或路径含空格没引号;后者八成是你下了 32 位
ffprobe
却在 64 位 Go 程序里调用(或反过来),Windows 会静默拒绝加载。 实操建议: 立即学习 “ go语言免费学习笔记(深入) ”; 用绝对路径调用,例如
C:\tools\ffprobe.exe
,并在 Go 里用
filepath.Join
拼接,避免手动拼错斜杠 检查 Go 构建目标:运行
go env GOARCH
,确保下载的 FFmpeg 包匹配(amd64 / arm64) 别用第三方打包版(如某些“绿色版”),它们常删了
ffprobe.exe
只留
ffmpeg.exe
;去官网 ffmpeg.org/download 下 full build 调用前先
os.Stat
检查文件是否存在且可执行,比等 runtime 报错更早发现问题 真正麻烦的从来不是调用命令本身,而是
ffprobe
返回的字段像天气一样 unpredictable,还有 Windows 上二进制 ABI 的隐形对齐问题——这两块不提前压住,后面加再多重试逻辑都没用。

相关文章