本文演示瞭如何通過Api播放音頻和視頻文件,來獲得良好性能和愉快的用戶體驗,僅供學習分享使用,如有不足之處,還請指正。 ...
概述
Android多媒體框架支持各種常見的媒體類型,可以很容易地將音頻、視頻和圖像集成到App中。通過MediaPlayer Api,可以從應用程式資源(RAW)、文件系統或網路上數據流資源來播放音頻或視頻。本文演示瞭如何通過Api播放音頻和視頻文件,來獲得良好性能和愉快的用戶體驗,僅供學習分享使用,如有不足之處,還請指正。
涉及知識點
- MediaPlayer 可以用來控制audio/video文件或流播放的類。通過此類,可以方便的控制音頻/視頻文件的播放,暫停和停止等操作。
- Uri 統一資源標識符(Uniform Resource Identifier,或URI)是一個用於標識某一互聯網資源名稱的字元串。
- VideoView 自帶的一種播放視頻的組件。
- SurfaceView 可以通過後臺繪製顯示的視圖組件。
Activity中播放音頻
頁面上播放音頻文件,步驟如下:
1. 準備資源文件,並播放
1 private MediaPlayer mMediaPlayer; 2 3 /** 4 * 開始 5 * @param v 6 */ 7 public void bn_start(View v){ 8 if(mMediaPlayer==null) { 9 ready(); 10 } 11 mMediaPlayer.start(); 12 } 13 14 /** 15 * 創建MediaPlayer併到prepare狀態 16 */ 17 private void ready(){ 18 if(mMediaPlayer==null){ 19 mMediaPlayer=new MediaPlayer();//Idle 20 //Log.i("TAG", "ready: "+filePath); 21 File file=new File(Environment.getExternalStorageDirectory(),"goldfallen.mp3"); 22 Log.i("TAG", "ready: "+file.getPath()); 23 Log.i("TAG", "ready: "+file.exists()); 24 Uri uri= Uri.fromFile(file); 25 try { 26 mMediaPlayer.setDataSource(AudioActivity.this,uri); 27 mMediaPlayer.prepare();//Prepared 28 } catch (IOException e) { 29 Log.i("TAG", "ready: "+ e.getMessage()); 30 e.printStackTrace(); 31 } 32 } 33 }
2. 暫停播放
1 /** 2 * 暫停 3 * @param v 4 */ 5 public void bn_pause(View v){ 6 if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){ 7 mMediaPlayer.pause(); 8 } 9 }
3. 停止
1 /** 2 * 停止 3 * @param v 4 */ 5 public void bn_stop(View v){ 6 if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){ 7 mMediaPlayer.stop(); 8 mMediaPlayer.release(); 9 mMediaPlayer=null; 10 } 11 }
4. 釋放資源(當頁面銷毀時,播放資源也要同時釋放)
1 @Override 2 protected void onDestroy() { 3 if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){ 4 mMediaPlayer.stop(); 5 mMediaPlayer.release(); 6 mMediaPlayer=null; 7 } 8 super.onDestroy(); 9 }
5. 通過靜態函數創建對象
1 /** 2 * D:\Android\Project\DemoMedia\app\src\main\res\raw\A2012.mp3: 3 * Error: 'A' is not a valid file-based resource name character: 4 * File-based resource names must contain only lowercase a-z, 0-9, or underscore 5 */ 6 private void ready2(){ 7 if(mMediaPlayer==null){ 8 mMediaPlayer= MediaPlayer.create(this,R.raw.ab2012); 9 } 10 }
通過服務來播放音頻
當頁面關閉時,音頻文件還可以在後臺播放。步驟如下:
1. 定義後臺服務,當服務啟動時,創建MediaPlayer對象,並註冊服務接收對象。
1 public class AudioService extends Service { 2 3 private MediaPlayer mMediaPlayer; 4 5 private OperatorReceiver mReceiver; 6 7 public AudioService() { 8 } 9 10 @Override 11 public void onCreate() { 12 super.onCreate(); 13 mMediaPlayer=new MediaPlayer(); 14 mReceiver=new OperatorReceiver(); 15 IntentFilter filter=new IntentFilter("operator.receiver"); 16 registerReceiver(mReceiver,filter); 17 } 18 19 @Override 20 public IBinder onBind(Intent intent) { 21 return null; 22 } 23 24 @Override 25 public int onStartCommand(Intent intent, int flags, int startId) { 26 Log.i("TAG", "onStartCommand: ----ready "); 27 ready(); 28 return super.onStartCommand(intent, flags, startId); 29 } 30 31 @Override 32 public void onDestroy() { 33 if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){ 34 mMediaPlayer.stop(); 35 } 36 if(mMediaPlayer!=null){ 37 mMediaPlayer.release(); 38 mMediaPlayer=null; 39 } 40 unregisterReceiver(mReceiver); 41 super.onDestroy(); 42 } 43 44 private void start(){ 45 mMediaPlayer.start(); 46 } 47 48 private void pause(){ 49 mMediaPlayer.pause(); 50 } 51 52 private void stop(){ 53 mMediaPlayer.stop(); 54 ready(); 55 } 56 57 private void ready(){ 58 mMediaPlayer.reset(); 59 try { 60 String filePath= Environment.getExternalStorageDirectory()+"/ab2012.mp3"; 61 Log.i("TAG", "ready: "+filePath); 62 File file=new File(filePath); 63 if(file.exists()) { 64 mMediaPlayer.setDataSource(filePath); 65 mMediaPlayer.prepare(); 66 }else{ 67 Log.i("TAG", "ready: 文件不存在 "); 68 } 69 } catch (IOException e) { 70 Log.i("TAG", "ready: "+e.getMessage()); 71 e.printStackTrace(); 72 } 73 } 74 }
2. 操作接收者定義如下:
1 /** 2 * 操作接收器 3 */ 4 class OperatorReceiver extends BroadcastReceiver 5 { 6 @Override 7 public void onReceive(Context context, Intent intent) { 8 int cmd=intent.getIntExtra("cmd",-1); 9 Log.i("TAG", "onReceive: "+cmd); 10 switch (cmd){ 11 case Tools.PLAY: 12 start(); 13 break; 14 case Tools.PAUSE: 15 pause(); 16 break; 17 case Tools.STOP: 18 stop(); 19 break; 20 default: 21 start(); 22 break; 23 24 } 25 } 26 }
3. 啟動服務
1 Intent intent =new Intent(this,AudioService.class); 2 startService(intent);
4. 前臺Activity通過發送廣播命令進行控制音頻的播放與暫停
1 /** 2 * 開始 3 * @param v 4 */ 5 public void bn_start(View v){ 6 Intent intent=new Intent("operator.receiver"); 7 intent.putExtra("cmd",Tools.PLAY); 8 sendBroadcast(intent); 9 Log.i("TAG", "bn_start: "+"service"); 10 } 11 12 /** 13 * 暫停 14 * @param v 15 */ 16 public void bn_pause(View v){ 17 Intent intent=new Intent("operator.receiver"); 18 intent.putExtra("cmd",Tools.PAUSE); 19 sendBroadcast(intent); 20 } 21 22 /** 23 * 停止 24 * @param v 25 */ 26 public void bn_stop(View v){ 27 Intent intent=new Intent("operator.receiver"); 28 intent.putExtra("cmd",Tools.STOP); 29 sendBroadcast(intent); 30 }
5.通過後臺服務的方式,需要在AndroidManifest.xml文件中進行註冊
1 <service 2 android:name=".AudioService" 3 android:enabled="true" 4 android:exported="true"> 5 </service>
通過VideoView來播放視頻
通過VideoView進行播放視頻文件,只需要設置資源URI即可,具體如下:
1 private VideoView mVideoView; 2 @Override 3 protected void onCreate(Bundle savedInstanceState) { 4 super.onCreate(savedInstanceState); 5 setContentView(R.layout.activity_video); 6 mVideoView= (VideoView) this.findViewById(R.id.vv_info); 7 //設置路徑 8 File file=new File(Environment.getExternalStorageDirectory(),"DCIM/Camera/VID20190629142614.mp4"); 9 Log.i("TAG", "onCreate: "+file.getPath()); 10 if(!file.exists()){ 11 Log.i("TAG", "onCreate: 文件不存在"); 12 } 13 Uri uri=Uri.fromFile(file); 14 mVideoView.setVideoURI(uri); 15 //設置Media Controller 16 MediaController controller=new MediaController(this); 17 mVideoView.setMediaController(controller); 18 //獲取焦點 19 mVideoView.requestFocus(); 20 mVideoView.start(); 21 //設置播放完成事件 22 mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 23 @Override 24 public void onCompletion(MediaPlayer mp) { 25 Toast.makeText(VideoActivity.this, "播放完畢", Toast.LENGTH_SHORT).show(); 26 } 27 }); 28 }
通過MediaPlayer來播放視頻
通過MediaPlayer來播放視頻文件,然後通過SurfaceView來顯示視頻內容,具體步驟如下:
1.啟動,通過setDisplay來設置顯示內容
1 public void bn_start(View view) { 2 mMediaPlayer.reset();//到Idle狀態 3 //設置路徑 4 File file=new File(Environment.getExternalStorageDirectory(),"DCIM/Camera/VID20190629142614.mp4"); 5 Log.i("TAG", "onCreate: "+file.getPath()); 6 if(!file.exists()){ 7 Log.i("TAG", "onCreate: 文件不存在"); 8 } else { 9 Log.i("TAG", "onCreate: 文件存在 "); 10 } 11 Uri uri=Uri.fromFile(file); 12 try { 13 mMediaPlayer.setDataSource(this,uri); 14 mMediaPlayer.setDisplay(mSurfaceView.getHolder()); 15 mMediaPlayer.prepare(); 16 mMediaPlayer.start(); 17 } catch (IOException e) { 18 e.printStackTrace(); 19 } 20 }
2. 暫停與停止
1 public void bn_pause(View view){ 2 if(mMediaPlayer.isPlaying()){ 3 mMediaPlayer.pause(); 4 } 5 } 6 7 public void bn_stop(View view){ 8 if(mMediaPlayer.isPlaying()){ 9 mMediaPlayer.stop(); 10 } 11 }
3. 資源釋放
1 @Override 2 protected void onDestroy() { 3 if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){ 4 mMediaPlayer.stop(); 5 } 6 if(mMediaPlayer!=null){ 7 mMediaPlayer.release(); 8 mMediaPlayer=null; 9 } 10 super.onDestroy(); 11 }
許可權設置
如果要播放視頻,需要相應的許可權設置,併在安裝時獲取請求許可權
1 <uses-permission android:name="android.permission.INTERNET"/> 2 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 3 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 4 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
備註
合抱之木,生於毫末;九層之台,起於壘土;千里之行,始於足下。