RTMP推送的音視頻流的封裝形式和FLV格式相似,由此可知,向FMS推送H264和AAC直播流,需要首先發送"AVC sequence header"和"AAC sequence header",這兩項數據包含的是重要的編碼信息,沒有它們,解碼器將無法解碼。
AVC sequence header就是AVCDecoderConfigurationRecord結構,該結構在標準文檔“ISO-14496-15 AVC file format”中有詳細說明。
AAC sequence header存放的是AudioSpecificConfig結構,該結構則在“ISO-14496-3 Audio”中描述。AudioSpecificConfig結構的描述非常複雜,這裏我做一下簡化,事先設定要將要編碼的音頻格式,其中,選擇"AAC-LC"爲音頻編碼,音頻採樣率爲44100,於是AudioSpecificConfig簡化爲下表:
這樣,AVC sequence header和AAC sequence header的內容可以基本確定了,更詳細的信息,大家可以去翻閱相關文檔。
在發送這兩個header需要在前面分別加上 VideoTags、AudioTags 這連個tags都是1個字節(8bits)的數據
其中AudioTags每bit表示的意義如下圖:
其中SoundData 的組成如下:
當數據的第一個字節爲0時,後面跟AAC sequence header;
當數據的第一個字節爲1時,後面跟AAC 數據;
其中VideoTags每bit表示的意義如下圖:
發送的爲avc數據,所以,CodecID(後4bit)的值爲7
所以videodata的數據打包方式爲 ,具體的信息見下圖:
具體代碼實現:
//添加Flv的VideoTags
char* RtmpLiveEncoder::AddVideoTags(char* buf,bool isKeyframe)
{
//前面4字節表示FrameType,後面4字節表示CodecID
unsigned char flag = 0;
if (isKeyframe)
flag = 0x17;
else
flag = 0x27;
buf = UI08ToBytes(buf, flag);
buf = UI08ToBytes(buf, 1); // avc packet type (0, nalu) 包的類型,同步包爲0
buf = UI24ToBytes(buf, 0); // composition time 0爲打開,1爲關閉
return buf;
}
//添加Flv的AudioTags
char* RtmpLiveEncoder::AddAudioTags(char* buf)
{
//
unsigned char flag = 0;
flag = (10 << 4) | // soundformat "10 == AAC"
(3 << 2) | // soundrate "3 == 44-kHZ"
(1 << 1) | // soundsize "1 == 16bit"
1; // soundtype "1 == Stereo"
buf = UI08ToBytes(buf, flag);
buf = UI08ToBytes(buf, 1); // aac packet type (1, raw) 包的類型,同步包爲0
return buf;
}
這兩個函數返回的buf後面接需要發送的數據