Tone.js приложение — аудио не запустится до второго щелчка

#javascript #web-audio-api #tone.js

Вопрос:

Я знаю, что мне нужно действие пользователя, чтобы запустить веб-аудио на мобильном устройстве. Однако я последовал рекомендации возобновить (в случае Tone.js сигнал вызова.запуск()) при действии пользователя, но он все равно не работает. Вот соответствующие части моего кода:

 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 amp;amp; 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() действием пользователя. Я здесь в тупике.

Комментарии:

1. Обновление: Если я нажму ползунок регулировки громкости или выберу поле в другом месте страницы, звук будет воспроизводиться при первом касании.

Ответ №1:

Этот тональный код выглядит правильно. Я упростил его в коде, и он работал на мобильных устройствах с первого клика (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;
}

 

Вот ссылка на кодовую строку: https://codepen.io/joeweiss/pen/gOmeQVW

Комментарии:

1. С другой стороны … Есть touchstart ли событие, которое может инициировать звук при первом щелчке мыши? Обычно у меня есть Tone.start() за щелчком, пока он не будет инициализирован.

2. Спасибо. Теория заключается в том, что, хотя требуется действие пользователя, учитываются не все действия пользователя? Я займусь этим вопросом.

3. Похоже, ты можешь быть прав. От html.spec.whatwg.org/multipage/… Событием ввода, инициирующим активацию, является любое событие, чей атрибут isTrusted является истинным и чей тип один из: изменить контекстное меню щелчка мыши dblclick указатель мыши сброс отправить касание Набор событий не согласован в основных браузерах. См.выпуск № 3849.

4. Да, это общепринятый ответ, даже если он появился только в комментариях. Точное распределение доступных типов пользовательского ввода в браузерах вы сможете обнаружить, кузнечик. Спасибо Джей Икс Вайс