




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
【移動應用開發(fā)技術(shù)】Android音頻開發(fā)(3):如何播放一幀音頻
本文重點關(guān)注如何在Android平臺上播放一幀音頻數(shù)據(jù)。閱讀本文之前,建議先讀一下《Android音頻開發(fā)(1):基礎(chǔ)知識》,因為音頻開發(fā)過程中,經(jīng)常要涉及到這些基礎(chǔ)知識,掌握了這些重要的概念后,開發(fā)過程中的很多參數(shù)和流程就會更加容易理解。AndroidSDK提供了3套音頻播放的API,分別是:MediaPlayer,SoundPool,AudioTrack,關(guān)于它們的區(qū)別可以看這篇文章:《IntrotothethreeAndroidAudioAPIs》,簡單來說,MediaPlayer更加適合在后臺長時間播放本地音樂文件或者在線的流式資源;SoundPool則適合播放比較短的音頻片段,比如游戲聲音、按鍵聲、鈴聲片段等等,它可以同時播放多個音頻;而AudioTrack則更接近底層,提供了非常強大的控制能力,支持低延遲播放,適合流媒體和VoIP語音電話等場景。音頻的開發(fā),更廣泛地應用不僅僅局限于播放本地文件或者音頻片段,因此,本文重點關(guān)注如何利AudioTrackAPI來播放音頻數(shù)據(jù)(注意,使用AudioTrack播放的音頻必須是解碼后的PCM數(shù)據(jù))。1.AudioTrack的工作流程首先,我們了解一下AudioTrack的工作流程:(1)配置參數(shù),初始化內(nèi)部的音頻播放緩沖區(qū)(2)開始播放(3)需要一個線程,不斷地向AudioTrack的緩沖區(qū)“寫入”音頻數(shù)據(jù),注意,這個過程一定要及時,否則就會出現(xiàn)“underrun”的錯誤,該錯誤在音頻開發(fā)中比較常見,意味著應用層沒有及時地“送入”音頻數(shù)據(jù),導致內(nèi)部的音頻播放緩沖區(qū)為空。(4)停止播放,釋放資源2.AudioTrack的參數(shù)配置上面是AudioTrack的構(gòu)造函數(shù)原型,主要靠構(gòu)造函數(shù)來配置相關(guān)的參數(shù),下面一一解釋(再次建議先閱讀一下《Android音頻開發(fā)(1):基礎(chǔ)知識》):(1)streamType這個參數(shù)代表著當前應用使用的哪一種音頻管理策略,當系統(tǒng)有多個進程需要播放音頻時,這個管理策略會決定最終的展現(xiàn)效果,該參數(shù)的可選的值以常量的形式定義在AudioManager類中,主要包括:STREAM_VOCIE_CALL:電話聲音STREAM_SYSTEM:系統(tǒng)聲音STREAM_RING:鈴聲STREAM_MUSCI:音樂聲STREAM_ALARM:警告聲STREAM_NOTIFICATION:通知聲(2)sampleRateInHz采樣率,從AudioTrack源碼的“audioParamCheck”函數(shù)可以看到,這個采樣率的取值范圍必須在4000Hz~192000Hz之間。(3)channelConfig通道數(shù)的配置,可選的值以常量的形式定義在AudioFormat類中,常用的是CHANNEL_IN_MONO(單通道),CHANNEL_IN_STEREO(雙通道)(4)audioFormat這個參數(shù)是用來配置“數(shù)據(jù)位寬”的,可選的值也是以常量的形式定義在AudioFormat類中,常用的是ENCODING_PCM_16BIT(16bit),ENCODING_PCM_8BIT(8bit),注意,前者是可以保證兼容所有Android手機的。(5)bufferSizeInBytes這個是最難理解又最重要的一個參數(shù),它配置的是AudioTrack內(nèi)部的音頻緩沖區(qū)的大小,該緩沖區(qū)的值不能低于一幀“音頻幀”(Frame)的大小,而前一篇文章介紹過,一幀音頻幀的大小計算如下:intsize=采樣率x位寬x采樣時間x通道數(shù)采樣時間一般取2.5ms~120ms之間,由廠商或者具體的應用決定,我們其實可以推斷,每一幀的采樣時間取得越短,產(chǎn)生的延時就應該會越小,當然,碎片化的數(shù)據(jù)也就會越多。在Android開發(fā)中,AudioTrack類提供了一個幫助你確定這個bufferSizeInBytes的函數(shù),原型如下:intgetMinBufferSize(intsampleRateInHz,intchannelConfig,intaudioFormat);不同的廠商的底層實現(xiàn)是不一樣的,但無外乎就是根據(jù)上面的計算公式得到一幀的大小,音頻緩沖區(qū)的大小則必須是一幀大小的2~N倍,有興趣的朋友可以繼續(xù)深入源碼探究探究。實際開發(fā)中,強烈建議由該函數(shù)計算出需要傳入的bufferSizeInBytes,而不是自己手動計算。(6)modeAudioTrack提供了兩種播放模式,一種是static方式,一種是streaming方式,前者需要一次性將所有的數(shù)據(jù)都寫入播放緩沖區(qū),簡單高效,通常用于播放鈴聲、系統(tǒng)提醒的音頻片段;后者則是按照一定的時間間隔不間斷地寫入音頻數(shù)據(jù),理論上它可用于任何音頻播放的場景??蛇x的值以常量的形式定義在AudioTrack類中,一個是MODE_STATIC,另一個是MODE_STREAM,根據(jù)具體的應用傳入對應的值即可。4.示例代碼我將AudioTrack類的接口簡單封裝了一下,提供了一個AudioPlayer類,可以到我的Github下載:/Jhuster/Android/blob/master/Audio/AudioPlayer.java這里也貼出來一份:/*
*
COPYRIGHT
NOTICE
*
Copyright
(C)
2016,
Jhuster
<lujun.hust@>
*
/Jhuster/Android
*
*
@license
under
the
Apache
License,
Version
2.0
*
*
@file
AudioPlayer.java
*
*
@version
1.0
*
@author
Jhuster
*
@date
2016/03/13
*/
package
com.jhuster.audiodemo;
import
android.util.Log;
import
android.media.AudioFormat;
import
android.media.AudioManager;
import
android.media.AudioTrack;
public
class
AudioPlayer
{
private
static
final
String
TAG
=
"AudioPlayer";
private
static
final
int
DEFAULT_STREAM_TYPE
=
AudioManager.STREAM_MUSIC;
private
static
final
int
DEFAULT_SAMPLE_RATE
=
44100;
private
static
final
int
DEFAULT_CHANNEL_CONFIG
=
AudioFormat.CHANNEL_IN_STEREO;
private
static
final
int
DEFAULT_AUDIO_FORMAT
=
AudioFormat.ENCODING_PCM_16BIT;
private
static
final
int
DEFAULT_PLAY_MODE
=
AudioTrack.MODE_STREAM;
private
boolean
mIsPlayStarted
=
false;
private
int
mMinBufferSize
=
0;
private
AudioTrack
mAudioTrack;
public
boolean
startPlayer()
{
return
startPlayer(DEFAULT_STREAM_TYPE,DEFAULT_SAMPLE_RATE,DEFAULT_CHANNEL_CONFIG,DEFAULT_AUDIO_FORMAT);
}
public
boolean
startPlayer(int
streamType,
int
sampleRateInHz,
int
channelConfig,
int
audioFormat)
{
if
(mIsPlayStarted)
{
Log.e(TAG,
"Player
already
started
!");
return
false;
}
mMinBufferSize
=
AudioTrack.getMinBufferSize(sampleRateInHz,channelConfig,audioFormat);
if
(mMinBufferSize
==
AudioTrack.ERROR_BAD_VALUE)
{
Log.e(TAG,
"Invalid
parameter
!");
return
false;
}
Log.d(TAG
,
"getMinBufferSize
=
"+mMinBufferSize+"
bytes
!");
mAudioTrack
=
new
AudioTrack(streamType,sampleRateInHz,channelConfig,audioFormat,mMinBufferSize,DEFAULT_PLAY_MODE);
if
(mAudioTrack.getState()
==
AudioTrack.STATE_UNINITIALIZED)
{
Log.e(TAG,
"AudioTrack
initialize
fail
!");
return
false;
}
mIsPlayStarted
=
true;
Log.d(TAG,
"Start
audio
player
success
!");
return
true;
}
public
int
getMinBufferSize()
{
return
mMinBufferSize;
}
public
void
stopPlayer()
{
if
(!mIsPlayStarted)
{
return;
}
if
(mAudioTrack.getPlayState()
==
AudioTrack.PLAYSTATE_PLAYING)
{
mAudioTrack.stop();
}
mAudioTrack.release();
mIsPlayStarted
=
false;
Log.d(TAG,
"Stop
audio
player
success
!");
}
public
boolean
play(byte[]
audioData,
int
offsetInBytes,
int
sizeInBytes)
{
if
(!mIsPlayStarted)
{
Log.e(TAG,
"Player
not
started
!");
return
false;
}
if
(sizeInBytes
<
mMinBufferSize)
{
Log.e(TAG,
"audio
data
is
not
enough
!");
return
false;
}
if
(mAudioTrack.write(audioData,offsetInBytes,sizeInBytes)
!=
sizeInBytes)
{
Log.e(TAG,
"Could
not
write
all
the
samples
to
the
audio
device
!");
}
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 物業(yè)租賃管理合同協(xié)議
- 專柜裝修合同裝修合同協(xié)議
- 房屋轉(zhuǎn)讓協(xié)議合同書
- 聘請勞務合同
- 安置房買賣協(xié)議合同
- 小學六英語試卷答案
- 賣魚銷售合同范本
- 個人一周工作計劃
- 冷凍品供貨合同范本
- 三年級下冊音樂教案
- 《工程合同管理與招投標實訓》課程電子教案
- 標本溢灑應急預案
- 藥品類體外診斷試劑專項培訓課件
- 2024年有關(guān)對外擔保-股東會決議范本
- 老舊小區(qū)改造工程施工組織設計方案
- 建筑幕墻工程檢測知識考試題庫500題(含答案)
- 1shopee課程簡介認識蝦皮
- +一次函數(shù)復習課+教學設計 中考數(shù)學一輪復習(北師大版)
- 人教版一年級數(shù)學下冊全冊教案(表格式)
- 4.2基因表達與性狀的關(guān)系2表觀遺傳高一下學期生物人教版必修2
- 11BS4排水工程華北標圖集
評論
0/150
提交評論