基本用法
1.开一个线程完成耗时操作
new Thread(){ public void run(){ initPlayer(i); } }.start();
开启MediaPlayer的时候,由于需要调用底层native方法做硬件初始化,所以直接把初始化方法放到线程中
2.开启操作
-
注意holder的创建,需要底层native函数反应,是异步事件
-
player本身准备也要调用native函数,是异步事件
异步事件必须等待处理完毕后再使用相关方法,否则容易出现播不出来(黑屏)的现象
private void initPlayer(int i){ isTimeOut = false; //最好延时一下 try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } if(i >= videoPath.length){ return ; } if(TextUtils.isEmpty(videoPath[i])){ return; } try { //由于这个方法需要反复调用,每次reset复位 player.reset(); //设置要播放的资源 player.setDataSource(videoPath[i]); //准备播放 player.prepareAsync(); //获取一个holder, 内部应该是个异步事件,不能当下获取holder final SurfaceHolder holder = sfv.getHolder(); holder.addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { } @Override public void surfaceCreated(SurfaceHolder holder) { } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } }); //******创建holder完延时一下 SystemClock.sleep(40); //此处如果直接设置holder,可能会导致异常,结果是没有办法载入画面 //player.setDisplay(holder); //等待底层工作完毕后 开始播放 player.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { if(isTimeOut == false){ //******硬件初始化完毕后******* //******最后再设置holder****** player.setDisplay(holder); //******开始播放********* player.start(); currentPosition = 0; //重置播放位置 ThreadUtils.runUIThread(new Runnable(){ @Override public void run() { pb_wait.setVisibility(View.GONE); //加载完毕后让View消失 } }); } } }); } catch (Exception e) { e.printStackTrace(); } }
3.暂停&继续
暂停
//计算当前进度条所在位置 currentPosition = player.getCurrentPosition(); int totle = player.getDuration(); sb_prograss.setProgress((int)((((float)currentPosition)/totle)*100)); //将当前进度赋值给进度条 //System.out.println("**********stop********"+currentPosition+"*********************"); player.pause();
继续
player.seekTo(currentPosition); player.start();
4.释放资源
player.stop(); player.release(); player = null; //最好把player置位为null