基于librtmp客户端记录(H264+AAC)

本文详细介绍基于librtmp开发的RTMP客户端如何处理音视频数据,包括将数据转换为H264和AAC文件的过程,特别关注了FLV格式的解析与构建,以及在处理AAC音频时ADTS头部的添加技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  基于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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值