#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. Да, это общепринятый ответ, даже если он появился только в комментариях. Точное распределение доступных типов пользовательского ввода в браузерах вы сможете обнаружить, кузнечик. Спасибо Джей Икс Вайс