Android學習筆記(22) --- SoundPool的使用(填補MediaPlayer的不足)

一、使用MediaPlayer來播放音頻文件存在一些不足:

例如:資源佔用量較高、延遲時間較長、不支持多個音頻同時播放等。

這些缺點決定了MediaPlayer在某些場合的使用情況不會很理想,所有,一般的遊戲開發都是用的Soundpool。

在沒有了解Soundpool之前,我也是使用的普通的MediaPlayer進行文件播放,但這個方法不適合用於遊戲開發,因爲遊戲裏面經常要同時播放幾個音樂文件,用過MediaPlayer的朋友都該知道,它是不支持實時播放多個聲音的,而且還會出現或多或少的延遲,尤其是在快速連續播放聲音(比如連續猛點按鈕)時,會非常明顯,長的時候會出現3~5秒的延遲,【使用MediaPlayer.seekTo() 這個方法來解決此問題】;

相對於使用SoundPool存在的一些問題:

1. SoundPool是爲播放小文件而存在的。一般限定Soundpool播放文件的大小爲1M。

2. SoundPool提供了pause和stop方法,但這些方法建議最好不要輕易使用,因爲有些時候它們可能會使你的程序莫名其妙的終止。還有些朋友反映它們不會立即中止播放聲音,而是把緩衝區裏的數據播放完纔會停下來,也許會多播放一秒鐘。

3. 音頻格式建議使用OGG格式。使用WAV格式的音頻文件存放遊戲音效,經過反覆測試,在音效播放間隔較短的情況下會出現異常關閉的情況(有說法是SoundPool目前只對16bit的WAV文件有較好的支持)。後來將文件轉成OGG格式,問題得到了解決。

4.在使用SoundPool播放音頻的時候,如果在初始化中就調用播放函數進行播放音樂那麼根本沒有聲音,不是因爲沒有執行,而是SoundPool需要一準備時間!這就是剛剛我們說的用OnLoadCompleteListener來解決的問題。如果你非得是1.6甚至更低的話,那建議在播放的時候,將play放到一個點擊事件中去,當然在這個中也要注意一下兩點。

a、 別忘記綁定操作! mp.setOnCompletionListener(this);

b、如果你設置了循環播放 mp.setLooping(true); 的話,那麼永遠都不會監聽到播放完成的狀態!!

二、SoundPool

SoundPool

構造方法

構造方法

描述

public SoundPool (int maxStreams, int streamType, int srcQuality)

 

參數說明:

maxStreams:指定支持多少個文件

streamType:指定聲音類型

srcQuality:聲音品質

 

常見方法

方法名稱

描述

public int load (Context context, int resId, int priority)

從資源ID所對應的資源加載聲音

public int load (AssetFileDescriptor afd, int priority)

從原始資源文件中加載聲音

public int load (FileDescriptor fd, long offset, long length, int priority)

從原始資源文件中加載聲音並設置加載從哪開始到多長的聲音文件

public int load (String path, int priority)

從指定文件路徑加載聲音

public final void pause (int streamID)

暫停

public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

播放

參數說明:

soundID:資源ID

leftVolume:左頻道聲音

rightVolume:右頻道聲音

loop:-1代表循環,0代表不循環

rate:值0.5-2.0設置1爲正常

public final void release ()

釋放SoundPool對象資源

public final void stop (int streamID)

停止

public void setOnLoadCompleteListener (SoundPool.OnLoadCompleteListener listener)

設置監聽器,在加載音樂文件完成時觸發該事件


三、上代碼:

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainlayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffffff"
    android:orientation="vertical" >

    <Button
        android:id="@+id/bt"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>
SoundPoolActivity.java

import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class SoundPoolActivity extends Activity implements
		SoundPool.OnLoadCompleteListener{
	/** Called when the activity is first created. */
	private Button button;
	private int[] menuSound;
	private SoundPool mSoundPool = null;
	private int i =0;
	// private final Handler mHandler = new MyHandler();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		button = (Button) findViewById(R.id.bt);
		mSoundPool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 0);
		mSoundPool.setOnLoadCompleteListener(ViewgroupActivity.this);
		menuSound = new int[2];
		mSoundPool = new SoundPool(2, AudioManager.STREAM_SYSTEM, 0);
		menuSound[0] = mSoundPool.load(getApplicationContext(),
				R.raw.eng_music, 1);
		menuSound[1] = mSoundPool.load(getApplicationContext(),
				R.raw.eng_music, 1);
		
		button.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if((i%2)==0){
					i++;
					mSoundPool.play(menuSound[0], 10, 10, 0, 0, (float) 1);// 播放鈴聲
				}else {
					mSoundPool.play(menuSound[1], 10, 10, 0, 0, (float) 1);// 播放鈴聲
				}
				
			}
		});
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		mSoundPool.release();
		mSoundPool.stop(menuSound[0]);
		mSoundPool.stop(menuSound[1]);
		super.onDestroy();

	}

	@Override
	public void onLoadComplete(SoundPool arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub

	}

}


發佈了51 篇原創文章 · 獲贊 41 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章