基於librtmp客戶端記錄(H264+AAC)

  基於librtmp開發rtmp客戶端的demo,主要是按照雷神的demo(見5.1)來修改,修改後的demo能將獲取到的音視頻數據寫成h264文件及aac文件。

1、flv格式

  介紹flv格式的博客有很多,個人覺得5.2及5.3結合起來看比較好,其中5.2的script tag應該得值是12纔是對的。摘錄些重要的。
在這裏插入圖片描述
  flv的tag類型有三種,video(9), audio(8), script_data(12)。
  tag的組成如下:
在這裏插入圖片描述
  如果視頻格式是AVC(h264)的話,VideoTagHeader會多出4個字節的信息分別是一字節的AVCPacketType 和3字節的CompositionTime。
來自參考5.3的video tag及audio tag的圖。
在這裏插入圖片描述
在這裏插入圖片描述

2、注意

  h264的sps及pps數據在發送視頻幀之前會首先單獨發送過來,需要做保存,因爲有些rtmp serevr不會在每一個I幀前添加這些信息。
  收到的AAC音頻需要根據解析到AAC格式信息添加adts頭部,代表AAC音頻採樣率的2bit其值總是3

3、添加ADTS頭部

/* *注意,這裏的packetLen參數爲raw aac Packet Len + 7; 7 bytes adts header */
static void addADTStoPacket(char* packet, int packetLen, int frequence) 
{
      int profile = 2;  //AAC LC,MediaCodecInfo.CodecProfileLevel.AACObjectLC;
      int freqIdx = -1;  //48K, 見後面註釋avpriv_mpeg4audio_sample_rates中32000對應的數組下標,來自ffmpeg源碼
      int chanCfg = 2;  //見後面註釋channel_configuration,Stero雙聲道立體聲

     int avpriv_mpeg4audio_sample_rates[] = {
          96000, 88200, 64000, 48000, 44100, 32000,
                  24000, 22050, 16000, 12000, 11025, 8000, 7350
      };

      for(int i = 0; i < 13 ; ++i)
      {
          if(frequence == avpriv_mpeg4audio_sample_rates[i])
          {
              freqIdx = i;
              break;
          }
      }
     
     if(freqIdx == -1)
     {
         printf("Invaild frequence [%d] \n", frequence);
         return ;
     }
      /*int avpriv_mpeg4audio_sample_rates[] = {
          96000, 88200, 64000, 48000, 44100, 32000,
                  24000, 22050, 16000, 12000, 11025, 8000, 7350
      };
      channel_configuration: 表示聲道數chanCfg
      0: Defined in AOT Specifc Config
      1: 1 channel: front-center
      2: 2 channels: front-left, front-right
      3: 3 channels: front-center, front-left, front-right
      4: 4 channels: front-center, front-left, front-right, back-center
      5: 5 channels: front-center, front-left, front-right, back-left, back-right
      6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
      7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
      8-15: Reserved
      */

      // fill in ADTS data
      packet[0] = 0xFF;
      packet[1] = 0xF1;
      packet[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
      packet[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11));
      packet[4] = (char)((packetLen&0x7FF) >> 3);
      packet[5] = (char)(((packetLen&7)<<5) + 0x1F);
      packet[6] = 0xFC;
}

4、demo

  centos6.9上實現的demo,能同時寫下flv,h264及AAC文件(只針對48KHZ ,AAC-LC,16bit採樣位數)

5、參考

《1》、最簡單的基於librtmp的示例:接收(RTMP保存爲FLV)
《2》、flv格式詳解+實例剖析
《3》、FLV文件(H264 + AAC)格式超詳細分析
《4》、LIBRTMP(3)
《5》、使用librtmp接收數據時要注意的問題
《6》、libRTMP使用說明
《7》librtmp獲取視頻流和音頻流2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章