利用ffmpeg录制rtsp流的方法总结(一)
这里主要结合平时对音视频的学习,将ffmpeg录制rtsp的方法在这里记录下。
首先,一般的录制过程都是按照如下的流程图进行录制,除非某些不存在音频的特殊情况。
这个是总体的录制流程,然而这个流程对于推流来说也适用。因此对于流程中每一步的实现,需要弄明白。
在进入主题之前,有必要对视频的基础知识有一个了解,这是十分有必要的。
这里可以参考雷神的博客https://blog.****.net/leixiaohua1020/article/details/18893769
封装格式:MP4,RMVB,TS,FLV,AVI
视频编码格式:H264,MPEG2,VC-1
音频编码格式:AAC,MP3,AC-3,G711
视频像素格式:YUV,RGB
音频像素格式:PCM
一般录制过程中,原始视频音频编码格式可能与我们所期待的格式或者参数不同,这需要对音视频进行解码后,重新进行编码,然后封装成我们所需要的格式。其中难点包括音视频的编解码,以及视频格式封装。
我们在录制rtsp流之前,需要了解我们所获取的流的相关信息。
这个我们可以通过av_dump_format()函数查看。
可以通过网上给定测试的rtsp流地址进行测试:rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov
此部分所引用ffmpeg库为4.0版本
#include<iostream>
extern "C"{
#include <libavformat/avformat.h>
}
using namespace std;
int OpenRtspStream(const char* url,AVFormatContext **ic)
{
AVDictionary* options = NULL;
int ret=-1;
ret=av_dict_set(&options,"rtsp_transport", "tcp", 0);
if(ret<0)
return -1;
ret=av_dict_set(&options,"stimeout","10000000",0);
if(ret<0)
return -1;
if(avformat_open_input(ic,url,NULL,&options)!=0) //avformat_close_input 关闭
{
if(!(*ic))
avformat_free_context(*ic);
return -1;
}
if(avformat_find_stream_info(*ic,NULL)<0)
{
if(!(*ic))
{
avformat_close_input(ic);
avformat_free_context(*ic);
}
return -1;
}
printf("-----------rtsp流输入信息--------------\n");
av_dump_format(*ic, 0, url,0);
printf("---------------------------------------\n");
printf("\n");
return 0;
}
void main()
{
AVFormatContext *ifmt=NULL;
ifmt=avformat_alloc_context();
if(!ifmt)
{
cout<<"avformatcontext alloc error"<<endl;
goto end;
}
ret=OpenRtspStream(url,&ifmt);
if(ret<0)
{
cout<<"摄像机网络不通"<<endl;
goto end;
}
end:
getchar();
}
通过打印的信息可以知道所获取到的流中视频和音频的编码格式。如果与我们目标格式不一致,就需要进行相应的转码。
下面将开始介绍如何进行rtsp流保存为MP4文件的方法。
目前比较常用生成MP4文件方法有两种:
1.通过ffmpeg进行MP4封装
2.通过第三方库MP4V2进行封装
后面将分别具体介绍这两种方法的封装。