• 【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: }
  • 相关阅读:
    SQL Server 2008 R2——VC++ ADO 操作 多线程操作 代码结构
    SQL Server 2008 R2——VC++ ADO 操作 参数化查询
    SQL Server 2008 R2——VC++ ADO 操作 事务
    SQL Server 2008 R2——VC++ ADO 操作 存储过程
    SQL Server 2008 R2——开发资料搜集
    SQL Server 2008 R2——学习/练习/错误/总结/搜集
    CListCtrl中删除多个不连续的行
    C++基础——子类转父类转子类 (派生类转基类转派生类)
    魔改——MDI多视图模板Tab/标签页 初始化/操作控件
    魔改——MFC SDI程序 转换为 MDI程序
  • 原文地址:https://www.cnblogs.com/yichouangle/p/2741629.html
Copyright © 2020-2023  润新知