上一篇文章写过“解决基于librtmp库的rtmp直播服务第一帧图出现比较慢的问题”,针对这个问题,我在上一篇文章中分析过主要是因为播放器调用了ffmpeg中的接口avformat_find_stream_info()。如何加速avformat_find_stream_info()接口函数的返回,可以采用如下方法:1、减少该接口函数的探测时间,不过这样做可能会牺牲探测的准确率;2、如果音视频来源比较单一,可以事先指定某些参数,比如视频编码格式等加速该接口的返回。今天我讲讲我采用的第三种方法:人为增加音频数据,加速该接口函数的返回。
首先封装librtmp推送音频数据接口,代码如下:
int rtmp_client_send_audio(int handle,const char *data,int len, long timetamp){context_t t = {0,"",NULL};mutex_lock(&g_mutex);std::map<int, context_t>::iterator it = g_contexts.find(handle);if (it!=g_contexts.end()){t = it->second;}mutex_unlock(&g_mutex);if (t.rtmp == NULL) return rc_code_fail;if (data == NULL || len <= 0) return rc_code_fail;RTMPPacket *packet;unsigned char *body;packet = (RTMPPacket *)malloc((sizeof(RTMPPacket)+RTMP_MAX_HEADER_SIZE) + len + 2);memset(packet, 0, (sizeof(RTMPPacket)+RTMP_MAX_HEADER_SIZE));packet->m_body = (char*)packet + (sizeof(RTMPPacket)+RTMP_MAX_HEADER_SIZE);body = (unsigned char *) packet->m_body;body[0] = 0xAF;body[1] = 0x01;memcpy(&body[2],data,len);packet->m_packetType = RTMP_PACKET_TYPE_AUDIO;packet->m_nBodySize = len + 2;packet->m_nChannel = 0x06;packet->m_nTimeStamp = timetamp;packet->m_hasAbsTimestamp = 0;packet->m_headerType = RTMP_PACKET_SIZE_LARGE;packet->m_nInfoField2 = t.rtmp->m_stream_id;int ret = RTMP_SendPacket(t.rtmp,packet,TRUE);free(packet);if (!ret){RTMP_Log(RTMP_LOGDEBUG,"RTMP_SendPacket fail");return rc_code_fail;}return rc_code_ok;
}
推送音频数据:
char audio_buff[40];
FILE* fpAAC = fopen("./audio.aac","rb");
fread(audio_buff,1,30,fpAAC);
rtmp_client_send_audio(ctx->rtmp_stream_handle, (const char*)audio_buff, 30, frame_count*40 - 20);
rtmp_client_send_audio(ctx->rtmp_stream_handle, (const char*)audio_buff, 30, frame_count*40);
针对上述程序做一些必要的解释。我的音频数据为白噪声,大小为30bytes,编码格式为AAC编码,文件格式为adts,adts的头部为固定7字节。每发送一个视频帧数据同时发送两个音频帧数据。音频帧数据链接为。
通过上述人为添加音频数据,实验测试能够明显加速函数avformat_find_stream_info()的返回。减少第一帧图片的耗时。