如何使用 ar.js 触发多个视频

How to trigger multiple videos with ar.js

最终更新 2019 年 9 月 13 日 11:50pm: 此代码适用于多个自定义标记,但这些标记不能太相似。我以前的自定义标记都是星星,有轻微的差异,我认为这不知何故把它绊倒了。但有了更新、更独特的标记,它就起作用了。

尽管如此,由于某些原因,这并没有影响使用 "separate components" 方法时的结果。


更新时间:2019 年 9 月 13 日:以下代码适用于 hiro 和汉字预设标记以及一个自定义标记。但是,当我添加 多个 自定义标记时,视频会冻结在额外的标记上。我希望每个标记都能触发独特的视频(一些视频将在多个标记中重复使用)。在我当前的代码中,我只是让它们全部触发两个视频。 *如何让此代码与多个自定义标记一起使用?

<!-- A-FRAME -->
<script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script>
<script 
src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.6.0/aframe/build/aframe- 
ar.js"></script> 
<script src="https://cdn.rawgit.com/donmccurdy/aframe- 
extras/v4.1.2/dist/aframe-extras.min.js"></script> 
<script src="https://rawgit.com/mayognaise/aframe-gif- 
shader/master/dist/aframe-gif-shader.min.js"></script> 

<!-- jQuery library -->
<script 
 src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> 
</script> 

<!-- Latest compiled and minified CSS -->
<script 
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"> 
</script> 

<!-- vidhandler component -->
<script>
AFRAME.registerComponent('vidhandler', {
schema: {
  target: {type: 'string'}
},
init: function() {
    this.videoNodes = document.querySelectorAll(this.data.target)
},
tick: function() {
    if (this.el.object3D.visible == true) {
        if (!this.toggle) {
            this.toggle = true;
            for (let i = 0; i < this.videoNodes.length; i++) {
                this.videoNodes[i].play();
            } 
        }
    } else {
        if (this.toggle) {
          for (let i = 0; i < this.videoNodes.length; i++) {
            this.videoNodes[i].pause();
          }
          this.toggle = false;
        }
    }
}
});
</script>

<!-- assets for vidhandler -->
<a-assets >
    <video crossOrigin="Anonymous" Id="vid" 
loop="true"src="assets\textures\alpha.webm">
    </video>
    <video crossOrigin="Anonymous" Id="videonew" loop="true" src="assets\textures\VideoNew.mp4">
    </video>     
</a-assets>

 <!-- marker1: hollywood star 1 -->
 <a-marker  vidhandler="target: #vid, #videonew" type='pattern' url='https://raw.githubusercontent.com/merowell/custom-markers-with-video/master/aframe/examples/assets/hollywood-stars/patt/pattern-hollywood-star1.patt'>
    <!-- add transparent video (.webm) -->
    <a-plane  position='0 .3 0' width='3' height='2' rotation="-90 0 0" material='transparent:true;alphaTest:0;src:#vid'></a-plane>

    <!-- add non transparent video (.mp4) -->
    <a-plane  position='0 .2 0' width='1.5' height='1.5' rotation="-90 0 0" material='src:#videonew'></a-plane>
</a-marker>


<!-- marker2: hollywood star 2 -->
<a-marker  vidhandler="target: #vid, #videonew" type='pattern' url='https://raw.githubusercontent.com/merowell/custom-markers-with-video/master/aframe/examples/assets/hollywood-stars/patt/pattern-hollywood-star2.patt'>
     <!-- add transparent video (.webm) -->
    <a-plane  position='0 .3 0' width='3' height='2' rotation="-90 0 0" material='transparent:true;alphaTest:0;src:#vid'></a-plane>

    <!-- add non transparent video (.mp4) -->
    <a-plane  position='0 .2 0' width='1.5' height='1.5' rotation="-90 0 0" material='src:#videonew'></a-plane>
</a-marker>

9-12-19 更新:如何播放带有单独标记的单独视频,并可选择重新使用某些视频?使用以下代码,视频显示为静态图像:

<!-- vidhandler component -->
<script>
AFRAME.registerComponent('vidHandler', {
// define a variable in which we will keep the video element
schema: {
 targets: {type: "string"}
},
 init: function() {
    this.toggle = false;
    this.vidNodes = document.querySelectorAll(this.data.targets);
    for (let i = 0; i < this.vidNodes.length; i++) {
          this.vidNodes[i].pause();
    }
},
tick: function() {
    if (this.el.object3D.visible == true) {
        if (!this.toggle) {
            this.toggle = true;
            for (let i = 0; i < this.vidNodes.length; i++) {
              this.vidNodes[i].play();
            }
        }
    } else {
        this.toggle = false;
        for (let i = 0; i < this.vidNodes.length; i++) {
          this.vidNodes[i].pause();
        }
    }
}
});
</script>

原问题:

请原谅我,因为我对此很陌生....

我正在使用 ar.js 和框架来创建 webAR 体验。我正在使用两个不同的标记来触发两个不同的视频。

如何让 Aframe.register 组件分别触发我的两个视频?这两个视频被列为资产,具有以下 ID:#vid #videonew

预期结果是两个标记显示循环播放的独特视频,无论两个标记都显示在网络摄像头上,还是只是其中一个标记。但实际结果是视频只有在两个标记都显示给网络摄像头时才会播放。否则,视频单独显示为静态图像。

<!-- Video Player -->
<script>
AFRAME.registerComponent('vidhandler', {
init: function() {
    this.toggle = false;
    this.vidNodes = document.querySelectorAll("#vid, #videonew");
    for (let i = 0; i < this.vidNodes.length; i++) {
          this.vidNodes[i].pause();
    }
},
tick: function() {
    if (this.el.object3D.visible == true) {
        if (!this.toggle) {
            this.toggle = true;
            for (let i = 0; i < this.vidNodes.length; i++) {
              this.vidNodes[i].play();
            }
        }
    } else {
        this.toggle = false;
        for (let i = 0; i < this.vidNodes.length; i++) {
          this.vidNodes[i].pause();
        }
    }
}
});
</script>

<a-assets >
    <video crossOrigin="Anonymous" preload="auto"  Id="vid" loop="true"   webkit-playsinline playsinline controls>
       <source  type="video/webm"  src="assets\textures\alpha.webm">
       <h3>Error : Your browser does not support.</h3>
      <!-- FOR NOTMAL VIDEO YOU CAN USE MP4 or WEBM BUT FOR ALPHA VIDEO YOU NEED TO USE .WEBM FORMAT-->
    </video>

     <video crossOrigin="Anonymous" preload="auto"  Id="videonew" loop="true"   webkit-playsinline playsinline controls>
       <source  type="video/webm"  src="assets\textures\VideoNew.mp4">
       <h3>Error : Your browser does not support.</h3>
      <!-- FOR NOTMAL VIDEO YOU CAN USE MP4 or WEBM BUT FOR ALPHA VIDEO YOU NEED TO USE .WEBM FORMAT-->
    </video>
</a-assets>

1。一个标记触发两个视频

document.querySelectorAll(selector) returns 具有匹配元素的容器 (NodeList)。 要在每个视频上调用 .play(),您需要 iterate through the container 并在每个元素上调用它。


每个 this.vid.play()this.vid.pause() 需要替换为:

for (let i = 0; i < this.vid.length; i++) {
    this.vid[i].play() // or this.vid[i].pause()
}

此外,将其重命名为 this.videoNodes 也无妨:)


this 故障中查看如何使用 aframe 和 ar.js

触发两个视频

2。两个标记,每个标记都有一个独特的视频

无需为每个标记复制组件,您只需要进行修改即可为组件提供视频。这样您就可以对不同的视频元素使用相同的组件。我们可以用组件 schema.

来实现

js - 使用模式中的元素

AFRAME.registerComponent('vidHandler', {
  // define a variable in which we will keep the video element
  schema: {
     video: {type: 'selector'},
  },
  init: function() {
     // use the video from the schema
     this.video = this.data.video
     this.video.pause()
  },
  tick: function() {
    if (this.el.object3D.visible == true) {
      if (!this.toggle) {
        this.toggle = true;
        this.video.play()
      }
     } else {
      this.toggle = false;
      this.video.pause()
    }
  }
})

HTML - 向组件提供元素

<a-assets>
   <video id="one">
   <video id="two">
</a-assets>
<a-marker preset="hiro" vidhandler="video: #one">
    <a-box material='src: #one'></a-box>
</a-marker>
<a-marker preset="kanji" vidhandler="video: #two">
    <a-box material='src: #two'></a-box>
</a-marker>   

3。两个标记触发任意数量的视频

现在我们为组件提供了一个选择器,但我们也可以提供一个字符串来提供 document.querySelectorAll() 方法:

// <a-marker videohandler="videos: #one, #two">
// videohandler insides:
schema: {
  videos: {type: 'string'}
},
init: function() {
    this.videoNodes = document.querySelectorAll(this.data.target)
},
// the rest like in the first case

虽然这里有一些问题。

  • 确保只有在标记丢失时才暂停视频。否则,一个组件将在每次滴答时暂停视频。
  • 如果您想在另一个标记上从头开始播放视频,则需要在标记丢失后缓存时间戳。

工作故障here

@Piotr 回答了这个问题并提供了一个很好的例子来解决这个问题:https://glitch.com/edit/#!/stack-57863016?path=arjs.html:3:0

谢谢!另外,我失败的地方是我没有在 a-marker 部分包含 'vidhandler'。

终于!我明白了 --- 为了让单独的视频与单独的标记一起播放,我需要创建第二个组件。每个标记需要一个唯一的组件处理程序,至少,这就是我让它工作的方式。