FFmpeg:av_dump_format输出错误元数据,ffprobe显示正常的问题求助
问题:av_dump_format无法正确显示MP3流信息
我在Windows系统上使用如下配置编译了FFmpeg 7.1源码:
configuration: --toolchain=msvc --arch=x86_64 --enable-x86asm --enable-asm --enable-shared --enable-w32threads --prefix=/D/build
使用av_dump_format打印test.mp3元数据时输出无效流信息,代码如下:
extern "C" { #include <libavformat/avformat.h> } int main() { av_log_set_level(AV_LOG_DEBUG); auto url = "D:/music/test.mp3"; AVFormatContext* fmt; auto ret = avformat_open_input(&fmt, url, nullptr, nullptr); if (ret < 0) { av_log(nullptr, AV_LOG_ERROR, "Cannot open %s format : %s", url, av_err2str(ret)); exit(EXIT_FAILURE); } av_dump_format(fmt, 0, url, 0); }
输出结果:
[AVFormatContext @ 000001768E65BC40] Opening 'D:/music/test.mp3' for reading [file @ 000001768E65C180] Setting default whitelist 'file,crypto,data' [mp3 @ 000001768E65BC40] Format mp3 probed with size=4096 and score=51 id3v2 ver:4 flags:00 len:35 [mp3 @ 000001768E65BC40] pad 576 576 [mp3 @ 000001768E65BC40] Skipping 0 bytes of junk at 462. Input #0, mp3, from 'D:/music/test.mp3': Metadata: encoder : Lavf58.76.100 Duration: N/A, bitrate: N/A Stream #0:0, 0, 1/14112000: Audio: mp3, 0 channels Metadata: encoder : Lavc58.13
可见流信息无效,但用相同编译配置构建的ffprobe打印该文件元数据显示正常:
ffprobe version 7.0.1 Copyright (c) 2007-2024 the FFmpeg developers built with Microsoft (R) C/C++ Optimizing Compiler Version 19.41.34123 for x64 configuration: --toolchain=msvc --arch=x86_64 --enable-x86asm --enable-asm --enable-shared --enable-w32threads --prefix=/D/build WARNING: library configuration mismatch avutil configuration: --toolchain=msvc --arch=x86_64 --enable-x86asm --enable-asm --enable-shared --enable-w32threads --disable-programs --disable-doc --disable-static --prefix=/D/build avcodec configuration: --toolchain=msvc --arch=x86_64 --enable-x86asm --enable-asm --enable-shared --enable-w32threads --disable-programs --disable-doc --disable-static --prefix=/D/build avformat configuration: --toolchain=msvc --arch=x86_64 --enable-x86asm --enable-asm --enable-shared --enable-w32threads --disable-programs --disable-doc --disable-static --prefix=/D/build avdevice configuration: --toolchain=msvc --arch=x86_64 --enable-x86asm --enable-asm --enable-shared --enable-w32threads --disable-programs --disable-doc --disable-static --prefix=/D/build avfilter configuration: --toolchain=msvc --arch=x86_64 --enable-x86asm --enable-asm --enable-shared --enable-w32threads --disable-programs --disable-doc --disable-static --prefix=/D/build swscale configuration: --toolchain=msvc --arch=x86_64 --enable-x86asm --enable-asm --enable-shared --enable-w32threads --disable-programs --disable-doc --disable-static --prefix=/D/build swresample configuration: --toolchain=msvc --arch=x86_64 --enable-x86asm --enable-asm --enable-shared --enable-w32threads --disable-programs --disable-doc --disable-static --prefix=/D/build libavutil 59. 8.100 / 59. 39.100 libavcodec 61. 3.100 / 61. 19.100 libavformat 61. 1.100 / 61. 7.100 libavdevice 61. 1.100 / 61. 3.100 libavfilter 10. 1.100 / 10. 4.100 libswscale 8. 1.100 / 8. 3.100 libswresample 5. 1.100 / 5. 3.100 Input #0, mp3, from 'D:\music\test.mp3': Metadata: encoder : Lavf58.76.100 Duration: 00:05:00.12, start: 0.025057, bitrate: 128 kb/s Stream #0:0: Audio: mp3 (mp3float), 44100 Hz, stereo, fltp, 128 kb/s Metadata: encoder : Lavc58.13
疑问
为何av_dump_format无法正确显示流信息?该如何修复?
解答
原因
avformat_open_input仅完成文件头的解析工作,并未读取足够的流数据来填充AVStream结构体中的完整参数(比如采样率、声道数、码率、时长等)。而ffprobe内部会自动调用avformat_find_stream_info扫描文件,获取并填充完整的流信息,所以能正常显示所有媒体参数。
修复方法
在调用av_dump_format之前,添加avformat_find_stream_info调用,确保流信息被正确解析并填充。同时要添加错误处理和资源释放逻辑,避免内存泄漏。修改后的代码如下:
extern "C" { #include <libavformat/avformat.h> #include <stdlib.h> } int main() { av_log_set_level(AV_LOG_DEBUG); const char* url = "D:/music/test.mp3"; AVFormatContext* fmt = nullptr; // 打开输入文件 int ret = avformat_open_input(&fmt, url, nullptr, nullptr); if (ret < 0) { av_log(nullptr, AV_LOG_ERROR, "Cannot open %s format : %s", url, av_err2str(ret)); exit(EXIT_FAILURE); } // 获取完整的流信息 ret = avformat_find_stream_info(fmt, nullptr); if (ret < 0) { av_log(nullptr, AV_LOG_ERROR, "Failed to retrieve stream info: %s", av_err2str(ret)); avformat_close_input(&fmt); exit(EXIT_FAILURE); } // 打印媒体格式信息 av_dump_format(fmt, 0, url, 0); // 释放资源 avformat_close_input(&fmt); return EXIT_SUCCESS; }
补充说明
avformat_find_stream_info会读取部分媒体流数据,分析并填充AVFormatContext和AVStream中的详细参数,这是获取完整媒体信息的必要步骤。- 调用该函数后必须检查返回值,处理可能的错误。
- 所有打开的
AVFormatContext必须调用avformat_close_input释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者グルグル
相关产品推荐
相关产品推荐

