【移動應用開發(fā)技術(shù)】Android音頻開發(fā)(3):如何播放一幀音頻_第1頁
【移動應用開發(fā)技術(shù)】Android音頻開發(fā)(3):如何播放一幀音頻_第2頁
【移動應用開發(fā)技術(shù)】Android音頻開發(fā)(3):如何播放一幀音頻_第3頁
【移動應用開發(fā)技術(shù)】Android音頻開發(fā)(3):如何播放一幀音頻_第4頁
【移動應用開發(fā)技術(shù)】Android音頻開發(fā)(3):如何播放一幀音頻_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論