天天看点

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,如需转载请自行联系原作者

继续阅读