基本概念
最近在做一個音樂相關(guān)的項目,對音樂的播放的基本操作是免不了的瑟由,作為android 小白的我來說第一時間想到了使用MediaPlayer來實現(xiàn)絮重。
SoundPool 顧名思義是聲音的池子〈蹩啵看看下面SoundPool官方文檔的解釋:
<!--soundpool 用來管理和播放音頻文件的-->
The SoundPool class manages and plays audio resources for applications.
A SoundPool is a collection of samples that can be loaded into memory
from a resource inside the APK or from a file in the file system.
SoundPool 與 MediaPlayer
為什么他們要用SoundPool 而不用MediaPlayer? 它們有什么區(qū)別呢青伤?
為了以后就不用對著英文翻譯,就把整個SoundPool文檔翻譯了一下:
除了低延遲播放之外殴瘦,SoundPool還可以管理一次渲染的音頻流數(shù)量狠角。當構(gòu)建SoundPool對象時,maxStreams參數(shù)設(shè)置可從此單個SoundPool一次播放的最大流數(shù)痴施。 SoundPool跟蹤活動流的數(shù)量擎厢。如果超過了最大數(shù)量的數(shù)據(jù)流究流,SoundPool會根據(jù)優(yōu)先級自動停止先前播放的數(shù)據(jù)流辣吃,然后根據(jù)該優(yōu)先級按年齡自動停止动遭。限制數(shù)據(jù)流的最大數(shù)量有助于限制CPU負載,并減少混音會影響視覺效果或UI性能的可能性神得。
聲音可以通過設(shè)置非零循環(huán)值來循環(huán)厘惦。值為-1會導(dǎo)致聲音永久循環(huán)。在這種情況下哩簿,應(yīng)用程序必須顯式調(diào)用stop()函數(shù)來停止聲音宵蕉。任何其他非零值將導(dǎo)致聲音重復(fù)指定的次數(shù),例如节榜,值為3會導(dǎo)致聲音總共播放4次羡玛。
播放速率也可以改變。 1.0的播放速率會導(dǎo)致聲音以其原始頻率播放(如果需要宗苍,重新采樣至硬件輸出頻率)稼稿。 2.0的播放速率會使聲音以原始頻率的兩倍播放,0.5的播放速度會使其以原始頻率的一半播放讳窟。播放速率范圍是0.5到2.0吕朵。
優(yōu)先級從低到高嗜诀,即數(shù)字越大,優(yōu)先級越高。當創(chuàng)建SoundPool時哮塞,對play()的調(diào)用會導(dǎo)致活動流的數(shù)量超過maxStreams參數(shù)所設(shè)置的值時使用優(yōu)先級。在這種情況下匾七,流分配器將停止最低優(yōu)先級的流赦邻。如果有多個具有相同低優(yōu)先級的流,它將選擇最舊的流停止坑雅。在新流的優(yōu)先級低于所有活動流的情況下辈挂,新的聲音將不會播放,并且play()函數(shù)將返回0的流ID霞丧。
讓我們來看一個典型的用例:一個游戲包含多個層次的游戲呢岗。對于每個級別,都有一組只有該級別使用的獨特聲音蛹尝。在這種情況下后豫,游戲邏輯應(yīng)該在第一級加載時創(chuàng)建一個新的SoundPool對象。關(guān)卡數(shù)據(jù)本身可能包含此關(guān)卡使用的聲音列表突那。加載邏輯遍歷調(diào)用相應(yīng)SoundPool.load()函數(shù)的聲音列表挫酿。這通常應(yīng)該在流程的早期完成,以便在需要播放之前有時間將音頻解壓為原始PCM格式愕难。
一旦聲音加載并開始播放早龟,應(yīng)用程序可以通過調(diào)用SoundPool.play()來觸發(fā)聲音惫霸。播放流可以暫停或恢復(fù)葱弟,應(yīng)用程序還可以通過實時調(diào)整播放速率來改變音高壹店,以獲得多普勒效應(yīng)或綜合效果。
請注意芝加,由于流可因資源限制而停止硅卢,因此streamID是對流的特定實例的引用。如果流停止以允許播放更高優(yōu)先級的流藏杖,則流不再有效将塑。但是,應(yīng)用程序可以無錯地調(diào)用streamID上的方法蝌麸。這可能有助于簡化程序邏輯点寥,因為應(yīng)用程序不需要關(guān)注流生命周期。
在我們的例子中来吩,當玩家完成關(guān)卡時敢辩,游戲邏輯應(yīng)該調(diào)用SoundPool.release()來釋放所有正在使用的本地資源,然后將SoundPool參考設(shè)置為null误褪。如果玩家開始另一個關(guān)卡责鳍,則會創(chuàng)建一個新的SoundPool,聲音會被載入兽间,然后重新開始播放历葛。
從SoundPool文檔中,以及小白對MediaPlayer 之前的簡單使用嘀略,總結(jié)了亮點:
soundPool 相比MediaPlayer 播放延時更低恤溶;
soundPool 適用于播放聲音短促的音樂文件(10s以內(nèi)的)
支持多個音頻同時播放
基本使用
-
構(gòu)造方法
SoundPool (int maxStreams, int streamType, int srcQuality)
//maxStreams 設(shè)置soundpool對象的并發(fā)流的最大數(shù)量
//streamType 設(shè)置流的類型,一般為STREAM_MUSIC
//srcQuality 采樣轉(zhuǎn)換率的質(zhì)量 現(xiàn)在沒有什么效果 0 設(shè)為默認
但在上面的構(gòu)造方法在api 21 被廢棄了帜羊。API 21 以后使用SoundPool.Builder創(chuàng)建soundpool對象實例:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
mSoundPool = new SoundPool.Builder()
.setMaxStreams(maxSteams)
.build();
} else {
mSoundPool = new SoundPool(maxSteams, AudioManager.STREAM_MUSIC, 0);
}
-
常用方法
加載音頻文件
與MediaPlayer相同 SoundPool 加載音頻文件有多種方式
<!--加載應(yīng)用資源文件--> 注意:切忌使用文件名相同咒程,格式名不同的文件example.mp3 ,example.wav
int load(Context context, int resId, int priority)
<!--從音頻文件路徑加載-->
int load(String path, int priority)
<!--從asset 文件中加載-->
int load(AssetFileDescriptor afd, int priority)
<!--從文件中加載-->
int load(FileDescriptor fd, long offset, long length, int priority)
上述方法加載音頻返回一個sound ID. 這個ID就是用來播放對應(yīng)加載音樂文件以及相應(yīng)操作的標識。
控制播放等一些其他設(shè)置
stop(int streamID)
pause(int streamID)
resume(int streamID)
release()
<!--設(shè)置循環(huán)播放 (0 不循環(huán), -1 循環(huán))-->
setLoop(int streamID, int loop)
<!--設(shè)置有播放優(yōu)先級-->
setPriority(int streamID, int priority)
<!--設(shè)置播放播放速度 rate值 0.5 ~2.0 之間-->
setRate(int streamID, float rate)
setVolume(int streamID, float leftVolume, float rightVolume)
<!--相對于load方法-->
unload(int soundID)
<!--此方法會遍歷所有正在播放的音樂 并設(shè)置flag 讼育,在autoResume的時候恢復(fù)播放-->
autoPause()
autoResume()
監(jiān)聽
setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener)
SoundPool 使用起來還是很簡單的帐姻。還是想總結(jié)一下做個筆記。
每天都有進步奶段。