自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android SoundPool 音效播放庫

移動(dòng)開發(fā) Android
這里只是介紹了我們?nèi)绾握_使用SoundPool?以及相關(guān)api。如果你看完了整個(gè)內(nèi)容,我相信你在使用SoundPool進(jìn)行播放音頻時(shí),就不會(huì)出現(xiàn)無法播放,播放失敗等情況了。

1. 介紹

我們?nèi)绻朐趹?yīng)用中進(jìn)行播放一些音效,例如提示音,提示短語等簡短的音頻文件??梢允褂?SoundPool 這個(gè)工具進(jìn)行快捷播放。

它利用 MediaCodec? 服務(wù)為音頻解碼為一個(gè)原始16位 PCM? 流。這個(gè)特性使得應(yīng)用程序可以進(jìn)行流壓縮,而無須忍受在播放音頻時(shí)解壓所帶來的CPU負(fù)載和時(shí)延。SoundPool 會(huì)將音頻解碼后進(jìn)行預(yù)編碼到內(nèi)存中。然后再根據(jù)需求進(jìn)行播放。

匯總特性如下:

  1. 單個(gè)文件不能大于1M。如果解碼的音頻超過1兆字節(jié)的存儲(chǔ)空間,則該音頻將被截?cái)唷?/li>
  2. 可以一次性播放多個(gè)音頻。通過設(shè)置maxStreams?設(shè)置單個(gè)SoundPool?中可以播放的最大音頻數(shù)量。如果播放數(shù)量超過最大數(shù)量,SoundPool?會(huì)根據(jù)優(yōu)先級(jí)自動(dòng)關(guān)閉先前播放的音頻。(PS:默認(rèn)限制數(shù)量maxStreams=1,限制最大數(shù)量有助于限制CPU負(fù)載,降低音頻混合影響視覺效果或UI性能的可能性。)
  3. 可設(shè)置循環(huán)播放,也可以指定播放次數(shù)。
  4. 可以設(shè)置播放速度,最大為2倍數(shù),最小為0.5倍數(shù)。進(jìn)行音頻的快速播放或者慢速播放。
  5. 可以設(shè)置優(yōu)先級(jí)(priority?)。優(yōu)先級(jí)從低到高,即數(shù)字越高,優(yōu)先級(jí)越高。當(dāng)調(diào)用play()?會(huì)導(dǎo)致活動(dòng)流的數(shù)量超過創(chuàng)建SoundPool時(shí)maxStreams?參數(shù)所確定的值時(shí),將使用優(yōu)先級(jí)。在這種情況下,流分配器將停止優(yōu)先級(jí)最低的流。如果有多個(gè)流具有相同的低優(yōu)先級(jí),它將選擇最舊的流停止。在新流的優(yōu)先級(jí)低于所有活動(dòng)流的情況下,新聲音將不會(huì)播放,play()?函數(shù)將返回streamID為零。(ps:該功能暫時(shí)還沒有效果,后續(xù)版本會(huì)支持優(yōu)先級(jí)配置)
  6. 不用關(guān)心各種音頻流的生命周期,調(diào)用各種streamID的相關(guān)方法不會(huì)因?yàn)檎也坏讲シ帕鞫霈F(xiàn)各種錯(cuò)誤和異常。

以上信息來源于 Android-32 android\media\SoundPool.java 源碼中的注釋

總而言之就是:

使用SoundPool? 可以播放多種音頻,甚至可以混音播放。但是不能播放比較大的音頻文件。長時(shí)間的音頻建議使用 MediaPlayer。

2. 使用

老版本SoundPool?是可以直接new SoundPool()?進(jìn)行創(chuàng)建的,但是自從Android-API 21 之后就被廢棄了。改為SoundPool.Builder?進(jìn)行創(chuàng)建SoundPool對(duì)象。

PS:SoundPool?對(duì)象不是一個(gè)單例對(duì)象,所以,我們其實(shí)是可以創(chuàng)建多個(gè)SoundPool對(duì)象的,但是不建議大量創(chuàng)建,影響性能。

主要步驟為:

  1. 創(chuàng)建SoundPool對(duì)象。
  2. 調(diào)用soundPool.load() 加載音頻文件。加載成功后返回soundId,如果是0就代表加載失敗了。
  3. 監(jiān)聽setOnLoadCompleteListener方法,得到音頻文件是否加載成功。
  4. 調(diào)用soundPool.play()進(jìn)行音頻播放。使用soundId進(jìn)行播放。播放成功后會(huì)返回streamId,我們之后可以通過該streamId進(jìn)行暫停,恢復(fù),停止,修改循環(huán)次數(shù),修改優(yōu)先級(jí),修改聲音等。
  5. 界面關(guān)閉時(shí),調(diào)用soundPool.release()釋放資源。會(huì)釋放所有加載的音頻文件。

2.1 創(chuàng)建 SoundPool

SoundPool.Builder spb = new SoundPool.Builder();
SoundPool soundPool = spb.build(); //創(chuàng)建SoundPool對(duì)象

上述方法就創(chuàng)建了一個(gè)soundPool?播放對(duì)象了。默認(rèn)最大 MaxStreams=1?,默認(rèn)音效為:AudioAttributes.USAGE_MEDIA。

我們?nèi)绻朐O(shè)置最大streams數(shù)量,需要通過Builder對(duì)象進(jìn)行設(shè)置:

SoundPool.Builder spb = new SoundPool.Builder();
spb.setMaxStreams(15); //但是不建議將這個(gè)值設(shè)置的較大,較大會(huì)占用比較大的內(nèi)存空間的。

其次就是配置AudioAttributes(音頻屬性了)。

SoundPool.Builder spb = new SoundPool.Builder();
AudioAttributes mAudioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME).build();
spb.setAudioAttributes(attrBuilder.build());

下面詳細(xì)介紹音頻屬性的相關(guān)配置項(xiàng)。

2.1.1 音頻屬性-AudioAttributes

音頻屬性類中,有很多配置項(xiàng)。這里只是簡單介紹部分,更詳細(xì)的建議大家可以通過源碼進(jìn)行查詢了解。

聲音用途-usage

那么默認(rèn)情況下配置的setUsage(AudioAttributes.USAGE_MEDIA)是什么呢?

是用來描述音頻的用途為媒體文件使用的,其他可選配置如下:

AudioAttributes.USAGE_UNKNOWN://用法未知時(shí)要使用的用法值。也就是這個(gè)音頻預(yù)期用途不屬于以下定義的
AudioAttributes.USAGE_MEDIA: //當(dāng)用途為媒體(如音樂或電影配樂)時(shí)要使用的用途值。
AudioAttributes.USAGE_VOICE_COMMUNICATION: //當(dāng)使用是語音通信(如電話或VoIP)時(shí)要使用的使用值。
AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING://在呼叫信號(hào)中使用時(shí)使用的用法值,例如“忙碌”的嘟嘟聲或DTMF音調(diào)。
AudioAttributes.USAGE_ALARM: //當(dāng)使用是警報(bào)(例如喚醒警報(bào))時(shí)要使用的使用值。
AudioAttributes.USAGE_NOTIFICATION://使用情況為通知時(shí)要使用的使用情況值。
AudioAttributes.USAGE_NOTIFICATION_RINGTONE://當(dāng)使用是電話鈴聲時(shí)要使用的使用值。
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST: //當(dāng)使用是請(qǐng)求進(jìn)入/結(jié)束通信(如VoIP通信或視頻會(huì)議)時(shí)要使用的使用值。
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT://當(dāng)使用是“即時(shí)”通信(如聊天或短信)的通知時(shí)使用的使用值。
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED://當(dāng)用途是通知非即時(shí)類型的通信(如電子郵件)時(shí)要使用的用途值。
AudioAttributes.USAGE_NOTIFICATION_EVENT: //當(dāng)使用是為了吸引用戶的注意力時(shí)要使用的使用值,例如提醒或電池電量不足警告。
AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY: //用于輔助功能時(shí)要使用的用法值,例如用于屏幕閱讀器。
AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: //當(dāng)用途是駕駛或?qū)Ш椒较驎r(shí)要使用的用途值。
AudioAttributes.USAGE_ASSISTANCE_SONIFICATION: //當(dāng)使用是聲音處理時(shí)要使用的使用值,例如用戶界面聲音。
AudioAttributes.USAGE_GAME: //用于游戲音頻時(shí)要使用的用法值。
AudioAttributes.USAGE_VIRTUAL_SOURCE: //用于虛擬資源生產(chǎn)時(shí)的用途值。
AudioAttributes.USAGE_ASSISTANT://用于對(duì)用戶查詢、音頻指令或幫助話語的音頻響應(yīng)的用法值。

示例代碼如:

AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
attrBuilder.setUsage(AudioAttributes.USAGE_GAME);

當(dāng)我們不配置setUsage()?的時(shí)候,音頻屬性默認(rèn)的用途描述為:AudioAttributes.USAGE_INVALID 該值為無效值,僅用于未初始化的用法值。

所以,建議大家還是根據(jù)自己的音頻文件的使用用途,進(jìn)行配置相關(guān)的用途值。

PS1:這個(gè)Usage用途值是用來告訴系統(tǒng),我們這個(gè)音頻文件是屬于什么類型的。 如果關(guān)注過手機(jī)音量設(shè)置,就會(huì)知道我們可以針對(duì)通知,鬧鐘,音樂,視頻游戲,通話等不同場景設(shè)置相關(guān)音量。

這個(gè)用途決定了我們的音頻文件會(huì)被系統(tǒng)哪個(gè)音量設(shè)置進(jìn)行控制。

PS2:這也就是為啥有些app中的音效在手機(jī)媒體音效都禁音了,還在播放。因?yàn)樗赡軐⒙曇舻挠猛緲?biāo)注為了通知鈴聲等。

首次啟動(dòng)SoundPool?進(jìn)行播放音頻時(shí),沒有配置Usage參數(shù)值,這個(gè)時(shí)候程序觸發(fā)了系統(tǒng)提示音的播放。

那么我們的SoundPool?調(diào)用load()就會(huì)得到返回值為0。音頻加載失敗。

AudioAttributes 類除了上面的聲音用途(Usage)以外。還有一些其他方法:

  • setContentType(int contentType)?:設(shè)置描述音頻信號(hào)的內(nèi)容類型的屬性,例如語音或音樂??蛇x參數(shù)如下:
  • AudioAttributes.CONTENT_TYPE_UNKNOWN: 默認(rèn)值,當(dāng)內(nèi)容類型未知或不是定義的內(nèi)容類型時(shí)要使用的內(nèi)容類型值。
  • AudioAttributes.CONTENT_TYPE_MOVIE:當(dāng)內(nèi)容類型為配樂(通常伴隨電影或電視節(jié)目)時(shí)要使用的內(nèi)容類型值
  • AudioAttributes.CONTENT_TYPE_MUSIC:內(nèi)容類型為音樂時(shí)要使用的內(nèi)容類型值。
  • AudioAttributes.CONTENT_TYPE_SONIFICATION:當(dāng)內(nèi)容類型是用于伴隨用戶動(dòng)作的聲音時(shí)使用的內(nèi)容類型值,例如表示按鍵的嘟嘟聲或聲音效果,或事件,例如游戲中收到的獎(jiǎng)金的聲音類型。這些聲音大多是合成的或簡短的 Foley 音。
  • AudioAttributes.CONTENT_TYPE_SPEECH:當(dāng)內(nèi)容類型為語音時(shí)要使用的內(nèi)容類型值。
  • setFlage(int flags):設(shè)置標(biāo)志的組合。設(shè)置的參數(shù)將會(huì)與已有值進(jìn)行位運(yùn)算。參數(shù)有兩個(gè)選項(xiàng):
  • AudioAttributes.FLAG_AUDIBILITY_ENFORCED:定義一種行為的標(biāo)志,其中聲音的可聽性將由系統(tǒng)確保。
  • AudioAttributes.FLAG_HW_AV_SYNC:請(qǐng)求使用支持硬件A/V同步的輸出流的標(biāo)志。
  • setAllowedCapturePolicy(int capturePolicy):指定其他應(yīng)用程序或系統(tǒng)是否可以捕獲音頻。這個(gè)配置的結(jié)果會(huì)組合在Flags參數(shù)中的。
  • AudioAttributes.ALLOW_CAPTURE_BY_ALL?:默認(rèn)值,指示音頻可以被任何應(yīng)用程序捕獲。這個(gè)捕獲會(huì)受到Usage參數(shù)的影響,因?yàn)樯婕懊舾胁僮?。從Android API 29 開始只能捕獲USAGE_UNKNOWN,USAGE_MEDIA和USAGE_GAME。
  • AudioAttributes.ALLOW_CAPTURE_BY_SYSTEM:指示音頻只能由系統(tǒng)應(yīng)用程序捕獲。系統(tǒng)應(yīng)用程序可以捕獲多種用途,如輔助功能、實(shí)時(shí)字幕、用戶指南等等但要遵守以下限制:1.音頻不能離開設(shè)備,2.音頻不能傳遞給第三方應(yīng)用程序,3.音頻不能以高于16kHz 16位單聲道的質(zhì)量。
  • AudioAttributes.ALLOW_CAPTURE_BY_NONE?:指示任何應(yīng)用程序都不會(huì)錄制音頻,即使是系統(tǒng)應(yīng)用程序也是如此。鼓勵(lì)使用ALLOW_CAPTURE_BY_SYSTEM而不是此值,因?yàn)橄到y(tǒng)應(yīng)用程序?yàn)橛脩籼峁┝酥匾杏玫墓δ埽ㄈ鐚?shí)時(shí)字幕和可訪問性)。
  • setHapticChannelsMuted(boolean muted): 指定在播放音頻觸覺耦合數(shù)據(jù)時(shí)是否應(yīng)靜音觸覺。默認(rèn)情況下,觸覺通道處于禁用狀態(tài)。簡單理解就是,當(dāng)在播放音頻時(shí)。按鍵聲音,觸摸反饋等會(huì)設(shè)置為禁止?fàn)顟B(tài)。
  • true:默認(rèn)值,設(shè)置觸覺反饋靜音。
  • false:設(shè)置允許觸摸反饋聲音。
  • setIsContentSpatialized(boolean isSpatialized):指定是否已經(jīng)對(duì)內(nèi)容進(jìn)行了空間化處理。如果有,則將其設(shè)置為true將防止諸如雙重處理之類的問題。
  • true:已經(jīng)對(duì)音頻內(nèi)容進(jìn)行了空間化處理,系統(tǒng)不需要再進(jìn)行雙重處理了。
  • false:默認(rèn)值,沒有對(duì)音頻進(jìn)行空間化處理。
  • setSpatializationBehavior(int sb) :設(shè)置使用空間化的行為。主要有兩個(gè)可選參數(shù):(PS:沒有太能理解這個(gè)方法的意義,應(yīng)該是需要更多的音頻相關(guān)知識(shí)才能弄明白吧。)
  • AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER:指示與這些屬性相關(guān)聯(lián)的音頻內(nèi)容的常量永遠(yuǎn)不應(yīng)該被虛擬化。
  • AudioAttributes.SPATIALIZATION_BEHAVIOR_AUTO:默認(rèn)值,指示與這些屬性相關(guān)聯(lián)的音頻內(nèi)容將遵循默認(rèn)的平臺(tái)行為,關(guān)于哪些內(nèi)容將被空間化或不被空間化。

除了上面的方法。我們經(jīng)常也看到一些分享的代碼中,并沒有使用上面的方法,而是只使用setLegacyStreamType()方法:

AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);

這個(gè)方法主要用來設(shè)置從傳統(tǒng)流類型推斷的屬性。AudioAttributes將會(huì)通過從遺留流類型派生的信息初始化某些屬性。

簡單理解就是,我們配置的Usage,ContentType,F(xiàn)lage?等等信息數(shù)據(jù)。AudioAttributes會(huì)從系統(tǒng)歷史痕跡中找到某個(gè)音頻流的屬性,進(jìn)行復(fù)用配置。

官方注釋中,建議我們少使用該方法,而應(yīng)該通過setUsage,setContentType等方法明確設(shè)置音頻的用法和內(nèi)容類型等信息。

由于會(huì)覆蓋我們配置的Usage,ContentType,F(xiàn)lage,HapticChannelsMuted等方法值。

所以如果使用setLegacyStreamType? 就不要使用上面的配置音頻相關(guān)信息的方法。因?yàn)閟etLegacyStreamType優(yōu)先級(jí)高,會(huì)覆蓋掉我們配置的信息。該方法的建議傳參有6個(gè)值:

但是首先會(huì)先從歷史痕跡中獲取信息,獲取不到的才會(huì)按照下面的配置項(xiàng)進(jìn)行默認(rèn)初始化。

  • AudioManager.STREAM_VOICE_CALL:將會(huì)ContentType設(shè)置為 CONTENT_TYPE_SPEECH,Usage設(shè)置為USAGE_VOICE_COMMUNICATION。
  • AudioManager.STREAM_SYSTEM:將會(huì)ContentType設(shè)置為 CONTENT_TYPE_SONIFICATION,Usage設(shè)置為USAGE_ASSISTANCE_SONIFICATION。
  • AudioManager.STREAM_RING:將會(huì)ContentType設(shè)置為 CONTENT_TYPE_SONIFICATION,Usage設(shè)置為USAGE_NOTIFICATION_RINGTONE。
  • AudioManager.STREAM_MUSIC:將會(huì)ContentType設(shè)置為 CONTENT_TYPE_MUSIC,Usage設(shè)置為USAGE_NOTIFICATION_RINGTONE。
  • AudioManager.STREAM_ALARM:將會(huì)ContentType設(shè)置為 CONTENT_TYPE_SONIFICATION,Usage設(shè)置為USAGE_NOTIFICATION_RINGTONE。
  • AudioManager.STREAM_NOTIFICATION:將會(huì)ContentType設(shè)置為 CONTENT_TYPE_SONIFICATION,Usage設(shè)置為USAGE_NOTIFICATION_RINGTONE。

除了上面六個(gè)傳參外,還可以傳一下其他的。這里就不詳細(xì)說明了。

音效的相關(guān)配置到這里就差不多了。我們繼續(xù)接著處理SoundPool播放。

2.2 加載音頻文件

當(dāng)我們初始化基本的音頻播放器信息之后。我們就可以進(jìn)行加載音頻文件了。

SoundPool?通過load()?方法進(jìn)行加載文件??梢詮腶ssets,raw,本地磁盤等進(jìn)行加載音頻。

下面介紹這幾種加載方式。

例如,從res?資源目錄下raw文件中加載音頻:

soundPool.load(this, R.raw.drill,1);

例如,從assets?目錄下加載音頻文件:從assets目錄下的sound文件夾中加載名為zinyan.mp3的音頻文件。

AssetFileDescriptor descriptor = null;
try {
descriptor = am.openFd("sound/zinyan.mp3");
} catch (IOException e) {
e.printStackTrace();
}
if(descriptor!=null){
soundPool.load(descriptor, 1);
}

例如,從本地磁盤中加載音頻文件:

soundPool.load("本地文件路徑", 1);

還可以從FileDescriptor中加載音頻文件進(jìn)行播放。傳offset=0,length=文件大小,protity=1就可以了。

傳值中的protity 目前沒有效果。為了將來的兼容性,請(qǐng)使用值1。這個(gè)值就是所謂的優(yōu)先級(jí)。

PS:常見應(yīng)用是將部分音頻存儲(chǔ)在assets目錄或者raw目錄下。而如果是有比較多音效,那需要進(jìn)行在線下載后調(diào)用FileDescripor進(jìn)行加載。

當(dāng)我們使用load()?進(jìn)行加載音頻時(shí),如果音頻文件正確那么就會(huì)返回一個(gè)id。該值為sound Id。

如果是錯(cuò)誤會(huì)返回0。代表我們的音頻文件并沒有被轉(zhuǎn)為PCM流。

在這里我們需要注意一下,SoundID只是以下兩個(gè)方法才會(huì)使用到。

soundPool.play(soundId,1,1,1,0,1f)
soundPool.stop(soundId);

PS:soundId? 和streamID并不是同一個(gè)值,雖然我們打印輸出的時(shí)候可能都顯示的一樣的數(shù)。但是并不能代表兩個(gè)是一致的。

如果你確保該音頻文件是一個(gè)比較高頻使用的音頻,那么可以在初始化的時(shí)候批量調(diào)用load()方法進(jìn)行預(yù)加載。

之后在需要播放的地方,直接調(diào)用soundPool.play? 傳遞該soundId就可以了。

在實(shí)際使用中,提取音頻文件到內(nèi)存。然后可以進(jìn)行play播放,中間的耗時(shí)是非常短的。但是,我們?nèi)稳徊荒苤苯泳蛨?zhí)行play播放,因?yàn)闀r(shí)間再短它也是有耗時(shí)的。如果沒有加載完成就播放,是沒有聲音的

2.3 監(jiān)聽加載狀態(tài)

當(dāng)我們使用load()方法進(jìn)行加載之后,只是將音頻文件提取存儲(chǔ)在內(nèi)存中了。這個(gè)提取和存儲(chǔ)過程是在異步線程中進(jìn)行操作的。所以并不會(huì)影響到我們UI線程的顯示。

示例如下:

//加載完畢,執(zhí)行音頻播放
soundPool.setOnLoadCompleteListener((soundPool, sampleId, status) -> {
Log.e("onLoadComplete", "音頻加載狀態(tài)(0表示加載成功):" + status);
int streamID = soundPool.play(soundId, 1, 1, 1, 0, 1f);

});

因?yàn)槲业囊纛l文件需要?jiǎng)討B(tài)切換,而且量比較少。所以直接在加載完畢的回調(diào)中。

執(zhí)行了play播放。

如果是相對(duì)固定,并且加載比較多的情況下。建議通過HashMap?進(jìn)行存儲(chǔ)streamId和soundId

其中 sampleId?就是聲音樣本ID。也就是load?方法中返回的soundId。

2.4 播放音頻

當(dāng)我們調(diào)用soundPool.play()?方法的時(shí)候,該方法調(diào)用成功會(huì)返回streamId,如果調(diào)用失敗就會(huì)返回0。

而該方法的完整傳值為:

soundPool.play(int soundID, float leftVolume, float rightVolume,
int priority, int loop, float rate)

soundID?: load()?函數(shù)返回的soundID?值,告訴soudPool要播放哪個(gè)音頻。

leftVolume:左側(cè)音量值(范圍0.0~1.0)。左聲道聲音值。

rightVolume:右側(cè)音量值(范圍0.0~1.0)。右聲道聲音值。

priority:音頻流播放優(yōu)先級(jí)(0=最低優(yōu)先級(jí),通常默認(rèn)讓設(shè)置為1)。

loop:循環(huán)模式(0=無循環(huán),-1=永遠(yuǎn)循環(huán),其他表示數(shù)字表示當(dāng)前數(shù)字對(duì)應(yīng)的循環(huán)次數(shù)+默認(rèn)播放的一次。例如循環(huán)2次,那么實(shí)際播放3次)。

rate:播放速率(1.0=正常播放,范圍為0.5~2.0),也就是0.5倍慢放,1正常,2倍快放。

這些配置,在初始化播放的時(shí)候就需要配置上。

我們?nèi)绻シ懦晒笙胄薷穆暤?,?yōu)先級(jí)(暫時(shí)意義沒有多大),循環(huán)模式,播放速率等。調(diào)用相關(guān)方法修改即可:

int streamId = soundPool.play(soundId, 1, 1, 1, 0, 1f);
soundPool.setLoop(streamId,1); //循環(huán)一次
soundPool.setVolume(streamId,1,1);
soundPool.setPriority(streamId,1);
soundPool.setRate(streamId,1f);

要注意了,這些修改方法的調(diào)用前提是已經(jīng)執(zhí)行play?方法得到streamID之后才有意義。

否則是沒有意義和作用的。因?yàn)檫@些修改方法中streamID傳錯(cuò)了也不會(huì)觸發(fā)崩潰等錯(cuò)誤的。

相較于MediaPlayer。SoundPool因?yàn)獒槍?duì)的都是一些快速簡單的音效。

所以是沒有音頻播放結(jié)束的回調(diào)方法的。我們?nèi)绻约合胫酪纛l播放完畢,可以自己寫一個(gè)時(shí)間線程,線程結(jié)束后就當(dāng)音頻已經(jīng)播放完畢了吧。

雖然沒有音頻結(jié)束的監(jiān)聽。但是我們可以針對(duì)音頻做停止,暫停和恢復(fù)等操作。

2.5 暫停,恢復(fù),停止

當(dāng)我們配置loop?循環(huán)模式為-1 無限循環(huán)時(shí)。我們需要主動(dòng)調(diào)用stop停止方法才能中斷音頻的播放。

soundPool.stop(streamId);//停止
soundPool.pause(streamId);//暫停
soundPool.resume(streamId);//恢復(fù)

當(dāng)我們調(diào)用stop?停止之后是不能通過resume進(jìn)行恢復(fù)的。

要想恢復(fù),只能是重新調(diào)用play方法進(jìn)行播放。

以上是單個(gè)音頻流的操作,SoundPool還提供了批量操作的方法:

soundPool.autoPause(); //批量暫停
soundPool.autoResume(); //批量恢復(fù)

2.6 釋放資源

在一開始就介紹了SoundPool會(huì)將音頻文件加載到內(nèi)存中。

我們操作比較多的音頻后,要注意資源的釋放。

否則會(huì)造成比較大的內(nèi)存占用。

請(qǐng)注意:當(dāng)我們調(diào)用音頻的stop()?方法時(shí),只是將音頻流給回收了,也就是streamId失效了。

但是soundId?還是生效狀態(tài),也就是說load()方法加載到內(nèi)存中的資源是并沒有被釋放的。

釋放資源有兩種方法,釋放某個(gè)音頻:

soundPool.unload(soundId);//移除指定的加載的的音頻文件

如果該soundId指向的音頻文件不存在,也不會(huì)造成錯(cuò)誤的。

上述的方法是移除某一個(gè)音頻文件的加載,其他加載的音頻文件是不會(huì)受到影響的。

釋放全部音頻:

soundPool.release();
soundPool = null;

當(dāng)我們,使用release?方法進(jìn)行操作時(shí),會(huì)將load?加載的全部資源進(jìn)行釋放,也會(huì)釋放SoundPool?對(duì)象使用的所有內(nèi)存和本機(jī)資源。簡單理解就是soundPool對(duì)象和null沒有什么區(qū)別了

后面該對(duì)象就不能再被使用了。要想使用就需要重新new一個(gè)新對(duì)象,并賦值音頻屬性,加載音頻文件等操作。

3. 小結(jié)

這里只是介紹了我們?nèi)绾握_使用SoundPool?以及相關(guān)api。如果你看完了整個(gè)內(nèi)容,我相信你在使用SoundPool進(jìn)行播放音頻時(shí),就不會(huì)出現(xiàn)無法播放,播放失敗等情況了。

如果覺得本篇內(nèi)容對(duì)你有一點(diǎn)點(diǎn)幫助,希望能夠給我點(diǎn)個(gè)贊鼓勵(lì)一下,謝謝。

責(zé)任編輯:武曉燕 來源: Zinyan
相關(guān)推薦

2013-05-21 14:10:11

Android游戲開發(fā)SoundPool類同時(shí)多音效

2012-04-17 12:47:27

cocos2d-x

2013-05-21 13:33:02

Android游戲開發(fā)異步音樂播放

2015-10-28 13:29:21

音頻源碼audio

2011-06-02 09:23:58

Android 效果

2014-10-20 09:55:02

2013-06-14 17:28:11

Windows PhoWP開發(fā)播放聲音

2012-12-27 14:29:38

Android開發(fā)流媒體

2013-07-01 10:53:05

2023-07-06 10:40:41

微軟Windows

2011-09-09 11:28:35

Android Mus

2015-01-22 15:44:55

Android源碼音樂播放器

2021-08-09 14:00:24

微軟Windows 11Windows

2010-01-27 16:21:29

Android多媒體播

2011-06-07 15:38:29

2011-09-08 13:36:26

Android Wid播放器

2022-06-20 05:59:35

5G技術(shù)音視頻技術(shù)安卓系統(tǒng)

2010-10-26 09:00:48

Winamp應(yīng)用

2012-12-24 09:04:04

iOSUnity3D

2013-04-19 01:42:02

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)