分享一个Android上封装好的视频播放类
最近刚好有在安卓上播放网络视频的一个需求,网上搜了一圈之后找到一个小demo,使用之后觉得作者想法不错,但是代码当中有点问题,会有IllegaleState报错。调整了一下,并且加了个支持几种状态变化的interface,在MediaPlayer状态的处理上多做了一些工作,旧的有问题的代码就不放出来了,看看没错的版本吧。可能有看官会觉得做interface来执行这些事件有些多余,视频播放当中很多执行不是立即生效的,有部分操作实际上是类似异步的,因此做这个还是有必要的,保证了MediaPlayer状态不冲突。另外,安卓支持什么格式,这个就支持什么格式,没有额外的解码功能。
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.ProgressBar;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by chenzhidong on 15-3-15.
*/
public class Player implements MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnSeekCompleteListener, SurfaceHolder.Callback {
private int videoWidth;
private int videoHeight;
public MediaPlayer mediaPlayer;
private SurfaceHolder surfaceHolder;
private ProgressBar skbProgress;
private Timer mTimer = new Timer();
public long pos = 0;
public int seek = 0;
private PlayerListener listener;
public Player(SurfaceView surfaceView, ProgressBar skbProgress, PlayerListener listener) {
this.listener = listener;
this.skbProgress = skbProgress;
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mTimer.schedule(mTimerTask, 0, 1000);
}
TimerTask mTimerTask = new TimerTask() {
@Override
public void run() {
if (mediaPlayer == null)
{
return;
}
if (mediaPlayer.isPlaying() && skbProgress.isPressed() == false)
{
handleProgress.sendEmptyMessage(0);
}
}
};
Handler handleProgress = new Handler() {
public void handleMessage(Message msg) {
int position = mediaPlayer.getCurrentPosition()/1000;
int duration = mediaPlayer.getDuration()/1000;
if (duration > 0)
{
pos = skbProgress.getMax() * position / duration;
skbProgress.setProgress((int)pos);
}
if (listener != null)
{
listener.onPlayProgressChangeListener(position, duration);
}
}
;
};
public void play() {
if (mediaPlayer != null && !mediaPlayer.isPlaying())
{
mediaPlayer.start();
if(listener!=null)
listener.onStartListener(mediaPlayer.getCurrentPosition());
}
}
public void playUrl(String videoUrl) {
if (mediaPlayer != null)
{
try
{
mediaPlayer.reset();
mediaPlayer.setDataSource(videoUrl);
mediaPlayer.prepareAsync();//prepare之后自动播放
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (IllegalStateException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
public void playUrl(String videoUrl, int seek) {
if (mediaPlayer != null)
{
try
{
mediaPlayer.reset();
mediaPlayer.setDataSource(videoUrl);
mediaPlayer.prepareAsync();
this.seek = seek*1000;
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (IllegalStateException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
public void pause() {
if (mediaPlayer != null && mediaPlayer.isPlaying())
{
mediaPlayer.pause();
if (listener != null)
{
listener.onPauseListener(mediaPlayer.getCurrentPosition()/1000);
}
}
}
public void stop() {
if (mediaPlayer != null && mediaPlayer.isPlaying())
{
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
if (listener != null)
{
listener.onStopListener();
}
}
}
public void seek(int seekTo){
if(mediaPlayer!=null)
{
if(!mediaPlayer.isPlaying())
mediaPlayer.start();
mediaPlayer.seekTo(seekTo*1000);
}
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
if (mediaPlayer != null)
{
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(surfaceHolder);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(false);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnSeekCompleteListener(this);
if(listener!=null)
{
listener.onInited();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
if (mediaPlayer != null)
{
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}
}
@Override
public void onPrepared(MediaPlayer arg0) {
videoWidth = mediaPlayer.getVideoWidth();
videoHeight = mediaPlayer.getVideoHeight();
if (videoHeight != 0 && videoWidth != 0)
{
arg0.start();
if (seek > 0)
{
arg0.seekTo(seek);
}
if (listener != null)
{
listener.onStartListener(arg0.getCurrentPosition());
}
}
}
@Override
public void onCompletion(MediaPlayer arg0) {
mTimerTask.cancel();
mTimer.cancel();
if (mediaPlayer != null)
{
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
listener.onCompleteListener();
}
}
@Override
public void onBufferingUpdate(MediaPlayer arg0, int bufferingProgress) {
skbProgress.setSecondaryProgress(bufferingProgress);
//int currentProgress = skbProgress.getMax() * mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration();
//Log.e(currentProgress + "% play", bufferingProgress + "% buffer");
if (listener != null)
{
listener.onLoadProgressChangeListener(bufferingProgress);
}
}
@Override
public void onSeekComplete(MediaPlayer mediaPlayer) {
if(mediaPlayer!=null)
{
if (listener != null)
{
listener.onSeekListener(mediaPlayer.getCurrentPosition());
}
}
}
public interface PlayerListener {
abstract public void onPlayProgressChangeListener(int current, int max);
abstract public void onLoadProgressChangeListener(int percent);
abstract public void onCompleteListener();
abstract public void onStartListener(int start);
abstract public void onPauseListener(int position);
abstract public void onStopListener();
abstract public void onSeekListener(int seekto);
abstract public void onInited();
}
}
以上是播放的类,调用的过程很简单,将布局中的surfaceview和progressbar以及listener作为参数传给new出来的Player,如下:
SurfaceView view_video=(SurfaceView)findViewById(R.id.activity_play_video);
ProgressBar view_progress=(ProgressBar)findViewById(R.id.activity_play_progress);
Player player=new Player(view_video,view_progress,new Player.PlayerListener() {
@Override
public void onPlayProgressChangeListener(int current, int max) {
Log.v("Pull","playing: "+current+":"+max);
}
@Override
public void onLoadProgressChangeListener(int percent) {
Log.v("Pull","loading: "+percent+"%");
}
@Override
public void onCompleteListener() {
Log.v("Pull","finish playing video");
}
@Override
public void onStartListener(int start) {
Log.v("Pull","started");
}
@Override
public void onPauseListener(int position) {
Log.v("Pull","paused");
}
@Override
public void onStopListener() {
Log.v("Pull","stoped");
}
@Override
public void onSeekListener(int seekto) {
Log.v("Pull","jump to: "+seekto);
}
@Override
public void onInited() {
//player.playUrl("http://url"); //从头播放
//player.playUrl("http://url",123); //从123秒处开始播放
}
});
当然此处的ProgressBar
也可以换成SeekBar
,这样就支持拖动了,只要在拖动之后调用player的seek函数即可。
That's all.
相关文章
上一篇: 各种磁盘RAID简明介绍下一篇: MySQL_Binlog_Table_Filter