Я пытаюсь понять аспект воспроизведения образцов JavaScript Web Audio API. В частности, я использую API веб-аудио для воспроизведения очень короткого семпла (на самом деле семпл «щелчок» для метронома).
Вот что я делаю:
let sample = this.setupSample(this.audioContext, click1);
sample.start(time);
sample.stop(time + this.noteLength);
Этот фрагмент кода работает, если я запускаю приложение с настольного компьютера (моего компьютера), но когда я пытаюсь запустить приложение с мобильного устройства, как только я нажимаю кнопку «Пуск» для воспроизведения метронома, я получаю следующую ошибку:
InvalidStateError: The object is in an invalid state.
93| sample.stop(time + this.noteLength);
Первое, что я попробовал, - это прокомментировать эту строку:
let sample = this.setupSample(this.audioContext, click1);
sample.start(time);
// sample.stop(time + this.noteLength);
Таким образом, приложение корректно работает как с настольных компьютеров, так и с мобильных.
Итак, мне кажется, что вызывать stop () для уже завершившейся выборки не нужно, а может быть, и неправильно. Отсюда мой вопрос: неправильно ли вызывать stop () для уже завершенного образца? Должен ли я считать, что он неявно вызывается, если образец остановился (закончился) сам по себе? Кроме того, почему я не получаю эту ошибку InvalidStateError с рабочего стола?
Спасибо.
Обновлено: для большей ясности вот что делает setupSample:
setupSample = (audioContext, samplePath) => {
const source = audioContext.createBufferSource();
const myRequest = new Request(samplePath);
fetch(myRequest).then(function(response) {
return response.arrayBuffer();
}).then(function(buffer) {
audioContext.decodeAudioData(buffer, function(decodedData) {
source.buffer = decodedData;
source.connect(audioContext.destination);
})
})
return source;
}
Он возвращает источник, подключенный к месту назначения AudioContext. Я добавил все определение метода в свой вопрос.
Когда time присваивается значение? Возможно ли, что вы устанавливаете время остановки как время в прошлом? Я всегда стараюсь использовать context.currentTime вместо того, чтобы назначать его переменной, где могу. ИЛИ Возможно, буфер не полностью инициализирован данными, которые вы ему передаете. Поэтому вы каким-то образом запускаете / останавливаете неполный буфер.
time - это переменная, изначально установленная на 0, затем после каждой доли она увеличивается на значение secondsPerBeat (то есть сколько секунд длится каждый удар). Так что не должно быть проблем с установкой времени остановки в прошлом. Кроме того, я провел тест с использованием осциллятора вместо образца, и у меня не было ошибки на stop(). Следовательно, я думаю, что ошибка вызывает stop() на уже законченном семпле. Тем не менее, я не могу понять, почему я получаю ошибку только на мобильном телефоне.
@ Boaz-ReinstateMonica, stop унаследован от родительского класса AudioScheduledSourceNode. MDN указывает Multiple calls to stop() are allowed., но не упоминает о вызове stop на не воспроизводящемся источнике



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Насколько я могу судить,
stopне является методом, определенным в API веб-аудио. Что возвращаетsetupSample?