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

黑色是因为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 {
	
	}

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

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

相关文章

【C++】C++11(二)

目录 九、可变参数模板十、lambda表达式10.1 C98中的一个例子10.2 lambda表达式10.3 lambda表达式语法10.3.1 lambda表达式各部分说明10.3.2 捕获列表说明 10.4 函数对象与lambda表达式 十一、包装器11.1 function包装器11.2 bind 十二、线程库12.1 线程12.1.1 thread类的简单介…

《零基础Go语言算法实战》【题目 1-16】字符串的遍历与比较

《零基础Go语言算法实战》 【题目 1-16】字符串的遍历与比较 给出两个字符串&#xff0c;请编写程序以确定能否将其中一个字符串重新排列后变成另一个字符串&#xff0c; 并规定大小写是不同的字符&#xff0c;空格也作为字符考虑。保证两个字符串的长度小于或等于 5000。 …

Type-C单口便携显示器-LDR6021

Type-C单口便携显示器是一种新兴的显示设备&#xff0c;它凭借其便携性、高性能和广泛的应用场景等优势&#xff0c;正在成为市场的新宠。以下是Type-C单口便携显示器的具体运用方式&#xff1a; 一、连接与传输 1. **设备连接**&#xff1a;Type-C单口便携显示器通过Type-C接…

聚类系列 (二)——HDBSCAN算法详解

在进行组会汇报的时候&#xff0c;为了引出本研究动机&#xff08;论文尚未发表&#xff0c;暂不介绍&#xff09;&#xff0c;需要对DBSCAN、OPTICS、和HDBSCAN算法等进行详细介绍。在查询相关资料的时候&#xff0c;发现网络上对于DBSCAN算法的介绍非常多与细致&#xff0c;但…

玩转 JMeter:Random Order Controller让测试“乱”出花样

嘿&#xff0c;各位性能测试的小伙伴们&#xff01;今天咱要来唠唠 JMeter 里超级有趣又超实用的 Random Order Controller&#xff08;随机顺序控制器&#xff09;&#xff0c;它就像是性能测试这场大戏里的“魔术棒”&#xff0c;轻轻一挥&#xff0c;就能让测试场景变得千变…

L1G5000 XTuner 微调个人小助手认知

使用 XTuner 微调 InternLM2-Chat-7B 实现自己的小助手认知 1 环境配置与数据准备步骤 0. 使用 conda 先构建一个 Python-3.10 的虚拟环境步骤 1. 安装 XTuner 修改提供的数据步骤 0. 创建一个新的文件夹用于存储微调数据步骤 1. 创建修改脚本步骤 2. 执行脚本步骤 3. 查看数据…

UE5 使用内置组件进行网格切割

UE引擎非常强大&#xff0c;直接内置了网格切割功能并封装为蓝图节点&#xff0c;这项功能在UE4中就存在&#xff0c;并且无需使用Chaos等模块。那么就来学习下如何使用内置组件实现网格切割。 1.配置测试用StaticMesh 对于被切割的模型&#xff0c;需要配置一些参数。以UE5…

springmvc执行分析

步骤分析 1.浏览器客户端携带请求路径&#xff0c;本案例中是“/hello”&#xff0c;通过 web.xml 中的前端控制器配置&#xff0c;发送请求到前端控制器(DispatcherServlet)&#xff0c;并加载 SpringMVC.xml 配置文件&#xff0c;将 HelloController 加载进IOC容器当中&…

LLM - Llama 3 的 Pre/Post Training 阶段 Loss 以及 logits 和 logps 概念

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145056912 Llama 3 是 Meta 公司发布的开源大型语言模型&#xff0c;包括具有 80 亿和 700 亿参数的预训练和指令微调的语言模型&#xff0c;支持…

【python基础——异常BUG】

什么是异常(BUG) 检测到错误,py编译器无法继续执行,反而出现错误提示 如果遇到错误能继续执行,那么就捕获(try) 1.得到异常:try的执行,try内只可以捕获一个异常 2.预案执行:except后面的语句 3.传入异常:except … as uestcprint(uestc) 4.没有异常:else… 5.鉴定完毕,收尾的语…

(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验六----流域综合处理(超超超详细!!!)

流域综合处理 流域综合治理是根据流域自然和社会经济状况及区域国民经济发展的要求,以流域水流失治理为中心,以提高生态经济效益和社会经济持续发展为目标,以基本农田优化结构和高效利用及植被建设为重点,建立具有水土保持兼高效生态经济功能的半山区流域综合治理模式。数字高程…

设计模式与游戏完美开发(3)

更多内容可以浏览本人博客&#xff1a;https://azureblog.cn/ &#x1f60a; 该文章主体内容来自《设计模式与游戏完美开发》—蔡升达 第二篇 基础系统 第五章 获取游戏服务的唯一对象——单例模式&#xff08;Singleton&#xff09; 游戏实现中的唯一对象 在游戏开发过程中…

VSCode 在Windows下开发时使用Cmake Tools时输出Log乱码以及CPP文件乱码的终极解决方案

在Windows11上使用VSCode开发C程序的时候&#xff0c;由于使用到了Cmake Tools插件&#xff0c;在编译运行的时候&#xff0c;会出现输出日志乱码的情况&#xff0c;那么如何解决呢&#xff1f; 这里提供了解决方案&#xff1a; 当Settings里的Cmake: Output Log Encoding里设…

Solidity入门: 函数

函数 Solidity语言的函数非常灵活&#xff0c;可以进行各种复杂操作。在本教程中&#xff0c;我们将会概述函数的基础概念&#xff0c;并通过一些示例演示如何使用函数。 我们先看一下 Solidity 中函数的形式: function <function name>(<parameter types>) {in…

基于 Python 自动化接口测试(踩坑与实践)

文档&#xff1a;基于 Python 的自动化接口测试 目录 背景问题描述与解决思路核心代码修改点及其详细解释最终测试结果后续优化建议 1. 问题背景 本项目旨在使用 Python 模拟浏览器的请求行为&#xff0c;测试文章分页接口的可用性。测试目标接口如下&#xff1a; bashcoder…

Spring Boot教程之五十一:Spring Boot – CrudRepository 示例

Spring Boot – CrudRepository 示例 Spring Boot 建立在 Spring 之上&#xff0c;包含 Spring 的所有功能。由于其快速的生产就绪环境&#xff0c;使开发人员能够直接专注于逻辑&#xff0c;而不必费力配置和设置&#xff0c;因此如今它正成为开发人员的最爱。Spring Boot 是…

web-app uniapp监测屏幕大小的变化对数组一行展示数据作相应处理

web-app uniapp监测屏幕大小的变化对数组一行展示数据作相应处理 1.uni.getSystemInfoSync().screenWidth; 获取屏幕宽度 2.uni.onWindowResize&#xff08;&#xff09; 实时监测屏幕宽度变化 3.根据宽度的大小拿到每行要展示的数量itemsPerRow 4.为了确保样式能够根据 items…

使用强化学习训练神经网络玩俄罗斯方块

一、说明 在 2024 年暑假假期期间&#xff0c;Tim学习并应用了Q-Learning &#xff08;一种强化学习形式&#xff09;来训练神经网络玩简化版的俄罗斯方块游戏。在本文中&#xff0c;我将详细介绍我是如何做到这一点的。我希望这对任何有兴趣将强化学习应用于新领域的人有所帮助…

计算机网络 (32)用户数据报协议UDP

前言 用户数据报协议&#xff08;UDP&#xff0c;User Datagram Protocol&#xff09;是计算机网络中的一种重要传输层协议&#xff0c;它提供了无连接的、不可靠的、面向报文的通信服务。 一、基本概念 UDP协议位于传输层&#xff0c;介于应用层和网络层之间。它不像TCP那样提…

如何将 DotNetFramework 项目打包成 NuGet 包并发布

如何将 DotNetFramework 项目打包成 NuGet 包并发布 在软件开发过程中&#xff0c;将项目打包成 NuGet 包并发布到 NuGet 库&#xff0c;可以让其他开发者方便地引用和使用你的项目成果。以下是将 WixWPFWizardBA 项目打包成 NuGet 包并发布的详细步骤&#xff1a; 1. 创建 .n…