THREE.js的VideoTexture以及CanvasTexture在部分浏览器以及小程序webview中纯黑不起作用的解决办法

news2025/1/8 15:59:15

黑色是因为video没有自动播放导致的。
而且video必须设置muted(静音)属性,否则视频都无法播放;
如果不设置muted,也可以用设置x5-video-player-type="h5" 替代(意为兼容qq浏览器,解决在小程序中黑色的问题)

  const coverVideoTarget = document.getElementById('coverVideo');
  function initThree(){
    scene = new THREE.Scene();
    // camera = new THREE.Camera();
    camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,10000);
    camera.matrixAutoUpdate = false;
    scene.add(camera);
    scene.add(new THREE.AmbientLight(0xffffff, 1.5));
  
    root = new THREE.Object3D();
    root.matrixAutoUpdate = false;
    scene.add(root);


    renderer = new THREE.WebGLRenderer({ canvas: canvas, alpha: true, antialias: true });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(webglWidth, webglHeight);
    setVideo('./video/18912265449355602.mp4');
    // setModel();
  }
  function setVideo(videoUrl){
      console.log('setVideo')
      coverVideoTarget.src = videoUrl;
      const texture = new THREE.VideoTexture(coverVideoTarget);
      var mat = new THREE.MeshBasicMaterial({map: texture,transparent:true});
  
      const geo = new THREE.PlaneGeometry(400,240);
      // const geo = new THREE.PlaneGeometry(20,12);
      coverVideo = new THREE.Mesh(geo, mat);
      coverVideo.position.z = -50;
      coverVideo.position.x = 140;
      coverVideo.position.y = 200;
      root.add(coverVideo);
  }

  function setVideo2(videoUrl){
      console.log('setVideo2')
      coverVideoTarget.src = videoUrl;
      let vWidth = 400, vHeight = 240;
      coverVideoTarget.addEventListener('canplay', function () {
        vWidth = this.videoWidth;
        vHeight = this.videoHeight;
      });
  
       var canvas_process = document.createElement('canvas');// 未被加入body。用于绘制video帧图片并传入tracker识别使用
       var context_process = canvas_process.getContext('2d');
       const texture = new THREE.CanvasTexture(canvas_process);
       function update() {
        context_process.fillStyle = 'black';
        context_process.fillRect(0, 0, vWidth, vHeight);
        context_process.drawImage(coverVideoTarget, 0, 0, vWidth, vHeight);
        texture.needsUpdate = true;
        requestAnimationFrame(update);
      }
      update();
      var mat = new THREE.MeshBasicMaterial({map: texture,transparent:true});
  
      const geo = new THREE.PlaneGeometry(400,240);
      // const geo = new THREE.PlaneGeometry(20,12);
      coverVideo = new THREE.Mesh(geo, mat);
      coverVideo.position.z = -50;
      coverVideo.position.x = 140;
      coverVideo.position.y = 200;
      root.add(coverVideo);
  }
  
function initNFT(marker, videoUrl) {// video宽高比 240 : 360
    if (typeof(NFTworker) !== 'undefined') {
      NFTworker.terminate();
      NFTworker = undefined;
    }
    // setVideo(videoUrl);
    NFTworker = new Worker('../js/imgTracker.worker.js');
    NFTworker.postMessage({ type: "initNFT", pw: trackImgWidth, ph: trackImgHeight, trackData: './../examples/Data/camera_para.dat', marker: marker });
    var resultTime = new Date().getTime(),noResultTime = 0;
    NFTworker.onmessage = function (ev) {
      var msg = ev.data;
      switch (msg.type) {
        case "nftInitSuccess": {
          var proj = JSON.parse(msg.proj);
          proj[0] *= ratioW;
          proj[4] *= ratioW;
          proj[8] *= ratioW;
          proj[12] *= ratioW;
          proj[1] *= ratioH;
          proj[5] *= ratioH;
          proj[9] *= ratioH;
          proj[13] *= ratioH;
          setMatrix(camera.projectionMatrix, proj);
          nftProcess();
          break;
        }
        case 'found': {
          // console.log('found')
          coverVideo && (coverVideo.visible = true);
          coverVideoTarget.play();
          setMatrix(root.matrix, JSON.parse(msg.matrixGL_RH));
          renderer.render(scene, camera);
          resultTime = new Date().getTime();
          nftProcess();
          break;
        }
        case 'noResult': {
          coverVideo && (coverVideo.visible = false);
          coverVideoTarget.pause();
          renderer.render(scene, camera);
          var noResultTime = new Date().getTime();
          if (noResultTime - resultTime > 3000) {
            console.log('go track');
            // trackProcess('track');
            nftProcess();
          } else {
            nftProcess();
          }
          break;
        }
      }
    };
  };
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>ALVA Image Tracker</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=0.5, maximum-scale=1">
  <link rel="stylesheet" href="css/nft-style.css">
</head>
<style>
  #coverVideo{
    /* visibility: hidden; */
    position: fixed;
    /* left: 0px; */
    left: -1000000px;
    top:0px;
    z-index: 10000;
    width: 320px;
    height: 240px;
    background-color: pink;
  }
</style>
<body>
  <div id="loading" >
    <span class="loading-text">Loading, please wait</span>
  </div>
  <div id="app">
    <video
      loop
      autoplay
      muted
      playsinline
      id="cameraVideo">
    </video>
    <video id="coverVideo" loop controls  webkit-playsinline="true" x-webkit-airplay="true"
    playsinline="true" x5-video-player-type="h5" preload="auto" src='./video/18912265449355602.mp4'></video>

    <canvas id="canvas"></canvas>
  </div>

  <script src="../vconsole.min.js"></script>
  <script src="js/third_party/three.js/three.js"></script>
  <script src="js/third_party/three.js/GLTFLoader.js"></script>
  <script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

  <script src="threejs_worker.js"></script>

</body>

</html>

	var imgTracker;
	var cameraVideo = document.getElementById( 'cameraVideo' );
	if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
	  var hint = { audio: false, video: true };
	  if( window.innerWidth < 800 ) { // 宽高比为2/3或者3/2
	    var width = ( window.innerWidth < window.innerHeight ) ? 240 : 360;
	    var height = ( window.innerWidth < window.innerHeight ) ? 360 : 240;
	    width = width * window.devicePixelRatio;
	    height = height * window.devicePixelRatio;
	
	    hint = {
	      audio: false,
	      video: {
	        facingMode: 'environment',// 调用后置摄像头
	        width: { min: width, max: width }
	      },
	    };
	  }
	  navigator.mediaDevices.getUserMedia( hint ).then( function( stream ) {
	    cameraVideo.srcObject = stream;
	    cameraVideo.addEventListener( 'loadedmetadata', function() {
	      cameraVideo.play();
	      start(cameraVideo);
	    } );
	  } ).catch(err => {
	    console.log('catch');
	  });
	} else {
	
	}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

极客说|微软 Phi 系列小模型和多模态小模型

作者&#xff1a;胡平 - 微软云人工智能高级专家 「极客说」 是一档专注 AI 时代开发者分享的专栏&#xff0c;我们邀请来自微软以及技术社区专家&#xff0c;带来最前沿的技术干货与实践经验。在这里&#xff0c;您将看到深度教程、最佳实践和创新解决方案。关注「极客说」&am…

解决 IntelliJ IDEA 中 Tomcat 日志乱码问题的详细指南

目录 前言1. 分析问题原因2. 解决方案 2.1 修改 IntelliJ IDEA 的 JVM 选项2.2 配置 Tomcat 实例的 VM 选项 2.2.1 设置 Tomcat 的 VM 选项2.2.2 添加环境变量 3. 进一步优化 3.1 修改 Tomcat 的 logging.properties3.2 修改操作系统默认编码 3.2.1 Windows 系统3.2.2 Linux …

某小程序sign签名参数逆向分析

文章目录 1. 写在前面2. 接口分析3. 分析还原 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…

医学图像分析工具02:3D Slicer || 医学影像可视化与分析工具 支持第三方插件

3D Slicer 是一款功能全面的开源医学影像分析软件&#xff0c;广泛应用于影像处理、三维建模、影像配准和手术规划等领域。它支持多种医学影像格式&#xff08;如 DICOM、NIfTI&#xff09;和丰富的插件扩展&#xff0c;是神经科学、放射学和生物医学研究中不可或缺的工具。 在…

Linux系统安装es详细教程

一、下载es及插件 从下面的网址进行对应es版本的下载https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.2-linux-x86_64.tar.gz &#xff0c;想要不同版本的es只需更换对应的版本号即可。 插件下载地址&#xff08;ik分词器、pinyin等&#xff09;es…

电子电气架构 --- 汽车总线基础介绍

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…

安装PyQt5-tools卡在Preparing metadata (pyproject.toml)解决办法

为了在VS code中使用PyQt&#xff0c;在安装PyQt5-tools时总卡在如下这一步 pyqt5 Preparing metadata (pyproject.toml)经过各种尝试&#xff0c;最终问题解决&#xff0c;在此记录方法。 首先进入PyQt5-tools官网查看其适配的Python版本&#xff0c;网址如下&#xff1a; h…

38 Opencv HOG特征检测

文章目录 HOGDescriptor 构造函数setSVMDetector 设置支持向量机&#xff08;SVM&#xff09;检测器&#xff0c;用于目标检测。compute 用于计算图像区域的HOG描述符。detectMultiScale 多尺度检测目标。示例 HOGDescriptor 构造函数 HOGDescriptor(); HOGDescriptor(const S…

分布式搜索引擎之elasticsearch基本使用3

分布式搜索引擎之elasticsearch基本使用3 1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要让es和kibana容器互联。这里先创建一个网络&#xff1a; docker network create es-net1.2.加载镜像 这里我们采用elasticsearch的7.12.1版本的镜像&…

人工智能知识分享第九天-机器学习_集成学习

集成学习 概念 集成学习是机器学习中的一种思想&#xff0c;它通过多个模型的组合形成一个精度更高的模型&#xff0c;参与组合的模型称为弱学习器&#xff08;基学习器&#xff09;。训练时&#xff0c;使用训练集依次训练出这些弱学习器&#xff0c;对未知的样本进行预测时…

在线机考|2024华为实习秋招春招编程题(最新)——第3题_个性化歌单推荐系统_300分(十一)

题目内容 假设你是音乐服务的开发者,为了提高用户体验需要解决推荐歌单的同质化问题,保证推荐给用户的所有歌单不包含相同歌曲的。给定一个包含N个歌单和M条歌单重复记录,每个歌单用一个从1到N的整数编号,歌单重复记录包含两个歌单的ID,表示两个歌单有相同的歌曲。 你的任…

学英语学压测:02jmeter组件-测试计划和线程组ramp-up参数的作用

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#xff1a;先看关键单词&#xff0c;再看英文&#xff0c;最后看中文总结&#xff0c;再回头看一遍英文原文&#xff0c;效果更佳&#xff01;&#xff01; 关键词 Functional Testing功能测试[ˈfʌŋkʃənəl ˈtɛstɪŋ]Sample样…

最新最详细的配置Node.js环境教程

配置Node.js环境 一、前言 &#xff08;一&#xff09;为什么要配置Node.js&#xff1f;&#xff08;二&#xff09;NPM生态是什么&#xff08;三&#xff09;Node和NPM的区别 二、如何配置Node.js环境 第一步、安装环境第二步、安装步骤第三步、验证安装第四步、修改全局模块…

PHP框架+gatewayworker实现在线1对1聊天--接收消息(7)

文章目录 接收消息的原理接收消息JavaScript代码 接收消息的原理 接收消息&#xff0c;就是接受服务器转发的客户端消息。并不需要单独创建函数&#xff0c;因为 ws.onmessage会自动接收消息。我们需要在这个函数里进行处理。因为初始化的时候&#xff0c;已经处理的init类型的…

当算法遇到线性代数(四):奇异值分解(SVD)

SVD分解的理论与应用 线性代数系列相关文章&#xff08;置顶&#xff09; 1.当算法遇到线性代数&#xff08;一&#xff09;&#xff1a;二次型和矩阵正定的意义 2.当算法遇到线性代数&#xff08;二&#xff09;&#xff1a;矩阵特征值的意义 3.当算法遇到线性代数&#xff0…

科研绘图系列:R语言科研绘图之标记热图(heatmap)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理画图系统信息参考介绍 科研绘图系列:R语言科研绘图之标记热图(heatmap) 加载R包 library(tidyverse) library(ggplot2) library(reshape)…

Mysql--基础篇--SQL(DDL,DML,窗口函数,CET,视图,存储过程,触发器等)

SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是用于管理和操作关系型数据库的标准语言。它允许用户定义、查询、更新和管理数据库中的数据。SQL是一种声明性语言&#xff0c;用户只需要指定想要执行的操作&#xff0c;而不需要详细说明如何…

Excel重新踩坑5:二级下拉列表制作;★数据透视表;

0、在excel中函数公式不仅可以写在单元格里面&#xff0c;还可以写在公式里面。 1、二级下拉列表制作&#xff1a; 2、数据透视表&#xff1a; 概念&#xff1a;通过拖拉就能实现复杂函数才能实现的数据统计问题。 概览&#xff1a;在插入选项中有个数据透视表&#xff0c;数…

Linux-----进程处理(waitpid,进程树,孤儿进程)

目录 waitpid等待 进程树 孤儿进程 waitpid等待 Linux中父进程除了可以启动子进程&#xff0c;还要负责回收子进程的状态。如果子进程结束后父进程没有正常回收&#xff0c;那么子进程就会变成一个僵尸进程——即程序执行完成&#xff0c;但是进程没有完全结束&#xff0c;其…

解决报错net.sf.jsqlparser.statement.select.SelectBody

在我们项目集成mybatis-plus时,总会遇到奇奇怪怪的报错,比如说下面的这个报错 而这个报错,是告诉我们的分页依赖冲突,要加个jsqlparser依赖来解决这个冲突,也相当于平衡,但是可能因为我们版本的不匹配,还是会报错,例如下面这样 但是我们是不知道到底是什么依赖冲突的,这个时候就…