【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )
文章目錄
- 一、 頭文件、成員變量準(zhǔn)備
- 二、 創(chuàng)建 FAAC 編碼器
- 三、 獲取并設(shè)置 FAAC 編碼器參數(shù)
- 四、 設(shè)置 FAAC 編碼器編碼標(biāo)準(zhǔn)
- 五、 設(shè)置 FAAC 編碼器 AAC 編碼規(guī)格
- 六、 設(shè)置 FAAC 編碼器輸入、輸出格式
- 七、 FAAC 設(shè)置音頻編碼參數(shù)代碼
Android 直播推流流程 : 手機(jī)采集視頻 / 音頻數(shù)據(jù) , 視頻數(shù)據(jù)使用 H.264 編碼 , 音頻數(shù)據(jù)使用 AAC 編碼 , 最后將音視頻數(shù)據(jù)都打包到 RTMP 數(shù)據(jù)包中 , 使用 RTMP 協(xié)議上傳到 RTMP 服務(wù)器中 ;
視頻推流 : 之前的一系列博客中完成手機(jī)端采集視頻數(shù)據(jù)操作 , 并將視頻數(shù)據(jù)傳遞給 JNI , 在 NDK 中使用 x264 將圖像轉(zhuǎn)為 H.264 格式的視頻 , 最后將 H.264 格式的視頻打包到 RTMP 數(shù)據(jù)包中 , 上傳到 RTMP 服務(wù)器中 ;
音頻推流 : 開始進(jìn)行音頻直播推流操作 , 先采集音頻 , 將音頻編碼為 AAC 格式 , 將編碼后的音頻打包成 RTMP 包 , 然后推流到服務(wù)器中 ;
NV21 格式圖像編碼為 H.264 視頻 , 需要設(shè)置 x264 編碼器參數(shù) , 對應(yīng) 【Android RTMP】x264 編碼器初始化及設(shè)置 ( 獲取 x264 編碼參數(shù) | 編碼規(guī)格 | 碼率 | 幀率 | B幀個數(shù) | 關(guān)鍵幀間隔 | 關(guān)鍵幀解碼數(shù)據(jù) SPS PPS ) 博客 ;
本博客中講解的是 , PCM 音頻采樣編碼為 AAC 音頻 , 如何設(shè)置 FACC 編碼器參數(shù) ;
一、 頭文件、成員變量準(zhǔn)備
1 . 導(dǎo)入包 : 使用 FACC 編碼器前 , 必須導(dǎo)入 facc.h 頭文件 ;
#include <faac.h>2 . 成員變量定義 : 在初始化 FACC 編碼器時 , 需要預(yù)先定義一些成員變量 , 這些變量在后續(xù)設(shè)置編碼器參數(shù) , 音頻編碼時都需要使用到 ;
① 輸入樣本個數(shù) : 輸入到 FAAC 編碼器中的需要進(jìn)行編碼的 PCM 樣本個數(shù) , 表示FAAC 編碼器最多一次可以接收的樣本個數(shù) ,
unsigned long mInputSamples;注意 : 是樣本個數(shù) , 不是字節(jié)數(shù) , 如果采樣位數(shù)是 888 位 , 那么 字節(jié)數(shù)=樣本個數(shù)字節(jié)數(shù) = 樣本個數(shù)字節(jié)數(shù)=樣本個數(shù) , 如果采樣位數(shù)是 161616 位 , 字節(jié)數(shù)=樣本個數(shù)×2字節(jié)數(shù) = 樣本個數(shù) \times 2字節(jié)數(shù)=樣本個數(shù)×2 ;
② FAAC 編碼器最大輸出字節(jié)數(shù) : 該參數(shù) mMaxOutputBytes 與上面的 mInputSamples 都要傳入 FAAC 編碼器創(chuàng)建函數(shù)中 , 用于接收創(chuàng)建 FAAC 編碼器后的返回值 , 創(chuàng)建之前這些值是不知道的 ;
unsigned long mMaxOutputBytes;③ FAAC 編碼器 : 用于將 PCM 音頻采樣編碼成 AAC 格式 ;
faacEncHandle mFaacEncHandle;④ FAAC 編碼輸出緩沖區(qū) : FAAC 編碼后的 AAC 裸數(shù)據(jù), 存儲到該緩沖區(qū)中 , 該緩沖區(qū)在初始化 FAAC 編碼器時創(chuàng)建 ; 初始化完成后 , 知道 FAAC 最大輸出緩沖區(qū)大小后 , 創(chuàng)建該輸出緩沖區(qū) , 其大小是 mMaxOutputBytes 字節(jié) ;
unsigned char* mFaacEncodeOutputBuffer;二、 創(chuàng)建 FAAC 編碼器
1 . 調(diào)用 faacEncOpen 函數(shù) , 創(chuàng)建 FAAC 編碼器 ;
2 . 函數(shù)原型解析 :
faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,unsigned int numChannels,unsigned long *inputSamples,unsigned long *maxOutputBytes);① unsigned long sampleRate 參數(shù) : 音頻采樣率 ;
② unsigned int numChannels 參數(shù) : 音頻通道參數(shù) ;
③ unsigned long *mInputSamples 參數(shù) : 輸入樣本個數(shù), 需要進(jìn)行編碼的 PCM 音頻樣本個數(shù) , FAAC 編碼器最多一次可以接收的樣本個數(shù) ;
④ unsigned long *mMaxOutputBytes 參數(shù) : 輸出數(shù)據(jù)最大字節(jié)數(shù) ;
⑤ faacEncHandle 返回值 : FAAC 音頻編碼器 ;
3 . 創(chuàng)建 FAAC 編碼器 代碼示例 :
mFaacEncHandle = faacEncOpen(sampleRateInHz, channelConfig, &mInputSamples, &mMaxOutputBytes);三、 獲取并設(shè)置 FAAC 編碼器參數(shù)
1 . 獲取編碼器參數(shù) : 先獲取參數(shù), 然后設(shè)置參數(shù), 最后再設(shè)置回去
faacEncConfigurationPtr configurationPtr = faacEncGetCurrentConfiguration(mFaacEncHandle);2 . 設(shè)置編碼器參數(shù) : 為 mFaacEncHandle 音頻編碼器設(shè)置 configurationPtr 編碼器參數(shù)
faacEncSetConfiguration(mFaacEncHandle, configurationPtr);先獲取 FAAC 編碼器參數(shù) faacEncConfigurationPtr 結(jié)構(gòu)體 , 然后設(shè)置編碼器參數(shù) , 最后再將編碼器參數(shù) 設(shè)置回 FAAC 編碼器 FaacEncHandle ;
四、 設(shè)置 FAAC 編碼器編碼標(biāo)準(zhǔn)
設(shè)置 FAAC 編碼器編碼標(biāo)準(zhǔn) : 可以設(shè)置 MPEG2 , 或 MPEG4 , 目前一般設(shè)置 MPEG4 標(biāo)準(zhǔn) ;
// 設(shè)置編碼格式標(biāo)準(zhǔn), 使用 MPEG4 新標(biāo)準(zhǔn) configurationPtr->mpegVersion = MPEG4;五、 設(shè)置 FAAC 編碼器 AAC 編碼規(guī)格
1 . AAC 編碼規(guī)格 : 999 種 ;
- MPEG-2 AAC LC低復(fù)雜度規(guī)格(Low Complexity)
- MPEG-2 AAC Main主規(guī)格
- MPEG-2 AAC SSR可變采樣率規(guī)格(Scaleable Sample Rate)
- MPEG-4 AAC LC低復(fù)雜度規(guī)格(Low Complexity)
- MPEG-4 AAC Main主規(guī)格, MPEG-4 AAC SSR可變采樣率規(guī)格(Scaleable Sample Rate)
- MPEG-4 AAC LTP長時期預(yù)測規(guī)格(Long Term Predicition)
- MPEG-4 AAC LD低延遲規(guī)格(Low Delay)
- MPEG-4 AAC HE高效率規(guī)格(High Efficiency)
2 . 這里選擇低復(fù)雜度規(guī)格 : MPEG-4 AAC LC低復(fù)雜度規(guī)格(Low Complexity) 是最常用的 AAC 編碼規(guī)格, 即兼顧了編碼效率, 有保證了音質(zhì);
( 使用更高音質(zhì), 極大降低編碼效率, 音質(zhì)提升效果有限 ; 再提升編碼效率, 會使音質(zhì)降低很多 )
configurationPtr->aacObjectType = LOW;六、 設(shè)置 FAAC 編碼器輸入、輸出格式
1 . 設(shè)置編碼器的輸入格式 : 這里設(shè)置輸入的 PCM 的采樣位數(shù)是 161616 位 ;
configurationPtr->inputFormat = FAAC_INPUT_16BIT;2 . 設(shè)置編碼器的輸出格式 : 這里設(shè)置輸出格式 0, 就是 FAAC 將 PCM 采樣進(jìn)行編碼, 編碼出的格式是 AAC 原始數(shù)據(jù) , 即沒有解碼信息的 ADIF 和 ADTS 的 AAC 純樣本裸數(shù)據(jù) ;
configurationPtr->outputFormat = 0;參考 【Android RTMP】音頻數(shù)據(jù)采集編碼 ( AAC 音頻格式解析 | FLV 音頻數(shù)據(jù)標(biāo)簽解析 | AAC 音頻數(shù)據(jù)標(biāo)簽頭 | 音頻解碼配置信息 ) 博客的 AAC 格式音頻解析 , AAC 有兩種格式 :
- 音頻數(shù)據(jù)交換格式 ( Audio Data Interchange Format )
- 音頻數(shù)據(jù)傳輸流格式 ( Audio Data Transport Stream )
此處使用的不是上述兩種格式的任意一種 , 而是 AAC 的純樣本裸數(shù)據(jù) ;
七、 FAAC 設(shè)置音頻編碼參數(shù)代碼
1 . 成員變量定義代碼 :
/*** 輸入樣本個數(shù), 需要進(jìn)行編碼的 PCM 音頻樣本個數(shù)* FAAC 編碼器最多一次可以接收的樣本個數(shù)* 傳遞下面兩個數(shù)值的地址到 faacEncOpen 函數(shù)中, 用于當(dāng)做返回值使用** 該數(shù)據(jù)需要返回給 Java 層* Java 層每次從 AudioRecord 中讀取 mInputSamples 個數(shù)據(jù)*/unsigned long mInputSamples;/*** FAAC 編碼器最多一次可以接收的樣本個數(shù)* 傳遞下面兩個數(shù)值的地址到 faacEncOpen 函數(shù)中, 用于當(dāng)做返回值使用*/unsigned long mMaxOutputBytes;/*** PCM 音頻 FAAC 編碼器* 將 PCM 采樣數(shù)據(jù)編碼成 FAAC 編碼器*/faacEncHandle mFaacEncHandle;/*** FAAC 編碼輸出緩沖區(qū)* FAAC 編碼后的 AAC 裸數(shù)據(jù), 存儲到該緩沖區(qū)中* 該緩沖區(qū)在初始化 FAAC 編碼器時創(chuàng)建*/unsigned char* mFaacEncodeOutputBuffer;2 . FACC 編碼器參數(shù)初始化代碼 :
/*** 設(shè)置音頻編碼參數(shù)* @param sampleRateInHz 音頻采樣率* @param channelConfig 音頻采樣通道, 單聲道 / 立體聲*/ void AudioChannel::setAudioEncoderParameters(int sampleRateInHz, int channelConfig) {// 設(shè)置音頻通道參數(shù), 單聲道 / 立體聲mChannelConfig = channelConfig;/*打開編碼器faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,unsigned int numChannels,unsigned long *mInputSamples,unsigned long *mMaxOutputBytes);unsigned long sampleRate 參數(shù) : 音頻采樣率unsigned int numChannels 參數(shù) : 音頻通道參數(shù)unsigned long *mInputSamples 參數(shù) : 輸入樣本個數(shù), 需要進(jìn)行編碼的 PCM 音頻樣本個數(shù)FAAC 編碼器最多一次可以接收的樣本個數(shù)unsigned long *mMaxOutputBytes 參數(shù) : 輸出數(shù)據(jù)最大字節(jié)數(shù)faacEncHandle 返回值 : FAAC 音頻編碼器注意上述 樣本個數(shù), 字節(jié)個數(shù) 區(qū)別 : 16 位采樣位數(shù), 一個樣本有 2 字節(jié)*/mFaacEncHandle = faacEncOpen(sampleRateInHz, channelConfig, &mInputSamples, &mMaxOutputBytes);// 獲取編碼器當(dāng)前參數(shù)// 先獲取參數(shù), 然后設(shè)置參數(shù), 最后再設(shè)置回去faacEncConfigurationPtr configurationPtr = faacEncGetCurrentConfiguration(mFaacEncHandle);// 設(shè)置編碼格式標(biāo)準(zhǔn), 使用 MPEG4 新標(biāo)準(zhǔn)configurationPtr->mpegVersion = MPEG4;/*設(shè)置 AAC 編碼規(guī)格, 有 9 種MPEG-2 AAC LC低復(fù)雜度規(guī)格(Low Complexity), MPEG-2 AAC Main主規(guī)格, MPEG-2 AAC SSR可變采樣率規(guī)格(Scaleable Sample Rate)MPEG-4 AAC LC低復(fù)雜度規(guī)格(Low Complexity), MPEG-4 AAC Main主規(guī)格, MPEG-4 AAC SSR可變采樣率規(guī)格(Scaleable Sample Rate)MPEG-4 AAC LTP長時期預(yù)測規(guī)格(Long Term Predicition), MPEG-4 AAC LD低延遲規(guī)格(Low Delay), MPEG-4 AAC HE高效率規(guī)格(High Efficiency)這里選擇低復(fù)雜度規(guī)格, 可選參數(shù)有 4 種MPEG-4 AAC LC低復(fù)雜度規(guī)格(Low Complexity) 是最常用的 AAC 編碼規(guī)格, 即兼顧了編碼效率, 有保證了音質(zhì);使用更高音質(zhì), 極大降低編碼效率, 音質(zhì)提升效果有限再提升編碼效率, 會使音質(zhì)降低很多*/configurationPtr->aacObjectType = LOW;// 采樣位數(shù) 16 位configurationPtr->inputFormat = FAAC_INPUT_16BIT;/*AAC 音頻文件有兩種格式 ADIF 和 ADTSAAC 文件解碼時 : 音頻解碼信息定義在頭部, 后續(xù)音頻數(shù)據(jù)解碼按照音頻數(shù)據(jù)長度音頻數(shù)據(jù)交換格式 ( Audio Data Interchange Format ) , 只有一份音頻解碼信息 , 存儲在文件開頭這種格式適合存儲音頻文件 , 節(jié)省空間 , 但是必須從開始播放才可以 , 從中間位置無法播放 ;音頻數(shù)據(jù)傳輸流格式 ( Audio Data Transport Stream ) , 每隔一段音頻數(shù)據(jù)就會有一份音頻解碼信息 , 這種格式適合音頻流傳輸 , 可以在任何位置開始解碼播放 ;RTMP 推流時, 不使用上述兩種格式推流視頻時, 先將 SPS, PPS 解碼數(shù)據(jù)包的信息推流到服務(wù)器上推流音頻時, 也是將解碼相關(guān)的數(shù)據(jù)先推流到服務(wù)器中AAC 編碼時, 會編碼成 ADTS 數(shù)據(jù)但是推流音頻時, 推流的是 AAC 裸數(shù)據(jù), 需要將 ADTS 音頻格式中的頭信息去掉博客中截圖 FLV 第一幀 AAC 音頻數(shù)據(jù)標(biāo)簽 和 后續(xù) AAC 音頻數(shù)據(jù)標(biāo)簽這里設(shè)置輸出格式 0, 就是 FAAC 將 PCM 采樣進(jìn)行編碼, 編碼出的格式是 AAC 原始數(shù)據(jù)即沒有解碼信息的 ADIF 和 ADTS 的 AAC 純樣本裸數(shù)據(jù)*/configurationPtr->outputFormat = 0;// 為 mFaacEncHandle 音頻編碼器設(shè)置 configurationPtr 編碼器參數(shù)faacEncSetConfiguration(mFaacEncHandle, configurationPtr);// 初始化輸出緩沖區(qū), 保存 FAAC 編碼輸出數(shù)據(jù)mFaacEncodeOutputBuffer = new unsigned char[mMaxOutputBytes]; }總結(jié)
以上是生活随笔為你收集整理的【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android RTMP】音频数据采集
- 下一篇: 【Android RTMP】音频数据采集