基本概念
最近在做一個音樂相關(guān)的項目,對音樂的播放的基本操作是免不了的,作為android 小白的我來說第一時間想到了使用MediaPlayer來實現(xiàn)。
SoundPool 顧名思義是聲音的池子??纯聪旅?a target="_blank" rel="nofollow">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ù)量。當(dāng)構(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負(fù)載,并減少混音會影響視覺效果或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)先級越高。當(dāng)創(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)注流生命周期。
在我們的例子中,當(dāng)玩家完成關(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è)為默認(rèn)
但在上面的構(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)操作的標(biāo)識。
控制播放等一些其他設(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é)一下做個筆記。
每天都有進(jìn)步。