javascript - 在<a-frame>实体上触发 'sound-ended'的最有效方法是什么

标签 javascript audio aframe webvr

我正在研究基于A帧的叙事结构。

我将语音文件分为三个部分,目标是仅在满足正确条件的情况下才触发序列中的每个音频。

我已经尝试过nar1.addEventListener('sound-ended',newCurrent),但是没有运气。
为简化起见,我将省略条件:

<!DOCTYPE html>
<html class="a-html">
  <head>
    <meta charset="utf-8">
    <title>Panorama</title>
    <meta name="description" content="Panorama — A-Frame">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script>
  </head>
  <body>
    <button id="play-button" class="centerPos">Begin Your Experience</button>
    <a-scene vr-mode-ui="enabled: true" stats>
    <a-assets>
        <!-- SOUNDS -->
        <audio id="n1" src="snd/dt_narration_1.mp3" preload="auto">
        <audio id="n2" src="snd/dt_narration_2.mp3" preload="auto">
        <audio id="n3" src="snd/dt_narration_3.mp3" preload="auto">
    </a-assets>
    <!-- SOUNDS -->
        <a-sound id="nar1" src="#n1" autoplay="false" position="0 5 0"></a-sound>
        <a-sound id="nar2" src="#n2" autoplay="false" position="0 5 0"></a-sound>
        <a-sound id="nar3" src="#n3" autoplay="false" position="0 5 0"></a-sound>
    </a-scene>
  </body>
</html>
<script>
// sound assets
var nar_1 = document.getElementById('n1');
var nar_2 = document.getElementById('n2');
var nar_3 = document.getElementById('n3');

// a-sound entities
var nar1 = document.getElementById('nar1');
var nar2 = document.getElementById('nar2');
var nar3 = document.getElementById('nar3');

// listeners attached to entities
nar1.addEventListener("sound-ended", newCurrent);
nar2.addEventListener("sound-ended", newCurrent);
nar3.addEventListener("sound-ended", newCurrent);

// Play button, required by browsers to grab user interaction before autoplaying videos.
document.getElementById('play-button').addEventListener("click", function(e){
nar_1.play();  // launch the first voice over
this.style.display = 'none';
}, false);

function newCurrent(){
    // if conditions are met and its not the last audio, trigger next audio.
    console.log("story control enter.  You made it!");
}
</script>

最佳答案

嗯,也许是因为您正在使用<audio>元素,所以您必须侦听<audio>元素上的事件?如果您传递一个内联URL,我认为它将创建一个BufferSource(即sound-ended所基于的),而media元素则不会。不要在实体上使用sound-ended,请尝试:

document.querySelector("#n1").addEventListener('ended', newCurrent, false);

组件样式

您也可以将代码编写为在当前代码结束后播放声音的组件。
AFRAME.registerComponent('play-next-sound', {
  schema: {type: 'selector'},

  init: function () {
    var targetEl = this.data;  // Specified via schema.
    var soundEl = this.el;

    soundEl.addEventListener('sound-ended', function () {
      targetEl.components.sound.playSound();
    });
  }
});

然后:
<a-sound id="nar1" src="#n1" autoplay="false" position="0 5 0" play-next-sound="#nar2"></a-sound>
<a-sound id="nar2" src="#n2" autoplay="false" position="0 5 0" play-next-sound="#nar3"></a-sound>
<a-sound id="nar3" src="#n3" autoplay="false" position="0 5 0"></a-sound>

其他几种方法可以做到这一点:
  • 让组件发出事件并使用sound.on属性触发它,而不是手动播放声音。
  • 而不是链接它们,而是让一个父实体包含所有它们,并让一个组件捕获所有子对象并顺序播放。
  • 关于javascript - 在<a-frame>实体上触发 'sound-ended'的最有效方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39838449/

    相关文章:

    javascript - 获取 A 框架中实体的方向向量

    javascript - A 帧动画框在特定区域随机移动

    javascript - threejs - 将 UV 坐标标准化为 0 和 1 问题

    javascript - FullCalendar 事件显示为细线

    android - Android MediaRecorder-SetAudioEncodingBitRate-HowTo [duplicate]

    javascript - 使用 ajax 时监听浏览器后退按钮并将 html 数据保存为对象。是好是坏?

    ios - iOS 中的音频信号处理

    css - 没有 'controls' 的音频元素在 Chrome 中消失

    javascript - 如何在扩展后台页面访问localStorage?

    javascript - 自定义 Intl.Collat​​ors?