说明
保存rtsp流这里其实是将循环读取到的AVPacket保存到本地,具体需要保存视频或音频或其他可自行判断码流类型。
注:以下代码表示了如何写入本地H264。该方法经测试rtsp流可正常写入,但若输入是本地视频文件而非rtsp时则读入该h264时找不到正常的解码器或索引。
代码
// 注册
av_register_all();
avformat_network_init();
// 初始化上下文
AVFormatContext *avFormatContext = avformat_alloc_context();
// 打开rtsp
int result = avformat_open_input(&avFormatContext,"rtsp流url",nullptr,&avDictionary);
if(result != 0)
{
//ErrorStr("FFmpeg - run \"avformat_open_input\" fail。error code:"+NUM2STR(result));
char buf[1024] = {
0};
av_strerror(result,buf,1024);
qDebug() << buf;
return;
}
// 查找流信息
result = avformat_find_stream_info(avFormatContext,nullptr);
// 查找视频码流
int VideoStream = -1;
for(int index = 0;index<avFormatContext->nb_streams;index++)
{
if(avFormatContext->streams[index]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
VideoStream = index;
break;
}
}
// 查找视频解码器
avCodecContext = avFormatContext->streams[VideoStream]->codec;
AVCodec *avCodec = avcodec_find_decoder(avCodecContext->codec_id);
// 打开视频解码器
result = avcodec_open2(avCodecContext,avCodec,nullptr);
if(result < 0)
{
ErrorStr("FFmpeg - run \"avcodec_open2\" fail。error code:"+NUM2STR(result));
return;
}
// 文件
FILE *fpSaveVideo = nullptr;
fpSaveVideo = fopen("xxx.h264", "wb");
// 读帧并处理 - 这里处理1000次
for(int index=0;index<1000;++index)
{
// 初始化数据包
AVPacket *avPacket = av_packet_alloc();
av_init_packet(avPacket);
// 读取一帧
result = av_read_frame(avFormatContext,avPacket);
// 此包数据是否为视频码流后写入本地文件
if (avPacket->stream_index == VideoStream)
{
fwrite(avPacket->data, 1, avPacket->size, fpSaveVideo);
fflush(fpSaveVideo);
}
// 释放
av_packet_free(&avPacket);
avPacket = nullptr;
}
// 关闭文件
if(fpSaveVideo)
{
fclose(fpSaveVideo);
}
fpSaveVideo = nullptr;
关注
微信公众号搜索"Qt_io_"或"Qt开发者中心"了解更多关于Qt、C++开发知识.。
笔者 - jxd