avformat_open_input用于打开音视频文件并初始化AVFormatContext,必须配合avformat_find_stream_info才能获取准确的时长和分辨率;其duration单位为微秒,宽高需遍历流查找AVMEDIA_TYPE_VIDEO类型并读取codecpar->width/height。

用 FFmpeg 的 avformat_open_input 获取视频时长和分辨率
直接调用 FFmpeg C API 是最可靠的方式,不依赖外部命令或封装库。关键在于打开文件后解析流信息,而不是读帧——避免耗时解码。
-
avformat_open_input打开文件后必须调用avformat_find_stream_info,否则duration和codecpar->width/height可能为 0 或无效值 - 视频流通常在
AVMediaType::AVMEDIA_TYPE_VIDEO类型的流中,但有些文件(如某些 MP4)可能把视频流索引不是 0,需遍历ic->streams查找 -
AVFormatContext::duration单位是微秒(AV_TIME_BASE),要除以AV_TIME_BASE转成秒;若为AV_NOPTS_VALUE,说明容器没写 duration,得 fallback 到stream->duration * av_q2d(stream->time_base) - 分辨率从
stream->codecpar->width和stream->codecpar->height读,注意:有些编码(如 AV1)可能含旋转标志(codecpar->sample_aspect_ratio或 extradata 中的rotation),但宽高本身不含旋转
为什么不用 cv::VideoCapture?
OpenCV 的 cv::VideoCapture 在某些格式(尤其是 HEVC、AV1、部分 MOV)上会失败或返回 0×0 分辨率,且 CAP_PROP_POS_MSEC 无法代表总时长——它只是当前帧时间戳,不是媒体时长。
-
cap.get(cv::CAP_PROP_FRAME_COUNT)对大多数非 AVI 容器返回 -1,不可靠 -
cap.get(cv::CAP_PROP_POS_AVI_RATIO)仅对 AVI 有效,其他格式行为未定义 - OpenCV 默认不启用硬件解码,打开大文件时可能卡住数秒甚至崩溃,而 FFmpeg 可设
AVFMT_NOFILE标志跳过实际 I/O 初始化
轻量替代方案:调用 ffprobe 命令行并解析 JSON
如果项目不允许链接 FFmpeg 库,用 ffprobe -v quiet -print_format json -show_entries format=duration,stream=width,height -show_entries stream_tags=rotate input.mp4 是最快落地方式。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 务必加
-v quiet,否则 stderr 会混入日志干扰 JSON 解析 - JSON 输出里
streams[0].width不一定对应视频流,需检查streams[0].codec_type == "video",建议用jq '.streams[] | select(.codec_type=="video") | {width, height, duration}' input.json预处理 - Windows 下注意路径空格,要用双引号包裹文件路径:
ffprobe ".../my video.mp4" - macOS/Linux 上
ffprobe通常随ffmpeg一起安装;Windows 需单独下载静态 build 并确保PATH包含其目录
常见错误:avformat_open_input 返回负值或分辨率全为 0
这不是代码写错,而是输入文件损坏、路径权限不足,或 FFmpeg 编译时没启用对应 demuxer(比如没编译 mov 支持却去读 MP4)。
立即学习“C++免费学习笔记(深入)”;
- 检查返回值:
if (ret —— <code>av_err2str能输出具体原因,如Invalid data found when processing input - 确认
av_register_all()(旧版)或avformat_network_init()(新版)已调用;FFmpeg 4.0+ 已自动注册,但若静态链接且裁剪了组件,仍可能缺失 - 某些网络流或加密 MP4(如 Apple FairPlay)无法获取元数据,FFmpeg 会静默失败,此时
ffprobe同样报错,需提前判断协议类型
真正麻烦的是带 DRM 或自定义 moov box 的私有格式,这种连 ffprobe 都无能为力,只能靠厂商提供 SDK —— 但这种情况极少出现在通用场景里。

















