【问题标题】:Tone.js app - audio won't start until second clickTone.js 应用程序 - 直到第二次点击音频才会开始
【发布时间】:2021-08-22 02:21:32
【问题描述】:

我知道我需要用户操作才能在移动设备上启动网络音频。但是,我已按照建议在用户操作上恢复(在 Tone.js 调用 Tone.start() 的情况下),但它仍然不起作用。 以下是我的代码的相关部分:

keyElement.addEventListener("touchstart", notePressed, false);
keyElement.addEventListener("touchend", noteReleased, false);

function notePressed(event) {
        let dataset = event.target.dataset;
        if (!dataset["pressed"]) {
            let octave = +dataset["octave"];
            oscList[octave][dataset["note"]] = playTone(dataset["frequency"]);
            dataset["pressed"] = "yes";
        }
        event.preventDefault(); event.stopPropagation();
    }
function noteReleased(event) {
      let dataset = event.target.dataset;

      if (dataset && dataset["pressed"]) {
        let octave = +dataset["octave"];
        oscList[octave][dataset["note"]].triggerRelease();
        delete oscList[octave][dataset["note"]];
        delete dataset["pressed"];
      }
    } 
function playTone(freq) {
        let synth = new Tone.Synth().toDestination();
        let now = Tone.now();
        Tone.start();
        synth.triggerAttack(freq, now);
        return synth;
    } 

它在第二次触摸时工作正常,但在第一次触摸后我收到有关音频上下文被暂停的警告,即使标准是当用户操作调用 start() 时它会恢复。我被难住了。

【问题讨论】:

  • 更新:如果我与音量滑块或页面其他地方的选择框进行交互,音频将在第一次触摸时播放。

标签: javascript web-audio-api tone.js


【解决方案1】:

提示音代码看起来正确。我在 CodePen 中对其进行了简化,它在移动设备上首次点击 (iOS) 即可使用。

var keyElement = document.getElementById("play");

keyElement.addEventListener("touchstart", notePressed, false);
keyElement.addEventListener("touchend", noteReleased, false);

// Added mouse ELs to test on non-mobile.
keyElement.addEventListener("mousedown", notePressed, false); 
keyElement.addEventListener("mouseup", noteReleased, false);

var pressedTone;

function notePressed(event) {
  console.log("notePressed");
  pressedTone = playTone(440);
  event.preventDefault();
  event.stopPropagation();
}
function noteReleased(event) {
  pressedTone.triggerRelease();
}
function playTone(freq) {
  console.log("playTone", freq);
  let synth = new Tone.Synth().toDestination();
  let now = Tone.now();
  Tone.start();
  synth.triggerAttack(freq, now);
  return synth;
}

这里是 CodePen 的链接:https://codepen.io/joeweiss/pen/gOmeQVW

【讨论】:

  • 再想一想...touchstart 是一个可以在第一次点击时启动音频的事件吗?我通常在点击后有 Tone.start() 直到它被初始化。
  • 谢谢。理论是,虽然需要用户操作,但并非所有用户操作都算数?我会调查的。
  • 看起来你可能是对的。来自html.spec.whatwg.org/multipage/… 激活触发输入事件是isTrusted 属性为true 且类型为以下之一的任何事件: change click contextmenu dblclick mouseup pointerup reset submit touchend 事件设置在主要浏览器之间不一致。请参阅问题 #3849。
  • 是的,这是公认的答案,即使它只出现在 cmets 中。浏览器中可接受的用户输入类型的确切分布将由您来发现,蚱蜢。谢谢 J.X. 韦斯
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多