Я создал веб-приложение, которое воспроизводит 16 звуковых дорожек в цикле, используя API-интерфейс Web Audio и ванильный JavaScript. Пока что он работает на настольных компьютерах в Safari, Chrome и Firefox и на устройствах Android. Однако он не работает на iPhone или iPad.
Запуск звукового контекста запускается нажатием кнопки «Пуск» на странице, которая затем отображает элементы управления (кнопку воспроизведения и кнопку отключения звука для каждого из 16 треков).
На iPhone страница не загружается после начального экрана, поэтому я предполагаю, что аудио-контекст не запускается, хотя я не уверен, почему это так. В предыдущем посте я читал, что это связано с тем, что iOS не позволяет запускать аудио-контекст, если он не запущен пользователем. Я подумал, что кнопки «Пуск» на странице будет достаточно, но это, к сожалению, не сработало.
Любая экспертиза по веб-аудио API будет принята с благодарностью!
constructor(context, urlList, callback) {
this.context = context;
this.urlList = urlList;
this.onload = callback;
this.bufferList = [];
this.loadCount = 0;
}
loadBuffer = (url, index) => {
// Load buffer asynchronously
const request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
const loader = this;
request.onload = function() {
// Asynchronously decode the audio file data in request.response
loader.context.decodeAudioData(
request.response,
function(buffer) {
if (!buffer) {
alert('error decoding file data: ' + url);
return;
}
loader.bufferList[index] = buffer;
if (++loader.loadCount == loader.urlList.length)
loader.onload(loader.bufferList);
loadingScreen.style.display = 'none';
loadedContent.style.display = 'block';
},
function(error) {
console.error('decodeAudioData error', error);
}
);
};
request.onerror = function() {
alert('BufferLoader: XHR error');
};
request.send();
};
load = () => {
for (let i = 0; i < this.urlList.length; ++i)
this.loadBuffer(this.urlList[i], i);
};
}
//INIT
// Keep track of all loaded buffers.
const buffers = {};
// Page-wide audio context.
let context = null;
const trackRef = {
rhodes: { bufferToLoad: './audio/rhodes.mp3', muteRef: muteRhodes },
rhodes2: { bufferToLoad: './audio/rhodes2.mp3', muteRef: muteRhodes2 },
conga: { bufferToLoad: './audio/conga.mp3', muteRef: muteConga },
kick: { bufferToLoad: './audio/kick.mp3', muteRef: muteKick },
clap: { bufferToLoad: './audio/clap.mp3', muteRef: muteClap },
snare: { bufferToLoad: './audio/snare.mp3', muteRef: muteSnare },
ohh: { bufferToLoad: './audio/ohh.mp3', muteRef: muteOhh },
chh: { bufferToLoad: './audio/chh.mp3', muteRef: muteChh },
piano: { bufferToLoad: './audio/piano.mp3', muteRef: mutePiano },
bass1: { bufferToLoad: './audio/bass1.mp3', muteRef: muteBass1 },
bass2: { bufferToLoad: './audio/bass2.mp3', muteRef: muteBass2 },
vox1: { bufferToLoad: './audio/vox1.mp3', muteRef: muteVox1 },
vox2: { bufferToLoad: './audio/vox2.mp3', muteRef: muteVox2 },
vox3: { bufferToLoad: './audio/vox3.mp3', muteRef: muteVox3 },
vox4: { bufferToLoad: './audio/vox4.mp3', muteRef: muteVox4 },
vox5: { bufferToLoad: './audio/vox5.mp3', muteRef: muteVox5 }
};
const tracks = Object.keys(trackRef);
// console.log(buffersToLoad);
// Loads all sound samples into the buffers object.
function loadBuffers() {
// Array-ify
const trackNames = [];
const paths = [];
for (let trackName in trackRef) {
const path = trackRef[trackName].bufferToLoad;
trackNames.push(trackName);
paths.push(path);
}
bufferLoader = new BufferLoader(context, paths, function(bufferList) {
for (let i = 0; i < bufferList.length; i++) {
const buffer = bufferList[i];
const trackName = trackNames[i];
buffers[trackName] = buffer;
}
});
bufferLoader.load();
}
const setUpAudioContext = () => {
try {
// Fix up prefixing
const AudioContext = (window.AudioContext =
window.AudioContext || window.webkitAudioContext);
context = new AudioContext();
} catch (e) {
alert('Web Audio API not supported in this browser');
}
loadBuffers();
};
// document.addEventListener('DOMContentLoaded', setUpAudioContext);
startButton.addEventListener('click', setUpAudioContext);