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