android自定义视频播放器

来源:互联网 发布:家里蹲 知乎 编辑:程序博客网 时间:2024/05/28 19:23

在网上找了很多相关资料,感觉没有自己想要的,最后决定还是自己来写一个吧。

源代码已经放到资源库中,欢迎下载:http://download.csdn.net/detail/luozhi3527/5353003

程序通过surface+mediaplayer来实现,自定义控制台。能播放本地视频和网络视频。

主要实现代码如下:

package com.xluo.mediaplayertest;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.app.ProgressDialog;import android.media.AudioManager;import android.media.MediaPlayer;import android.media.MediaPlayer.OnCompletionListener;import android.media.MediaPlayer.OnErrorListener;import android.media.MediaPlayer.OnInfoListener;import android.media.MediaPlayer.OnPreparedListener;import android.media.MediaPlayer.OnSeekCompleteListener;import android.media.MediaPlayer.OnVideoSizeChangedListener;import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.Display;import android.view.KeyEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.WindowManager;import android.widget.ImageButton;import android.widget.LinearLayout;import android.widget.SeekBar;import android.widget.TextView;import android.widget.Toast;import android.widget.SeekBar.OnSeekBarChangeListener;public class TestVideoPlayer extends Activity implements OnCompletionListener,OnErrorListener,OnInfoListener,OnPreparedListener,OnSeekCompleteListener,OnVideoSizeChangedListener,SurfaceHolder.Callback{    public static final String TAG = "TestVideoPlayer";            private boolean isExit = false;    private int currentMusicPosition; //当前音量String url =null;private Uri uri;private String name;private ImageButton playBtn = null;//播放、暂停private TextView playtime = null;//已播放时间private TextView durationTime = null;//总时间private TextView VideoName = null;private SeekBar seekbar = null;//进度private SeekBar soundBar = null;//音量调节private Handler handler = new Handler(){public void handleMessage(Message msg){super.handleMessage(msg);switch (msg.what) {case 1:if(mediaPlayer!=null)currentPosition = mediaPlayer.getCurrentPosition();seekbar.setProgress(currentPosition);playtime.setText(toTime(currentPosition));handler.sendEmptyMessage(1);break;default:break;}}};//用于进度条private int currentPosition;//当前播放位置private ProgressDialog dialog;  //加载等待框private AudioManager mAudioManager = null;private View video_contrlbar,titlebar;private boolean isControlBarShow = true;    Display currentDisplay;    SurfaceView surfaceView;    SurfaceHolder surfaceHolder;    MediaPlayer mediaPlayer;//使用的是MediaPlayer来播放视频    int ScurrentPosition;  //音量     Timer showController = new Timer();    TimerTask timerTask ;   private Handler fHandler = new Handler(){public void handleMessage(Message msg){super.handleMessage(msg);switch(msg.what){case 1:video_contrlbar.setVisibility(View.GONE);titlebar.setVisibility(View.GONE);isControlBarShow = false;break;default:break;}}};//用于控制台显隐    boolean readyToPlayer = false;        @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);  //设置屏幕常亮        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置满屏        setContentView(R.layout.activity_main);                name = "晴天";        url = "/sdcard/sunny_night.mp4";  //网络视频和本地视频都可以的        Log.d(TAG," url :"+url);                dialog = new ProgressDialog(this);  //设置等待dialog.setMessage("加载中...");dialog.show();//控制台video_contrlbar = (View)findViewById(R.id.video_contrlbar);titlebar = (View)findViewById(R.id.video_titlebar);showControlBar();/*时间*/playtime = (TextView)findViewById(R.id.video_playtime);//已经播放的时间durationTime = (TextView)findViewById(R.id.video_duration);//总时间VideoName = (TextView)findViewById(R.id.play_movie_name);VideoName.setText(name);/*播放、暂停、停止按钮设置*/playBtn = (ImageButton)findViewById(R.id.video_playBtn);//开始播放playBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mediaPlayer.isPlaying()){pause();playBtn.setBackgroundResource(R.drawable.video_play_selector);} else{play();playBtn.setBackgroundResource(R.drawable.video_pause_selector);}}});//进度条seekbar = (SeekBar)findViewById(R.id.video_seekbar);seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {if(fromUser)mediaPlayer.seekTo(progress);}});/*音量控制条*/soundBar = (SeekBar)findViewById(R.id.video_sound);soundBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// TODO Auto-generated method stubif (fromUser){int ScurrentPosition = soundBar.getProgress();mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, ScurrentPosition, 0);}}});        surfaceView = (SurfaceView)findViewById(R.id.SurfaceView);          surfaceHolder = surfaceView.getHolder();        surfaceHolder.addCallback(this);        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);                surfaceView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubshowControlBar(); //点击屏幕时,调出控制台;}});                setup();        currentDisplay = getWindowManager().getDefaultDisplay();    }        private void showControlBar(){   //控制台的显隐    video_contrlbar.setVisibility(View.VISIBLE);    titlebar.setVisibility(View.VISIBLE);    isControlBarShow = true;    if(timerTask != null){    timerTask.cancel();    }    timerTask = new TimerTask(){    @Override    public void run() {    // TODO Auto-generated method stub    if(isControlBarShow){    Message msg = fHandler.obtainMessage(1);    fHandler.sendMessage(msg);    }    }                };        showController.schedule(timerTask, 5000);  //5秒后隐藏    }    Runnable contrlShow = new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubvideo_contrlbar.setVisibility(View.GONE);titlebar.setVisibility(View.GONE);isControlBarShow = false;fHandler.postDelayed(contrlShow, 5000);}        };        @Override        public void surfaceChanged(SurfaceHolder holder, int format, int width,                        int height) {                        }                private void loadClip(){    if (mediaPlayer != null) {    mediaPlayer.reset();    mediaPlayer.release();    mediaPlayer = null;    }    mediaPlayer = new MediaPlayer();//创建多媒体对象            mediaPlayer.setOnCompletionListener(this);            mediaPlayer.setOnErrorListener(this);            mediaPlayer.setOnPreparedListener(this);            mediaPlayer.setOnSeekCompleteListener(this);            mediaPlayer.setOnVideoSizeChangedListener(this);                //ListEntity entity = dbDao.find(position);    //Log.d(TAG,"list entity object :"+entity);    //String url = entity.getUrl();    Log.d(TAG,"url :"+url);    uri = Uri.parse(url);    Log.d(TAG,"media url :"+url);        //uri = Uri.withAppendedPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,    //"" + pos);        try {        mediaPlayer.setDataSource(this, uri);            } catch (Exception e) {    e.printStackTrace();    }            }        private void setup(){    loadClip();    try {    mediaPlayer.prepare();    mediaPlayer.setOnPreparedListener(new OnPreparedListener() {        @Override    public void onPrepared(final MediaPlayer mp) {    seekbar.setMax(mp.getDuration());//设置播放进度条最大值    handler.sendEmptyMessage(1);//向handler发送消息,启动播放进度条    playtime.setText(toTime(mp.getCurrentPosition()));//初始化播放时间    durationTime.setText(toTime(mp.getDuration()));//设置时间    mp.seekTo(currentPosition);//初始化MediaPlayer播放位置    /*获得最大音量*/    mAudioManager = (AudioManager) TestVideoPlayer.this.getSystemService(TestVideoPlayer.this.AUDIO_SERVICE);    int maxSound = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_MUSIC );        /*获得当前音量*/    int currentSound = mAudioManager.getStreamVolume( AudioManager.STREAM_MUSIC );        soundBar.setMax(maxSound);    soundBar.setProgress(currentSound);    }    });        } catch (Exception e) {    e.printStackTrace();    }    }        private void play(){    Log.d(TAG,"cancel dialog:"+dialog);    /*  设置视频尺寸  */    int tmpWidth = currentDisplay.getHeight();    int tmpHeight = currentDisplay.getWidth();                surfaceView.setLayoutParams(new LinearLayout.LayoutParams(tmpHeight,tmpWidth*3/4));    if(dialog != null){    dialog.dismiss();    }    mediaPlayer.start();    playBtn.setBackgroundResource(R.drawable.video_pause_selector);    }        private void pause(){    mediaPlayer.pause();    }            public String toTime(int time) {    time /= 1000;    int minute = time / 60;    int hour = minute / 60;    int second = time % 60;    minute %= 60;    return String.format("%02d:%02d:%02d", hour,minute, second);    }            @Override        public void surfaceCreated(SurfaceHolder holder) {        Log.d(TAG,"surafce created");        mediaPlayer.setDisplay(surfaceHolder);//若无次句,将只有声音而无图像       play();        }        @Override        public void surfaceDestroyed(SurfaceHolder holder) {   //surface销毁时结束播放,防止按下home键后仍有声音,但无法播放图像。                if (mediaPlayer != null) {    mediaPlayer.reset();    mediaPlayer.release();    mediaPlayer = null;    }    finish();                        }        @Override        public void onVideoSizeChanged(MediaPlayer arg0, int arg1, int arg2) {                        }        @Override        public void onSeekComplete(MediaPlayer mp) {                        }        @Override        public void onPrepared(MediaPlayer mp) {                       }        @Override        public boolean onInfo(MediaPlayer arg0, int whatInfo, int extra) {                return false;        }        @Override        public boolean onError(MediaPlayer arg0, int arg1, int arg2) {                return false;        }        @Override        public void onCompletion(MediaPlayer arg0) { //播放完后自动退出                finish();        }        public boolean onKeyDown(int keyCode, KeyEvent event) {        switch (keyCode) {    case KeyEvent.KEYCODE_BACK:    exitBy2Click();    break;    case KeyEvent.KEYCODE_VOLUME_DOWN:    //音量键的控制,调出控制台    Log.d(TAG,"to pressed voice down");    showControlBar();    currentMusicPosition = soundBar.getProgress();    currentMusicPosition--;    mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentMusicPosition, 0);    soundBar.setProgress(currentMusicPosition);    break;    case KeyEvent.KEYCODE_VOLUME_UP:    Log.d(TAG,"to pressed voice up");    showControlBar();    currentMusicPosition = soundBar.getProgress();    currentMusicPosition++;    mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentMusicPosition, 0);    soundBar.setProgress(currentMusicPosition);    break;    default:    super.onKeyDown(keyCode, event);      }    return true;    }                private void exitBy2Click(){    Timer tExit = null;    if (isExit == false) {    isExit = true; // 准备退出    Toast.makeText(this, "再按一次退出播放", Toast.LENGTH_SHORT).show();    tExit = new Timer();    tExit.schedule(new TimerTask() {    @Override    public void run() {    isExit = false; // 取消退出    }    }, 2000); // 如果2秒钟内没有按下返回键,则启动定时器取消掉刚才执行的任务    } else {    if (mediaPlayer != null) {    mediaPlayer.release();    mediaPlayer.reset();    mediaPlayer = null;    }    finish();    }    }}

主要代码都有注释,没必要再做解释。

原创粉丝点击