vitamio视频播放器

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 11:18   790   0

视频功能:

1、视频播放的控制台,进度条,播放、暂停按钮、播放时长,返回按钮,播放影片的名称

2、调节音量

3、调节亮度

4、拖动屏幕来进行视频的快进跟快退

5、视频在横竖屏切换的时候的显示(注:动态改变vidwoView的高度能解决切换的时候自适应的问题)

开发的资料:

1、首先要有vitamio的library,这里是我修改过的一个 :http://download.csdn.net/detail/u012808234/8959989

2、然后就是一个vitamio的api文档,网上直接搜就好了;

然后就是真正的开发了

首先新建一个项目 :Vitamio_Demo, 然后就是把vitamio的library导入。
(1)在第一次进入的时候一定要对vitamio进行初始化及检查,
  1. newAsyncTask<Object,Object,Object>(){
  2. @Override
  3. protectedObjectdoInBackground(Object...params){
  4. Vitamio.initialize(getApplicationContext());
  5. if(Vitamio.isInitialized(getApplicationContext()))
  6. returnnull;
  7. //反射解压
  8. try{
  9. Classc=Class.forName("io.vov.vitamio.Vitamio");
  10. MethodextractLibs=c.getDeclaredMethod("extractLibs",newClass[]{android.content.Context.class,int.class});
  11. extractLibs.setAccessible(true);
  12. extractLibs.invoke(c,newObject[]{getApplicationContext(),R.raw.libarm});
  13. //FieldvitamioLibraryPath=c.getDeclaredField("vitamioLibraryPath");
  14. //
  15. //AndroidContextUtils.getDataDir(ctx)+"libs/"
  16. }catch(NoSuchMethodExceptione){
  17. Log.e("extractLibs",e.toString());
  18. e.printStackTrace();
  19. }catch(IllegalArgumentExceptione){
  20. e.printStackTrace();
  21. }catch(IllegalAccessExceptione){
  22. e.printStackTrace();
  23. }catch(InvocationTargetExceptione){
  24. e.printStackTrace();
  25. }catch(ClassNotFoundExceptione){
  26. e.printStackTrace();
  27. }
  28. returnnull;
  29. }
  30. }.execute();
new AsyncTask<Object, Object, Object>() {
   @Override
   protected Object doInBackground(Object... params) {

    Vitamio.initialize(getApplicationContext());
    if (Vitamio.isInitialized(getApplicationContext()))
     return null;

    //反射解压
    try {
     Class c = Class.forName("io.vov.vitamio.Vitamio");
     Method extractLibs = c.getDeclaredMethod("extractLibs", new Class[] { android.content.Context.class, int.class });
     extractLibs.setAccessible(true);
     extractLibs.invoke(c, new Object[] { getApplicationContext(), R.raw.libarm });
     
//     Field vitamioLibraryPath = c.getDeclaredField("vitamioLibraryPath");
//
//      AndroidContextUtils.getDataDir(ctx) + "libs/"
     
    } catch (NoSuchMethodException e) {
     Log.e("extractLibs", e.toString());
     e.printStackTrace();
    } catch (IllegalArgumentException e) {
     e.printStackTrace();
    } catch (IllegalAccessException e) {
     e.printStackTrace();
    } catch (InvocationTargetException e) {
     e.printStackTrace();
    } catch (ClassNotFoundException e) {
     e.printStackTrace();
    }
    return null;
   }
  }.execute();

(2) 实现一堆接口:OnClickListener, OnCompletionListener, OnInfoListener,
OnPreparedListener, OnErrorListener, OnBufferingUpdateListener, OnSeekCompleteListener

  1. privatevoidstopPlayer(){
  2. if(mVideoView!=null)
  3. mVideoView.pause();
  4. }
  5. privatevoidstartPlayer(){
  6. if(mVideoView!=null)
  7. mVideoView.start();
  8. }
  9. privatebooleanisPlaying(){
  10. returnmVideoView!=null&&mVideoView.isPlaying();
  11. }
  12. /**是否?自动恢复播放,用于自动暂停,恢复播放*/
  13. privatebooleanneedResume;
  14. @Override
  15. publicbooleanonInfo(MediaPlayerarg0,intarg1,intarg2){
  16. switch(arg1){
  17. caseMediaPlayer.MEDIA_INFO_BUFFERING_START:
  18. //?缓存,暂停播?
  19. if(isPlaying()){
  20. stopPlayer();
  21. needResume=true;
  22. }
  23. mLoadingView.setVisibility(View.VISIBLE);
  24. break;
  25. caseMediaPlayer.MEDIA_INFO_BUFFERING_END:
  26. //缓存完成,继续播?
  27. if(needResume){
  28. startPlayer();
  29. }
  30. mLoadingView.setVisibility(View.GONE);
  31. break;
  32. caseMediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
  33. //显示下载速度
  34. break;
  35. }
  36. returntrue;
  37. }
  38. /**
private void stopPlayer() {
  if (mVideoView != null)
   mVideoView.pause();
 }

 private void startPlayer() {
  if (mVideoView != null)
   mVideoView.start();
 }

 private boolean isPlaying() {
  return mVideoView != null && mVideoView.isPlaying();
 }

 /** 是否?自动恢复播放,用于自动暂停,恢复播放 */
 private boolean needResume;

 @Override
 public boolean onInfo(MediaPlayer arg0, int arg1, int arg2) {
  switch (arg1) {
  case MediaPlayer.MEDIA_INFO_BUFFERING_START:
   // ?缓存,暂停播?
   if (isPlaying()) {
    stopPlayer();
    needResume = true;
   }
   mLoadingView.setVisibility(View.VISIBLE);
   break;
  case MediaPlayer.MEDIA_INFO_BUFFERING_END:
   // 缓存完成,继续播?
   if (needResume) {
    startPlayer();
   }
   mLoadingView.setVisibility(View.GONE);
   break;
  case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
   // 显示 下载速度
   break;
  }
  return true;
 }

 /**
  1. *播放完成
  2. */
  3. @Override
  4. publicvoidonCompletion(MediaPlayerarg0){
  5. }
  6. /**
  7. *//在视频预处理完成后调用。在视频预处理完成后被调用。此时视频的宽度、高度、宽高比信息已经获取到,此时可调用seekTo让视频从指定位置开始播放。
  8. */
  9. @Override
  10. publicvoidonPrepared(MediaPlayerarg0){
  11. }
  12. /**
  13. *在异步操作调用过程中发生错误时调用。例如视频打开失败。
  14. */
  15. @Override
  16. publicbooleanonError(MediaPlayerarg0,intarg1,intarg2){
  17. mLoadingView.setVisibility(View.GONE);
  18. mTv_NoPlay.setVisibility(View.VISIBLE);
  19. returnfalse;
  20. }
  21. /**
  22. *在网络视频流缓冲变化时调用。
  23. *
  24. *@paramarg0
  25. *@paramarg1
  26. */
  27. @Override
  28. publicvoidonBufferingUpdate(MediaPlayerarg0,intarg1){
  29. mTv_NoPlay.setVisibility(View.GONE);
  30. mLoadingView.setVisibility(View.VISIBLE);
  31. }
  32. /**
  33. *在seek操作完成后调用。
  34. */
  35. @Override
  36. publicvoidonSeekComplete(MediaPlayerarg0){
  37. }
  38. privateMediaController.PlayControlmPlayControll=newPlayControl(){
  39. @Override
  40. publicvoiddownLoad(){
  41. }
  42. @Override
  43. publicvoidcollect(){
  44. }
  45. };
  46. lt;spanstyle="white-space:pre"></span>//点击开始暂停的回调
  47. privateonPauseListenermPauseListener=newonPauseListener(){
  48. @Override
  49. publicvoidonPause(){
  50. Log.d("pause","pause");
  51. }
  52. @Override
  53. publicvoidonPlay(){
  54. Log.e("onPlay","play");
  55. }
  56. };
  57. @Override
  58. publicvoidonClick(Viewarg0){
  59. //TODOAuto-generatedmethodstub
  60. }
  * 播放完成
  */
 @Override
 public void onCompletion(MediaPlayer arg0) {
 }

 /**
  * //在视频预处理完成后调用。在视频预处理完成后被调用。此时视频的宽度、高度、宽高比信息已经获取到,此时可调用seekTo让视频从指定位置开始播放。
  */
 @Override
 public void onPrepared(MediaPlayer arg0) {
 }

 /**
  * 在异步操作调用过程中发生错误时调用。例如视频打开失败。
  */
 @Override
 public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
  mLoadingView.setVisibility(View.GONE);
  mTv_NoPlay.setVisibility(View.VISIBLE);
  return false;
 }

 /**
  * 在网络视频流缓冲变化时调用。
  * 
  * @param arg0
  * @param arg1
  */
 @Override
 public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
  mTv_NoPlay.setVisibility(View.GONE);
  mLoadingView.setVisibility(View.VISIBLE);
 }

 /**
  * 在seek操作完成后调用。
  */
 @Override
 public void onSeekComplete(MediaPlayer arg0) {
 }

 private MediaController.PlayControl mPlayControll = new PlayControl() {

  @Override
  public void downLoad() {

  }

  @Override
  public void collect() {
  }

 };

<span style="white-space:pre"> </span>//点击开始暂停的回调
 private onPauseListener mPauseListener = new onPauseListener() {

  @Override
  public void onPause() {
   Log.d("pause", "pause");
  }

  @Override
  public void onPlay() {
   Log.e("onPlay", "play");
  }
 };

 @Override
 public void onClick(View arg0) {
  // TODO Auto-generated method stub
  
 }


然后就是实现他们的方法

(3) 然后初始化videoView, 进度条,等等的控件。

  1. if(mPath.startsWith("http:"))
  2. mVideoView.setVideoURI(Uri.parse(mPath));
  3. else
  4. mVideoView.setVideoPath(mPath);
  5. //设置显示名称
  6. mMediaController=newMediaController(MainActivity.this,mVideoView);
  7. mMediaController.setmPlayControl(mPlayControll);
  8. mMediaController.setOnPauseListener(mPauseListener);
  9. mVideoView.setMediaController(mMediaController);
  10. mMediaController.setFileName("哈哈哈");
  11. intmCurrentOrientation=getResources().getConfiguration().orientation;
  12. if(mCurrentOrientation==Configuration.ORIENTATION_PORTRAIT){
  13. Utils.full(false,MainActivity.this);
  14. mRl_PlayView.setLayoutParams(newLinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,400));
  15. if(mVideoView!=null){
  16. mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_STRETCH,0);
  17. }
  18. }elseif(mCurrentOrientation==Configuration.ORIENTATION_LANDSCAPE){
  19. Utils.full(true,MainActivity.this);
  20. mRl_PlayView.setLayoutParams(newLinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
  21. if(mVideoView!=null)
  22. mVideoView.setVideoLayout(mLayout,0);
  23. }
  24. mVideoView.requestFocus();
  if (mPath.startsWith("http:"))
    mVideoView.setVideoURI(Uri.parse(mPath));
   else
    mVideoView.setVideoPath(mPath);
   // 设置显示名称
   mMediaController = new MediaController(MainActivity.this, mVideoView);
   mMediaController.setmPlayControl(mPlayControll);
   mMediaController.setOnPauseListener(mPauseListener);
   mVideoView.setMediaController(mMediaController);
   mMediaController.setFileName("哈哈哈");
   
   int mCurrentOrientation = getResources().getConfiguration().orientation;
   if (mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT) {
    Utils.full(false, MainActivity.this);
    mRl_PlayView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 400));
    if (mVideoView != null){
//     mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_STRETCH, 0);
     }
   } else if (mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
    Utils.full(true, MainActivity.this);
    mRl_PlayView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    if (mVideoView != null)
     mVideoView.setVideoLayout(mLayout, 0);
   }
   mVideoView.requestFocus();
   

(4)然后就是进行音量调节,快进,快退亮度的调节,使用手势监听就能实现这一点

  1. <spanstyle="white-space:pre"></span>mGestureDetector=newGestureDetector(newMyGestureListener());
<span style="white-space:pre"> </span>mGestureDetector = new GestureDetector(new MyGestureListener());
然后就是在onTouch 跟onScroll 里边进行处理;

现在我是把屏幕分成平均的俩分,如果是在左边滑动,而且没有在快进回事快退的时候就是调整亮度,反之就是调整音量。

在调整进度的时候是不能调整亮度的,我加了这判断,而且视频只有在快进已经快退完成以后才进行视频的seekTo()。

  1. /**滑动*/
  2. @Override
  3. publicbooleanonScroll(MotionEvente1,MotionEvente2,floatdistanceX,floatdistanceY){
  4. mMediaController.hide();
  5. floatmOldX=e1.getX(),mOldY=e1.getY();
  6. inty=(int)e2.getRawY();
  7. intx=(int)e2.getRawX();
  8. Displaydisp=getWindowManager().getDefaultDisplay();
  9. intwindowWidth=disp.getWidth();
  10. intwindowHeight=disp.getHeight();
  11. if(Math.abs(x-mOldX)>20&&!isUp_downScroll){//执行快进快退
  12. isFast_Forword=true;
  13. mFast_forward=x-mOldX;
  14. fast_ForWord(mFast_forward);
  15. }elseif(mOldX>windowWidth*1.0/2&&Math.abs(mOldY-y)>3&&!isFast_Forword)//右边滑动
  16. onVolumeSlide((mOldY-y)/windowHeight);
  17. elseif(mOldX<windowWidth/2.0&&Math.abs(mOldY-y)>3&&!isFast_Forword)//左边滑动
  18. onBrightnessSlide((mOldY-y)/windowHeight);
  19. returnsuper.onScroll(e1,e2,distanceX,distanceY);
  20. }
/** 滑动 */
  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
   mMediaController.hide();
   float mOldX = e1.getX(), mOldY = e1.getY();
   int y = (int) e2.getRawY();
   int x = (int) e2.getRawX();
   Display disp = getWindowManager().getDefaultDisplay();
   int windowWidth = disp.getWidth();
   int windowHeight = disp.getHeight();

   if (Math.abs(x- mOldX) >20 && !isUp_downScroll) { //执行快进快退
    isFast_Forword = true;
     mFast_forward = x - mOldX;
     fast_ForWord(mFast_forward);
   }else if (mOldX > windowWidth * 1.0 / 2 && Math.abs(mOldY - y) > 3 && !isFast_Forword)// 右边滑动
    onVolumeSlide((mOldY - y) / windowHeight);
   else if (mOldX < windowWidth / 2.0 && Math.abs(mOldY - y) > 3 && !isFast_Forword)// 左边滑动
    onBrightnessSlide((mOldY - y) / windowHeight);
   return super.onScroll(e1, e2, distanceX, distanceY);
  }


调整音量:

  1. /**
  2. *滑动改变声音大小
  3. *
  4. *@parampercent
  5. */
  6. privatevoidonVolumeSlide(floatpercent){
  7. isUp_downScroll=true;
  8. if(mVolume==-1){
  9. mVolume=mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
  10. if(mVolume<0)
  11. mVolume=0;
  12. //显示
  13. mOperationBg.setImageResource(R.drawable.video_volumn_bg);
  14. mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
  15. }
  16. intindex=(int)(percent*mMaxVolume)+mVolume;
  17. if(index>mMaxVolume)
  18. index=mMaxVolume;
  19. elseif(index<0)
  20. index=0;
  21. //变更声音
  22. mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,index,0);
  23. //变更进度条
  24. ViewGroup.LayoutParamslp=mOperationPercent.getLayoutParams();
  25. lp.width=findViewById(R.id.operation_full).getLayoutParams().width*index/mMaxVolume;
  26. mOperationPercent.setLayoutParams(lp);
  27. }
 /**
  * 滑动改变声音大小
  * 
  * @param percent
  */
 private void onVolumeSlide(float percent) {
  isUp_downScroll = true;
  if (mVolume == -1) {
   mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
   if (mVolume < 0)
    mVolume = 0;

   // 显示
   mOperationBg.setImageResource(R.drawable.video_volumn_bg);
   mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
  }

  int index = (int) (percent * mMaxVolume) + mVolume;
  if (index > mMaxVolume)
   index = mMaxVolume;
  else if (index < 0)
   index = 0;

  // 变更声音
  mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);

  // 变更进度条
  ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
  lp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume;
  mOperationPercent.setLayoutParams(lp);
 }


调整亮度:

  1. /**
  2. *滑动改变亮度
  3. *
  4. *@parampercent
  5. */
  6. privatevoidonBrightnessSlide(floatpercent){
  7. isUp_downScroll=true;
  8. if(mBrightness<0){
  9. mBrightness=getWindow().getAttributes().screenBrightness;
  10. if(mBrightness<=0.00f)
  11. mBrightness=0.50f;
  12. if(mBrightness<0.01f)
  13. mBrightness=0.01f;
  14. //显示
  15. mOperationBg.setImageResource(R.drawable.video_brightness_bg);
  16. mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
  17. }
  18. WindowManager.LayoutParamslpa=getWindow().getAttributes();
  19. lpa.screenBrightness=mBrightness+percent;
  20. if(lpa.screenBrightness>1.0f)
  21. lpa.screenBrightness=1.0f;
  22. elseif(lpa.screenBrightness<0.01f)
  23. lpa.screenBrightness=0.01f;
  24. getWindow().setAttributes(lpa);
  25. ViewGroup.LayoutParamslp=mOperationPercent.getLayoutParams();
  26. lp.width=(int)(findViewById(R.id.operation_full).getLayoutParams().width*lpa.screenBrightness);
  27. mOperationPercent.setLayoutParams(lp);
  28. }
/**
  * 滑动改变亮度
  * 
  * @param percent
  */
 private void onBrightnessSlide(float percent) {
  isUp_downScroll = true;
  if (mBrightness < 0) {
   mBrightness = getWindow().getAttributes().screenBrightness;
   if (mBrightness <= 0.00f)
    mBrightness = 0.50f;
   if (mBrightness < 0.01f)
    mBrightness = 0.01f;

   // 显示
   mOperationBg.setImageResource(R.drawable.video_brightness_bg);
   mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
  }
  WindowManager.LayoutParams lpa = getWindow().getAttributes();
  lpa.screenBrightness = mBrightness + percent;
  if (lpa.screenBrightness > 1.0f)
   lpa.screenBrightness = 1.0f;
  else if (lpa.screenBrightness < 0.01f)
   lpa.screenBrightness = 0.01f;
  getWindow().setAttributes(lpa);

  ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
  lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);
  mOperationPercent.setLayoutParams(lp);
 }
在手势进行快进快退的时候让时间进行改变:

  1. privatevoidfast_ForWord(floatdis){
  2. longcurrentProgress;
  3. longduration=mVideoView.getDuration();
  4. if(mVideoView.getCurrentPosition()+500*(long)dis<0)
  5. currentProgress=0;
  6. else
  7. currentProgress=mVideoView.getCurrentPosition()+500*(long)dis;
  8. mTv_progress.setText(Utils.generateTime(currentProgress)+"/"+Utils.generateTime(duration));
  9. if(dis>0)
  10. mIv_Progress_bg.setImageResource(R.drawable.btn_fast_forword);
  11. else
  12. mIv_Progress_bg.setImageResource(R.drawable.btn_back_forword);
  13. mFl_Progress.setVisibility(View.VISIBLE);
  14. }
private void fast_ForWord(float dis){
  long currentProgress ;
  long duration  = mVideoView.getDuration();
  if (mVideoView.getCurrentPosition() + 500*(long)dis < 0) 
   currentProgress = 0;
  else
   currentProgress = mVideoView.getCurrentPosition() + 500*(long)dis;
  mTv_progress.setText(Utils.generateTime(currentProgress) + "/" + Utils.generateTime(duration));
  if (dis > 0) 
   mIv_Progress_bg.setImageResource(R.drawable.btn_fast_forword);
  else
   mIv_Progress_bg.setImageResource(R.drawable.btn_back_forword);
  mFl_Progress.setVisibility(View.VISIBLE);
 }


改变进度是在onTouch 的action _up 的时候执行的:

  1. @Override
  2. publicbooleanonTouchEvent(MotionEventevent){
  3. if(mGestureDetector.onTouchEvent(event))
  4. returntrue;
  5. //处理手势结束
  6. switch(event.getAction()&MotionEvent.ACTION_MASK){
  7. caseMotionEvent.ACTION_UP:
  8. endGesture();
  9. break;
  10. }
  11. returnsuper.onTouchEvent(event);
  12. }
  13. /**手势结束*/
  14. privatevoidendGesture(){
  15. mVolume=-1;
  16. mBrightness=-1f;
  17. if(isFast_Forword){
  18. onSeekProgress(mFast_forward);
  19. }
  20. //隐藏
  21. mDismissHandler.removeMessages(0);
  22. mDismissHandler.sendEmptyMessageDelayed(0,800);
  23. }
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  if (mGestureDetector.onTouchEvent(event))
   return true;

  // 处理手势结束
  switch (event.getAction() & MotionEvent.ACTION_MASK) {
  case MotionEvent.ACTION_UP:
   endGesture();
   break;
  }

  return super.onTouchEvent(event);
 }

 /** 手势结束 */
 private void endGesture() {
  mVolume = -1;
  mBrightness = -1f;
  if (isFast_Forword) {
   onSeekProgress(mFast_forward);
  }
  // 隐藏
  mDismissHandler.removeMessages(0);
  mDismissHandler.sendEmptyMessageDelayed(0, 800);
 }
  1. <spanstyle="white-space:pre"></span>onSeekProgress(long)是调整进度的:<prename="code"class="java">privatevoidonSeekProgress(floatdis){
  2. Log.e("position==",mVideoView.getCurrentPosition()+500*(long)dis+"/"+mVideoView.getDuration());
  3. mVideoView.seekTo(mVideoView.getCurrentPosition()+500*(long)dis);
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP