android实现视频的播放一般有三种方式,一:调用系统的播放器播放;二:利用VideoView播放;三:利用MediaPlayer和SurfaceView播放,此demo分别实现了这三种方式,其中VideoView的方式还支持播放内部存储raw文件夹下的视频。
demo:下载地址
MainActivity源码(实现前两种方式):
package fk.androiddemo_029;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;
import java.io.File;
public class MainActivity extends Activity implements View.OnClickListener {
Button but1, but2, but3;
String SDCardRoot;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but1 = (Button) findViewById(R.id.but1);
but1.setOnClickListener(this);
but2 = (Button) findViewById(R.id.but2);
but2.setOnClickListener(this);
but3 = (Button) findViewById(R.id.but3);
but3.setOnClickListener(this);
//得到当前外部存储设备的目录
SDCardRoot = Environment.getExternalStorageDirectory().getPath() + File.separator;
//File.separator为文件分隔符”/“,方便之后在目录下创建文件
}
@Override
public void onClick(View view) {
if (view == but1) {//调用系统的默认播放器
Intent intent = new Intent("android.intent.action.VIEW");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Uri uri = Uri.fromFile(new File(SDCardRoot+"test.mp4"));
intent.setDataAndType(uri, "video/mp4");
this.startActivity(intent);
} else if (view == but2) {//VideoView方法
VideoView videoView = (VideoView)this.findViewById(R.id.videoView);
videoView.setMediaController(new MediaController(this));//设置控制面板
//方法一:两SD,一RAW
//Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.test);
//Uri uri = Uri.parse(SDCardRoot+"test.mp4");
//Uri uri = Uri.fromFile(new File(SDCardRoot+"test.mp4"));
//videoView.setVideoURI(uri);
//方法二:一SD,一RAW
videoView.setVideoPath("android.resource://"+getPackageName()+"/"+R.raw.test);
//videoView.setVideoPath(SDCardRoot+"test.mp4");
videoView.start();
videoView.requestFocus();//请求焦点
} else {//MediaPlayer和Surface方法
Intent intent=new Intent(this,VideoSurfaceDemo.class);
intent.putExtra("videoPath",SDCardRoot+"test.mp4");
startActivity(intent);
}
}
}
VideoSurfaceDemo源码(实现第三种方式):
package fk.androiddemo_029;
import android.app.Activity;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
/**
* 该实例中使用MediaPlayer完成播放,同时界面使用SurfaceView来实现
*
* 这里我们实现MediaPlayer中很多状态变化时的监听器
*
* 使用Mediaplayer时,也可以使用MediaController类,但是需要实现MediaController.mediaController接口
* 实现一些控制方法。
*
* 然后,设置controller.setMediaPlayer(),setAnchorView(),setEnabled(),show()就可以了,这里不再实现
* @author Administrator
*/
public class VideoSurfaceDemo extends Activity implements View.OnClickListener {
private SurfaceView surface1;
private Button start, stop, pause;
private MediaPlayer mediaPlayer1;
private int position = 0;
private SeekBar seekBarVideo;
Timer timer;
TimerTask timerTask;
String videoPath="";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_surface);
videoPath=getIntent().getStringExtra("videoPath");
surface1 = (SurfaceView) findViewById(R.id.surface1);
surface1.getHolder().setKeepScreenOn(true);//设置播放时打开屏幕
surface1.getHolder().addCallback(new SurfaceViewLis());//设置监听
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
pause = (Button) findViewById(R.id.pause);
start.setOnClickListener(this);
stop.setOnClickListener(this);
pause.setOnClickListener(this);
seekBarVideo=(SeekBar)findViewById(R.id.seekBar_video);//进度条
seekBarVideo.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
position=seekBar.getProgress();
if (mediaPlayer1!=null&&mediaPlayer1.isPlaying()) {
mediaPlayer1.seekTo(position);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
});
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.start://从新开始播放
if(mediaPlayer1==null) play();
else {
mediaPlayer1.seekTo(0);
mediaPlayer1.start();
}
break;
case R.id.pause://暂停,播放
if(mediaPlayer1!=null) {
if (mediaPlayer1.isPlaying()) mediaPlayer1.pause();
else mediaPlayer1.start();
}
break;
case R.id.stop:
if(mediaPlayer1!=null){//结束
if (mediaPlayer1.isPlaying()) mediaPlayer1.stop();
timer.cancel();//停止TimerTask
timer.purge();//清理cancel的TimerTask
mediaPlayer1.release();// 释放mediaplayer否则的话会占用内存
mediaPlayer1=null;
}
break;
default:
break;
}
}
public void play() {//重新播放函数
mediaPlayer1 = new MediaPlayer();
mediaPlayer1.reset();
mediaPlayer1.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer1.setDisplay(surface1.getHolder());//把视频输出到SurfaceView上
try {
mediaPlayer1.setDataSource(videoPath);//设置数据
mediaPlayer1.prepare();
} catch (IOException e) {
e.printStackTrace();
}
//调整surface宽高,获取视频宽高都要在prepare()后调用,否则返回0
int srceenW=getWindowManager().getDefaultDisplay().getWidth();//屏幕宽
double hwRadio=(double)mediaPlayer1.getVideoHeight()/(double)mediaPlayer1.getVideoWidth();
surface1.getHolder().setFixedSize(srceenW,(int)(hwRadio*srceenW));
int max=mediaPlayer1.getDuration();//返回毫秒,要在prepare()后调用,否则返回-1
seekBarVideo.setMax(max);//设置进度条的最大值
timer=new Timer();//用定时器不停更新进度条
timerTask=new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
seekBarVideo.setProgress(mediaPlayer1.getCurrentPosition());
}
};
timer.schedule(timerTask, 0, 500);//(调用run方法,第一次延时,以后间隔毫秒)
mediaPlayer1.start();//开始播放
}
private class SurfaceViewLis implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (position == 0) play();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {}
}
}
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
VideoView布局:
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
SurfaceView布局:
<SurfaceView
android:id="@+id/surface1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
注意:测试文件存放于项目raw文件夹下,和外部存储的根部录下。
运行截图: