讀古今文學網 > Android程序設計:第2版 > 播放音頻和視頻 >

播放音頻和視頻

Android提供了播放音頻和視頻文件的標準方式:MediaPlayer類。對於音頻內容,還可以播放原始數據,這在複雜的應用中很有用,可以動態生成音頻數據。

MediaPlayer在其生命週期中要經歷以下幾種狀態:

Idle

MediaPlayer完成實例化。

Initialized

設置媒體資源。

Preparing

MediaPlayer在準備要播放的媒體資源。

Prepared

MediaPlayer已經準備好播放。

Started

開始播放。

Paused

播放暫停。

Playback complete

媒體資源播放完成(可以再次開始播放)。

Stopped

MediaPlayer不再打算播放資源。

End

刪除了MediaPlayer,釋放資源。

關於這些狀態的詳細信息,可以查看開發者網站中提供的狀態圖:http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram。要使用MediaPlayer,列出將其添加到應用中所需的各個步驟是很有幫助的:

1.調用create方法創建MediaPlayer實例(空閒狀態)。

2.使用要播放的媒體資源初始化MediaPlayer(初始化狀態)。

3.調用prepare方法,讓MediaPlayer為播放做好準備(包含正在準備和已準備好狀態)。

4.調用start方法使MediaPlayer進入播放狀態(啟動狀態)。

5.在播放過程中,可以隨意暫停、停止或重播MediaPlayer(啟動、暫停、回放完成和停止狀態)。

6.一旦完成播放,記得調用release方法,釋放MediaPlayer相關的資源(最終狀態)。

本章後續內容將對這些步驟進行更詳細的介紹。

音頻播放

播放音頻有兩種方式:MediaPlayer和AudioTrack。MediaPlayer是標準的、簡單的播放方式,其數據必須是文件形式的或基於流的。相反,AudioTrack直接訪問內存中的原始音頻數據。

MediaPlayer音頻播放

第一次使用MediaPlayer時,應該確定是否要使用應用資源中的文件。如果要使用,MediaPlayer提供了很方便的靜態方法,它可以設置數據源並讓播放器做好準備:


MediaPlayer mediaplayer = MediaPlayer.create(this, R.raw.example);
  

如果不使用應用資源,例如指向文件系統(如SD卡等)中的音頻文件,或者是在Web站點上的音頻文件(如http://SomeServer/SomeAudioFile.mp3),則需要手工設置和調用數據源。可以使用下面這個方法從URI中獲取數據:


setDataSource(context, uri)
  

第一個參數context是MediaPlayer訪問應用本身的資源的途徑,以便能夠解析URI,其可以是應用的context或活動的context。

另一種方式是通過絕對路徑調用:


setDataSource(path)
  

API版本9支持把一些輔助效果(如混響效果)添加到播放器中。在調用prepare方法之前,設置數據源時可以設置任何你想要的效果:


MediaPlayer mediaplayer = new MediaPlayer;
// Uri mediaReference = \"http://someUriToaMediaFile.mp3\";
// mediaplayer.setDataSource(this, mediaReference);
// use absolute path
mediaplayer.setDataSource(\"/sdcard/somefile.mp3\");
// prepare mediaplayer
mediaplayer.prepare;
  

MediaPlayer準備好後,就可以播放了:


mediaplayer.start;
  

在播放過程中,播放器可以暫停或停止。當處於暫停狀態時,可以再次調用start方法啟動播放。一旦MediaPlayer被停止了,則需要執行reset方法進行重置,使用之前的數據源重新初始化,並調用prepare方法,才能重新啟動。先來看看以下代碼:


mediaplayer.pause; // pausing
mediaplayer.start; // going from pause to play
mediaplayer.stop; // stopping
...
// to be able to play again reset must be called
mediaplayer.reset;
// now the media player must be reinitialized to play again
  

當MediaPlayer正在播放時,可以通過getCurrentPosition方法跟蹤文件的當前位置,它會返回文件已經播放了多長時間,單位是ms:


mediaplayer.getCurrentPosition;
  

一旦不再需要MediaPlayer,要確保釋放它,這樣就可以釋放資源給系統使用:


mediaplayer.release;
  

AudioTrack音頻播放

AudioTrack提供了更直接的音頻播放方式。下面這個例子說明了如何設置AudioTrack的各個參數:


File mediafile = new File(mediaFilePath);
short audio = new short[(int) (mediafile.length/2)];
// read in file and fill up audio
AudioTrack audiotrack = new AudioTrack(
                                // stream type
                    AudioManager.STREAM_MUSIC,
                                // frequency
                    11025,
                                // channel config
—mono, stereo, etc.
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                // audio encoding
                    AudioFormat.ENCODING_PCM_16BIT,
                                // length
                    audio.length,
                                // mode
                    AudioTrack.MODE_STREAM
                    );
 

AudioTrack方法提供音頻流的類型(音樂、鈴聲、報警、語音呼叫等)、以Hz表示的採樣比率(44100、22050和11025)、音頻配置(單聲道或立體聲)、音頻格式/編碼、以字節數表示的音頻長度、模式(靜態或流式)。配置好Android的AudioTrack後,它自己知道如何使用設備的硬件接口,並能提供流暢的音樂播放體驗。

要播放音頻,只需執行play方法,就可以把數據寫到硬件中:


// start playing state
audiotrack.play;
// write audio to hardware
audiotrack.write(audio, 0, audio.length);
  

要暫停播放,可以使用pause方法:


// pause
audiotrack.pause;
  

要停止播放,可以把它設置成停止狀態。如果不再需要播放音頻,就要釋放資源。如果要重新播放音頻,則必須重新執行初始化:


// stop
audiotrack.stop;
// release all resources
audiotrack.release;
  

視頻播放

視頻播放和音頻播放不同,其只能使用MediaPlayer。沒有類似AudioTrack功能的視頻播放器。對於MediaPlayer,視頻播放和音頻播放類似,但是這裡還必須指定一個視圖(名為surface),視頻在該視圖上顯示。Android提供了包括surface在內的便捷的控制方式:VideoView視圖。下面將給出其使用方式。它還包含可選的控制器,該控制器支持用戶通過簡單的界面控制播放,包括啟動、停止及暫停播放的各個按鈕,以及用來控制視頻播放進度的可向前或向後拖動的進度條:


// create the view (in this case it is already included in the layout resource)
VideoView videoview = (VideoView) findViewById(R.id.videoview);
videoview.setKeepScreenOn(true);
// used if streaming
if (videouri != null) videoview.setVideoURI(videouri);
// absolute path if it is a file
else videoview.setVideoPath(videopath);
// let\'s add a media control so we can control the playback
mediacontroller = new MediaController(this);
mediacontroller.setAnchorView(videoview);
videoview.setMediaController(mediacontroller);
if (videoview.canSeekForward)
videoview.seekTo(videoview.getDuration/2);
// start the playback
videoview.start;