cocos2dx 3.x 播放视频bug

cocos2dx 3.x 播放视频bug,第1张

概述/* * Copyright (C) 2006 The Android Open Source Project * Copyright (c) 2014 Chukong Technologies Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this f
/* * copyright (C) 2006 The AndroID Open Source Project * copyright (c) 2014 Chukong TechnologIEs Inc. * * licensed under the Apache license,Version 2.0 (the "license"); * you may not use this file except in compliance with the license. * You may obtain a copy of the license at * *      http://www.apache.org/licenses/liCENSE-2.0 * * Unless required by applicable law or agreed to in writing,software * distributed under the license is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implIEd. * See the license for the specific language governing permissions and * limitations under the license. */package org.cocos2dx.lib;import androID.app.AlertDialog;import androID.content.DialogInterface;import androID.content.Intent;import androID.content.res.AssetfileDescriptor;import androID.content.res.Resources;import androID.media.AudioManager;import androID.media.MediaPlayer;import androID.media.MediaPlayer.OnErrorListener;import androID.net.Uri;import androID.util.Log;import androID.vIEw.Gravity;import androID.vIEw.MotionEvent;import androID.vIEw.SurfaceHolder;import androID.vIEw.SurfaceVIEw;import androID.Widget.FrameLayout;import androID.Widget.MediaController.MediaPlayerControl;import java.io.IOException;import java.util.Map;public class Cocos2dxVIDeoVIEw extends SurfaceVIEw implements MediaPlayerControl {    private String TAG = "Cocos2dxVIDeoVIEw";        private Uri         mVIDeoUri;       private int         mDuration;    // all possible internal states    private static final int STATE_ERROR              = -1;    private static final int STATE_IDLE               = 0;    private static final int STATE_PREPARING          = 1;    private static final int STATE_PREPARED           = 2;    private static final int STATE_PLAYING            = 3;    private static final int STATE_PAUSED             = 4;    private static final int STATE_PLAYBACK_COMPLETED = 5;    /**     * mCurrentState is a VIDeoVIEw object's current state.     * mTargetState is the state that a method caller intends to reach.     * For instance,regardless the VIDeoVIEw object's current state,* calling pause() intends to bring the object to a target state     * of STATE_PAUSED.     */    private int mCurrentState = STATE_IDLE;    private int mTargetState  = STATE_IDLE;    // All the stuff we need for playing and showing a vIDeo    private SurfaceHolder mSurfaceHolder = null;    private MediaPlayer mMediaPlayer = null;    private int         mVIDeoWIDth = 0;    private int         mVIDeoHeight = 0;        private OnVIDeoEventListener mOnVIDeoEventListener;    private MediaPlayer.OnPreparedListener mOnPreparedListener;    private int         mCurrentBufferPercentage;    private OnErrorListener mOnErrorListener;        // recording the seek position while preparing    private int         mSeekWhenPrepared;      protected Cocos2dxActivity mCocos2dxActivity = null;        protected int mVIEwleft = 0;    protected int mVIEwtop = 0;    protected int mVIEwWIDth = 0;    protected int mVIEwHeight = 0;        protected int mVisibleleft = 0;    protected int mVisibletop = 0;    protected int mVisibleWIDth = 0;    protected int mVisibleHeight = 0;        protected boolean mFullScreenEnabled = false;    protected int mFullScreenWIDth = 0;    protected int mFullScreenHeight = 0;        private int mVIEwTag = 0;    private boolean isComplete = false;        public Cocos2dxVIDeoVIEw(Cocos2dxActivity activity,int tag) {        super(activity);                mVIEwTag = tag;        mCocos2dxActivity = activity;        initVIDeoVIEw();    }    @OverrIDe    protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) {        if (mVIDeoWIDth == 0 || mVIDeoHeight == 0) {            setMeasuredDimension(mVIEwWIDth,mVIEwHeight);            Log.i(TAG,""+mVIEwWIDth+ ":" +mVIEwHeight);        }        else {            setMeasuredDimension(mVisibleWIDth,mVisibleHeight);            Log.i(TAG,""+mVisibleWIDth+ ":" +mVisibleHeight);        }            }        public voID setVIDeoRect(int left,int top,int maxWIDth,int maxHeight) {        mVIEwleft = left;        mVIEwtop = top;        mVIEwWIDth = maxWIDth;        mVIEwHeight = maxHeight;                fixSize(mVIEwleft,mVIEwtop,mVIEwWIDth,mVIEwHeight);    }        public voID setFullScreenEnabled(boolean enabled,int wIDth,int height) {        if (mFullScreenEnabled != enabled) {            mFullScreenEnabled = enabled;            if (wIDth != 0 && height != 0) {                mFullScreenWIDth = wIDth;                mFullScreenHeight = height;            }                        fixSize();        }    }        public int resolveAdjustedSize(int desiredSize,int measureSpec) {        int result = desiredSize;        int specMode = MeasureSpec.getMode(measureSpec);        int specsize =  MeasureSpec.getSize(measureSpec);        switch (specMode) {            case MeasureSpec.UnspecIFIED:                /* Parent says we can be as big as we want. Just don't be larger                 * than max size imposed on ourselves.                 */                result = desiredSize;                break;            case MeasureSpec.AT_MOST:                /* Parent says we can be as big as we want,up to specsize.                 * Don't be larger than specsize,and don't be larger than                 * the max size imposed on ourselves.                 */                result = Math.min(desiredSize,specsize);                break;            case MeasureSpec.EXACTLY:                // No choice. Do what we are told.                result = specsize;                break;        }                return result;    }    private boolean mNeedResume = false;        @OverrIDe    public voID setVisibility(int visibility) {        if (visibility == INVISIBLE) {            mNeedResume = isPlaying();            if (mNeedResume) {                mSeekWhenPrepared = getCurrentposition();            }        }        else if (mNeedResume){            start();            mNeedResume = false;        }        super.setVisibility(visibility);    }        private voID initVIDeoVIEw() {        mVIDeoWIDth = 0;        mVIDeoHeight = 0;        getHolder().addCallback(mSHCallback);        //Fix issue#11516:Can't play vIDeo on AndroID 2.3.x        getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);        setFocusable(true);        setFocusableIntouchMode(true);        mCurrentState = STATE_IDLE;        mTargetState  = STATE_IDLE;    }        @OverrIDe    public boolean ontouchEvent(MotionEvent event) {        if((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP)        {            if (isPlaying()) {                pause();            } else if(mCurrentState == STATE_PAUSED){                resume();            }        }                return true;    }        private boolean mIsAssetRouse = false;    private String mVIDeofilePath = null;    private static final String AssetResourceRoot = "assets/";        public voID setVIDeofilename(String path) {        if (path.startsWith(AssetResourceRoot)) {            path = path.substring(AssetResourceRoot.length());        }        if (path.startsWith("/")) {            mIsAssetRouse = false;            setVIDeoURI(Uri.parse(path),null);        }        else {            mVIDeofilePath = path;            mIsAssetRouse = true;            setVIDeoURI(Uri.parse(path),null);        }    }        public voID setVIDeoURL(String url) {        mIsAssetRouse = false;        setVIDeoURI(Uri.parse(url),null);    }    /**     * @hIDe     */    private voID setVIDeoURI(Uri uri,Map<String,String> headers) {        mVIDeoUri = uri;        mSeekWhenPrepared = 0;        mVIDeoWIDth = 0;        mVIDeoHeight = 0;        openVIDeo();        requestLayout();        invalIDate();    }        public voID stopPlayback() {        if (mMediaPlayer != null) {            mMediaPlayer.stop();            mMediaPlayer.release();            mMediaPlayer = null;            mCurrentState = STATE_IDLE;            mTargetState  = STATE_IDLE;        }    }    private voID openVIDeo() {        if (mSurfaceHolder == null) {            // not ready for playback just yet,will try again later            return;        }        if (mIsAssetRouse) {            if(mVIDeofilePath == null)                return;        } else if(mVIDeoUri == null) {            return;        }                // Tell the music playback service to pause        // Todo: these constants need to be published somewhere in the framework.        Intent i = new Intent("com.androID.music.musicservicecommand");        i.putExtra("command","pause");        mCocos2dxActivity.sendbroadcast(i);        // we shouldn't clear the target state,because somebody might have        // called start() prevIoUsly        release(false);                try {            //if (mMediaPlayer == null) {                mMediaPlayer = new MediaPlayer();                mMediaPlayer.setonPreparedListener(mPreparedListener);                mMediaPlayer.setonVIDeoSizeChangedListener(mSizeChangedListener);                                mMediaPlayer.setonCompletionListener(mCompletionListener);                mMediaPlayer.setonErrorListener(mErrorListener);                mMediaPlayer.setonBufferingUpdateListener(mBufferingUpdateListener);                                mMediaPlayer.setdisplay(mSurfaceHolder);                mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);                mMediaPlayer.setScreenOnWhilePlaying(true);            //}                        mDuration = -1;            mCurrentBufferPercentage = 0;            if (mIsAssetRouse) {                AssetfileDescriptor afd = mCocos2dxActivity.getAssets().openFd(mVIDeofilePath);                mMediaPlayer.setDataSource(afd.getfileDescriptor(),afd.getStartOffset(),afd.getLength());            } else {                mMediaPlayer.setDataSource(mCocos2dxActivity,mVIDeoUri);            }                        mMediaPlayer.prepareAsync();            /**             * Don't set the target state here either,but preserve the target state that was there before.             */            mCurrentState = STATE_PREPARING;        } catch (IOException ex) {            Log.w(TAG,"Unable to open content: " + mVIDeoUri,ex);            mCurrentState = STATE_ERROR;            mTargetState = STATE_ERROR;            mErrorListener.onError(mMediaPlayer,MediaPlayer.MEDIA_ERROR_UNKNowN,0);            return;        } catch (IllegalArgumentException ex) {            Log.w(TAG,0);            return;        }    }        private boolean mKeepRatio = false;        public voID setKeepRatio(boolean enabled) {        mKeepRatio = enabled;        fixSize();    }    public voID fixSize() {        if (mFullScreenEnabled) {            fixSize(0,mFullScreenWIDth,mFullScreenHeight);        } else {            fixSize(mVIEwleft,mVIEwHeight);        }    }        public voID fixSize(int left,int height) {        if (mVIDeoWIDth == 0 || mVIDeoHeight == 0) {            mVisibleleft = left;            mVisibletop = top;            mVisibleWIDth = wIDth;            mVisibleHeight = height;        }        else if (wIDth != 0 && height != 0) {            if (mKeepRatio) {                if ( mVIDeoWIDth * height  > wIDth * mVIDeoHeight ) {                    mVisibleWIDth = wIDth;                    mVisibleHeight = wIDth * mVIDeoHeight / mVIDeoWIDth;                } else if ( mVIDeoWIDth * height  < wIDth * mVIDeoHeight ) {                    mVisibleWIDth = height * mVIDeoWIDth / mVIDeoHeight;                    mVisibleHeight = height;                }                mVisibleleft = left + (wIDth - mVisibleWIDth) / 2;                mVisibletop = top + (height - mVisibleHeight) / 2;            } else {                mVisibleleft = left;                mVisibletop = top;                mVisibleWIDth = wIDth;                mVisibleHeight = height;            }        }        else {            mVisibleleft = left;            mVisibletop = top;            mVisibleWIDth = mVIDeoWIDth;            mVisibleHeight = mVIDeoHeight;        }                getHolder().setFixedSize(mVisibleWIDth,mVisibleHeight);                FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT);        lParams.leftmargin = mVisibleleft;        lParams.topmargin = mVisibletop;        lParams.gravity = Gravity.top | Gravity.left;        setLayoutParams(lParams);    }    protected     MediaPlayer.OnVIDeoSizeChangedListener mSizeChangedListener =        new MediaPlayer.OnVIDeoSizeChangedListener() {            public voID onVIDeoSizeChanged(MediaPlayer mp,int height) {                mVIDeoWIDth = mp.getVIDeoWIDth();                mVIDeoHeight = mp.getVIDeoHeight();                if (mVIDeoWIDth != 0 && mVIDeoHeight != 0) {                    getHolder().setFixedSize(mVIDeoWIDth,mVIDeoHeight);                }            }    };        MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {        public voID onPrepared(MediaPlayer mp) {            mCurrentState = STATE_PREPARED;            if (mOnPreparedListener != null) {                mOnPreparedListener.onPrepared(mMediaPlayer);            }                        mVIDeoWIDth = mp.getVIDeoWIDth();            mVIDeoHeight = mp.getVIDeoHeight();            // mSeekWhenPrepared may be changed after seekTo() call            int seekToposition = mSeekWhenPrepared;              if (seekToposition != 0) {                seekTo(seekToposition);            }                        if (mVIDeoWIDth != 0 && mVIDeoHeight != 0) {                fixSize();            }                         if (mTargetState == STATE_PLAYING || !isComplete)              {                if (seekToposition != 0)                 {                    seekTo(seekToposition);                }                start();            }        }    };    private MediaPlayer.OnCompletionListener mCompletionListener =        new MediaPlayer.OnCompletionListener() {        public voID onCompletion(MediaPlayer mp) {            mCurrentState = STATE_PLAYBACK_COMPLETED;            mTargetState = STATE_PLAYBACK_COMPLETED;                        release(true);            if (mOnVIDeoEventListener != null) {                mOnVIDeoEventListener.onVIDeoEvent(mVIEwTag,EVENT_COMPLETED);            }        }    };            private static final int EVENT_PLAYING = 0;    private static final int EVENT_PAUSED = 1;    private static final int EVENT_StopPED = 2;    private static final int EVENT_COMPLETED = 3;        public interface OnVIDeoEventListener    {         voID onVIDeoEvent(int tag,int event);    }    private MediaPlayer.OnErrorListener mErrorListener =        new MediaPlayer.OnErrorListener() {        public boolean onError(MediaPlayer mp,int framework_err,int impl_err) {            Log.d(TAG,"Error: " + framework_err + "," + impl_err);            mCurrentState = STATE_ERROR;            mTargetState = STATE_ERROR;            /* If an error handler has been supplIEd,use it and finish. */            if (mOnErrorListener != null) {                if (mOnErrorListener.onError(mMediaPlayer,framework_err,impl_err)) {                    return true;                }            }            /* Otherwise,pop up an error dialog so the user kNows that             * something bad has happened. Only try and pop up the dialog             * if we're attached to a window. When we're going away and no             * longer have a window,don't bother showing the user an error.             */            if (getwindowToken() != null) {                Resources r = mCocos2dxActivity.getResources();                int messageID;                                if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {                    // messageID = com.androID.internal.R.string.VIDeoVIEw_error_text_invalID_progressive_playback;                    messageID = r.getIDentifIEr("VIDeoVIEw_error_text_invalID_progressive_playback","string","androID");                } else {                    // messageID = com.androID.internal.R.string.VIDeoVIEw_error_text_unkNown;                    messageID = r.getIDentifIEr("VIDeoVIEw_error_text_unkNown","androID");                }                                int TitleID = r.getIDentifIEr("VIDeoVIEw_error_Title","androID");                int buttonStringID = r.getIDentifIEr("VIDeoVIEw_error_button","androID");                                new AlertDialog.Builder(mCocos2dxActivity)                        .setTitle(r.getString(TitleID))                        .setMessage(messageID)                        .setPositivebutton(r.getString(buttonStringID),new DialogInterface.OnClickListener() {                                    public voID onClick(DialogInterface dialog,int whichbutton) {                                        /* If we get here,there is no onError Listener,so                                         * at least inform them that the vIDeo is over.                                         */                                        if (mOnVIDeoEventListener != null) {                                            mOnVIDeoEventListener.onVIDeoEvent(mVIEwTag,EVENT_COMPLETED);                                        }                                    }                                })                        .setCancelable(false)                        .show();            }            return true;        }    };    private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =        new MediaPlayer.OnBufferingUpdateListener() {        public voID onBufferingUpdate(MediaPlayer mp,int percent) {            mCurrentBufferPercentage = percent;        }    };    /**     * Register a callback to be invoked when the media file     * is loaded and ready to go.     *     * @param l The callback that will be run     */    public voID setonPreparedListener(MediaPlayer.OnPreparedListener l)    {        mOnPreparedListener = l;    }    /**     * Register a callback to be invoked when the end of a media file     * has been reached during play back.     *     * @param l The callback that will be run     */    public voID setonCompletionListener(OnVIDeoEventListener l)    {        mOnVIDeoEventListener = l;    }    /**     * Register a callback to be invoked when an error occurs     * during play back or setup.  If no Listener is specifIEd,* or if the Listener returned false,VIDeoVIEw will inform     * the user of any errors.     *     * @param l The callback that will be run     */    public voID setonErrorListener(OnErrorListener l)    {        mOnErrorListener = l;    }    SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback()    {        public voID surfaceChanged(SurfaceHolder holder,int format,int w,int h)        {        	boolean isValIDState = (mTargetState == STATE_PLAYING) || !isComplete;             boolean hasValIDSize = (mVIDeoWIDth == w && mVIDeoHeight == h);            if (mMediaPlayer != null && isValIDState && hasValIDSize) {                if (mSeekWhenPrepared != 0) {                    seekTo(mSeekWhenPrepared);                }                start();            }        }        public voID surfaceCreated(SurfaceHolder holder)        {            mSurfaceHolder = holder;            openVIDeo();        }        public voID surfaceDestroyed(SurfaceHolder holder)        {        	 if(mCurrentState == STATE_PLAYING) {         		 isComplete = mMediaPlayer.getCurrentposition() == mMediaPlayer.getDuration();         		 mSeekWhenPrepared = mMediaPlayer.getCurrentposition();        	 }            mSurfaceHolder = null;                        release(true);        }    };    /*     * release the media player in any state     */    private voID release(boolean cleartargetstate) {        if (mMediaPlayer != null) {            mMediaPlayer.reset();            mMediaPlayer.release();            mMediaPlayer = null;            mCurrentState = STATE_IDLE;            if (cleartargetstate) {                mTargetState  = STATE_IDLE;            }        }    }        public voID start() {        if (isInPlaybackState()) {            mMediaPlayer.start();            mCurrentState = STATE_PLAYING;            if (mOnVIDeoEventListener != null) {                mOnVIDeoEventListener.onVIDeoEvent(mVIEwTag,EVENT_PLAYING);            }        }        mTargetState = STATE_PLAYING;    }    public voID pause() {        if (isInPlaybackState()) {            if (mMediaPlayer.isPlaying()) {                mMediaPlayer.pause();                mCurrentState = STATE_PAUSED;                if (mOnVIDeoEventListener != null) {                    mOnVIDeoEventListener.onVIDeoEvent(mVIEwTag,EVENT_PAUSED);                }            }        }        mTargetState = STATE_PAUSED;    }        public voID stop() {        if (isInPlaybackState()) {            if (mMediaPlayer.isPlaying()) {               stopPlayback();                if (mOnVIDeoEventListener != null) {                    mOnVIDeoEventListener.onVIDeoEvent(mVIEwTag,EVENT_StopPED);                }            }        }    }    public voID suspend() {        release(false);    }    public voID resume() {        if (isInPlaybackState()) {            if (mCurrentState == STATE_PAUSED) {                mMediaPlayer.start();                mCurrentState = STATE_PLAYING;                if (mOnVIDeoEventListener != null) {                    mOnVIDeoEventListener.onVIDeoEvent(mVIEwTag,EVENT_PLAYING);                }            }        }    }    public voID restart() {        if (isInPlaybackState()) {            mMediaPlayer.seekTo(0);            mMediaPlayer.start();            mCurrentState = STATE_PLAYING;            mTargetState = STATE_PLAYING;        }    }    // cache duration as mDuration for faster access    public int getDuration() {        if (isInPlaybackState()) {            if (mDuration > 0) {                return mDuration;            }            mDuration = mMediaPlayer.getDuration();            return mDuration;        }        mDuration = -1;        return mDuration;    }    public int getCurrentposition() {        if (isInPlaybackState()) {            return mMediaPlayer.getCurrentposition();        }        return 0;    }    public voID seekTo(int msec) {        if (isInPlaybackState()) {            mMediaPlayer.seekTo(msec);            mSeekWhenPrepared = 0;        } else {            mSeekWhenPrepared = msec;        }    }    public boolean isPlaying() {        return isInPlaybackState() && mMediaPlayer.isPlaying();    }    public int getBufferPercentage() {        if (mMediaPlayer != null) {            return mCurrentBufferPercentage;        }        return 0;    }    public boolean isInPlaybackState() {        return (mMediaPlayer != null &&                mCurrentState != STATE_ERROR &&                mCurrentState != STATE_IDLE &&                mCurrentState != STATE_PREPARING);    }    @OverrIDe    public boolean canPause() {        return true;    }    @OverrIDe    public boolean canSeekBackward() {        return true;    }    @OverrIDe    public boolean canSeekForward() {        return true;    }            public int getAudioSessionID () {       return mMediaPlayer.getAudioSessionID();    }}


@H_502_4@


@H_502_4@

做了一下改动.@H_502_4@

主要参考:http://blog.sina.com.cn/s/blog_93add5520102w6n9.HTML@H_502_4@

很感谢这个博主,哈哈@H_502_4@


@H_502_4@

@H_502_4@ 总结

以上是内存溢出为你收集整理的cocos2dx 3.x 播放视频bug全部内容,希望文章能够帮你解决cocos2dx 3.x 播放视频bug所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1082761.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存