Android之MediaPlayer播放一般音頻與SoundPool播放短促的音效

來源:互聯網
上載者:User
【1】使用MediaPlayer實現一般的音頻播放
  • MediaPlayer播放通常的音頻檔案

 

MediaPlayer mediaPlayer = new MediaPlayer();<br />if (mediaPlayer.isPlaying()) {<br /> mediaPlayer.reset();//重設為初始狀態<br />}<br />mediaPlayer.setDataSource("/mnt/sdcard/god.mp3");<br />mediaPlayer.prepare();//緩衝<br />mediaPlayer.start();//開始或恢複播放<br />mediaPlayer.pause();//暫停播放<br />mediaPlayer.start();//恢複播放<br />mediaPlayer.stop();//停止播放<br />mediaPlayer.release();//釋放資源<br />mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {//播出完畢事件<br /> @Override public void onCompletion(MediaPlayer arg0) {<br /> mediaPlayer.release();<br /> }<br />});<br />mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {// 錯誤處理事件<br /> @Override public boolean onError(MediaPlayer player, int arg1, int arg2) {<br /> mediaPlayer.release();<br /> return false;<br /> }<br />}); 

  • 程式樣本:

/**<br /> * 音頻播放器<br /> * @author kay<br /> */<br />public class PlayActivity extends Activity<br />{<br />private static final String TAG = "PlayActivity";<br /> private EditText filenameText;<br /> private MediaPlayer mediaPlayer;<br /> private String filename;<br /> private int position;</p><p> @Override<br /> public void onCreate(Bundle savedInstanceState)<br /> {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.main);<br /> filenameText = (EditText)this.findViewById(R.id.filename);</p><p> //對mediaPlayer進行執行個體化<br /> mediaPlayer = new MediaPlayer();<br /> ButtonClickListener listener = new ButtonClickListener();<br /> //擷取4個按鈕<br /> Button playButton = (Button)this.findViewById(R.id.play);<br /> Button pauseButton = (Button)this.findViewById(R.id.pause);<br /> Button resetButton = (Button)this.findViewById(R.id.reset);<br /> Button stopButton = (Button) this.findViewById(R.id.stop);<br /> //設定4個按鈕的監聽<br /> playButton.setOnClickListener(listener);<br /> pauseButton.setOnClickListener(listener);<br /> resetButton.setOnClickListener(listener);<br /> stopButton.setOnClickListener(listener);<br /> Log.i(TAG, "onCreate()");<br /> }</p><p> @Override<br />protected void onRestoreInstanceState(Bundle savedInstanceState)<br /> {<br />this.filename = savedInstanceState.getString("filename");<br />this.position = savedInstanceState.getInt("position");<br />super.onRestoreInstanceState(savedInstanceState);<br />Log.i(TAG, "onRestoreInstanceState()");<br />}<br />@Override<br />protected void onSaveInstanceState(Bundle outState)<br />{<br />outState.putString("filename", filename);<br />outState.putInt("position", position);<br />super.onSaveInstanceState(outState);<br />Log.i(TAG, "onSaveInstanceState()");<br />}</p><p>private void play() throws IOException<br />{<br />//擷取檔案路徑<br />File audioFile = new File(Environment.getExternalStorageDirectory(),filename);<br />mediaPlayer.reset();<br />mediaPlayer.setDataSource(audioFile.getAbsolutePath());<br />mediaPlayer.prepare();<br />mediaPlayer.start();<br />}</p><p>//如果突然電話到來,停止播放音樂<br />@Override<br />protected void onPause()<br />{<br />if(mediaPlayer.isPlaying())<br />{<br />//儲存當前播放點<br />position = mediaPlayer.getCurrentPosition();<br />mediaPlayer.stop();<br />}<br />super.onPause();<br />}</p><p>//<br />@Override<br />protected void onResume()<br />{<br />//如果電話結束,繼續播放音樂<br />if(position>0 && filename!=null)<br />{<br />try<br />{<br />play();<br />mediaPlayer.seekTo(position);<br />position = 0;<br />}<br />catch (IOException e)<br />{<br />Log.e(TAG, e.toString());<br />}<br />}<br />super.onResume();<br />}</p><p>//對mediaPlayer進行摧毀<br />@Override<br />protected void onDestroy()<br />{<br /> mediaPlayer.release();<br />super.onDestroy();<br />Log.i(TAG, "onDestroy()");<br />}<br />private final class ButtonClickListener implements View.OnClickListener<br />{<br />@Override<br />public void onClick(View v)<br />{<br />//先得到文字框中的內容<br />filename = filenameText.getText().toString();<br />//得到button<br />Button button = (Button) v;<br />try<br />{<br />//通過傳過來的Buttonid可以判斷Button的類型<br />switch (v.getId())<br />{<br />case R.id.play:<br />play();<br />break;</p><p>case R.id.pause:<br />if(mediaPlayer.isPlaying())<br />{<br />mediaPlayer.pause();<br />button.setText(R.string.continue1);//讓這個按鈕上的文字顯示為繼續<br />}<br />else<br />{<br />mediaPlayer.start();//繼續播放<br />button.setText(R.string.pause);<br />}<br />break;</p><p>case R.id.reset:<br />if(mediaPlayer.isPlaying())<br />{<br />mediaPlayer.seekTo(0);//讓它從0開始播放<br />}<br />else<br />{<br />play();//如果它沒有播放,就讓它開始播放<br />}<br />break;</p><p>case R.id.stop:<br />//如果它現正播放的話,就讓他停止<br />if(mediaPlayer.isPlaying())<br />mediaPlayer.stop();<br />break;<br />}<br />}<br />catch (Exception e)<br />{<br />Log.e(TAG, e.toString());<br />}<br />}<br /> }<br />} 

【2】使用SoundPool實現短促的音效

 

     在Android開發中我們經常使用MediaPlayer來播放音頻檔案,但是MediaPlayer存在一些不足,例如:資源佔用量較高、延遲時間較長、不支援多個音頻同時播放等。這些缺點決定了MediaPlayer在某些場合的使用方式不會很理想,例如在對時間精準度要求相對較高的遊戲開發中。

     在遊戲開發中我們經常需要播放一些遊戲音效(比如:子彈爆炸,物體撞擊等),這些音效的共同特點是短促、密集、延遲程度小。在這樣的情境下,我們可以使用SoundPool代替MediaPlayer來播放這些音效。 

    SoundPool(android.media.SoundPool),顧名思義是聲音池的意思,主要用於播放一些較短的聲音片段,支援從程式的資源或檔案系統載入。與MediaPlayer相比,SoundPool的優勢在於CPU資源佔用量低和反應延遲小。另外,SoundPool還支援自行設定聲音的品質、音量、播放比率等參數,支援通過ID對多個音頻流進行管理。

  • SoundPool存在的缺陷

    1.SoundPool最大隻能申請1M的記憶體空間,這就意味著我們只能用一些很短的聲音片段,而不是用它來播放歌曲或者做遊戲背景音樂。

  2.SoundPool提供了pause和stop方法,但這些方法建議最好不要輕易使用,因為有些時候它們可能會使你的程式莫名其妙的終止。建議使用這兩個方法的時候儘可能多做測試工作,還有些朋友反映它們不會立即中止播放聲音,而是把緩衝區裡的資料播放完才會停下來,也許會多播放一秒鐘。

  3.SoundPool的效率問題。其實SoundPool的效率在這些播放類中算是很好的了,但是有的朋友在G1中測試它還是有100ms左右的延遲,這可能會影響使用者體驗。也許這不能管SoundPool本身,因為到了效能比較好的Droid中這個延遲就可以讓人接受了。

  在現階段SoundPool有這些缺陷,但也有著它不可替代的優點,基於這些我們建議大在如下情況中多使用SoundPool:1.應用程式中的聲效(按鍵提示音,訊息等)2.遊戲中密集而短暫的聲音(如多個飛船同時爆炸)

  • SoundPool使用方法

 

 

 

開發步驟:

1>往項目的res/raw目錄中放入音效檔案。

2>建立SoundPool對象,然後調用SoundPool.load()載入音效,調用SoundPool.play()方法播放指定音效檔案。

public class AudioActivity extends Activity<br />{<br />private SoundPool pool;<br />@Override<br />public void onCreate(Bundle savedInstanceState)<br />{<br />super.onCreate(savedInstanceState);<br />setContentView(R.layout.main);<br />//指定聲音池的最大音頻流數目為10,聲音品質為5<br />pool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);<br />//載入音頻流,返回在池中的id<br />final int sourceid = pool.load(this, R.raw.pj, 0);<br />Button button = (Button)this.findViewById(R.id.button);<br />button.setOnClickListener(new View.OnClickListener()<br />{<br />public void onClick(View v)<br />{ //播放音頻,第二個參數為左聲道音量;第三個參數為右聲道音量;第四個參數為優先順序;第五個參數為迴圈次數,0不迴圈,-1迴圈;第六個參數為速率,速率 最低0.5最高為2,1代表正常速度<br />pool.play(sourceid, 1, 1, 0, -1, 1);<br />}<br />});<br />}<br />} 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.