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

人气:632 发布:2022-10-16 标签: queryselector aframe ar.js

问题描述

最终更新 2019 年 9 月 13 日晚上 11:50:此代码适用于多个自定义标记,但标记不能太相似.我以前的自定义标记都是具有轻微差异的星星,我认为这以某种方式绊倒了它.但是有了更新、更独特的标记,它就起作用了.

FINAL UPDATE 9/13/2019 11:50pm : This code works with several custom markers, however the markers cannot be too similar. My previous custom markers were all stars with mild differences, and I think this was tripping it up somehow. But with newer, more unique markers, it works.

但出于某种原因,这并没有影响使用单独组件"方法时的结果.

For some reason, though, this did not affect the result when using the "separate components" method.

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

Updated: 9/13/2019 : The below code works with hiro and kanji preset markers and one custom marker. However, when I add multiple custom markers, the videos freeze on the extra markers. I would like each marker to trigger unique videos (some videos will be re-used in several markers). In my current code, I just have them all triggering both videos. *How can I get this code to work with multiple custom markers?

<!-- 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 更新:如何使用单独的标记播放单独的视频,并可选择重复使用某些视频?使用以下代码,视频显示为静态图像:

Updated 9-12-19 : how to play separate videos with separate markers, with option to re-use certain videos? With the following code, the videos display as a static image:

<!-- 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>

原始问题:

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

Please forgive me as I am very new to this....

我将 ar.js 与 aframe 结合使用来创建 webAR 体验.我使用两个不同的标记来触发两个不同的视频.

I'm using ar.js with aframe to create a webAR experience. I'm using two different markers to trigger two different videos.

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

How do I make the Aframe.register component trigger both of my videos separately? The two videos are listed as assets, with the following IDs: #vid #videonew

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

the expected results are for the two markers to display a unique video that loops, whether both markers are shown to the webcam, or if it's just one of the markers. But the actual result is the videos only play if both markers are shown to the webcam. Otherwise, individually, the videos display as a static image.

<!-- 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) 返回具有匹配元素的容器 (NodeList).要在每个视频上调用 .play(),您需要 遍历容器 并在每个元素上调用它.

1. One marker triggers two videos

document.querySelectorAll(selector) returns a container (NodeList) with the matching elements. To call .play() on each video, you need to iterate through the container and call it on each element.

每个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 也无妨:)

Also it wouldn't hurt to rename it to this.videoNodes :)

查看 this 故障,了解如何使用 aframe 和 ar 触发两个视频.js

Check out in this glitch how you can do triggering two videos with aframe, and ar.js

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

No need to duplicate the component for each marker, you only need a modification which will allow providing the video to the component. That way you can use the same component, for different video elements. We can achieve that with the components schema.

js - 使用架构中的元素

js - using the element from the schema

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

虽然这里有一些问题.

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

工作故障此处.

461