前兩篇文章通過麥克風硬件和攝像頭硬件分別采集音頻和視頻的多媒體數據,在得到的多媒體數據通常是以編碼文件的格式存儲,在用戶需要展示時,可通過設備的內置擴音器或藍牙耳機等硬件播放音頻,通過設備的顯示屏或外接投影儀等硬件播放照片、動畫或視頻。
可以將這些展示類設備分為兩類。
一類是內置類多媒體硬件,是通過線路硬連接到設備CPU控制中心,所以在應用程序中可直接調取系統提供的相關接口直接使用這類設備。比如移動手機的內置擴音器、聽筒、有線耳機、屏幕等硬件。
另一類是外接類多媒體硬件,是通過配合下文即將介紹的藍牙或網絡等通訊類硬件,通過無線軟連接到設備CPU控制中心,在使用這類設備前,必須先配合通訊類硬件的使用。比如藍牙耳機、投影儀等硬件。
本篇只介紹在內置類多媒體硬件上的使用流程。
播放音頻
對於音頻的播放,主要借助內置擴音器,使用系統提供的android.media.MediaPlayer類。
使用其無參構造方法后,調用該對象的setDataSource(String path)
等系列方法,設置要播放的音頻源。該系列方法有多個重寫,除了上邊參數 path 所表示的本地文件格式的音頻源,還可以設置遠程網絡 Uri 格式的音頻源。
除此之外,還需要設置播放的音頻流類型,不過設置方法在不同版本上有所區別。
在Android5.0即API級別21之前,調用setAudioStreamType(int streamtype)
方法,參數 streamtype 是由android.media.AudioManager音頻管理類定義的常量,其值包括標記為語音通話音頻流的AudioManager.STREAM_VOICE_CALL=0
,標記為系統音頻流的AudioManager.STREAM_SYSTEM=1
,語音鈴聲的AudioManager.STREAM_RING=2
,或者多媒體音樂流的AudioManager.STREAM_MUSIC=3
等多種音頻流類型。
從Android5.0即API級別21開始,改用setAudioAttributes(AudioAttributes attributes)
方法,參數 attributes 是android.media.AudioAttributes音頻屬性類構造的對象,而AudioAttributes
對象則是通過android.media.AudioAttributes.Builder建造者模式構造的。在無參構造建造者AudioAttributes.Builder
對象后,調用setUsage(int usage)
方法設置音頻屬性的使用者,調用setContentType(int contentType)
方法設置音頻流內容類型,上述方法中的參數 usage 和參數 contentType 都是AudioAttributes
定義的常量值。之后通過build()
方法返回AudioAttributes
音頻屬性類的實例化對象。
在音頻相關參數設置之后,就可以准備音頻以通過系統獲取相關硬件設備了。
在加載本地的小文件時,可以直接調用 prepare()
方法,代碼執行到此處時會停止后續代碼運行,直到獲取到相關資源,才會繼續執行音頻准備完成之后的相關操作。因此在系統主線程中調用該方法時需要注意ANR異常。
通常在加載網絡資源或過大的文件時,調用prepareAsync()
方法,該方法會異步獲取相關資源,后續代碼繼續執行,而當應用程序獲取到相關資源后,將回調setOnPreparedListener(MediaPlayer.OnPreparedListener listener)
中傳入的 listener 參數對象的onPrepared(MediaPlayer mp)
方法,而這里的參數 mp 也就是上文調用prepareAsync()
的MediaPlayer
對象。因此在實現android.media.MediaPlayer.OnPreparedListener接口的onPrepared(MediaPlayer mp)
方法中,可以繼續執行音頻准備完成之后的相關操作。
在音頻准備完成之后,便可以在合適的時機執行音頻的播放流程了。
調用start()
方法即可開始播放;
在音頻播放過程中,同樣可以調用pause()
方法暫停播放;
調用seekTo(long msec, int mode)
方法可以將播放位置移動到參數 msec 指定的毫秒級同步時刻,參數 mode 是MediaPlayer
中的常量值,包括實際定位到參數 msec 指定的同步位置之前的MediaPlayer.SEEK_PREVIOUS_SYNC=0
,實際定位到參數 msec 指定的同步位置之后的MediaPlayer.SEEK_NEXT_SYNC=1
,實際定位到參數 msec 指定的同步位置最近的MediaPlayer.SEEK_CLOSEST_SYNC=2
等幾種可選模式;
調用stop()
方法停止播放,將會釋放應用程序所獲取的包括硬件的相關資源。
顯示圖片或視頻
對於靜態圖片的展示,通常使用android.widget.ImageView類似控件,直接加載靜態圖片。
對於無聲的動態圖展示,通常使用android.view.SurfaceView控件,在該控件上可以繪制幾乎任何你能想到的效果。
對於自帶音頻的有聲動圖(即視頻)展示,可以使用上述方案的結合,也可使用系統提供的android.widget.VideoView控件,可以更方便的加載視頻並展示。
同時,由於圖片或視頻展示都只是借助屏幕繪制,所以使用界面繪制展示一文中的相關知識內容即可實現。而且其他開發者和團隊也開發了一系列的相關庫以供使用,這在學習過程中並不算難點,故不再贅述。