RTMP流生成MP4文件方法总结

Rtmp流生成MP4文件的流程基本上与rtsp流类似,可以参考前一篇RTSP流封装成MP4方法总结

这里主要针对rtmp与rtsp不同的地方进行说明:
1.rtmp流的写法与rtsp流不太一样
利用ffmpeg进行拉取rtmp流,一般在流末尾添加“ live=1”。例如 “rtmp://10.13.10.251/live/test live=1”。如果是librtmp库则不需要加"live=1"。

2.针对网络不通,rtmp流与rtsp流处理方式不一致
rtsp可以通过av_dict_set(&options,“stimeout”,“10000000”,0)函数设置超时,而rtmp只能通过设置回调才能跳出阻塞。测试中发现,早期的ffmpeg版本回调函数不起作用,后来发现ffmpeg4.1版本回调可以跳出阻塞,能很好解决之前遇到的阻塞问题。详细代码如下:
RTMP流生成MP4文件方法总结_第1张图片
RTMP流生成MP4文件方法总结_第2张图片
3.RTMP流中SPS与PPS获取方式与RTSP有所不同
利用ffmpeg拉取rtmp流,sps与pps也存储在ic->streams[video_index]->codecpar->extradata中,但是有所不同。处理Rtsp时,00 00 00 01后直接是sps或pps内容,而处理Rtmp时,在00 00 00 01后是sps或pps长度,后面紧随的是其内容,因此,解析extradata方式有所不一样,如下为解析rtmp中sps和pps代码:

    int ret=NO_VALUE;
	int sps_pps_size=0;
	int sps_pps_length;
	sps_pps_size=ic->streams[video_index]->codecpar->extradata_size;
	*temp_buffer=(uint8_t*)malloc(sps_pps_size*sizeof(uint8_t));
	if(!(*temp_buffer))
	{
		ret=MALLOC_ERROR;
		return ret;
	}

	int sps_length=0,pps_length=0;
	(*temp_buffer)[0]=0;
	(*temp_buffer)[1]=0;
	(*temp_buffer)[2]=0;
	(*temp_buffer)[3]=1;
	sps_length=ic->streams[video_index]->codecpar->extradata[6]*256+ic->streams[video_index]->codecpar->extradata[7];
	for(int j=0;jstreams[video_index]->codecpar->extradata[j+8];
	(*temp_buffer)[sps_length+4]=0;
	(*temp_buffer)[sps_length+5]=0;
	(*temp_buffer)[sps_length+6]=0;
	(*temp_buffer)[sps_length+7]=1;
	pps_length=ic->streams[video_index]->codecpar->extradata[9+sps_length]*256+ic->streams[video_index]->codecpar->extradata[10+sps_length];
	for(int k=0;kstreams[video_index]->codecpar->extradata[k+11+sps_length];
	sps_pps_length=pps_length+sps_length+8;
	//for(int l=0;l

4.RTMP写H264数据与RTSP不同
由于h264裸流数据是直接写入到MP4中,中间不经过解码后编码,因此此部分与rtsp有所不一样。这里需要用到av_bitstream_filter_init(“h264_mp4toannexb”)获取H264裸流数据,可以参考最简单的基于FFmpeg的封装格式处理:视音频复用器
H264过滤器使用很简单
首先是定义: h264bsfc=av_bitstream_filter_init(“h264_mp4toannexb”)

然后使用av_bitstream_filter_filter()对每个视频的packet数据进行过滤,示例如下:

			if(packet.stream_index==video_index)
			{
				ret=av_bitstream_filter_filter(h264bsfc,in_video_ctx,NULL,&packet.data,&packet.size,packet.data,packet.size,0);
				if(ret<0)
				{
					ret=AV_BITSTREAM_FILTER_ERROR;
					break;
				}
				ret=Wrtie_H264_MP4v2VFR(&packet,mp4encord);  //变帧率录制
				if(ret<0)
				{
					av_packet_unref(&packet);
					break;
				}
			}	

最后记得释放占用内存: av_bitstream_filter_close(h264bsfc)

最终利用可执行程序进行录制,可以生成完整的MP4文件。如果需要,请点击testMerge进行下载。
RTMP流生成MP4文件方法总结_第3张图片
由于dll文件所占用资源较大,所以dll与原始工程分开放置。
dll下载链接:链接:https://pan.baidu.com/s/1UlpTfaT4J2SP3zpMcLs0ng
源码工程下载地址为:https://download.csdn.net/download/unfound/11605796

你可能感兴趣的:(音视频)