android使用SoundPool播放音效的方法
在Android開(kāi)發(fā)中我們經(jīng)常使用MediaPlayer來(lái)播放音頻文件,但是MediaPlayer存在一些不足,例如:資源占用量較高、延遲時(shí)間較長(zhǎng)、不支持多個(gè)音頻同時(shí)播放等。這些缺點(diǎn)決定了MediaPlayer在某些場(chǎng)合的使用情況不會(huì)很理想,例如在對(duì)時(shí)間精準(zhǔn)度要求相對(duì)較高的游戲開(kāi)發(fā)中。
在游戲開(kāi)發(fā)中我們經(jīng)常需要播放一些游戲音效(比如:子彈爆炸,物體撞擊等),這些音效的共同特點(diǎn)是短促、密集、延遲程度小。在這樣的場(chǎng)景下,我們可以使用SoundPool代替MediaPlayer來(lái)播放這些音效。
SoundPool(android.media.SoundPool),顧名思義是聲音池的意思,主要用于播放一些較短的聲音片段,支持從程序的資源或文件系統(tǒng)加載。與MediaPlayer相比,SoundPool的優(yōu)勢(shì)在于CPU資源占用量低和反應(yīng)延遲小。另外,SoundPool還支持自行設(shè)置聲音的品質(zhì)、音量、播放比率等參數(shù),支持通過(guò)ID對(duì)多個(gè)音頻流進(jìn)行管理。
就現(xiàn)在已知的資料來(lái)說(shuō),SoundPool有一些設(shè)計(jì)上的BUG,從固件版本1.0開(kāi)始有些還沒(méi)有修復(fù),我們?cè)谑褂弥袘?yīng)該小心再小心。相信將來(lái)Google會(huì)修復(fù)這些問(wèn)題,但我們最好還是列出來(lái):
1. SoundPool最大只能申請(qǐng)1M的內(nèi)存空間,這就意味著我們只能用一些很短的聲音片段,而不是用它來(lái)播放歌曲或者做游戲背景音樂(lè)。
2. SoundPool提供了pause和stop方法,但這些方法建議最好不要輕易使用,因?yàn)橛行r(shí)候它們可能會(huì)使你的程序莫名其妙的終止。建議使用這兩個(gè)方法的時(shí)候盡可能多做測(cè)試工作,還有些朋友反映它們不會(huì)立即中止播放聲音,而是把緩沖區(qū)里的數(shù)據(jù)播放完才會(huì)停下來(lái),也許會(huì)多播放一秒鐘。
3. SoundPool的效率問(wèn)題。其實(shí)SoundPool的效率在這些播放類(lèi)中算是很好的了,但是有的朋友在G1中測(cè)試它還是有100ms左右的延遲,這可能會(huì)影響用戶體驗(yàn)。也許這不能管SoundPool本身,因?yàn)榈搅诵阅鼙容^好的Droid中這個(gè)延遲就可以讓人接受了。
在現(xiàn)階段SoundPool有這些缺陷,但也有著它不可替代的優(yōu)點(diǎn),基于這些我們建議大在如下情況中多使用SoundPool:1.應(yīng)用程序中的聲效(按鍵提示音,消息等)2.游戲中密集而短暫的聲音(如多個(gè)飛船同時(shí)爆炸)
1.相關(guān)方法介紹:
1)構(gòu)造方法:
SoundPool(int maxStreams, int streamType, int srcQuality) 參數(shù)依次是:
①指定支持多少個(gè)聲音,SoundPool對(duì)象中允許同時(shí)存在的最大流的數(shù)量。
②指定聲音類(lèi)型,流類(lèi)型可以分為STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING,STREAM_MUSIC 和 STREAM_ALARM四種類(lèi)型。在AudioManager中定義。
③指定聲音品質(zhì)(采樣率變換質(zhì)量),一般直接設(shè)置為0!
在低版本中可以用上述構(gòu)造方法,而API 21(Android 5.0)后這個(gè)構(gòu)造方法就過(guò)時(shí)了! 而用到一個(gè)SoundPool.Builder的東東,我們要實(shí)例化SoundPool只需調(diào)用:
SoundPool.Builder spb = new SoundPool.Builder(); spb.setMaxStreams(10); spb.setAudioAttributes(null); //轉(zhuǎn)換音頻格式 SoundPool sp = spb.build(); //創(chuàng)建SoundPool對(duì)象
要使用上述代碼的話,TargetSDK版本要設(shè)置大于等于21哦!而且如果minSDK版本小于21 會(huì)出現(xiàn)下面的提醒:
2)常用方法介紹:
①加載聲音資源:
- load(Context context, int resId, int priority)
- load(String path, int priority)
- load(FileDescriptor fd, long offset, long length, int priority)
- load(AssetFileDescriptor afd, int priority) 上述方法都會(huì)返回一個(gè)聲音的ID,后面我們可以通過(guò)這個(gè)ID來(lái)播放指定的聲音
參數(shù)介紹:
- context:上下文
- resId:資源id
- priority:沒(méi)什么用的一個(gè)參數(shù),建議設(shè)置為1,保持和未來(lái)的兼容性
- path:文件路徑
- FileDescriptor:貌似是流吧,這個(gè)我也不知道
- AssetFileDescriptor:從asset目錄讀取某個(gè)資源文件,用法:
AssetFileDescriptor descriptor = assetManager.openFd("biaobiao.mp3");
②播放控制:
play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
參數(shù)依次是:
- soundID:Load()返回的聲音ID號(hào)
- leftVolume:左聲道音量設(shè)置
- rightVolume:右聲道音量設(shè)置
- priority:指定播放聲音的優(yōu)先級(jí),數(shù)值越高,優(yōu)先級(jí)越大。
- loop:指定是否循環(huán):-1表示無(wú)限循環(huán),0表示不循環(huán),其他值表示要重復(fù)播放的次數(shù)
- rate:指定播放速率:1.0的播放率可以使聲音按照其原始頻率,而2.0的播放速率,可以使聲音按照其 原始頻率的兩倍播放。如果為0.5的播放率,則播放速率是原始頻率的一半。播放速率的取值范圍是0.5至2.0。
③資源釋放:
可以調(diào)用release()方法釋放所有SoundPool對(duì)象占據(jù)的內(nèi)存和資源,當(dāng)然也可以根據(jù)聲音 ID來(lái)釋放!
3.使用代碼示例:
運(yùn)行效果圖:
當(dāng)點(diǎn)擊按鈕的時(shí)候會(huì),"Duang"一下,這里演示了兩種load的方法,分別是raw和assests!
關(guān)鍵代碼:
MainActivity.java:
private void initSP() throws Exception{ //設(shè)置最多可容納5個(gè)音頻流,音頻的品質(zhì)為5 mSoundPool = new SoundPool(5, AudioManager.STREAM_SYSTEM, 5); soundID.put(1, mSoundPool.load(this, R.raw.duang, 1)); soundID.put(2 , mSoundPool.load(getAssets().openFd("biaobiao.mp3") , 1)); //需要捕獲IO異常 soundID.put(3, mSoundPool.load(this, R.raw.duang, 1)); soundID.put(4, mSoundPool.load(this, R.raw.duang, 1)); soundID.put(5, mSoundPool.load(this, R.raw.duang, 1)); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_play1: mSoundPool.play(soundID.get(1), 1, 1, 0, 0, 1); break; case R.id.btn_play2: mSoundPool.play(soundID.get(2), 1, 1, 0, 0, 1); break; case R.id.btn_play3: mSoundPool.play(soundID.get(3), 1, 1, 0, 0, 1); break; case R.id.btn_play4: mSoundPool.play(soundID.get(4), 1, 1, 0, 0, 1); break; case R.id.btn_play5: mSoundPool.play(soundID.get(5), 1, 1, 0, 0, 1); break; case R.id.btn_release: mSoundPool.release(); //回收SoundPool資源 break; }
代碼非常簡(jiǎn)單,另外如果你點(diǎn)擊了最后一個(gè)按鈕的話,SoundPool就會(huì)被釋放,然后再其他按鈕 就不會(huì)Duang了哦~
4.OnLoadCompleteListener監(jiān)聽(tīng)聲音文件是否加載完畢
嗯,這個(gè)是臨時(shí)想起的,寫(xiě)完在寫(xiě)另一篇的時(shí)候突然想起,用法也很簡(jiǎn)單,我們可以 往上面的代碼中添加OnLoadCompleteListener這個(gè)東東,然后重寫(xiě)onLoadComplete()方法 ,最后為SoundPool對(duì)象設(shè)置這個(gè)東東即可!
mSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { @Override public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { Toast.makeText(MainActivity.this,"加特技準(zhǔn)備完畢~",Toast.LENGTH_SHORT).show(); } });
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android SoundPool實(shí)現(xiàn)簡(jiǎn)短小音效
- Android使用SoundPool播放短音效
- Android使用SoundPool實(shí)現(xiàn)播放音效
- Android使用SoundPool播放音效實(shí)例
- Android使用SoundPool實(shí)現(xiàn)播放音頻
- Android中SoundPool的使用步驟實(shí)例
- Android使用SoundPool播放音效
- Android多媒體應(yīng)用使用SoundPool播放音頻
- Android編程實(shí)現(xiàn)使用SoundPool播放音樂(lè)的方法
- Android利用SoundPool實(shí)現(xiàn)音樂(lè)池
相關(guān)文章
Android高級(jí)開(kāi)發(fā)之性能優(yōu)化典范
本文從電量,視圖,內(nèi)存三個(gè)性能方面的知識(shí)點(diǎn)給大家介紹android高級(jí)開(kāi)發(fā)之性能優(yōu)化的相關(guān)知識(shí),希望對(duì)大家有所幫助2016-05-05Android 點(diǎn)擊生成二維碼功能實(shí)現(xiàn)代碼
二維碼,我們也稱(chēng)作QRCode,QR表示quick response即快速響應(yīng),在很多App中我們都能見(jiàn)到二維碼的身影,最常見(jiàn)的莫過(guò)于微信了。接下來(lái)給大家介紹android 點(diǎn)擊生成二維碼功能實(shí)現(xiàn)代碼,需要的朋友參考下吧2017-11-11APK包名修改 請(qǐng)問(wèn)如何修改APK包名
今天,想在android手機(jī)上安裝兩個(gè)相同的應(yīng)用,本以為可以安裝不同版本的,試了幾次,均相互覆蓋了,于是,只能設(shè)法修改apk所對(duì)應(yīng)的包名(package name),需要了解的朋友可以參考下2012-12-12Android開(kāi)發(fā)實(shí)現(xiàn)長(zhǎng)按返回鍵彈出關(guān)機(jī)框功能
這篇文章主要介紹了Android開(kāi)發(fā)實(shí)現(xiàn)長(zhǎng)按返回鍵彈出關(guān)機(jī)框功能,涉及Android針對(duì)長(zhǎng)按事件的響應(yīng)與處理相關(guān)操作技巧,需要的朋友可以參考下2017-09-09SafeList?in?Flutter?and?Dart小技巧
這篇文章主要為大家介紹了SafeList?in?Flutter?and?Dart小技巧,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Android getSystemService用法實(shí)例總結(jié)
這篇文章主要介紹了Android getSystemService用法,結(jié)合實(shí)例形式總結(jié)分析了getSystemService獲取系統(tǒng)Service的相關(guān)使用方法與注意事項(xiàng),需要的朋友可以參考下2016-01-01Android實(shí)現(xiàn)雙層ViewPager嵌套
這篇文章主要介紹了Android實(shí)現(xiàn)雙層ViewPager嵌套,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04最好用的Android省市區(qū)三級(jí)聯(lián)動(dòng)選擇效果
這篇文章主要為大家詳細(xì)介紹了最好用的Android省市區(qū)三級(jí)聯(lián)動(dòng)選擇效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02