Cocos2dx3.11.1Android播放视频,后台 黑屏,无法记忆播放bug修改
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Cocos2dx3.11.1Android播放视频,后台 黑屏,无法记忆播放bug修改,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含18334字,纯文字阅读大概需要27分钟。
内容图文
/* * 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; privateint mDuration; // all possible internal statesprivatestaticfinalint STATE_ERROR = -1; privatestaticfinalint STATE_IDLE = 0; privatestaticfinalint STATE_PREPARING = 1; privatestaticfinalint STATE_PREPARED = 2; privatestaticfinalint STATE_PLAYING = 3; privatestaticfinalint STATE_PAUSED = 4; privatestaticfinalint 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. */privateint mCurrentState = STATE_IDLE; privateint mTargetState = STATE_IDLE; private boolean isComplete = false; //插入一个变量,用来记录是不是完成播放 // All the stuff we need for playing and showing a videoprivate SurfaceHolder mSurfaceHolder = null; private MediaPlayer mMediaPlayer = null; privateint mVideoWidth = 0; privateint mVideoHeight = 0; private OnVideoEventListener mOnVideoEventListener; private MediaPlayer.OnPreparedListener mOnPreparedListener; privateint mCurrentBufferPercentage; private OnErrorListener mOnErrorListener; // recording the seek position while preparingprivateint mSeekWhenPrepared; protected Cocos2dxActivity mCocos2dxActivity = null; protectedint mViewLeft = 0; protectedint mViewTop = 0; protectedint mViewWidth = 0; protectedint mViewHeight = 0; protectedint mVisibleLeft = 0; protectedint mVisibleTop = 0; protectedint mVisibleWidth = 0; protectedint mVisibleHeight = 0; protectedboolean mFullScreenEnabled = false; protectedint mFullScreenWidth = 0; protectedint mFullScreenHeight = 0; privateint mViewTag = 0; public Cocos2dxVideoView(Cocos2dxActivity activity,int tag) { super(activity); mViewTag = tag; mCocos2dxActivity = activity; initVideoView(); } @Override protectedvoid onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mVideoWidth == 0 || mVideoHeight == 0) { mViewWidth = mVisibleWidth; //解决黑屏。由于某些原因导致mViewWidth、mViewHeight变为0 mViewHeight = mVisibleHeight; setMeasuredDimension(mViewWidth, mViewHeight); Log.i(TAG, ""+mViewWidth+ ":" +mViewHeight); } else { setMeasuredDimension(mVisibleWidth, mVisibleHeight); Log.i(TAG, ""+mVisibleWidth+ ":" +mVisibleHeight); } } publicvoid setVideoRect(int left, int top, int maxWidth, int maxHeight) { mViewLeft = left; mViewTop = top; mViewWidth = maxWidth; mViewHeight = maxHeight; fixSize(mViewLeft, mViewTop, mViewWidth, mViewHeight); } publicvoid setFullScreenEnabled(boolean enabled, int width, int height) { if (mFullScreenEnabled != enabled) { mFullScreenEnabled = enabled; if (width != 0 && height != 0) { mFullScreenWidth = width; mFullScreenHeight = height; } fixSize(); } } publicint 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; } privateboolean mNeedResume = false; @Override publicvoid setVisibility(int visibility) { if (visibility == INVISIBLE) { mNeedResume = isPlaying(); if (mNeedResume) { mSeekWhenPrepared = getCurrentPosition(); } } elseif (mNeedResume){ start(); mNeedResume = false; } super.setVisibility(visibility); } privatevoid 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 publicboolean onTouchEvent(MotionEvent event) { if((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) { if (isPlaying()) { pause(); resume(); } elseif(mCurrentState == STATE_PAUSED){ resume(); } } returntrue; } privateboolean mIsAssetRouse = false; private String mVideoFilePath = null; privatestaticfinal String AssetResourceRoot = "assets/"; publicvoid 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); } } publicvoid setVideoURL(String url) { mIsAssetRouse = false; setVideoURI(Uri.parse(url), null); } /** * @hide */privatevoid setVideoURI(Uri uri, Map<String, String> headers) { mVideoUri = uri; mSeekWhenPrepared = 0; mVideoWidth = 0; mVideoHeight = 0; openVideo(); requestLayout(); invalidate(); } publicvoid stopPlayback() { if (mMediaPlayer != null) { mMediaPlayer.stop(); mMediaPlayer.release(); mMediaPlayer = null; mCurrentState = STATE_IDLE; mTargetState = STATE_IDLE; } } privatevoid openVideo() { if (mSurfaceHolder == null) { // not ready for playback just yet, will try again laterreturn; } if (mIsAssetRouse) { if(mVideoFilePath == null) return; } elseif(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, "Unable to open content: " + mVideoUri, ex); mCurrentState = STATE_ERROR; mTargetState = STATE_ERROR; mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0); return; } } privateboolean mKeepRatio = false; publicvoid setKeepRatio(boolean enabled) { mKeepRatio = enabled; fixSize(); } publicvoid fixSize() { if (mFullScreenEnabled) { fixSize(0, 0, mFullScreenWidth, mFullScreenHeight); } else { fixSize(mViewLeft, mViewTop, mViewWidth, mViewHeight); } } publicvoid fixSize(int left, int top, int width, int height) { if (mVideoWidth == 0 || mVideoHeight == 0) { mVisibleLeft = left; mVisibleTop = top; mVisibleWidth = width; mVisibleHeight = height; } elseif (width != 0 && height != 0) { if (mKeepRatio) { if ( mVideoWidth * height > width * mVideoHeight ) { mVisibleWidth = width; mVisibleHeight = width * mVideoHeight / mVideoWidth; } elseif ( 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() { publicvoid onVideoSizeChanged(MediaPlayer mp, int width, int height) { mVideoWidth = mp.getVideoWidth(); mVideoHeight = mp.getVideoHeight(); if (mVideoWidth != 0 && mVideoHeight != 0) { getHolder().setFixedSize(mVideoWidth, mVideoHeight); } } }; MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() { publicvoid onPrepared(MediaPlayer mp) { mCurrentState = STATE_PREPARED; if (mOnPreparedListener != null) { mOnPreparedListener.onPrepared(mMediaPlayer); } mVideoWidth = mp.getVideoWidth(); mVideoHeight = mp.getVideoHeight(); // mSeekWhenPrepared may be changed after seekTo() callint seekToPosition = mSeekWhenPrepared; if (seekToPosition != 0) { seekTo(seekToPosition); } if (mVideoWidth != 0 && mVideoHeight != 0) { fixSize(); } if (mTargetState == STATE_PLAYING) { start(); } } }; private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() { publicvoid onCompletion(MediaPlayer mp) { mCurrentState = STATE_PLAYBACK_COMPLETED; mTargetState = STATE_PLAYBACK_COMPLETED; release(true); if (mOnVideoEventListener != null) { mOnVideoEventListener.onVideoEvent(mViewTag,EVENT_COMPLETED); } } }; privatestaticfinalint EVENT_PLAYING = 0; privatestaticfinalint EVENT_PAUSED = 1; privatestaticfinalint EVENT_STOPPED = 2; privatestaticfinalint EVENT_COMPLETED = 3; publicinterface OnVideoEventListener { void onVideoEvent(int tag,int event); } private MediaPlayer.OnErrorListener mErrorListener = new MediaPlayer.OnErrorListener() { publicboolean 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)) { returntrue; } } /* 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", "string", "android"); } int titleId = r.getIdentifier("VideoView_error_title", "string", "android"); int buttonStringId = r.getIdentifier("VideoView_error_button", "string", "android"); new AlertDialog.Builder(mCocos2dxActivity) .setTitle(r.getString(titleId)) .setMessage(messageId) .setPositiveButton(r.getString(buttonStringId), new DialogInterface.OnClickListener() { publicvoid 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(); } returntrue; } }; private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() { publicvoid 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 */publicvoid 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 */publicvoid 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 */publicvoid setOnErrorListener(OnErrorListener l) { mOnErrorListener = l; } SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback() { publicvoid surfaceChanged(SurfaceHolder holder, int format, int w, int h) { boolean isValidState = (mTargetState == STATE_PLAYING)|| !isComplete; //2.加入isComplete判断 boolean hasValidSize = (mVideoWidth == w && mVideoHeight == h); if (mMediaPlayer != null && isValidState && hasValidSize) { if (mSeekWhenPrepared != 0) { seekTo(mSeekWhenPrepared); } start(); } } publicvoid surfaceCreated(SurfaceHolder holder) { mSurfaceHolder = holder; openVideo(); } publicvoid surfaceDestroyed(SurfaceHolder holder) { // after we return from this we can‘t use the surface any more mSurfaceHolder = null; if(mCurrentState == STATE_PLAYING) { isComplete = mMediaPlayer.getCurrentPosition() == mMediaPlayer.getDuration(); //保存一下当前进度和是否播放完成 mSeekWhenPrepared = mMediaPlayer.getCurrentPosition();//保存一下当前进度和是否播放完成 } release(true); } }; /* * release the media player in any state */privatevoid release(boolean cleartargetstate) { if (mMediaPlayer != null) { mMediaPlayer.reset(); mMediaPlayer.release(); mMediaPlayer = null; mCurrentState = STATE_IDLE; if (cleartargetstate) { mTargetState = STATE_IDLE; } } } publicvoid start() { if (isInPlaybackState()) { mMediaPlayer.start(); mCurrentState = STATE_PLAYING; if (mOnVideoEventListener != null) { mOnVideoEventListener.onVideoEvent(mViewTag, EVENT_PLAYING); } } mTargetState = STATE_PLAYING; } publicvoid pause() { if (isInPlaybackState()) { if (mMediaPlayer.isPlaying()) { mMediaPlayer.pause(); mCurrentState = STATE_PAUSED; if (mOnVideoEventListener != null) { mOnVideoEventListener.onVideoEvent(mViewTag, EVENT_PAUSED); } } } mTargetState = STATE_PAUSED; } publicvoid stop() { if (isInPlaybackState()) { if (mMediaPlayer.isPlaying()) { stopPlayback(); if (mOnVideoEventListener != null) { mOnVideoEventListener.onVideoEvent(mViewTag, EVENT_STOPPED); } } } } publicvoid suspend() { release(false); } publicvoid resume() { if (isInPlaybackState()) { if (mCurrentState == STATE_PAUSED) { mMediaPlayer.start(); mCurrentState = STATE_PLAYING; if (mOnVideoEventListener != null) { mOnVideoEventListener.onVideoEvent(mViewTag, EVENT_PLAYING); } } } } publicvoid restart() { if (isInPlaybackState()) { mMediaPlayer.seekTo(0); mMediaPlayer.start(); mCurrentState = STATE_PLAYING; mTargetState = STATE_PLAYING; } } // cache duration as mDuration for faster accesspublicint getDuration() { if (isInPlaybackState()) { if (mDuration > 0) { return mDuration; } mDuration = mMediaPlayer.getDuration(); return mDuration; } mDuration = -1; return mDuration; } publicint getCurrentPosition() { if (isInPlaybackState()) { return mMediaPlayer.getCurrentPosition(); } return 0; } publicvoid seekTo(int msec) { if (isInPlaybackState()) { mMediaPlayer.seekTo(msec); mSeekWhenPrepared = 0; } else { mSeekWhenPrepared = msec; } } publicboolean isPlaying() { return isInPlaybackState() && mMediaPlayer.isPlaying(); } publicint getBufferPercentage() { if (mMediaPlayer != null) { return mCurrentBufferPercentage; } return 0; } publicboolean isInPlaybackState() { return (mMediaPlayer != null && mCurrentState != STATE_ERROR && mCurrentState != STATE_IDLE && mCurrentState != STATE_PREPARING); } @Override publicboolean canPause() { returntrue; } @Override publicboolean canSeekBackward() { returntrue; } @Override publicboolean canSeekForward() { returntrue; } publicint getAudioSessionId () { return mMediaPlayer.getAudioSessionId(); } }
上面是解决问题的代码。
不知道怎么在代码前面插入话了。
写在后面吧
版本 3.11.1
问题描述:
Android播放视频的时候,后台,再切回来,导致 视频无法播放。黑屏。
解决之后:
后台回来正常记忆播放。没有问题。
原文:http://www.cnblogs.com/zhangfeitao/p/6245409.html
内容总结
以上是互联网集市为您收集整理的Cocos2dx3.11.1Android播放视频,后台 黑屏,无法记忆播放bug修改全部内容,希望文章能够帮你解决Cocos2dx3.11.1Android播放视频,后台 黑屏,无法记忆播放bug修改所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。