您的位置:首页 > 其它

通过RTMP协议将AAC数据发送到流媒体服务器

2015-12-01 16:21 393 查看

简介

本文是利用windows API得到PCM格式的音频数据,并转换成AAC格式。然后将AAC数据利用RTMP协议发送到流媒体服务器。


步骤

1)直接调用windows API可以获取PCM格式的音频数据,然后利用Faac库转换成AAC。这个过程比较简单
2)发送AAC数据到流媒体服务器:
a)首先,发送解码信息:在服务器得到AAC数据后需要将其解码,所以在发送AAC数据前,最好先发送AAC数据的解码数据。这个解码数据在转换成之前已经由Faac生成,直接调用Faac提供的接口即可。将解码信息封装成RTMPPacket发送到服务器。
b)再开始发送AAC数据:利用rtmp协议将AAC数据封装成RTMPPacket


封装过程

1)封装解码信息:


RTMPPacket * packet;
unsigned char * body;
int len;
len = spec_len;  /*spec data长度,一般是2*/

packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE + len + 2);
memset(packet, 0, RTMP_HEAD_SIZE);

packet->m_body = (char *)packet + RTMP_HEAD_SIZE;
body = (unsigned char *)packet->m_body;

/*AF 00 + AAC RAW data*/
body[0] = 0xAF;//AAC 44100Hz 2Channel
body[1] = 0x00;
memcpy(&body[2], spec_buf, len); /*spec_buf是AAC sequence header数据*/

packet->m_packetType = RTMP_PACKET_TYPE_AUDIO;
packet->m_nBodySize = len + 2;
packet->m_nChannel = 0x04;
packet->m_nTimeStamp = 0;
packet->m_hasAbsTimestamp = 0;
packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
packet->m_nInfoField2 = m_pRtmp->m_stream_id;

/*调用发送接口*/
bool result=RTMP_SendPacket(m_pRtmp, packet, 1);
free(packet);


注意:body前两个字符是根据AAC格式音频的不同频率和通道计算得到的。详情见AAC格式详解

2)封装普通AAC数据信息


long timeoffset=0;
static unsigned long countAudioTime = 0;
if (countAudioTime > 0){
timeoffset = (countAudioTime - 1) *((int)(1024 * 1000/nSampleRate));//
}
countAudioTime++;
data += 7;
size -= 7;

// 发送AAC音频数据帧
if (size<=0)
{
return false;
}

RTMPPacket packet;
unsigned char *body;

RTMPPacket_Reset(&packet);
RTMPPacket_Alloc(&packet, size + 2);
//packet.m_body = (char*)packet + RTMP_HEAD_SIZE;
body = (unsigned char*)packet.m_body;

//AF 01 + AAC RAW data
body[0] = 0xAF;
body[1] = 0x01;
memcpy(&body[2], data, size);
packet.m_packetType = RTMP_PACKET_TYPE_AUDIO;
packet.m_nBodySize = size + 2;
packet.m_nChannel = 0x04;
packet.m_nTimeStamp = timeoffset;
packet.m_hasAbsTimestamp = 0;
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
packet.m_nInfoField2 = m_pRtmp->m_stream_id;

//调用发送接口
bool result = RTMP_SendPacket(m_pRtmp, &packet, 1);
RTMPPacket_Free(&packet);


注意:1)timeoffset 值得计算;2)body的前两个字符与封装解码信息包中的body的前两个字符相似,只是第二字符变成了1;其实,第二个字符中,0表示是解码信息,1表示是普通AAC数据;详情见AAC格式详解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息