欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

cocos creater 视频控件videoplayer动态切换到canvas下面(弹幕/自定义controls/显示二次开发)

程序员文章站 2022-03-16 15:41:46
功能需求:1. 之前有videoplayer的使用 不影响之前的功能2. cocos组件 需要显示到视频上边 3. android/ios/web 端实现4. cocos creater 版本 2.1.3参考链接:https://worthatry.cn/cocos-creator-ru-he-shi-bei-jing-tou-ming/设计思路:不影响原来的加载实现添加新的方法调用 swapUpToCanvas 在不修改原来代码的基础上。新写的代码手动调用swapUpToCanvas...

功能需求:

1. 之前有videoplayer的使用 不影响之前的功能
2. cocos组件 需要显示到视频上边 
3. android/ios/web 端实现
4. cocos creater 版本 2.1.3

参考链接:
https://worthatry.cn/cocos-creator-ru-he-shi-bei-jing-tou-ming/

设计思路:

不影响原来的加载实现
添加新的方法调用 swapUpToCanvas 在不修改原来代码的基础上。新写的代码手动调用swapUpToCanvas 使视频控件切换到 canvas 下边

方案实现:

cocos js代码修改:

		// 可以添加到 main.js 游戏启动之前 
		// 也可以添加到 第一个场景 的js 文件中
		// 开启cocos creater 的canvas 支持透明
        cc.macro.ENABLE_TRANSPARENT_CANVAS = true;

cocos scene 设置

  1. 场景camera设置 opaque属性为true
    cocos creater 视频控件videoplayer动态切换到canvas下面(弹幕/自定义controls/显示二次开发)
  2. 设置 camera 的backgroundColor 的alpha为0
    cocos creater 视频控件videoplayer动态切换到canvas下面(弹幕/自定义controls/显示二次开发)

web端代码修改

		// 在VideoPlayerImpl 基类里边添加如下方法
		swapUpToCanvas:function swapUpToCanvas(){
            this._video && (this._video.style.zIndex = -1);
      	},

安卓端代码修改

  1. 为了不影响旧代码的效果 我们不需要修改 Cocos2dxVideoHelper.java (如果没有上下切换的需求 可以直接设置取消置顶)
	private void _createVideoView(int index) {
        Cocos2dxVideoView videoView = new Cocos2dxVideoView(mActivity,index);
        sVideoViews.put(index, videoView);
        FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.WRAP_CONTENT,
                FrameLayout.LayoutParams.WRAP_CONTENT);
        mLayout.addView(videoView, lParams);
        // 设置 video 置顶。 如果没有切换video 层级的需求 可以直接注释这句
        videoView.setZOrderOnTop(true);
        videoView.setVideoViewEventListener(videoEventListener);
    }
  1. 修改 AppActivity.java 文件 设置渲染支持透明通道
	public Cocos2dxGLSurfaceView onCreateView() {
        //Log.e("--- cccccc ---", "onCreateView 111");
        Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
        // TestCpp should reate stencil buffer
        // glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
	
		// 设置支持透明通道
        glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 8);
        glSurfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);
        glSurfaceView.setZOrderMediaOverlay(true);

        return glSurfaceView;
    }
  1. 修改 Cocos2dxVideoView.java 文件 解除原始videoPlayer 控件的点击拦击
	public boolean onTouchEvent(MotionEvent event) {
        if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {
            this.sendEvent(EVENT_CLICKED);
        }
        // return true;
        return false; 		// 因为video 显示到canvas下边了。所以没必要拦截点击 
    }
  1. 修改 Cocos2dxVideoHelper.java 添加方法swapUpToCanvas
	// 备注 这里只写了实现方式。 具体js调用java方法 请参考: _startVideo / _pauseVideo / _stopVideo 等其余引擎代码的实现。
	private void swapUpToCanvas(int index) {
        Cocos2dxVideoView view = sVideoViews.get(index);
        Log.d("cocosswap", "swapUpToCanvas: start");
        if (view != null) {
            Log.d("cocosswap", "swapUpToCanvas: success");
            view.setZOrderOnTop(false);
        }
    }

ios端代码的修改:

  1. 修改CCApplication-ios.mm 渲染格式 支持透明通道
void Application::onCreateView(PixelFormat& pixelformat, DepthFormat& depthFormat, int& multisamplingCount)
{
	// 修改渲染格式 支持 透明通道
    pixelformat = PixelFormat::RGBA8;
    depthFormat = DepthFormat::DEPTH24_STENCIL8;

    multisamplingCount = 0;
}
  1. 修改 video 添加到 canvas 窗口下边
  • 2.1 方法1 直接把cocos 的窗口的父节点创建一个两个节点。一层显示video 一层显示cocos(这种方式 调起照相机的时候 opengl会报错 具体原因未知)
// AppController.mm 文件修改如下内容

	// 先添加videoView再添加cocosView
    UIViewController* rvC = [[UIViewController alloc]init];
    // 视频view
    UIView *videoView = [[UIView alloc] initWithFrame:bounds];
    videoView.tag = 10; // 通过tag找到view
    [rvC.view addSubview:videoView];
    // 引擎view
    UIView *cocosView = _viewController.view;
    cocosView.frame = bounds;//
    cocosView.backgroundColor = [UIColor clearColor];
    [rvC.view addSubview:cocosView];
    
    // Set RootViewController to window
    if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
    {
        // warning: addSubView doesn't work on iOS6
         [window addSubview: rvC.view]; //新的rootView
    }
    else
    {
        // use this method on ios6
        [window setRootViewController:rvC]; //新的rootView
    }

// VideoPlayer-ios.mm 代码修改如下内容

// 备注 这里只写了实现方式。 具体js调用oc方法 请参考: play / pause / resume 等其余引擎代码的实现。
-(void)swapUpToCanvas{
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    // cocos 的父节点里 把video 的预设层级取出来 添加video
    [[[eaglview superview] viewWithTag:10] addSubview:self.playerController.view];
}
  • 2.2 方法2 不修改原始 cocos 的结构。 通过 keywindow 获取video节点
// 我们是项目中是 自定义的viewControl.mm里修改 (正常工程应该是 AppController.mm)文件修改如下内容 初始化修改

	UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    alertWindow.windowLevel = UIWindowLevelAlert;
    alertWindow.backgroundColor = HexRGB(0xffa86f);
    alertWindow.rootViewController = self;
    self.view.frame = CGRectMake(0, 0, APP_SCREEN_WIDTH, APP_SCREEN_HEIGHT);
    // 视频view
    UIView *videoView = [[UIView alloc] init];
    videoView.backgroundColor = UIColor.blackColor;
    videoView.tag = 10; // 通过tag找到view
    [alertWindow addSubview:videoView];
    [videoView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.bottom.right.equalTo(alertWindow);
    }];
    self.cocosWindow = alertWindow;
    //--
    self.previousWindow = [UIApplication sharedApplication].keyWindow;
// VideoPlayer-ios.mm 代码修改如下内容

// 备注 这里只写了实现方式。 具体js调用oc方法 请参考: play / pause / resume 等其余引擎代码的实现。
-(void)swapUpToCanvas{
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    [[window viewWithTag:10] addSubview:self.playerController.view];
}

逻辑中 代码 调用swapUpToCanvas

			// 请注意调用时机。如果 不行的话 自行探索一下 我们项目组是这样调用的
			if(this._player.$VideoPlayer && this._player.$VideoPlayer.swapUpToCanvas){
                if (cc.sys.os == cc.sys.OS_IOS){
                	// ios 是 video 实例创建出来以后 才能调用 
                    this.node.runAction(cc.sequence(cc.delayTime(1), cc.callFunc(() => {
                            this._player.$VideoPlayer.swapUpToCanvas()
                        }),
                        cc.delayTime(1),cc.callFunc(() => {
                            this._player.$VideoPlayer.swapUpToCanvas()
                        }),
                        cc.delayTime(1),cc.callFunc(() => {
                            this._player.$VideoPlayer.swapUpToCanvas()
                        }),
                        cc.delayTime(1),cc.callFunc(() => {
                            this._player.$VideoPlayer.swapUpToCanvas()
                        })
                    ))
                } else {
                	// web / android 均可以直接调用 
                    this._player.$VideoPlayer.swapUpToCanvas()
                }
                
            }
        }
        

至此 项目中就可以动态切换 video 和 canvas 的层级了
video 需要在canvas上边 常规写法就可以
video 需要在canvas上边 创建videoPlayer 的时候。调用一下swapUpToCanvas 即可

本文地址:https://blog.csdn.net/qq_45504161/article/details/110294284