Cocos使用精灵组件显示相机内容

Cocos使用精灵组件显示相机内容

1. 为什么使用精灵渲染

在游戏引擎中,游戏场景内除webviewvideo外所有的节点都是渲染在Canvas上,这导致了webviewvideo只能存在于所有节点的最上层或最下层,而这种层级关系会出现节点事件无法正常监听或者webviewvideo被遮挡,为解决这个问题可以通过将影像渲染在精灵组件上。

2. 如何实现

2.1 添加视频标签

可以直接用代码创建,也可以在构建后添加到index.html文件中;

// 创建一个新的视频元素
let video = document.createElement("video");
// 设置视频元素的 ID
video.setAttribute('id', this._player_container_id);
// 设置视频预加载属性为自动
video.setAttribute('preload', 'auto');
// 将视频元素隐藏
video.setAttribute('hidden', 'hidden');
// 设置视频元素的样式,宽高都为0,以隐藏视频
video.setAttribute('style', 'width: 0px; height: 0px;')
// 将视频元素添加到文档的主体中
document.body.appendChild(video);

2.2 逻辑实现

原理是将视频内容根据自己设置的固定帧绘制在画布,再将纹理转换成精灵帧显示在精灵组件上;(适用于相机采集、直播采集、视频文件播放等)

private _texture: cc.Texture2D; // 用于存储纹理
private _canvas: HTMLCanvasElement; // HTML画布元素
private _canvasCtx: CanvasRenderingContext2D; // 画布的2D上下文
private _sprite: cc.Sprite; // 精灵组件

private spriteFrameCache: cc.SpriteFrame[] = []; // 精灵帧缓存数组
private index = 0; // 当前使用的缓存索引
private _video; // 视频元素

private lastUpdateTime = -1; // 上一次更新时间
private _Timer = 0; // 定时器

init() {
    // 创建画布并设置尺寸
    let canvas: HTMLCanvasElement = document.createElement('canvas');
    canvas.width = this.node.width; // 设置画布宽度
    canvas.height = this.node.height; // 设置画布高度
    this._canvas = canvas; // 保存画布引用
    this._canvasCtx = canvas.getContext('2d'); // 获取2D上下文
    this._sprite = this.getComponent(cc.Sprite); // 获取精灵组件
    this._texture = new cc.Texture2D(); // 创建新的纹理对象
    // 初始化两个精灵帧并存入缓存
    for (let i = 0; i < 2; i++) {
        this.spriteFrameCache.push(new cc.SpriteFrame()); // 创建精灵帧并加入缓存
    }
}
private async updateTexture(): Promise<void> {
    // 如果视频未定义,返回
    if (this._video == undefined) return;
    // 如果视频未暂停且当前时间与最后更新时间不同,进行更新
    if (!this._video.paused && this._video.currentTime !== this.lastUpdateTime) {
        this.lastUpdateTime = this._video.currentTime; // 更新最后更新时间
        this._Timer = 0; // 重置计时器
    } else if (this._Timer < 10) {
        this._Timer += 1 / 25; // 增加计时器
    } else {
        this.unschedule(this.updateTexture); // 取消调度
        this.clearSprite(); // 清空精灵
        this._Timer = 0; // 重置计时器
        console.log('updateTexture fail'); // 打印失败日志
        return; // 返回
    }
   
    // 在画布上绘制视频内容
    this._canvasCtx.drawImage(this._video, 0, 0, this.node.width, this.node.height);
    this._texture.initWithElement(this._canvas); // 用画布元素初始化纹理
    let spriteFrame = this.spriteFrameCache[this.index]; // 获取当前索引的精灵帧
    spriteFrame.setTexture(this._texture); // 设置精灵帧的纹理
    this._sprite.spriteFrame = spriteFrame; // 更新精灵的显示帧
    this.index = this.index ^ 1; // 切换索引(0 和 1 之间切换)
}
bind(cb): void {
    // 获取本地视频元素
    this._video = document.querySelector("#local_video").children[0];
    // 请求用户媒体(音频和视频)
    navigator.mediaDevices
        .getUserMedia({
            audio: true,
            video: true
        })
        .then((stream) => {
            this.handleSuccess(stream); // 成功时处理流
            this._video.play(); // 播放视频
            cb(); // 调用回调
        })
        .catch(this.handleError); // 处理错误
}
handleSuccess(stream) {
    this._video.srcObject = stream; // 将流设置为视频播放器的源对象
}
handleError(e) {
    console.log("绑定失败:"); // 输出错误信息
    console.log(e); // 输出具体错误
}
clearSprite() {
    this._sprite.spriteFrame = null; // 清空精灵的显示帧
}
/**调用测试 **/
test() {
    this.bind(() => { // 绑定视频流并在完成后执行回调
        this.unschedule(this.updateTexture); // 取消之前的调度
        this.schedule(this.updateTexture, 1 / 25, cc.macro.REPEAT_FOREVER); // 调度更新纹理的方法
        this.init(); // 初始化设置
    });
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/904374.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QT找不到ffmpeg链接库解决方法

error: undefined reference to avformat_network_init() 一个神奇的报错&#xff0c;查了很久&#xff0c;检查步骤&#xff1a; 1、检查了 pro工程文件 2、链接库的真实性和正确性 在main.cpp中调用没有报错&#xff0c;在其它cpp文件中调用就报错。 破案了&#xff0c;…

详细了解C++11(1)

大家好呀&#xff0c;我是残念&#xff0c;希望在你看完之后&#xff0c;能对你有所帮助&#xff0c;有什么不足请指正&#xff01;共同学习交流哦 本文由&#xff1a;残念ing原创CSDN首发&#xff0c;如需要转载请通知 个人主页&#xff1a;残念ing-CSDN博客&#xff0c;欢迎各…

04.DDD与CQRS

学习视频来源&#xff1a;DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid1940048&ctype0 文章目录 定义职责分离DDD与CQRS的关系领域模型和查询模型特点命令场景的领域模型查询场景的查询模型 架构方案领域事件方案1&#xff1a…

【运动的&高尔夫球】高尔夫球检测系统源码&数据集全套:改进yolo11-CA-HSFPN

改进yolo11-HWD等200全套创新点大全&#xff1a;高尔夫球检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.10.30 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”展示的系统图片或者视频可…

【python】flash-attn安装

这个命令&#xff1a; 确保使用正确的 CUDA 12.6 工具链 设置必要的 CUDA 环境变量 包含了常见的 GPU 架构支持 利用你的128核心进行并行编译 # 清理之前的安装 proxychains4 pip uninstall -y flash-attn# 获取 CUDA 路径 CUDA_PATH$(dirname $(dirname $(which nvcc)))# 使用…

得计算题者得天下!软考系统集成计算题详解!

软考中级系统集成项目管理工程师考试一共有《综合知识》和《案例分析》两门科目&#xff0c;而在这两科中都会涉及到计算题&#xff0c;特别是案例分析中&#xff0c;计算题每次考试都会占到一道大题&#xff0c;共25分&#xff0c;占到了科目总分的1/4&#xff0c;所以对于系统…

第2章 Android App开发基础

第 2 章 Android App开发基础 bilibili学习地址 github代码地址 本章介绍基于Android系统的App开发常识&#xff0c;包括以下几个方面&#xff1a;App开发与其他软件开发有什么不一 样&#xff0c;App工程是怎样的组织结构又是怎样配置的&#xff0c;App开发的前后端分离设计…

腾讯云视频文件上传云存储时自动将mp4格式转码成m3u8

针对问题&#xff1a; 弱网环境下或手机网络播放mp4格式视频卡顿。 存储环境&#xff1a;腾讯云对象存储。 处理流程&#xff1a; 1&#xff1a;登录腾讯云控制台&#xff0c;进入对象存储服务&#xff0c;找到对应的存储桶&#xff0c;点击进入。 在任务与工作流选项卡中找…

如何下载安装TestLink?

一、下载TestLink、XAMPP TestLink 下载 |SourceForge.net 备用&#xff1a;GitHub - TestLinkOpenSourceTRMS/testlink-code&#xff1a; TestLink开源测试和需求管理系统 下载XAMPP&#xff1a; Download XAMPP 注意&#xff1a;TestLink与PHP版本有关系&#xff0c;所以XA…

【AI学习】扩散模型的一点思考:生成过程为什么要增加噪声项

前面学习了扩散模型&#xff0c;并做了总结PPT。 其中有一个疑问&#xff1a;在生成过程中&#xff0c;就是下图的算法2中的第四步&#xff0c;为什么要在预测了噪声项后&#xff0c;Xt减去预测的噪声后&#xff0c;还有再叠加一个噪声项&#xff1f;就是增加的部分。 李宏毅…

Halcon 多相机统一坐标系(标定)

多相机统一坐标系是指将多个不同位置的相机的图像采集到同一个坐标系下进行处理和分析的方法。 在计算机视觉和机器视觉领域中&#xff0c;多相机统一坐标系被广泛应用于三维重建、立体视觉、目标跟踪等任务中。 以gen_binocular_rectification_map&#xff08;生成描述图像映…

访问jenkins页面报错

安装fontconfig 即可 yum install fontconfig -y 安装完之后重启jenkins systemctl restart jenkins 再访问

安卓13 连接usb设备后不更新ui

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码更改4.彩蛋1.前言 有些界面在链接usb设备后,ui会被刷新,导致闪烁问题。 2.问题分析 像这种问题一般是usb事件,导致的ui事件更新了,处理方法是禁止该事件 3.代码更改 这块我们就需要在输入事件管理里面…

从变量的角度理解 Hooks , 变得更简单了

从变量角度理解Hooks 在React的世界里&#xff0c;Hooks的引入为函数式组件带来了前所未有的灵活性和能力。它们让我们得以完全摆脱class式的写法&#xff0c;在函数式组件中完成生命周期管理、状态管理、逻辑复用等几乎全部组件开发工作。这次&#xff0c;我们就从变量的角度…

【面试经典150】day 9

目录 1.Z 字形变换 2.找出字符串中第一个匹配项的下标 3.文本左右对齐 1.Z 字形变换 class Solution {public String convert(String s, int numRows) {//明明是N字形变换if(numRows<2) return s;//rows是可扩展的字符串数组List<StringBuilder>rowsnew ArrayLi…

sudo apt install jupyter-notebook安装notebook失败E: Aborting install.

问题&#xff1a; sudo apt install jupyter-notebook安装notebook失败E: Aborting install. ~/jie/mywork/PointNetCFD$ sudo apt install jupyter-notebook --fix-missing Reading package lists... Done Building dependency tree Reading state information... Do…

软件工程实践项目:人事管理系统

一、项目的需求说明 通过移动设备登录app提供简单、方便的操作。根据公司原来的考勤管理制度&#xff0c;为公司不同管理层次提供相应的权限功能。通过app上面的各种标准操作&#xff0c;考勤管理无纸化的实现&#xff0c;使公司的考勤管理更加科学规范&#xff0c;从而节省考…

AI与低代码的碰撞:企业数字化转型的新引擎

引言 在当今的商业环境中&#xff0c;企业数字化转型已从选择题变成了必答题。面对日益复杂的市场竞争和不断变化的客户需求&#xff0c;传统的开发模式常常显得力不从心——开发周期冗长、技术门槛高、成本居高不下&#xff0c;企业很难快速响应市场变化。而在这种背景下&…

WPF中实现PasswordBox的双向绑定

我们知道一个属性想要实现双向绑定&#xff0c;最基本的便是这个属性需要时依赖属性&#xff0c;但是微软工程师在设计的时候Password并不是依赖属性&#xff0c;那我们想要实现双向绑定该怎么去做呢&#xff1f; 最常用的便是改造PasswordBox,为它增加一个扩展属性&#xff0c…

聚链成网,趣链科技参与 “跨链创新联合体”建设

近日&#xff0c;2024全球数商大会在上海举办。大会由上海数据集团和上海市数商协会联合主办&#xff0c;上海市数据局和浦东新区人民政府支持&#xff0c;以“数联全球&#xff0c;商通未来——‘链’接数字经济新未来”为主题&#xff0c;聚焦区块链技术和应用场景展开。 会上…