You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用FFmpeg的libAV库将H264编码数据封装到.mp4容器

基于libAV实现H.264码流封装MP4的实现步骤

你已经完成H.264编码的前提下,只需要额外补充复用器相关逻辑即可输出标准MP4文件,具体实现步骤如下:

1. 初始化复用器上下文

提前注册容器相关组件,创建指定MP4格式的输出上下文:

// 前置组件注册,全局仅需调用一次
av_register_all();
avformat_network_init();

AVFormatContext *fmt_ctx = NULL;
// 第四个参数传入你的输出文件路径
int ret = avformat_alloc_output_context2(&fmt_ctx, NULL, "mp4", "output_test.mp4");
if (ret < 0 || !fmt_ctx) {
    // 自定义错误处理逻辑
}

2. 关联视频流参数

创建输出视频流,参数和你正在用的H.264编码器上下文完全对齐:

AVStream *out_stream = avformat_new_stream(fmt_ctx, NULL);
if (!out_stream) {
    // 自定义错误处理逻辑
}
// 直接拷贝编码器的参数到输出流,避免手动配置出错
ret = avcodec_parameters_from_context(out_stream->codecpar, your_h264_encoder_ctx);
if (ret < 0) {
    // 自定义错误处理逻辑
}
// 时间基和编码器保持一致,避免后续时间戳换算错误
out_stream->time_base = your_h264_encoder_ctx->time_base;

特别注意:必须给H.264编码器开启全局头参数,否则MP4容器会缺少SPS/PPS信息,播放器无法识别:

your_h264_encoder_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

该参数要在打开编码器之前设置才生效。

3. 打开输出文件写入容器头

// 打开IO句柄
if (!(fmt_ctx->oformat->flags & AVFMT_NOFILE)) {
    ret = avio_open(&fmt_ctx->pb, "output_test.mp4", AVIO_FLAG_WRITE);
    if (ret < 0) {
        // 自定义错误处理逻辑
    }
}
// 写入MP4文件头
ret = avformat_write_header(fmt_ctx, NULL);
if (ret < 0) {
    // 自定义错误处理逻辑
}

4. 循环写入编码后的数据包

每次拿到编码输出的AVPacket后,先做时间基转换再写入容器:

// pkt是你编码得到的H.264数据包
av_packet_rescale_ts(pkt, your_h264_encoder_ctx->time_base, out_stream->time_base);
pkt->stream_index = out_stream->index;
// 写入容器,libAV会自动处理帧顺序、MP4 box组装
ret = av_interleaved_write_frame(fmt_ctx, pkt);
if (ret < 0) {
    // 自定义错误处理逻辑
}
// 用完记得释放packet
av_packet_unref(pkt);

5. 收尾释放资源

所有帧写入完成后执行:

// 写入MP4文件尾,补全所有容器元信息
av_write_trailer(fmt_ctx);
// 释放IO和上下文资源
if (!(fmt_ctx->oformat->flags & AVFMT_NOFILE)) {
    avio_close(fmt_ctx->pb);
}
avformat_free_context(fmt_ctx);

内容的提问来源于stack exchange,提问作者Aravind A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 15:12:02