转载:http://www.bdqn.cn/news/201311/12100.shtml

使用VideoView播放视频

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简单的Demo

VideoView其实没有什么难点,通过它自带的API方法,即可完成一段视频的播放,无非就是注意它方法的调用时机即可。下面通过一个简单的Demo,演示VideoView如何播放一段SD卡上的视频文件。在Demo中提供了四个Button,分别表示播放、暂停、重播、停止,并配合进度条显示。代码注释比较完整,细节部分这里不再累述。

布局代码:activity_videoview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <EditText
android:id="@+id/et_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="/sdcard/ykzzldx.mp4" /> <SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" > <Button
android:id="@+id/btn_play"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="播放" /> <Button
android:id="@+id/btn_pause"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="暂停" /> <Button
android:id="@+id/btn_replay"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="重播" /> <Button
android:id="@+id/btn_stop"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停止" />
</LinearLayout> <VideoView
android:id="@+id/vv_videoview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" /> </LinearLayout>

实现代码:VideoViewActivity.java

package cn.bgxt.videoviewdemo;

import java.io.File;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.Toast;
import android.widget.VideoView;
import android.widget.SeekBar.OnSeekBarChangeListener; public class VideoViewActivity extends Activity {
private final String TAG = "main";
private EditText et_path;
private Button btn_play, btn_pause, btn_replay, btn_stop;
private SeekBar seekBar;
private VideoView vv_video;
private boolean isPlaying; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_videoview); seekBar = (SeekBar) findViewById(R.id.seekBar);
et_path = (EditText) findViewById(R.id.et_path);
vv_video = (VideoView) findViewById(R.id.vv_videoview); btn_play = (Button) findViewById(R.id.btn_play);
btn_pause = (Button) findViewById(R.id.btn_pause);
btn_replay = (Button) findViewById(R.id.btn_replay);
btn_stop = (Button) findViewById(R.id.btn_stop); btn_play.setOnClickListener(click);
btn_pause.setOnClickListener(click);
btn_replay.setOnClickListener(click);
btn_stop.setOnClickListener(click); // 为进度条添加进度更改事件
seekBar.setOnSeekBarChangeListener(change);
} private OnSeekBarChangeListener change = new OnSeekBarChangeListener() { @Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 当进度条停止修改的时候触发
// 取得当前进度条的刻度
int progress = seekBar.getProgress();
if (vv_video != null && vv_video.isPlaying()) {
// 设置当前播放的位置
vv_video.seekTo(progress);
}
} @Override
public void onStartTrackingTouch(SeekBar seekBar) { } @Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) { }
};
private View.OnClickListener click = new View.OnClickListener() { @Override
public void onClick(View v) { switch (v.getId()) {
case R.id.btn_play:
play(0);
break;
case R.id.btn_pause:
pause();
break;
case R.id.btn_replay:
replay();
break;
case R.id.btn_stop:
stop();
break;
default:
break;
}
}
}; protected void play(int msec) {
Log.i(TAG, " 获取视频文件地址");
String path = et_path.getText().toString().trim();
File file = new File(path);
if (!file.exists()) {
Toast.makeText(this, "视频文件路径错误", 0).show();
return;
} Log.i(TAG, "指定视频源路径");
vv_video.setVideoPath(file.getAbsolutePath());
Log.i(TAG, "开始播放");
vv_video.start(); // 按照初始位置播放
vv_video.seekTo(msec);
// 设置进度条的最大进度为视频流的最大播放时长
seekBar.setMax(vv_video.getDuration()); // 开始线程,更新进度条的刻度
new Thread() { @Override
public void run() {
try {
isPlaying = true;
while (isPlaying) {
// 如果正在播放,没0.5.毫秒更新一次进度条
int current = vv_video.getCurrentPosition();
seekBar.setProgress(current); sleep(500);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
// 播放之后设置播放按钮不可用
btn_play.setEnabled(false); vv_video.setOnCompletionListener(new OnCompletionListener() { @Override
public void onCompletion(MediaPlayer mp) {
// 在播放完毕被回调
btn_play.setEnabled(true);
}
}); vv_video.setOnErrorListener(new OnErrorListener() { @Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// 发生错误重新播放
play(0);
isPlaying = false;
return false;
}
});
} /**
* 重新开始播放
*/
protected void replay() {
if (vv_video != null && vv_video.isPlaying()) {
vv_video.seekTo(0);
Toast.makeText(this, "重新播放", 0).show();
btn_pause.setText("暂停");
return;
}
isPlaying = false;
play(0); } /**
* 暂停或继续
*/
protected void pause() {
if (btn_pause.getText().toString().trim().equals("继续")) {
btn_pause.setText("暂停");
vv_video.start();
Toast.makeText(this, "继续播放", 0).show();
return;
}
if (vv_video != null && vv_video.isPlaying()) {
vv_video.pause();
btn_pause.setText("继续");
Toast.makeText(this, "暂停播放", 0).show();
}
} /*
* 停止播放
*/
protected void stop() {
if (vv_video != null && vv_video.isPlaying()) {
vv_video.stopPlayback();
btn_play.setEnabled(true);
isPlaying = false;
}
}
}

效果展示:

  

  

MediaController

提到VideoView不得不再说一些MediaController。虽然VideoView为我们提供了方便的API用于播放、暂停、停止等操作,但是还是需要我们编码完成,但是如果使用了MediaController的话,那么这些操作都可以省去。

MediaController可以用于配合VideoView播放一段视频,它为VideoView提供一个悬浮的操作栏,在操作栏中可以对 VideoView播放的视频进行控制,默认情况下,会悬浮显示三秒。它通过MediaController.setMediaPlayer()方法进行指定需要控制的VideoView,但是仅仅这样是不够的,MediaController的控制需要类似于双向控制,MediaController指定控制的VideoView,VideoView还需要指定那个MediaController来控制它,这需要使用 VideoView.setMediaController()方法。

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

boolean isShowing():当前悬浮控制栏是否显示。

void setMediaPlayer(MediaController.MediaPlayerControl player):设置控制的组件。

void setPrevNextListeners(View.OnClickListener next,View.OnClickListener prev):设置上一个视频、下一个视频的切换事件。

通过上面的方法可以看出setMediaPlayer()并非指定的是一个VideoView,而是一个MediaPlayerControl 接口,MediaPlayerControl接口内部定义了一些播放相关的播放、暂停、停止等操作,而VideoView实现了 MediaPlayerControl。

默认情况下,如果不通过setPrevNextListeners()设置切换视频的监听器,MediaController是不会显示这两个按钮的。

MediaController简单的Demo

上面已经讲过MediaController的一些内容,下面通过一个简单的Demo来演示一下MediaController控制VideoView播放视频。

布局代码:activity_controller.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <VideoView
android:id="@+id/vv_video"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

实现代码:ControllerActivity.java

package cn.bgxt.videoviewdemo;

import java.io.File;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView; public class ControllerActivity extends Activity {
private VideoView vv_video;
private MediaController mController; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_controller);
vv_video=(VideoView) findViewById(R.id.vv_video);
// 实例化MediaController
mController=new MediaController(this);
File file=new File("/sdcard/ykzzldx.mp4");
if(file.exists()){
// 设置播放视频源的路径
vv_video.setVideoPath(file.getAbsolutePath());
// 为VideoView指定MediaController
vv_video.setMediaController(mController);
// 为MediaController指定控制的VideoView
mController.setMediaPlayer(vv_video);
// 增加监听上一个和下一个的切换事件,默认这两个按钮是不显示的
mController.setPrevNextListeners(new OnClickListener() { @Override
public void onClick(View v) {
Toast.makeText(ControllerActivity.this, "下一个",0).show();
}
}, new OnClickListener() { @Override
public void onClick(View v) {
Toast.makeText(ControllerActivity.this, "上一个",0).show();
}
});
}
}
}

效果展示:

  

从上面展示的效果可以看出,MediaController不光为我们增加了控制栏来控制播放、暂停、快进、快退、切换上一视频、切换下一视频,还增加了进度条显示。

总结

本篇博客就讲解了VideoView和MediaController的内容。虽然使用MediaController非常的方便,基本上所有的操作都帮我们封装好了,但是封装即表示不够灵活,必须按照既定的规则去实现。所以一般专业的视频播放应用,还是会使用SurfaceView去完成。

Android实现播放视频的更多相关文章

  1. [转]Android WebView播放视频(包括全屏播放),androidwebview

    Android WebView播放视频(包括全屏播放),androidwebview 最近项目开发中用到了WebView播放视频的功能,总结了开发中犯过的错误,这些错误在开发是及容易遇到的,所以我这里 ...

  2. Android VideoView播放视频

    今天介绍一下Android的视频播放控件VideoView,下面介绍一下VideoView的使用步骤: 1.在界面布局中定义VideoView组件,或者在程序中创建VideoView组件. 2.调用V ...

  3. 【转】Android WebView 播放视频总结

    今天发现 WebView里播放优酷的视频点击播放按钮后没反应,于是看官方文档和搜索解决,下面是我在别人基础上做的补充:   android webView 无法播放视频,无法暂停,继续播放视频问题,无 ...

  4. Android OpenGL 播放视频学习

    1, 初步接触Open GL: http://www.cnblogs.com/TerryBlog/archive/2010/07/09/1774475.html 使用GLSurfaceView和Ren ...

  5. Android WebView播放视频flash(判断是否安装flash插件)

    Android WebView播放flash(判断是否安装flash插件)  最近帮一个同学做一个项目,断断续续的一些知识点记录一下.一个页面中有一个WebView,用来播放swf,如果系统中未安装f ...

  6. Android SurfaceView播放视频时横竖屏的调整

    对于横屏录制的视频就横屏播放,对于竖屏录制的视频就竖屏播放. 在mainifest文件里对负责播放的Activity添加以下属性“ android:configChanges="orient ...

  7. 微信Android自动播放视频(可交互,设置层级,无控制条,非X5)ffmpeg,jsmpeg.js,.ts视频

    原料: ffmpeg : http://ffmpeg.zeranoe.com/builds/  win64 https://evermeet.cx/ffmpeg/   mac OS X 64 jsmp ...

  8. android中使用surfaceview+MediaPlayer播放视频

    Android中播放视频主要有两种方式: 使用其自带的播放器.指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型 使用android自带的VideoView,这种方法 ...

  9. 手机浏览器自动播放视频video(设置autoplay无效)的解决方案

    1.问题的提出 某一天接了个需求,需要在手机的H5页面内加入视频,我开开心心做完,准备交付的时候,问题来了,PM想要用户一进入页面,视频就开始播放,不需要用户手动点击. 2.尝试解决 加autopla ...

随机推荐

  1. js与多行字符串

    JS里并没有标准的多行字符串的表示方法,但是在用模板的时候,为了保证模板的可阅读性,我们又不可避免的使用多行字符串,所以出现了各种搞法,这里以一段jade的模板作为示例,简单总结和对比一下. 字符串相 ...

  2. Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    去空格及特殊符号 s.strip().lstrip().rstrip(',') 复制字符串 #strcpy(sStr1,sStr2) sStr1 = 'strcpy' sStr2 = sStr1 sS ...

  3. linux opensuse 程序中上传文件大小限制

    上传文件大小限制 修改nginx主配置文件 /etc/nginx/nginx.conf增加配置 client_max_body_size 40m;  (说明:这里40m是最大支持上传40兆)

  4. js通过注册表找到本地软件安装路径并且执行

    场景:用js执行本地的安装软件,如果不存在就执行安装 操作步骤: 1.前台js代码 <script type="text/javascript"> function e ...

  5. 转载一些Android性能优化建议

    首先给出原文链接,感谢大神的经验分享:http://www.jointforce.com/jfperiodical/article/3553?utm_source=tuicool&utm_me ...

  6. 【实战Java高并发程序设计6】挑战无锁算法:无锁的Vector实现

    [实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...

  7. poj3750-小孩报数问题(约瑟夫环)

    一,题意: 中文题.二,思路: 1,输入. 2,无限循环1~n~1~n,直到输出n次,再跳出. 3,输出名字,并标记. 普通模拟版: #include<iostream> #include ...

  8. XMPP iOS客户端实现二:xcode项目配置

    1.下载XMPPFramework,下载地址:https://github.com/robbiehanson/XMPPFramework 2.创建项目并将XMPP库引入: 3.添加需要的库文件: 4. ...

  9. 解读ASP.NET 5 & MVC6系列(4):核心技术与环境配置

    asp.net 5是下一代的asp.net,该版本进行了全部重写以适用于跨平台,新新版本中,微软引入了如下工具与命令:DNVM.DNX.DNU. DNVM(.NET Version Manager): ...

  10. 剑指Offer面试题:21.从上到下打印二叉树

    一.题目:从上到下打印二叉树 题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印.例如输入下图中的二叉树,则依次打印出8.6.10.5.7.9.11. 二叉树节点的定义如下,采用 ...