使用C++语言和FFmpeg将h264文件封装成mp4文件
时间: 2023-11-22 17:53:48 浏览: 189
使用ffmpeg封装h264裸流为MP4文件
5星 · 资源好评率100%
要使用C++和FFmpeg将h264文件封装成mp4文件,可以按照以下步骤进行操作:
1. 安装FFmpeg库,可以从官网下载预编译的库,或者自行编译源代码。
2. 打开h264文件并读取其中的数据,可以使用FFmpeg提供的AVFormatContext和AVPacket来实现。
3. 创建输出文件并设置输出格式,这里需要使用FFmpeg提供的AVFormatContext和avformat_alloc_output_context2函数来创建输出文件。
4. 将h264数据写入输出文件,需要使用FFmpeg提供的av_interleaved_write_frame函数将数据写入输出文件。
5. 关闭输入和输出文件,释放资源。
下面是一个示例代码,演示如何使用C++和FFmpeg将h264文件封装成mp4文件:
```cpp
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdint.h>
#include <errno.h>
#include <ctime>
#include <vector>
extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
}
using namespace std;
int main(int argc, char* argv[])
{
if(argc < 3)
{
cout << "Usage: " << argv[0] << " input-file output-file" << endl;
return -1;
}
const char* input_file = argv[1];
const char* output_file = argv[2];
av_register_all();
AVFormatContext* ifmt_ctx = NULL;
if(avformat_open_input(&ifmt_ctx, input_file, NULL, NULL) < 0)
{
cout << "Could not open input file: " << input_file << endl;
return -1;
}
if(avformat_find_stream_info(ifmt_ctx, NULL) < 0)
{
cout << "Could not find stream information" << endl;
return -1;
}
av_dump_format(ifmt_ctx, 0, input_file, 0);
AVFormatContext* ofmt_ctx = NULL;
if(avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, output_file) < 0)
{
cout << "Could not create output context" << endl;
return -1;
}
AVOutputFormat* ofmt = ofmt_ctx->oformat;
for(int i = 0; i < ifmt_ctx->nb_streams; i++)
{
AVStream* in_stream = ifmt_ctx->streams[i];
AVStream* out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
if(!out_stream)
{
cout << "Failed allocating output stream" << endl;
return -1;
}
if(avcodec_copy_context(out_stream->codec, in_stream->codec) < 0)
{
cout << "Failed to copy codec context" << endl;
return -1;
}
out_stream->codec->codec_tag = 0;
if(ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
{
out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
}
av_dump_format(ofmt_ctx, 0, output_file, 1);
if(!(ofmt->flags & AVFMT_NOFILE))
{
if(avio_open(&ofmt_ctx->pb, output_file, AVIO_FLAG_WRITE) < 0)
{
cout << "Could not open output file: " << output_file << endl;
return -1;
}
}
if(avformat_write_header(ofmt_ctx, NULL) < 0)
{
cout << "Error occurred when opening output file" << endl;
return -1;
}
AVPacket pkt;
int frame_index = 0;
while(true)
{
AVStream* in_stream = NULL;
AVStream* out_stream = NULL;
if(av_read_frame(ifmt_ctx, &pkt) < 0)
{
break;
}
in_stream = ifmt_ctx->streams[pkt.stream_index];
out_stream = ofmt_ctx->streams[pkt.stream_index];
if(av_interleaved_write_frame(ofmt_ctx, &pkt) < 0)
{
cout << "Error muxing packet" << endl;
break;
}
cout << "Write frame " << frame_index << " (size=" << pkt.size << ")" << endl;
frame_index++;
av_free_packet(&pkt);
}
av_write_trailer(ofmt_ctx);
avformat_close_input(&ifmt_ctx);
if(ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
{
avio_close(ofmt_ctx->pb);
}
avformat_free_context(ofmt_ctx);
return 0;
}
```
需要注意的是,这只是一个简单的示例代码,不一定适用于所有情况。在实际使用中,还需要根据具体情况进行修改和调整。
阅读全文