Fixed VideoPlayer can't quitting the full screen mode by press the back key.

This commit is contained in:
Dhilan007 2014-07-17 21:10:26 +08:00
parent 21ea289eb1
commit 229b30ed8b
6 changed files with 147 additions and 86 deletions

View File

@ -292,6 +292,7 @@ public class Cocos2dxGLSurfaceView extends GLSurfaceView {
public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) { public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {
switch (pKeyCode) { switch (pKeyCode) {
case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_BACK:
Cocos2dxVideoHelper.mVideoHandler.sendEmptyMessage(Cocos2dxVideoHelper.KeyEventBack);
case KeyEvent.KEYCODE_MENU: case KeyEvent.KEYCODE_MENU:
case KeyEvent.KEYCODE_DPAD_LEFT: case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT: case KeyEvent.KEYCODE_DPAD_RIGHT:

View File

@ -40,7 +40,7 @@ public class Cocos2dxVideoHelper {
private FrameLayout mLayout = null; private FrameLayout mLayout = null;
private Cocos2dxActivity mActivity = null; private Cocos2dxActivity mActivity = null;
private SparseArray<Cocos2dxVideoView> sVideoViews = null; private SparseArray<Cocos2dxVideoView> sVideoViews = null;
private static VideoHandler mVideoHandler = null; static VideoHandler mVideoHandler = null;
Cocos2dxVideoHelper(Cocos2dxActivity activity,FrameLayout layout) Cocos2dxVideoHelper(Cocos2dxActivity activity,FrameLayout layout)
{ {
@ -64,6 +64,8 @@ public class Cocos2dxVideoHelper {
private final static int VideoTaskSetVisible = 9; private final static int VideoTaskSetVisible = 9;
private final static int VideoTaskRestart = 10; private final static int VideoTaskRestart = 10;
private final static int VideoTaskKeepRatio = 11; private final static int VideoTaskKeepRatio = 11;
private final static int VideoTaskFullScreen = 12;
final static int KeyEventBack = 13;
static class VideoHandler extends Handler{ static class VideoHandler extends Handler{
WeakReference<Cocos2dxVideoHelper> mReference; WeakReference<Cocos2dxVideoHelper> mReference;
@ -101,6 +103,16 @@ public class Cocos2dxVideoHelper {
helper._setVideoRect(msg.arg1, rect.left, rect.top, rect.right, rect.bottom); helper._setVideoRect(msg.arg1, rect.left, rect.top, rect.right, rect.bottom);
break; break;
} }
case VideoTaskFullScreen:{
Cocos2dxVideoHelper helper = mReference.get();
Rect rect = (Rect)msg.obj;
if (msg.arg2 == 1) {
helper._setFullScreenEnabled(msg.arg1, true, rect.right, rect.bottom);
} else {
helper._setFullScreenEnabled(msg.arg1, false, rect.right, rect.bottom);
}
break;
}
case VideoTaskPause: { case VideoTaskPause: {
Cocos2dxVideoHelper helper = mReference.get(); Cocos2dxVideoHelper helper = mReference.get();
helper._pauseVideo(msg.arg1); helper._pauseVideo(msg.arg1);
@ -144,6 +156,11 @@ public class Cocos2dxVideoHelper {
} }
break; break;
} }
case KeyEventBack: {
Cocos2dxVideoHelper helper = mReference.get();
helper.onBackKeyEvent();
break;
}
default: default:
break; break;
} }
@ -255,6 +272,38 @@ public class Cocos2dxVideoHelper {
} }
} }
public static void setFullScreenEnabled(int index,boolean enabled, int width,int height) {
Message msg = new Message();
msg.what = VideoTaskFullScreen;
msg.arg1 = index;
if (enabled) {
msg.arg2 = 1;
} else {
msg.arg2 = 0;
}
msg.obj = new Rect(0, 0, width, height);
mVideoHandler.sendMessage(msg);
}
private void _setFullScreenEnabled(int index, boolean enabled, int width,int height) {
Cocos2dxVideoView videoView = sVideoViews.get(index);
if (videoView != null) {
videoView.setFullScreenEnabled(enabled, width, height);
}
}
private void onBackKeyEvent() {
int viewCount = sVideoViews.size();
for (int i = 0; i < viewCount; i++) {
int key = sVideoViews.keyAt(i);
Cocos2dxVideoView videoView = sVideoViews.get(key);
if (videoView != null) {
videoView.setFullScreenEnabled(false, 0, 0);
mActivity.runOnGLThread(new VideoEventRunnable(key, 1024));
}
}
}
public static void startVideo(int index) { public static void startVideo(int index) {
Message msg = new Message(); Message msg = new Message();
msg.what = VideoTaskStart; msg.what = VideoTaskStart;

View File

@ -18,7 +18,6 @@
package org.cocos2dx.lib; package org.cocos2dx.lib;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.AssetFileDescriptor; import android.content.res.AssetFileDescriptor;
@ -27,7 +26,6 @@ import android.media.AudioManager;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener; import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri; import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
@ -75,7 +73,7 @@ public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl
// recording the seek position while preparing // recording the seek position while preparing
private int mSeekWhenPrepared; private int mSeekWhenPrepared;
protected Context mContext = null; protected Cocos2dxActivity mCocos2dxActivity = null;
protected int mViewLeft = 0; protected int mViewLeft = 0;
protected int mViewTop = 0; protected int mViewTop = 0;
@ -87,27 +85,17 @@ public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl
protected int mVisibleWidth = 0; protected int mVisibleWidth = 0;
protected int mVisibleHeight = 0; protected int mVisibleHeight = 0;
protected boolean mFullScreenEnabled = false;
protected int mFullScreenWidth = 0;
protected int mFullScreenHeight = 0;
private int mViewTag = 0; private int mViewTag = 0;
public Cocos2dxVideoView(Context context,int tag) { public Cocos2dxVideoView(Cocos2dxActivity activity,int tag) {
super(context); super(activity);
mViewTag = tag; mViewTag = tag;
mContext = context; mCocos2dxActivity = activity;
initVideoView();
}
public Cocos2dxVideoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
mContext = context;
initVideoView();
}
public Cocos2dxVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
initVideoView(); initVideoView();
} }
@ -115,11 +103,11 @@ public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mVideoWidth == 0 || mVideoHeight == 0) { if (mVideoWidth == 0 || mVideoHeight == 0) {
setMeasuredDimension(mViewWidth, mViewHeight); setMeasuredDimension(mViewWidth, mViewHeight);
Log.e(TAG, ""+mViewWidth+ ":" +mViewHeight); Log.i(TAG, ""+mViewWidth+ ":" +mViewHeight);
} }
else { else {
setMeasuredDimension(mVisibleWidth, mVisibleHeight); setMeasuredDimension(mVisibleWidth, mVisibleHeight);
Log.e(TAG, ""+mVisibleWidth+ ":" +mVisibleHeight); Log.i(TAG, ""+mVisibleWidth+ ":" +mVisibleHeight);
} }
} }
@ -131,6 +119,18 @@ public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl
mViewHeight = maxHeight; mViewHeight = maxHeight;
if (mVideoWidth != 0 && mVideoHeight != 0) { if (mVideoWidth != 0 && mVideoHeight != 0) {
fixSize(mViewLeft, mViewTop, mViewWidth, mVideoHeight);
}
}
public void setFullScreenEnabled(boolean enabled, int width, int height) {
if (mFullScreenEnabled != enabled) {
mFullScreenEnabled = enabled;
if (width != 0 && height != 0) {
mFullScreenWidth = width;
mFullScreenHeight = height;
}
fixSize(); fixSize();
} }
} }
@ -265,7 +265,7 @@ public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl
// TODO: these constants need to be published somewhere in the framework. // TODO: these constants need to be published somewhere in the framework.
Intent i = new Intent("com.android.music.musicservicecommand"); Intent i = new Intent("com.android.music.musicservicecommand");
i.putExtra("command", "pause"); i.putExtra("command", "pause");
mContext.sendBroadcast(i); mCocos2dxActivity.sendBroadcast(i);
// we shouldn't clear the target state, because somebody might have // we shouldn't clear the target state, because somebody might have
// called start() previously // called start() previously
@ -288,10 +288,10 @@ public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl
mDuration = -1; mDuration = -1;
mCurrentBufferPercentage = 0; mCurrentBufferPercentage = 0;
if (isAssetRouse) { if (isAssetRouse) {
AssetFileDescriptor afd = mContext.getAssets().openFd(fileName); AssetFileDescriptor afd = mCocos2dxActivity.getAssets().openFd(fileName);
mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength()); mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
} else { } else {
mMediaPlayer.setDataSource(mContext, mUri); mMediaPlayer.setDataSource(mCocos2dxActivity, mUri);
} }
mMediaPlayer.prepareAsync(); mMediaPlayer.prepareAsync();
@ -321,27 +321,35 @@ public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl
} }
public void fixSize() { public void fixSize() {
if (mViewWidth != 0 && mViewHeight != 0) { if (mFullScreenEnabled) {
fixSize(0, 0, mFullScreenWidth, mFullScreenHeight);
} else {
fixSize(mViewLeft, mViewTop, mViewWidth, mVideoHeight);
}
}
public void fixSize(int left,int top,int width,int height) {
if (width != 0 && height != 0) {
if (mKeepRatio) { if (mKeepRatio) {
if ( mVideoWidth * mViewHeight > mViewWidth * mVideoHeight ) { if ( mVideoWidth * height > width * mVideoHeight ) {
mVisibleWidth = mViewWidth; mVisibleWidth = width;
mVisibleHeight = mViewWidth * mVideoHeight / mVideoWidth; mVisibleHeight = width * mVideoHeight / mVideoWidth;
} else if ( mVideoWidth * mViewHeight < mViewWidth * mVideoHeight ) { } else if ( mVideoWidth * height < width * mVideoHeight ) {
mVisibleWidth = mViewHeight * mVideoWidth / mVideoHeight; mVisibleWidth = height * mVideoWidth / mVideoHeight;
mVisibleHeight = mViewHeight; mVisibleHeight = height;
} }
mVisibleLeft = mViewLeft + (mViewWidth - mVisibleWidth) / 2; mVisibleLeft = left + (width - mVisibleWidth) / 2;
mVisibleTop = mViewTop + (mViewHeight - mVisibleHeight) / 2; mVisibleTop = top + (height - mVisibleHeight) / 2;
} else { } else {
mVisibleLeft = mViewLeft; mVisibleLeft = left;
mVisibleTop = mViewTop; mVisibleTop = top;
mVisibleWidth = mViewWidth; mVisibleWidth = width;
mVisibleHeight = mViewHeight; mVisibleHeight = height;
} }
} }
else { else {
mVisibleLeft = mViewLeft; mVisibleLeft = left;
mVisibleTop = mViewTop; mVisibleTop = top;
mVisibleWidth = mVideoWidth; mVisibleWidth = mVideoWidth;
mVisibleHeight = mVideoHeight; mVisibleHeight = mVideoHeight;
} }
@ -437,7 +445,7 @@ public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl
* longer have a window, don't bother showing the user an error. * longer have a window, don't bother showing the user an error.
*/ */
if (getWindowToken() != null) { if (getWindowToken() != null) {
Resources r = mContext.getResources(); Resources r = mCocos2dxActivity.getResources();
int messageId; int messageId;
if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) { if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
@ -451,7 +459,7 @@ public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl
int titleId = r.getIdentifier("VideoView_error_title", "string", "android"); int titleId = r.getIdentifier("VideoView_error_title", "string", "android");
int buttonStringId = r.getIdentifier("VideoView_error_button", "string", "android"); int buttonStringId = r.getIdentifier("VideoView_error_button", "string", "android");
new AlertDialog.Builder(mContext) new AlertDialog.Builder(mCocos2dxActivity)
.setTitle(r.getString(titleId)) .setTitle(r.getString(titleId))
.setMessage(messageId) .setMessage(messageId)
.setPositiveButton(r.getString(buttonStringId), .setPositiveButton(r.getString(buttonStringId),

View File

@ -73,7 +73,7 @@ namespace experimental{
virtual void addEventListener(const VideoPlayer::ccVideoPlayerCallback& callback); virtual void addEventListener(const VideoPlayer::ccVideoPlayerCallback& callback);
virtual void onPlayEvent(VideoPlayer::EventType event); virtual void onPlayEvent(int event);
virtual void draw(Renderer *renderer, const Mat4& transform, uint32_t flags) override; virtual void draw(Renderer *renderer, const Mat4& transform, uint32_t flags) override;
protected: protected:

View File

@ -37,10 +37,10 @@
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
#define CLASS_NAME "org/cocos2dx/lib/Cocos2dxVideoHelper" #define CLASS_NAME "org/cocos2dx/lib/Cocos2dxVideoHelper"
void executeVideoCallback(int index,int event);
USING_NS_CC; USING_NS_CC;
static void executeVideoCallback(int index,int event);
extern "C" { extern "C" {
void Java_org_cocos2dx_lib_Cocos2dxVideoHelper_nativeExecuteVideoCallback(JNIEnv * env, jobject obj, jint index,jint event) { void Java_org_cocos2dx_lib_Cocos2dxVideoHelper_nativeExecuteVideoCallback(JNIEnv * env, jobject obj, jint index,jint event) {
executeVideoCallback(index,event); executeVideoCallback(index,event);
@ -87,6 +87,17 @@ void setVideoRectJNI(int index,int left,int top,int width,int height)
} }
} }
void setFullScreenEnabledJni(int index,bool enabled, int width, int height)
{
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "setFullScreenEnabled", "(IZII)V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID, index, enabled, width, height);
t.env->DeleteLocalRef(t.classID);
}
}
void setVideoURLJNI(int index,int videoSource,const std::string& videoUrl) void setVideoURLJNI(int index,int videoSource,const std::string& videoUrl)
{ {
JniMethodInfo t; JniMethodInfo t;
@ -166,16 +177,6 @@ VideoPlayer::VideoPlayer()
{ {
_videoPlayerIndex = createVideoWidgetJNI(); _videoPlayerIndex = createVideoWidgetJNI();
s_allVideoPlayers[_videoPlayerIndex] = this; s_allVideoPlayers[_videoPlayerIndex] = this;
auto listener = EventListenerKeyboard::create();
listener->onKeyReleased = [&](EventKeyboard::KeyCode keycode, cocos2d::Event* event){
if (keycode == EventKeyboard::KeyCode::KEY_BACKSPACE && _fullScreenEnabled)
{
this->setFullScreenEnabled(false);
}
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
} }
VideoPlayer::~VideoPlayer() VideoPlayer::~VideoPlayer()
@ -202,31 +203,23 @@ void VideoPlayer::draw(Renderer* renderer, const Mat4 &transform, uint32_t flags
{ {
cocos2d::ui::Widget::draw(renderer,transform,flags); cocos2d::ui::Widget::draw(renderer,transform,flags);
if ((flags&FLAGS_TRANSFORM_DIRTY) || _fullScreenDirty) if (flags & FLAGS_TRANSFORM_DIRTY)
{ {
_fullScreenDirty = false;
auto directorInstance = Director::getInstance(); auto directorInstance = Director::getInstance();
auto glView = directorInstance->getOpenGLView(); auto glView = directorInstance->getOpenGLView();
auto frameSize = glView->getFrameSize(); auto frameSize = glView->getFrameSize();
if (_fullScreenEnabled) auto winSize = directorInstance->getWinSize();
{
setVideoRectJNI(_videoPlayerIndex,0,0,frameSize.width,frameSize.height);
}
else
{
auto winSize = directorInstance->getWinSize();
auto leftBottom = convertToWorldSpace(Point::ZERO); auto leftBottom = convertToWorldSpace(Point::ZERO);
auto rightTop = convertToWorldSpace(Point(_contentSize.width,_contentSize.height)); auto rightTop = convertToWorldSpace(Point(_contentSize.width,_contentSize.height));
auto uiLeft = frameSize.width / 2 + (leftBottom.x - winSize.width / 2 ) * glView->getScaleX(); auto uiLeft = frameSize.width / 2 + (leftBottom.x - winSize.width / 2 ) * glView->getScaleX();
auto uiTop = frameSize.height /2 - (rightTop.y - winSize.height / 2) * glView->getScaleY(); auto uiTop = frameSize.height /2 - (rightTop.y - winSize.height / 2) * glView->getScaleY();
setVideoRectJNI(_videoPlayerIndex,uiLeft,uiTop, setVideoRectJNI(_videoPlayerIndex,uiLeft,uiTop,
(rightTop.x - leftBottom.x) * glView->getScaleX(), (rightTop.x - leftBottom.x) * glView->getScaleX(),
(rightTop.y - leftBottom.y) * glView->getScaleY()); (rightTop.y - leftBottom.y) * glView->getScaleY());
}
} }
#if CC_VIDEOPLAYER_DEBUG_DRAW #if CC_VIDEOPLAYER_DEBUG_DRAW
@ -241,7 +234,9 @@ void VideoPlayer::setFullScreenEnabled(bool enabled)
if (_fullScreenEnabled != enabled) if (_fullScreenEnabled != enabled)
{ {
_fullScreenEnabled = enabled; _fullScreenEnabled = enabled;
_fullScreenDirty = true;
auto frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();
setFullScreenEnabledJni(_videoPlayerIndex, enabled, frameSize.width, frameSize.height);
} }
} }
@ -344,17 +339,25 @@ void VideoPlayer::addEventListener(const VideoPlayer::ccVideoPlayerCallback& cal
_eventCallback = callback; _eventCallback = callback;
} }
void VideoPlayer::onPlayEvent(VideoPlayer::EventType event) void VideoPlayer::onPlayEvent(int event)
{ {
if (event == VideoPlayer::EventType::PLAYING) { if (event == 1024)
_isPlaying = true;
} else {
_isPlaying = false;
}
if (_eventCallback)
{ {
_eventCallback(this,event); _fullScreenEnabled = false;
}
else
{
VideoPlayer::EventType videoEvent = (VideoPlayer::EventType)event;
if (videoEvent == VideoPlayer::EventType::PLAYING) {
_isPlaying = true;
} else {
_isPlaying = false;
}
if (_eventCallback)
{
_eventCallback(this,videoEvent);
}
} }
} }
@ -385,7 +388,7 @@ void executeVideoCallback(int index,int event)
auto it = s_allVideoPlayers.find(index); auto it = s_allVideoPlayers.find(index);
if (it != s_allVideoPlayers.end()) if (it != s_allVideoPlayers.end())
{ {
s_allVideoPlayers[index]->onPlayEvent((VideoPlayer::EventType)event); s_allVideoPlayers[index]->onPlayEvent(event);
} }
} }

View File

@ -449,7 +449,7 @@ void VideoPlayer::addEventListener(const VideoPlayer::ccVideoPlayerCallback& cal
_eventCallback = callback; _eventCallback = callback;
} }
void VideoPlayer::onPlayEvent(VideoPlayer::EventType event) void VideoPlayer::onPlayEvent(int event)
{ {
if (event == VideoPlayer::EventType::PLAYING) { if (event == VideoPlayer::EventType::PLAYING) {
_isPlaying = true; _isPlaying = true;
@ -459,7 +459,7 @@ void VideoPlayer::onPlayEvent(VideoPlayer::EventType event)
if (_eventCallback) if (_eventCallback)
{ {
_eventCallback(this,event); _eventCallback(this, (VideoPlayer::EventType)event);
} }
} }