文章目录
音视频系列教程
课程目标
学习如何使用 FFmpeg 打开和读取媒体文件的基本信息,理解 AVFormatContext 的作用。
封装格式简介
在开始之前,先简单了解一下封装格式。
我们常见的视频文件(如 .mp4、.mkv、.avi)都是封装格式,它们把视频、音频、字幕等数据打包在一起。可以简单理解为:封装格式是"盒子",里面装着编码后的视频和音频数据。
封装格式 vs 编码格式:
- 封装格式(如 MP4、MKV):决定如何打包和组织数据
- 编码格式(如 H.264、AAC):决定如何压缩数据
举个例子,一个 .mp4 文件可能包含 H.264 编码的视频和 AAC 编码的音频,MP4 负责把它们打包在一起,并提供同步、元数据等功能。
常见的封装格式有 MP4(兼容性好)、MKV(支持多音轨)、FLV(流媒体)等。FFmpeg 可以处理这些格式,我们只需要知道如何打开和读取它们即可。
知识点
1. AVFormatContext 结构体
AVFormatContext 是 FFmpeg 中表示媒体文件格式上下文的核心结构体,包含了媒体文件的所有信息。
主要字段:
iformat:输入格式(如 MP4、MKV 等)nb_streams:流的数量streams:流数组duration:文件时长(以时间基为单位,通常是所有流中最长的时长)bit_rate:总码率(所有流的码率之和)
重要提示:容器级别 vs 流级别的时长和码率
容器级别(AVFormatContext)的时长和码率与单个流的时长和码率可能不一致:
-
时长差异:
- 容器时长:通常是所有流中最长的时长(例如视频流时长)
- 流时长:每个流有自己的时长,可能略有差异(特别是音频和视频的同步问题)
- 示例:视频流可能是 11.41 秒,音频流可能是 11.40 秒,容器时长取 11.41 秒
-
码率差异:
- 容器总码率:所有流的码率之和(视频码率 + 音频码率 + 其他流码率)
- 流码率:单个流的码率
- 示例:视频码率 2260 kbps + 音频码率 253 kbps ≈ 总码率 2517 kbps
-
如何获取单个流的时长和码率:
AVStream* video_stream = fmt_ctx->streams[video_index]; // 流的时长(以流的时间基为单位) int64_t stream_duration = video_stream->duration; // 转换为秒:stream_duration * av_q2d(video_stream->time_base) // 流的码率 int64_t stream_bitrate = video_stream->codecpar->bit_rate;
2. 媒体文件格式识别
FFmpeg 可以自动识别多种媒体文件格式:
- 视频格式:MP4、MKV、AVI、MOV、FLV 等
- 音频格式:MP3、AAC、WAV、FLAC 等
- 流媒体格式:RTMP、HLS、RTSP 等
3. 错误处理机制
FFmpeg 使用返回值表示操作结果:
0:成功- 负数:错误码(使用
av_strerror转换为错误信息) AVERROR_EOF:文件结束
实践内容
实践1:打开本地视频文件
API: avformat_open_input
AVFormatContext* fmt_ctx = nullptr;
const char* filename = "test.mp4";
int ret = avformat_open_input(&fmt_ctx, filename, nullptr, nullptr);
if (ret == 0) {
// 成功打开
LOG("Format: %s", fmt_ctx->iformat->name);
avformat_close_input(&fmt_ctx);
} else {
// 处理错误
char errbuf[AV_ERROR_MAX_STRING_SIZE

3682

被折叠的 条评论
为什么被折叠?



