1、android 音頻播放類
MediaPlayer和SoundPool均可以用來播放音頻。
區別是MediaPlayer佔用資源高,延遲時間高,播放長音樂的,而且不能同時播放多個音樂,
而SoundPool佔用資源較少,沒什麼延遲,但要提早加載,只能播放1M如下的音頻文件,能同時播放多個音樂
所以MediaPlayer通常用來播放背景音樂,而SoundPool主要用來播放遊戲音效。android
一、MediaPlayeride
1 //獲取實例: 2 MediaPlayer.create(Context context,int resId); //參數一:上下文對象,參數二:音樂資源ID,通常放在raw文件夾下。若是沒有raw就本身建立一個 3 4 //經常使用方法: 5 prepare();//爲播放音樂文件作準備工做 6 start();//播放音樂 7 pause();//暫停音樂播放 8 stop();//中止音樂播放 9 10 11 //MediaPlayer其它經常使用函數 12 setLooping(boolean looping);//設置音樂是否循環播放,true爲循環播放 13 seekTo(int msec);//將音樂播放跳轉到某一時間點,以毫秒爲單位 14 getDuration();//獲取播放的音樂文件總時間長度 15 getCurrentPosition();//獲取當前播放音樂時間點
注:pause()和stop(),主要的區別在於:暫停播放後能夠調用start()繼續播放,中止音樂播放後,須要調用prepare()再調用start()進行播放音樂。函數
固然不得不提AudioManager(音樂管理類,能夠獲取當前音樂大小以及最大音量)工具
1 // 獲取實例 2 AudioManager am = new AudioManager(); 3 4 //經常使用方法: 5 setStreamVolume(imt streamType,int index,int flags) ;//設置音量大小,參數一:音樂類型(AudioManager.STREAM_MUSIC),參數二:音量大小,參數三:設置一個或者多個標誌 6 getStreamVolume(int streamType);//獲取當前音量大小,參數 獲取音量大小類型 7 getStreamMaxVolume(int streamType);// 獲取當前音量最大值,參數獲取音量大小的類型
二、SoundPooloop
獲取實例:this
1 //參數一:容許同時播放的聲音最大值,參數二:聲音類型,參數三:聲音品質 2 new SoundPool(int maxStreams,int streamType,int srcQuality);
經常使用方法:spa
1 //加載音樂文件,返回音樂ID(音樂流文件數據) 參數一:Context實例,參數二:音樂文件ID, 2 //參數三:標誌優先考慮的聲音。目前使用沒有任何效果,只是具有兼容性價值。通常寫個1就能夠。 3 int load(Context context,int resId,int priority); 4 //音樂播放,播放失敗返回0,正常則返回非0值,參數一:加載後獲得的音樂文件,參數二:音量的左聲道 範圍0.0~1.0 參數三:音量的右聲道,範圍 0.0~1.0 5 //參數四:音樂流的優先級,0爲最低優先級,參數五:音樂播放次數,-1表示無限循環,0表示正常一次,大於0則表示循環次數, 6 //參數六:播放速率,取值範圍:0.5~2.0,1.0表示正常播放。 7 int play(int soundId,float leftVolume,float rightVolume,int proority,int loop,float rate); 8 pause(int streamID); //暫停音樂播放 ,參數:音樂文件加載後的流ID 9 stop(int streamID) ; //結束音樂播放 參數:音樂文件加載後的流ID 10 release(); //釋放SoundPool的資源 11 setLoop(int streamID,int loop); //設置循環次數 參數一:音樂文件加載後的流ID,參數二:循環次數 12 setReat(int streamID); //設置播放速率 13 setVolume(int streamID,float leftVolume,float rightVolume); //設置音量大小,參數二:左聲道音量,參數三:右聲道音量 14 setPriority(int streamID,int priority); //設置流的優先級,參數二:優先級值。
三、基於MediaPlayer的簡單播放器3d
導入drawable-mdpi(我通常是傳入這個drawable文件夾的) 三張播放、暫停、中止的圖片,res下新建raw文件夾並導入ten_year.mp3文件,注意Android的資源文件都不能中文和大寫字母命名。code
Activity主要代碼:對象
private ImageButton btn_start, btn_stop, btn_pause; private TextView tv; private MediaPlayer mp; // 聲明一個變量判斷是否爲暫停,默認爲false private boolean isPaused = false; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 經過findViewById找到資源 btn_start = (ImageButton) findViewById(R.id.btn_start); btn_stop = (ImageButton) findViewById(R.id.btn_stop); btn_pause = (ImageButton) findViewById(R.id.btn_pause); tv = (TextView) findViewById(R.id.myTextView1); // 建立MediaPlayer對象,將raw文件夾下的ten_year.mp3 mp = MediaPlayer.create(this, R.raw.ten_year); // 增長播放音樂按鈕的事件 btn_start.setOnClickListener(new ImageButton.OnClickListener() { @Override public void onClick(View v) { try { if (mp != null) { mp.stop(); } mp.prepare(); mp.start(); tv.setText("音樂播放中..."); } catch (Exception e) { tv.setText("播放發生異常..."); e.printStackTrace(); } } }); btn_stop.setOnClickListener(new ImageButton.OnClickListener() { @Override public void onClick(View v) { try { if (mp != null) { mp.stop(); tv.setText("音樂中止播放..."); } } catch (Exception e) { tv.setText("音樂中止發生異常..."); e.printStackTrace(); } } }); btn_pause.setOnClickListener(new ImageButton.OnClickListener() { @Override public void onClick(View v) { try { if (mp != null) { if (isPaused == false) { mp.pause(); isPaused = true; tv.setText("暫停播放!"); } else if (isPaused == true) { mp.start(); isPaused = false; tv.setText("繼續播放!"); } } } catch (Exception e) { tv.setText("發生異常..."); e.printStackTrace(); } } }); /* 當MediaPlayer.OnCompletionLister會運行的Listener */ mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { // @Override /* 覆蓋文件播出完畢事件 */ public void onCompletion(MediaPlayer arg0) { try { /* * 解除資源與MediaPlayer的賦值關係 讓資源能夠爲其它程序利用 */ mp.release(); /* 改變TextView爲播放結束 */ tv.setText("音樂播發結束!"); } catch (Exception e) { tv.setText(e.toString()); e.printStackTrace(); } } }); /* 當MediaPlayer.OnErrorListener會運行的Listener */ mp.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override /* 覆蓋錯誤處理事件 */ public boolean onError(MediaPlayer arg0, int arg1, int arg2) { // TODO Auto-generated method stub try { /* 發生錯誤時也解除資源與MediaPlayer的賦值 */ mp.release(); tv.setText("播放發生異常!"); } catch (Exception e) { tv.setText(e.toString()); e.printStackTrace(); } return false; } }); }
運行項目,聆聽音樂!
四、GameSoundPool音效播放的工具類
因爲音效的音頻文件太多了,建個map來管理,當要播放那個音效時,傳入相應的id便可。
主要代碼:
public class GameSoundPool { private MainActivity mainActivity; private SoundPool soundPool; private HashMap<Integer,Integer> map; public GameSoundPool(MainActivity mainActivity){ this.mainActivity = mainActivity; map = new HashMap<Integer,Integer>(); soundPool = new SoundPool(8,AudioManager.STREAM_MUSIC,0); } public void initGameSound(){ map.put(1, soundPool.load(mainActivity, R.raw.shoot, 1)); map.put(2, soundPool.load(mainActivity, R.raw.explosion, 1)); map.put(3, soundPool.load(mainActivity, R.raw.explosion2, 1)); map.put(4, soundPool.load(mainActivity, R.raw.explosion3, 1)); map.put(5, soundPool.load(mainActivity, R.raw.bigexplosion, 1)); map.put(6, soundPool.load(mainActivity, R.raw.get_goods, 1)); map.put(7, soundPool.load(mainActivity, R.raw.button, 1)); } //播放音效 public void playSound(int sound,int loop,boolean flag){ AudioManager am = (AudioManager)mainActivity.getSystemService(Context.AUDIO_SERVICE); float stramVolumeCurrent = am.getStreamVolume(AudioManager.STREAM_MUSIC); float stramMaxVolumeCurrent = am.getStreamVolume(AudioManager.STREAM_MUSIC); float volume = stramVolumeCurrent/stramMaxVolumeCurrent; if(flag) { soundPool.play(map.get(sound), volume, volume, 1, loop, 1.0f); } } }
因爲遊戲畫面常常會有按鈕點擊關閉音效,這裏的flag 參數主要用於控制是否播放。播放時調用
GameSoundPool.playSound(key, 0,soundFlag); 便可,key是定義具體的音效id,固然咱們也能夠爲了代碼可讀行寫成靜態全局變量傳進來。