【Libgdx原创】在Libgdx中播放视频2

之前写的那篇帖子采用的方法是将 Libgdx 的 GLSurfaceView 隐藏,再将 MediaPlayer 绑定的 SurfaceView添加到 Activity 的 ContentView,后来测试这种方法虽然可以播放视频,然用户按下Home或电源键时,Activity 会收到 onPause 事件,再次返回的时候 系统没有调用 onResume() 游戏就卡死了,没有响应,这样显然不行!

后来在 StackOverflow 上看到有人这样解决的:

SurfaceView.setZOrderMediaOverlay(boolean isMediaOverlay)

官方文档的大概意思是:将该 SurfaceView 作为一个浮动的View显示在其他窗口的上面,而不改变该窗口的 Zorder,

试了一下果然管用,还有另外一个方法是:

SurfaceView.setZOrderOnTop(boolean onTop);

这个方法是直接改变 SurfaceView 的 ZOrder,会覆盖掉在他上面的控件,有些地方不方便。

下面附上我封装的一个 VideoView 源码:

   1: package com.pobaby.shot;
   2:  
   3: import java.io.IOException;
   4:  
   5: import android.media.MediaPlayer;
   6: import android.net.Uri;
   7: import android.util.Log;
   8: import android.view.MotionEvent;
   9: import android.view.SurfaceHolder;
  10: import android.view.SurfaceView;
  11: import android.view.View;
  12:  
  13: import com.badlogic.gdx.Gdx;
  14:  
  15: public class VideoView extends SurfaceView implements SurfaceHolder.Callback, View.OnTouchListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnInfoListener,
  16:         MediaPlayer.OnCompletionListener {
  17:     private MediaPlayer mPlayer; // MediaPlayer对象
  18:     private GameActivity gameActivity;
  19:     private int resId;
  20:     private boolean surfaceCreated;
  21:  
  22:     public VideoView(GameActivity context) {
  23:         super(context);
  24:  
  25:         this.gameActivity = context;
  26:  
  27:         final SurfaceHolder holder = getHolder();
  28:         holder.addCallback(this); // 设置回调接口
  29:         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 设置为Buffer类型(播放视频&Camera预览)
  30:         setOnTouchListener(this);
  31:  
  32:         mPlayer = new MediaPlayer();
  33:         mPlayer.setScreenOnWhilePlaying(true);
  34:  
  35:         mPlayer.setOnPreparedListener(this);
  36:         mPlayer.setOnCompletionListener(this);
  37:         mPlayer.setOnErrorListener(this);
  38:         mPlayer.setOnInfoListener(this);
  39:     }
  40:  
  41:     public void setVideo(int resId) {
  42: //        Log.i(PobabyGame.TAG, "== setVideo ! == ");
  43:  
  44:         this.resId = resId;
  45:         Uri uri = Uri.parse("android.resource://" + gameActivity.getPackageName() + "/" + resId);
  46:  
  47:         try {
  48:             mPlayer.setDataSource(gameActivity, uri);
  49:         } catch (IllegalArgumentException e) {
  50:         } catch (SecurityException e) {
  51:         } catch (IllegalStateException e) {
  52:         } catch (IOException e) {
  53:         }
  54:     }
  55:  
  56:     @Override
  57:     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  58:     }
  59:  
  60:     @Override
  61:     public void surfaceCreated(final SurfaceHolder holder) {
  62:         surfaceCreated = true;
  63:         
  64:         mPlayer.setDisplay(holder); // 指定SurfaceHolder
  65:  
  66:         gameActivity.handler.post(new Runnable() {
  67:             @Override
  68:             public void run() {
  69:                 try {
  70:                     mPlayer.prepare();
  71:                 } catch (IllegalStateException e1) {
  72:                 } catch (IOException e1) {
  73:                 }
  74:             }
  75:         });
  76:     }
  77:  
  78:     @Override
  79:     public void surfaceDestroyed(SurfaceHolder holder) {
  80:         surfaceCreated = false;
  81:         
  82:         mPlayer.stop();
  83:         mPlayer.reset();
  84:     }
  85:  
  86:     @Override
  87:     public void onPrepared(MediaPlayer player) {
  88:         int wWidth = Gdx.graphics.getWidth();
  89:         int wHeight = Gdx.graphics.getHeight();
  90:  
  91:         /* 获得视频宽长 */
  92:         int vWidth = mPlayer.getVideoWidth();
  93:         int vHeight = mPlayer.getVideoHeight();
  94:  
  95:         /* 最适屏幕 */
  96:         float wRatio = (float) vWidth / (float) wWidth; // 宽度比
  97:         float hRatio = (float) vHeight / (float) wHeight; // 高度比
  98:         float ratio = Math.max(wRatio, hRatio); // 较大的比
  99:         vWidth = (int) Math.ceil((float) vWidth / ratio); // 新视频宽度
 100:         vHeight = (int) Math.ceil((float) vHeight / ratio); // 新视频高度
 101:  
 102:         // 改变SurfaceHolder大小
 103:         getHolder().setFixedSize(vWidth, vHeight);
 104:         mPlayer.seekTo(posttion);
 105:         mPlayer.start();
 106:     }
 107:  
 108:     @Override
 109:     public void onCompletion(MediaPlayer mp) {
 110: //        Toast.makeText(gameActivity, "video finished!", Toast.LENGTH_SHORT).show();
 111:  
 112:         mPlayer.release();
 113:         gameActivity.videoFinish(resId);
 114:     }
 115:  
 116:     @Override
 117:     public boolean onInfo(MediaPlayer mp, int what, int extra) {
 118:         Log.i(PobabyGame.TAG, String.format("onInfo(%d, %d)", what, extra));
 119:         return true;
 120:     }
 121:  
 122:     @Override
 123:     public boolean onError(MediaPlayer mp, int what, int extra) {
 124:         Log.e(PobabyGame.TAG, String.format("onError(%d, %d)", what, extra));
 125:         return true;
 126:     }
 127:  
 128:     @Override
 129:     public boolean onTouch(View v, MotionEvent event) {
 130:         if (event.getAction() == MotionEvent.ACTION_DOWN) {
 131:             if (gameActivity.button.getVisibility() == View.VISIBLE) {
 132:                 gameActivity.button.setVisibility(View.GONE);
 133:             } else {
 134:                 gameActivity.button.setVisibility(View.VISIBLE);
 135:             }
 136:         }
 137:  
 138:         return true;
 139:     }
 140:  
 141:     public void finish() {
 142:         mPlayer.stop(); // 大概不会调用 MediaPlayer.onCompletion
 143:         mPlayer.release();
 144:         gameActivity.videoFinish(resId);
 145:     }
 146:  
 147:     
 148:     int posttion;
 149:     public void pause() {
 150: //        Log.i(PobabyGame.TAG, "pause");
 151:     
 152:         posttion = mPlayer.getCurrentPosition();
 153:         mPlayer.pause();
 154:     }
 155:  
 156:     /**
 157:      * 暂停的时候,系统会销毁 SurfaceView ,所以在resume的时候相对于重新设置MediaPlayer
 158:      */
 159:     public void resume() {
 160: //        Log.i(PobabyGame.TAG, "resume");
 161:  
 162:         if(surfaceCreated){
 163:             mPlayer.start();
 164:         }else {
 165:             Uri uri = Uri.parse("android.resource://" + gameActivity.getPackageName() + "/" + resId);
 166:             try {
 167:                 mPlayer.setDataSource(gameActivity, uri);
 168:             } catch (IllegalArgumentException e) {
 169:             } catch (IllegalStateException e) {
 170:             } catch (IOException e) {
 171:             }
 172:         }
 173:     }
 174: }
原文地址:https://www.cnblogs.com/yichouangle/p/2741629.html