1. 程式人生 > >Android自定義視訊播放器(一)

Android自定義視訊播放器(一)

一、引言

我們在開發Android多媒體應用時,有兩種方式來播放多媒體資源。第一種是使用隱式的Intent,來使用系統或者手機已經安裝的第三方播放器應用來播放音視訊,第二種是使用Android自帶的、我們自定義的播放器來播放,這種主要是採用Android提供的MediaPlayer和VideoView來播放多媒體檔案,下面會逐一講述。兩種方式的程式碼如下:

//隱式方式,使用第三方播放器
 Intent intent = new Intent();      
 String url = "" 
 intent.setDataAndType(Uri.parse(url),"video/*");
 startActivity(intent);

//呼叫自定義播放器
Intent intent = new Intent(context,VideoActivity.class);
startActivity(intent);

對於自定義播放器,需要在VideoActivity的佈局檔案中,加入VideoView的定義,然後在VideoActivity中獲取,並使用:

setContentView(R.layout.activity_video);
videoView = findViewById(R.id.mVideoView);
//設定播放地址
videoView.setVideoPath(url);
//設定準備好了的監聽
videoView.setOnPreparedListener(new MyPreparedListener());
videoView.setOnErrorListener(new MyErrorListener());
videoView.setOnCompletionListener(new MyCompletionListener());
//為VideoView新增控制面板,用於暫停和播放
videoView.setMediaController(new MediaController(this));

二、MediaPlay

1、MediaPlayer,它主要是和虛擬機器的底層進行打交道,包括下面要講的VideoView也是對它的封裝和呼叫。

2、MediaPlayer,封裝了很多播放音視訊的方法,如: start、pause、stop。(下圖部分方法)
這裡寫圖片描述

3、MediaPlayer,可以播放本地和網路的音視訊,播放網路資源的時候,要聯網許可權。

4、MediaPlayer,可以支援的視訊格式:mp4、3gp、.m3u8(多用於直播)、直接用pc的.mp4檔案等

5、執行流程:
這裡寫圖片描述
6、各狀態說明:

  • 狀態1:Idel(空閒)狀態
    當 mediaplayer建立或者執行reset()方法後處於這個狀態。
  • 狀態2:Initialized(已初始化)狀態
    當呼叫mediaplayer的setDataResource()方法給mediaplayer設定播放的資料來源後,mediaplayer會處於該狀態。
  • 狀態3:Prepared(準備就續)狀態
    設定完資料來源後,呼叫mediaplayer的prepare()方法,讓mediaplayer準備播放。值得一提的是,這裡除了prepare()方法,還有prepareAsnyc()方法,此方法是非同步方法,一般用於網路視訊的緩衝。當緩衝完畢後,就會觸發準備完畢的事件。我們要做的就是監聽該事件(OnPreparedListener),當緩衝完成時,執行相應的操作。在此狀態上,我們可以呼叫seekTo()方法定位視訊,此方法不改變mediaplayer的狀態;亦可呼叫stop()放棄視訊播放,使mediaplayer處於Stopped狀態。一般我們會在此狀態上呼叫start()方法開始播放視訊。
  • 狀態4:Started(開始)狀態
    當處於Prepared狀態、Paused狀態和PlayebackCompeleted狀態時,呼叫Started()方法即可進入該狀態。在該狀態中,mediaplayer開始播放視訊,可以通過seekTo()方法和start()方法改變視訊播放的進度,當Looping為真且播放完畢後,它會重新開始播放(即迴圈播放);否則播放完畢後,會觸發事件並呼叫OnCompletionaListener.OnCompletion()方法,進行特定操作,並進入PlaybackCompleted狀態。在此狀態中,亦可呼叫pause()方法或者stop()方法讓視訊暫停或停止,此時mediaplayer分別處於Stopped和Paused狀態。
  • 狀態5:Stopped(停止)狀態
    當 mediaplayer處於Prepared、Started、Paused、PlaybackCompleted狀態時,呼叫stop()方法即可進入本狀態。應特別注意的是,在本狀態中,若想重新開始播放,不能直接呼叫start()方法,必須呼叫prepare()方法或prepareAsync()方法重新讓mediaplayer處於Prepared狀態方可呼叫start()方法播放視訊。
  • 狀態6:Paused(暫停)狀態
    當mediaplayer處於Started狀態是,呼叫pause()方法即可進入本狀態。在本狀態裡,可直接呼叫start()方法使,mediaplayer回到Started狀態,亦可呼叫stop()方法停止視訊播放,讓播放器處於停止態。
  • 狀態7:PlaybackCompleted(播放完成)狀態
    當mediaplayer播放完成且Looping為假時即可進入本狀態。在本狀態可呼叫start()方法使mediaplayer回到Started狀態(注意此時是從頭開始播放);亦可呼叫stop()方法使mediaplayer處於停止態,結束播放。
  • 狀態8:Error(錯誤)狀態
    當mediaplayer出現錯誤時處於此狀態。

三、VideoView

1、VideoView,用於顯示視訊,繼承SurfaceView類,實現MediaPlayerControl介面。

2、封裝了MediaPlayer的start、pause、stop,本質上是對MediaPlayer的呼叫。(如:pause()方法是對MediaPlayer的呼叫)
這裡寫圖片描述
3、SurfaceView,預設使用雙緩衝技術,它支援在子執行緒中繪製圖像,這樣就不會阻塞主執行緒了,所以它更適合於遊戲和視訊播放器的開發。

4、實現MediaPlayerControl介面,便於控制面板呼叫VideoView的方法

 public interface MediaPlayerControl {
        void    start();
        void    pause();
        int     getDuration();
        int     getCurrentPosition();
        void    seekTo(int pos);
        boolean isPlaying();
        int     getBufferPercentage();
        boolean canPause();
        boolean canSeekBackward();
        boolean canSeekForward();
        int     getAudioSessionId();
    }

videoview.setMediaController(new MediaController(this));

四、Activity的生命週期和橫豎屏切換的生命週期

Activity的生命週期流程圖
這裡寫圖片描述

1、正常建立一個Activity執行的方法
onCreate-->onStart-->onResume
2、正常銷燬一個Activity執行的方法
onPause-->onStop->onDestroy
3、A頁面跳轉到B頁面,點選返回,這個過程中的生命週期
(1)、B頁面完全覆蓋A頁面的情況
A跳轉B頁面的生命週期方法執行順序:
onPause(A)->onCreate(B)--->onStart(B)--->onResume(B)--->onStop(A)
B頁面點選後返回生命週期執行順序:
onPause(B)-->onRestart(A)-->onStart(A)-->onResume(A)->onStop(B)-->onDestroy(B)
(2)、B頁面不完全覆蓋A頁面的請求
A跳轉B頁面的生命週期方法執行順序
onPause(A)-->onCreate(B)-->onStart(B)-->onResume(B)
B頁面點選後返回生命週期執行順序
onPause(B)-->onResume(A)-->->onStop(B)-->onDestroy(B)
4、Activity橫豎屏切換的生命週期
(1)、預設情況,螢幕橫豎屏切換會讓Activity的生命週期重新執行:
onPause-->onStop-->onDestroy-->onCreate-->onStart-->onResume
(2)、在Manifest檔案中,相應的Activity配置如下,不會讓生命週期重新執行:
onPause-->onStop-->onDestroy

<activity android:name=".activity.VideoActivity"
        android:configChanges="keyboardHidden|screenSize|orientation"
        />

五、總結

1、其實想用VideoView播放視訊很簡單,只需要在佈局檔案裡,定義一個VideoView,然後在Activity中獲取到,設定播放地址,併為VideoView繫結幾個監聽器,就可以進行對視訊的播放了。
2、對於播放視訊的地址,可以分為:

 - 本地資源(我理解為只屬於這個應用的)
 - Internal URIs, 比如可以通過 Content Resolver 獲得的
 - External URLs (流媒體)

3、下圖為使用VideoView自帶的控制面板播放網路視訊的示意圖(自帶的控制面板看著有點醜哦):
這裡寫圖片描述