文章目录

  • 一、 头文件、成员变量准备
  • 二、 创建 FAAC 编码器
  • 三、 获取并设置 FAAC 编码器参数
  • 四、 设置 FAAC 编码器编码标准
  • 五、 设置 FAAC 编码器 AAC 编码规格
  • 六、 设置 FAAC 编码器输入、输出格式
  • 七、 FAAC 设置音频编码参数代码

Android 直播推流流程 : 手机采集视频 / 音频数据 , 视频数据使用 H.264 编码 , 音频数据使用 AAC 编码 , 最后将音视频数据都打包到 RTMP 数据包中 , 使用 RTMP 协议上传到 RTMP 服务器中 ;

视频推流 : 之前的一系列博客中完成手机端采集视频数据操作 , 并将视频数据传递给 JNI , 在 NDK 中使用 x264 将图像转为 H.264 格式的视频 , 最后将 H.264 格式的视频打包到 RTMP 数据包中 , 上传到 RTMP 服务器中 ;

音频推流 : 开始进行音频直播推流操作 , 先采集音频 , 将音频编码为 AAC 格式 , 将编码后的音频打包成 RTMP 包 , 然后推流到服务器中 ;

NV21 格式图像编码为 H.264 视频 , 需要设置 x264 编码器参数 , 对应 【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS ) 博客 ;

本博客中讲解的是 , PCM 音频采样编码为 AAC 音频 , 如何设置 FACC 编码器参数 ;

一、 头文件、成员变量准备


1 . 导入包 : 使用 FACC 编码器前 , 必须导入 facc.h 头文件 ;

#include <faac.h>

2 . 成员变量定义 : 在初始化 FACC 编码器时 , 需要预先定义一些成员变量 , 这些变量在后续设置编码器参数 , 音频编码时都需要使用到 ;

① 输入样本个数 : 输入到 FAAC 编码器中的需要进行编码的 PCM 样本个数 , 表示FAAC 编码器最多一次可以接收的样本个数 ,

unsigned long mInputSamples;

注意 : 是样本个数 , 不是字节数 , 如果采样位数是 888 位 , 那么 字节数=样本个数字节数 = 样本个数字节数=样本个数 , 如果采样位数是 161616 位 , 字节数=样本个数×2字节数 = 样本个数 \times 2字节数=样本个数×2 ;

② FAAC 编码器最大输出字节数 : 该参数 mMaxOutputBytes 与上面的 mInputSamples 都要传入 FAAC 编码器创建函数中 , 用于接收创建 FAAC 编码器后的返回值 , 创建之前这些值是不知道的 ;

unsigned long mMaxOutputBytes;

③ FAAC 编码器 : 用于将 PCM 音频采样编码成 AAC 格式 ;

faacEncHandle mFaacEncHandle;

④ FAAC 编码输出缓冲区 : FAAC 编码后的 AAC 裸数据, 存储到该缓冲区中 , 该缓冲区在初始化 FAAC 编码器时创建 ; 初始化完成后 , 知道 FAAC 最大输出缓冲区大小后 , 创建该输出缓冲区 , 其大小是 mMaxOutputBytes 字节 ;

unsigned char* mFaacEncodeOutputBuffer;

二、 创建 FAAC 编码器


1 . 调用 faacEncOpen 函数 , 创建 FAAC 编码器 ;

2 . 函数原型解析 :

faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,unsigned int numChannels,unsigned long *inputSamples,unsigned long *maxOutputBytes);

① unsigned long sampleRate 参数 : 音频采样率 ;

② unsigned int numChannels 参数 : 音频通道参数 ;

③ unsigned long *mInputSamples 参数 : 输入样本个数, 需要进行编码的 PCM 音频样本个数 , FAAC 编码器最多一次可以接收的样本个数 ;

④ unsigned long *mMaxOutputBytes 参数 : 输出数据最大字节数 ;

⑤ faacEncHandle 返回值 : FAAC 音频编码器 ;

3 . 创建 FAAC 编码器 代码示例 :

mFaacEncHandle = faacEncOpen(sampleRateInHz, channelConfig, &mInputSamples, &mMaxOutputBytes);

三、 获取并设置 FAAC 编码器参数


1 . 获取编码器参数 : 先获取参数, 然后设置参数, 最后再设置回去

faacEncConfigurationPtr configurationPtr = faacEncGetCurrentConfiguration(mFaacEncHandle);

2 . 设置编码器参数 : 为 mFaacEncHandle 音频编码器设置 configurationPtr 编码器参数

faacEncSetConfiguration(mFaacEncHandle, configurationPtr);

先获取 FAAC 编码器参数 faacEncConfigurationPtr 结构体 , 然后设置编码器参数 , 最后再将编码器参数 设置回 FAAC 编码器 FaacEncHandle ;

四、 设置 FAAC 编码器编码标准


设置 FAAC 编码器编码标准 : 可以设置 MPEG2 , 或 MPEG4 , 目前一般设置 MPEG4 标准 ;

// 设置编码格式标准, 使用 MPEG4 新标准
configurationPtr->mpegVersion = MPEG4;

五、 设置 FAAC 编码器 AAC 编码规格


1 . AAC 编码规格 : 999 种 ;

  • MPEG-2 AAC LC低复杂度规格(Low Complexity)
  • MPEG-2 AAC Main主规格
  • MPEG-2 AAC SSR可变采样率规格(Scaleable Sample Rate)
  • MPEG-4 AAC LC低复杂度规格(Low Complexity)
  • MPEG-4 AAC Main主规格, MPEG-4 AAC SSR可变采样率规格(Scaleable Sample Rate)
  • MPEG-4 AAC LTP长时期预测规格(Long Term Predicition)
  • MPEG-4 AAC LD低延迟规格(Low Delay)
  • MPEG-4 AAC HE高效率规格(High Efficiency)

2 . 这里选择低复杂度规格 : MPEG-4 AAC LC低复杂度规格(Low Complexity) 是最常用的 AAC 编码规格, 即兼顾了编码效率, 有保证了音质;

( 使用更高音质, 极大降低编码效率, 音质提升效果有限 ; 再提升编码效率, 会使音质降低很多 )

configurationPtr->aacObjectType = LOW;

六、 设置 FAAC 编码器输入、输出格式


1 . 设置编码器的输入格式 : 这里设置输入的 PCM 的采样位数是 161616 位 ;

configurationPtr->inputFormat = FAAC_INPUT_16BIT;

2 . 设置编码器的输出格式 : 这里设置输出格式 0, 就是 FAAC 将 PCM 采样进行编码, 编码出的格式是 AAC 原始数据 , 即没有解码信息的 ADIF 和 ADTS 的 AAC 纯样本裸数据 ;

configurationPtr->outputFormat = 0;

参考 【Android RTMP】音频数据采集编码 ( AAC 音频格式解析 | FLV 音频数据标签解析 | AAC 音频数据标签头 | 音频解码配置信息 ) 博客的 AAC 格式音频解析 , AAC 有两种格式 :

  • 音频数据交换格式 ( Audio Data Interchange Format )
  • 音频数据传输流格式 ( Audio Data Transport Stream )

此处使用的不是上述两种格式的任意一种 , 而是 AAC 的纯样本裸数据 ;

七、 FAAC 设置音频编码参数代码


1 . 成员变量定义代码 :

    /*** 输入样本个数, 需要进行编码的 PCM 音频样本个数* FAAC 编码器最多一次可以接收的样本个数* 传递下面两个数值的地址到 faacEncOpen 函数中, 用于当做返回值使用** 该数据需要返回给 Java 层* Java 层每次从 AudioRecord 中读取 mInputSamples 个数据*/unsigned long mInputSamples;/*** FAAC 编码器最多一次可以接收的样本个数* 传递下面两个数值的地址到 faacEncOpen 函数中, 用于当做返回值使用*/unsigned long mMaxOutputBytes;/*** PCM 音频 FAAC 编码器* 将 PCM 采样数据编码成 FAAC 编码器*/faacEncHandle mFaacEncHandle;/*** FAAC 编码输出缓冲区* FAAC 编码后的 AAC 裸数据, 存储到该缓冲区中* 该缓冲区在初始化 FAAC 编码器时创建*/unsigned char* mFaacEncodeOutputBuffer;

2 . FACC 编码器参数初始化代码 :

/*** 设置音频编码参数* @param sampleRateInHz    音频采样率* @param channelConfig     音频采样通道, 单声道 / 立体声*/
void AudioChannel::setAudioEncoderParameters(int sampleRateInHz, int channelConfig) {// 设置音频通道参数, 单声道 / 立体声mChannelConfig = channelConfig;/*打开编码器faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,unsigned int numChannels,unsigned long *mInputSamples,unsigned long *mMaxOutputBytes);unsigned long sampleRate 参数 : 音频采样率unsigned int numChannels 参数 : 音频通道参数unsigned long *mInputSamples 参数 : 输入样本个数, 需要进行编码的 PCM 音频样本个数FAAC 编码器最多一次可以接收的样本个数unsigned long *mMaxOutputBytes 参数 : 输出数据最大字节数faacEncHandle 返回值 : FAAC 音频编码器注意上述 样本个数, 字节个数 区别 : 16 位采样位数, 一个样本有 2 字节*/mFaacEncHandle = faacEncOpen(sampleRateInHz, channelConfig, &mInputSamples, &mMaxOutputBytes);// 获取编码器当前参数// 先获取参数, 然后设置参数, 最后再设置回去faacEncConfigurationPtr configurationPtr = faacEncGetCurrentConfiguration(mFaacEncHandle);// 设置编码格式标准, 使用 MPEG4 新标准configurationPtr->mpegVersion = MPEG4;/*设置 AAC 编码规格, 有 9 种MPEG-2 AAC LC低复杂度规格(Low Complexity), MPEG-2 AAC Main主规格, MPEG-2 AAC SSR可变采样率规格(Scaleable Sample Rate)MPEG-4 AAC LC低复杂度规格(Low Complexity), MPEG-4 AAC Main主规格, MPEG-4 AAC SSR可变采样率规格(Scaleable Sample Rate)MPEG-4 AAC LTP长时期预测规格(Long Term Predicition), MPEG-4 AAC LD低延迟规格(Low Delay), MPEG-4 AAC HE高效率规格(High Efficiency)这里选择低复杂度规格, 可选参数有 4 种MPEG-4 AAC LC低复杂度规格(Low Complexity) 是最常用的 AAC 编码规格, 即兼顾了编码效率, 有保证了音质;使用更高音质, 极大降低编码效率, 音质提升效果有限再提升编码效率, 会使音质降低很多*/configurationPtr->aacObjectType = LOW;// 采样位数 16 位configurationPtr->inputFormat = FAAC_INPUT_16BIT;/*AAC 音频文件有两种格式 ADIF 和 ADTSAAC 文件解码时 : 音频解码信息定义在头部, 后续音频数据解码按照音频数据长度音频数据交换格式 ( Audio Data Interchange Format ) , 只有一份音频解码信息 , 存储在文件开头这种格式适合存储音频文件 , 节省空间 , 但是必须从开始播放才可以 , 从中间位置无法播放 ;音频数据传输流格式 ( Audio Data Transport Stream ) , 每隔一段音频数据就会有一份音频解码信息 , 这种格式适合音频流传输 , 可以在任何位置开始解码播放 ;RTMP 推流时, 不使用上述两种格式推流视频时, 先将 SPS, PPS 解码数据包的信息推流到服务器上推流音频时, 也是将解码相关的数据先推流到服务器中AAC 编码时, 会编码成 ADTS 数据但是推流音频时, 推流的是 AAC 裸数据, 需要将 ADTS 音频格式中的头信息去掉博客中截图 FLV 第一帧 AAC 音频数据标签 和 后续 AAC 音频数据标签这里设置输出格式 0, 就是 FAAC 将 PCM 采样进行编码, 编码出的格式是 AAC 原始数据即没有解码信息的 ADIF 和 ADTS 的 AAC 纯样本裸数据*/configurationPtr->outputFormat = 0;// 为 mFaacEncHandle 音频编码器设置 configurationPtr 编码器参数faacEncSetConfiguration(mFaacEncHandle, configurationPtr);// 初始化输出缓冲区, 保存 FAAC 编码输出数据mFaacEncodeOutputBuffer = new unsigned char[mMaxOutputBytes];
}

【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )相关推荐

  1. 【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频采样数据 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )

    文章目录 安卓直播推流专栏博客总结 一. FAAC 编码器编码 AAC 音频采样数据 二. 封装 RTMP 音频数据头 三. 封装 RTMP 音频数据类型 四. 拷贝 AAC 音频数据到 RTMPPa ...

  2. 【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频解码信息 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )

    文章目录 安卓直播推流专栏博客总结 一. FAAC 编码器编码 AAC 音频解码信息 二. 封装 RTMP 音频数据头 三. 封装 RTMP 音频数据类型 四. 拷贝 AAC 音频数据到 RTMPPa ...

  3. 【Android RTMP】音频数据采集编码 ( FAAC 头文件与静态库拷贝到 AS | CMakeList.txt 配置 FAAC | AudioRecord 音频采样 PCM 格式 )

    文章目录 安卓直播推流专栏博客总结 一. FAAC 头文件与静态库拷贝到 Android Studio 二. CMakeList.txt 构建脚本配置 三. Java 层 AudioRecord 音频 ...

  4. 【Android RTMP】音频数据采集编码 ( 音频数据采集编码 | AAC 高级音频编码 | FAAC 编码器 | Ubuntu 交叉编译 FAAC 编码器 )

    文章目录 安卓直播推流专栏博客总结 一. 音频数据采集.编码 二. AAC 高级音频编码 三. FAAC 编码器 四. Ubuntu 18.04.4 交叉编译 FAAC 编码器 安卓直播推流专栏博客总 ...

  5. 【Android RTMP】音频数据采集编码 ( AAC 音频格式解析 | FLV 音频数据标签解析 | AAC 音频数据标签头 | 音频解码配置信息 )

    文章目录 安卓直播推流专栏博客总结 一. AAC 音频格式解析 二. FLV 音频数据标签解析 1. 分析 FLV 格式中的 AAC 音频格式数据 2. AAC 音频特殊配置 3. AAC 音频数据标 ...

  6. 【Android RTMP】安卓直播推流总结 ( 直播服务器搭建 | NV21 图像采集 | H.264 视频编码 | PCM 音频采集 | AAC 音频编码 | RTMP 包封装推流 )

    文章目录 一. 安卓直播推流专栏博客总结 二. 相关资源介绍 三. GitHub 源码地址 四. 整体 Android 直播推流数据到服务器并观看直播演示过程 Android 直播推流流程 : 手机采 ...

  7. 【Android RTMP】RTMP 直播推流阶段总结 ( 服务器端搭建 | Android 手机端编码推流 | 电脑端观看直播 | 服务器状态查看 )

    文章目录 安卓直播推流专栏博客总结 一. 服务器搭建 二. 手机端推流 三. 电脑端观看直播 四. RTMP 服务器端状态 安卓直播推流专栏博客总结 Android RTMP 直播推流技术专栏 : 0 ...

  8. 【Android RTMP】RTMPDump 封装 RTMPPacket 数据包 ( 关键帧数据格式 | 非关键帧数据格式 | x264 编码后的数据处理 | 封装 H.264 视频数据帧 )

    文章目录 安卓直播推流专栏博客总结 一. x264 编码后的 H.264 数据帧 二. RTMP 协议中 关键帧 / 非关键帧 数据格式 说明 三. 判定 H.264 帧数据分隔符 四. 初始化 RT ...

  9. 【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )

    文章目录 安卓直播推流专栏博客总结 一. x264 编码器参数设置引入 二. 获取 x264 编码器参数 三. 设置 x264 编码器编码规格 四. 设置 x264 编码器编码图像数据格式 五. 设置 ...

最新文章

  1. GIS项目中数据开源、工具开源、开发开源的解决方案
  2. windows bat 设置ip_A6v5.1网络版安装与防火墙设置
  3. UBoot常用命令手册
  4. MySQL子查询介绍
  5. 算法-排序-冒泡排序
  6. 微软为开源计算器加入全新的图形功能
  7. 一个可以参考的JVM内存分配
  8. 小程序中的setData的使用
  9. Zimbra的zmcontral服务无法起来,提示ldap有问题。
  10. 现在还有人玩暗黑2吗?
  11. php怎么画五星红旗,php基于GD库画五星红旗的方法,phpgd库五星红旗_PHP教程
  12. WMI的讲解(是什么,做什么,为什么)
  13. 数学建模优秀论文2(层次分析有关)
  14. photoshop另存为dds文件时的错误
  15. Lenovo XiaoXin Air13Pro Win10引导ubuntu19.10双系统
  16. 基于 java 的批量下载压缩包的实现
  17. C++Primer PLus 第五版读书笔记
  18. 百度测试实习面试记录
  19. 用U盘重装Win7系统方法
  20. 电池寿命增压器为android,一个涡轮增压器的寿命只有10年?

热门文章

  1. 比较经典的三层交换机实验
  2. 用JSON技术加快AJAX程序开发
  3. 启动nuxt项目fsevents报错
  4. LWIP再探----内存池管理
  5. 无法连接到数据库服务器 could not connect to server: Connection refused
  6. 存储过程里面的CASE,WHEN,THEN的用法
  7. Ajax调用webService(一) 不跨域。
  8. MYSQL 看书笔记
  9. dwr消息推送和tomcat集群
  10. 【Java架构:持续交付】一篇文章搞掂:持续交付理论