1. 程式人生 > >rtmp傳送H264及aac的音視訊

rtmp傳送H264及aac的音視訊

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後面接需要傳送的資料