Android多媒體架構套件含了擷取和回放音頻,視頻和各種類形的映像的功能,所以你可以很容易的把它們整合到你的應用中.你可以從儲存在資源中的檔案,檔案系統中的檔案,或從網路資料流中播放音頻或視頻,這些都是用MediaPlayer或JetPlayerAPI實現.你也可以使用MediaRecorderand Camera API來錄製聲音,視頻或抓取圖片.
下面的主題向你示範了如何使用Android架構來實現多媒體擷取和回放.
MediaPlayer
如何在你的應用中播放音視頻.
JetPlayer
如何使用通過JetCreator建立的內容播放互動音視頻.
Camera
如何在你的應用中使用一個裝置上的相機擷取圖片和視頻.
AudioCapture
如何在你的應用中錄製聲音.
媒體回放
Android多媒體架構支援播放很多常見的媒體類型,所以你可以使用MediaPlayerAPI很輕鬆的整合音視頻和映像到你的應用中.你可以從資源中,從檔案中,從網路上播放音視頻.
此文檔向你示範了如何寫一個媒體播放應用,如何與使用者和系統互動,從而獲得最好的效能和使用者體驗.
註:你只能把音視頻播放至標準的輸出裝置上.當前,它們是擴音器或藍芽耳機.你不能在電話通話時播放音頻檔案.
基礎
以下類被用於播放音頻和視頻:
MediaPlayer
此類是播放音視頻的主要API.
AudioManager
此類管理裝置上的音頻源和輸出.
Manifest聲明
在使用MediaPlayer開發之前,確保你的manifest中聲明了允許使用的相關特性.
InternetPermission - 如果你使用MediaPlayer來播放網路流中的內容,你的應用必須請求網路存取許可權.
<uses-permissionandroid:name="android.permission.INTERNET" />
WakeLock Permission -如果你的播放應用需要阻止螢幕變暗或阻止處理器睡眠,或使用MediaPlayer.setScreenOnWhilePlaying()或MediaPlayer.setWakeMode()方法,你必須請求此許可權.
<uses-permissionandroid:name="android.permission.WAKE_LOCK" />
使用MediaPlayer
媒體架構中最重要的組件之一就是MediaPlayer類.此類的對象可以用少量的設定即能擷取,解碼和播放音視頻.它支援多種媒體源,比如:
本地資源.
內部URI,比如你從ContentResolver取得的URI.
外部URI(流媒體)
要瞭解Android支援的媒體類型列表,請看AndroidSupported Media Formats 文檔.
下面是如何播放本地資源中的音訊例子(儲存在你的應用的res/raw/檔案夾下):
[java] MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start(); //不需要調用prepare(); create()為你做了
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start(); //不需要調用prepare(); create()為你做了
在例子中,"raw"資源是一個系統不會以某種方式進行分析的檔案.然而,此資源的內容不能是原始音頻,它應是一種適當編碼和格式化的媒體檔案(當然是被支援的格式).
以下是如何播放一個本地URI的例子(URI是你用ContentResolver擷取的):
[java] Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
從一個基於HTTP流的的遠程URL播放看起來是這樣的
[java] String url = "http://........"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();
String url = "http://........"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();
註:如果你傳入了一個URL來流式播放一個線上檔案,這個檔案必須前進式下載progressivedownload.
警告:當使用setDataSource()時你必須捕獲和傳遞IllegalArgumentException和IOException,因為你引用的檔案可能不存在.
非同步Preparation
使用MediaPlayer,在其本質上來說可以是簡單直接的.然而,對於一個典型android應用來說還有一些重要的事情要記住.例如,prepare()調用可能耗時很常,因為它可能需要擷取並開啟解碼媒體資料.所以,由於有些方法會執行很長時間,那麼你就不能從你的應用的UI線程中調用它.否則會導致UI掛起,直到此方法返回為止.這是很差勁的使用者體驗,還會導致一個ANR(應用沒有反應)錯誤.即使你認為你的資源載入的很快,但記住介面中任何耗時超過10秒的東西將導致一個顯著的暫停並使使用者對你的應用產生慢的印像.
要避免掛起UI線程,應產生另外的線程來"prepare"MediaPlayer並且在完成時通知主線程.然而,色雖然你可以親自寫線程中的邏輯,但是更常用的是使用架構所提供的一個方便的途徑:使用prepareAsync().此方法在後台開始"準備"過程並立即返回.當媒體"準備"完成,MediaPlayer.OnPreparedListener的onPrepared()方法(通過setOnPreparedListener()設定的)被調用.
管理狀態
對MediaPlayer要記住的另一個方面就是"基於狀態".即,MediaPlayer有一個內部的狀態,因為特定的操作只能在特定的狀態時才有效,所以你必須在寫代碼時一直注意到它的變化.如果你在錯誤的狀態下執行一個操作,系統可能拋出一個異常或導致一個意外的行為.
MediaPlayer類文檔中展示了一個完整的狀態圖例,它闡明了哪個方法使MediaPlayer從一個狀態進入另一個狀態.例如,當你建立一個新的MediaPlayer,它處於Idle狀態.此時,你應調用setDataSource()初始化它,使它進入"已初始化"狀態.之後,你應使用prepare()或prepareAsync()"準備"它.當MediaPlayer準備完成,它將進入Prepared狀態,這表示你可以調用start()來播放了.此時,表所示,你可以調用start(),pause(),和seekTo()以及其它一些方法使MediaPlayer的狀態在Started,Paused和PlaybackCompleted狀態之間轉換.當你調了stop(),注意你不能再調用start(),除非你重新prepare MediaPlayer.
當你寫代碼與MediaPlayer互動時,要時刻記住MediaPlayer的狀態變化圖,因為在錯誤的狀態下調用它的方法是常見的bug的原因.
摘自 nkmnkm的專欄