天天看點

Android--使用VideoView播放視訊

承香墨影

前言

  之前有講過如何使用SurfaceView配合MediaPlayer播放視訊,其實Android還為開發人員提供了另外一種更簡單的播 放視訊媒體的方式,那就是VideoView,本篇部落格就來講講VideoView如何播放視訊,最後将以一個簡單的Demo示範。

  本篇部落格的主要内容如下:

VideoView

VideoView簡單的Demo

MediaController

MediaController簡單的Demo

  VideoView,用于播放一段視訊媒體,它繼承了SurfaceView,位于"android.widget.VideoView",是一個視訊控件。

  既然是播放一段視訊,那麼不可避免的要涉及到一些開始、暫停、停止等操作,VideoView也為開發人員提供了對應的方法,這裡簡單介紹一些常用的:

int getCurrentPosition():擷取目前播放的位置。

int getDuration():擷取目前播放視訊的總長度。

isPlaying():目前VideoView是否在播放視訊。

void pause():暫停

void seekTo(int msec):從第幾毫秒開始播放。

void resume():重新播放。

void setVideoPath(String path):以檔案路徑的方式設定VideoView播放的視訊源。

void setVideoURI(Uri uri):以Uri的方式設定VideoView播放的視訊源,可以是網絡Uri或本地Uri。

void start():開始播放。

void stopPlayback():停止播放。

setMediaController(MediaController controller):設定MediaController控制器。

setOnCompletionListener(MediaPlayer.onCompletionListener l):監聽播放完成的事件。

setOnErrorListener(MediaPlayer.OnErrorListener l):監聽播放發生錯誤時候的事件。

setOnPreparedListener(MediaPlayer.OnPreparedListener l)::監聽視訊裝載完成的事件。

  上面的一些方法通過方法名就可以了解用途。和MediaPlayer配合SurfaceView播放視訊不同,VideoView播放之前無需編碼裝載視訊,它會在start()開始播放的時候自動裝載視訊。并且VideoView在使用完之後,無需編碼回收資源。

  VideoView其實沒有什麼難點,通過它自帶的API方法,即可完成一段視訊的播放,無非就是注意它方法的調用時機即可。下面通過一個 簡單的Demo,示範VideoView如何播放一段SD卡上的視訊檔案。在Demo中提供了四個Button,分别表示播放、暫停、重播、停止,并配合 進度條顯示。代碼注釋比較完整,細節部分這裡不再累述。

  布局代碼:activity_videoview.xml

 View Code

  實作代碼:VideoViewActivity.java

複制代碼

  1 package cn.bgxt.videoviewdemo;

  2 

  3 import java.io.File;

  4 

  5 import android.app.Activity;

  6 import android.media.MediaPlayer;

  7 import android.media.MediaPlayer.OnCompletionListener;

  8 import android.media.MediaPlayer.OnErrorListener;

  9 import android.os.Bundle;

 10 import android.util.Log;

 11 import android.view.View;

 12 import android.widget.Button;

 13 import android.widget.EditText;

 14 import android.widget.SeekBar;

 15 import android.widget.Toast;

 16 import android.widget.VideoView;

 17 import android.widget.SeekBar.OnSeekBarChangeListener;

 18 

 19 public class VideoViewActivity extends Activity {

 20     private final String TAG = "main";

 21     private EditText et_path;

 22     private Button btn_play, btn_pause, btn_replay, btn_stop;

 23     private SeekBar seekBar;

 24     private VideoView vv_video;

 25     private boolean isPlaying;

 26 

 27     @Override

 28     protected void onCreate(Bundle savedInstanceState) {

 29         // TODO Auto-generated method stub

 30         super.onCreate(savedInstanceState);

 31         setContentView(R.layout.activity_videoview);

 32 

 33         seekBar = (SeekBar) findViewById(R.id.seekBar);

 34         et_path = (EditText) findViewById(R.id.et_path);

 35         vv_video = (VideoView) findViewById(R.id.vv_videoview);

 36 

 37         btn_play = (Button) findViewById(R.id.btn_play);

 38         btn_pause = (Button) findViewById(R.id.btn_pause);

 39         btn_replay = (Button) findViewById(R.id.btn_replay);

 40         btn_stop = (Button) findViewById(R.id.btn_stop);

 41 

 42         btn_play.setOnClickListener(click);

 43         btn_pause.setOnClickListener(click);

 44         btn_replay.setOnClickListener(click);

 45         btn_stop.setOnClickListener(click);

 46 

 47         // 為進度條添加進度更改事件

 48         seekBar.setOnSeekBarChangeListener(change);

 49     }

 50 

 51     private OnSeekBarChangeListener change = new OnSeekBarChangeListener() {

 52 

 53         @Override

 54         public void onStopTrackingTouch(SeekBar seekBar) {

 55             // 當進度條停止修改的時候觸發

 56             // 取得目前進度條的刻度

 57             int progress = seekBar.getProgress();

 58             if (vv_video != null && vv_video.isPlaying()) {

 59                 // 設定目前播放的位置

 60                 vv_video.seekTo(progress);

 61             }

 62         }

 63 

 64         @Override

 65         public void onStartTrackingTouch(SeekBar seekBar) {

 66 

 67         }

 68 

 69         @Override

 70         public void onProgressChanged(SeekBar seekBar, int progress,

 71                 boolean fromUser) {

 72 

 73         }

 74     };

 75     private View.OnClickListener click = new View.OnClickListener() {

 76 

 77         @Override

 78         public void onClick(View v) {

 79 

 80             switch (v.getId()) {

 81             case R.id.btn_play:

 82                 play(0);

 83                 break;

 84             case R.id.btn_pause:

 85                 pause();

 86                 break;

 87             case R.id.btn_replay:

 88                 replay();

 89                 break;

 90             case R.id.btn_stop:

 91                 stop();

 92                 break;

 93             default:

 94                 break;

 95             }

 96         }

 97     };

 98 

 99     protected void play(int msec) {

100         Log.i(TAG, " 擷取視訊檔案位址");

101         String path = et_path.getText().toString().trim();

102         File file = new File(path);

103         if (!file.exists()) {

104             Toast.makeText(this, "視訊檔案路徑錯誤", 0).show();

105             return;

106         }

107         

108         Log.i(TAG, "指定視訊源路徑");

109         vv_video.setVideoPath(file.getAbsolutePath());

110         Log.i(TAG, "開始播放");

111         vv_video.start();

112         

113         // 按照初始位置播放

114         vv_video.seekTo(msec);

115         // 設定進度條的最大進度為視訊流的最大播放時長

116         seekBar.setMax(vv_video.getDuration());

117 

118         // 開始線程,更新進度條的刻度

119         new Thread() {

120 

121             @Override

122             public void run() {

123                 try {

124                     isPlaying = true;

125                     while (isPlaying) {

126                         // 如果正在播放,沒0.5.毫秒更新一次進度條

127                         int current = vv_video.getCurrentPosition();

128                         seekBar.setProgress(current);

129 

130                         sleep(500);

131                     }

132                 } catch (Exception e) {

133                     e.printStackTrace();

134                 }

135             }

136         }.start();

137         // 播放之後設定播放按鈕不可用

138         btn_play.setEnabled(false);

139 

140         vv_video.setOnCompletionListener(new OnCompletionListener() {

141 

142             @Override

143             public void onCompletion(MediaPlayer mp) {

144                 // 在播放完畢被回調

145                 btn_play.setEnabled(true);

146             }

147         });

148 

149         vv_video.setOnErrorListener(new OnErrorListener() {

150 

151             @Override

152             public boolean onError(MediaPlayer mp, int what, int extra) {

153                 // 發生錯誤重新播放

154                 play(0);

155                 isPlaying = false;

156                 return false;

157             }

158         });

159     }

160 

161     /**

162      * 重新開始播放

163      */

164     protected void replay() {

165         if (vv_video != null && vv_video.isPlaying()) {

166             vv_video.seekTo(0);

167             Toast.makeText(this, "重新播放", 0).show();

168             btn_pause.setText("暫停");

169             return;

170         }

171         isPlaying = false;

172         play(0);

173 

174     }

175 

176     /**

177      * 暫停或繼續

178      */

179     protected void pause() {

180         if (btn_pause.getText().toString().trim().equals("繼續")) {

181             btn_pause.setText("暫停");

182             vv_video.start();

183             Toast.makeText(this, "繼續播放", 0).show();

184             return;

185         }

186         if (vv_video != null && vv_video.isPlaying()) {

187             vv_video.pause();

188             btn_pause.setText("繼續");

189             Toast.makeText(this, "暫停播放", 0).show();

190         }

191     }

192 

193     /*

194      * 停止播放

195      */

196     protected void stop() {

197         if (vv_video != null && vv_video.isPlaying()) {

198             vv_video.stopPlayback();

199             btn_play.setEnabled(true);

200             isPlaying = false;

201         }

202     }

203 }

  效果展示:

  提到VideoView不得不再說一些MediaController。雖然VideoView為我們提供了友善的API用于播放、暫停、停止等操作,但是還是需要我們編碼完成,但是如果使用了MediaController的話,那麼這些操作都可以省去。

  MediaController可以用于配合VideoView播放一段視訊,它為VideoView提供一個懸浮的操作欄,在操作欄中可 以對VideoView播放的視訊進行控制,預設情況下,會懸浮顯示三秒。它通過MediaController.setMediaPlayer()方法 進行指定需要控制的VideoView,但是僅僅這樣是不夠的,MediaController的控制需要類似于雙向控 制,MediaController指定控制的VideoView,VideoView還需要指定那個MediaController來控制它,這需要使 用VideoView.setMediaController()方法。

  下面介紹一下MediaController的一些常用方法;

boolean isShowing():目前懸浮控制欄是否顯示。

void setPrevNextListeners(View.OnClickListener next,View.OnClickListener prev):設定上一個視訊、下一個視訊的切換事件。

  通過上面的方法可以看出setMediaPlayer()并非指定的是一個VideoView,而是一個 MediaPlayerControl接口,MediaPlayerControl接口内部定義了一些播放相關的播放、暫停、停止等操作,而 VideoView實作了MediaPlayerControl。

  預設情況下,如果不通過setPrevNextListeners()設定切換視訊的監聽器,MediaController是不會顯示這兩個按鈕的。

  上面已經講過MediaController的一些内容,下面通過一個簡單的Demo來示範一下MediaController控制VideoView播放視訊。

  布局代碼:activity_controller.xml

  實作代碼:ControllerActivity.java

 1 package cn.bgxt.videoviewdemo;

 2 

 3 import java.io.File;

 4 

 5 import android.app.Activity;

 6 import android.os.Bundle;

 7 import android.view.View;

 8 import android.view.View.OnClickListener;

 9 import android.widget.MediaController;

10 import android.widget.Toast;

11 import android.widget.VideoView;

12 

13 public class ControllerActivity extends Activity {

14     private VideoView vv_video;

15     private MediaController mController;

16     

17     @Override

18     protected void onCreate(Bundle savedInstanceState) {

19         super.onCreate(savedInstanceState);

20         setContentView(R.layout.activity_controller);

21         vv_video=(VideoView) findViewById(R.id.vv_video);

22         // 執行個體化MediaController

23         mController=new MediaController(this);

24         File file=new File("/sdcard/ykzzldx.mp4");

25         if(file.exists()){

26             // 設定播放視訊源的路徑

27             vv_video.setVideoPath(file.getAbsolutePath());

28             // 為VideoView指定MediaController

29             vv_video.setMediaController(mController);

30             // 為MediaController指定控制的VideoView

31             mController.setMediaPlayer(vv_video);

32             // 增加監聽上一個和下一個的切換事件,預設這兩個按鈕是不顯示的

33             mController.setPrevNextListeners(new OnClickListener() {

34                 

35                 @Override

36                 public void onClick(View v) {                    

37                     Toast.makeText(ControllerActivity.this, "下一個",0).show();

38                 }

39             }, new OnClickListener() {

40                 

41                 @Override

42                 public void onClick(View v) {

43                     Toast.makeText(ControllerActivity.this, "上一個",0).show();

44                 }

45             });

46         }

47     }

48 }

  從上面展示的效果可以看出,MediaController不光為我們增加了控制欄來控制播放、暫停、快進、快退、切換上一視訊、切換下一視訊,還增加了進度條顯示。

http://www.2cto.com/kf/201312/261877.html

    本文轉自 一點點征服   部落格園部落格,原文連結:http://www.cnblogs.com/ldq2016/p/5485306.html,如需轉載請自行聯系原作者

繼續閱讀