Я создаю сайт, где у меня есть аудиоэлемент HTML5, где я использую javascript для динамического обновления источника в зависимости от того, на какую дорожку нажимают пользователи.Это оборачивается веб-аудио API, который выполняет fft и использует его для управления сценой в три js.
Сайт работает правильно в Chrome и Firefox, однако в Safari аудио крайне проблематично.
Первая проблема заключалась в том, что safari не будет принимать источник в качестве дочернего узла аудио, если вы обновляете его динамически, вы должны указать src в теге audio.Я проверяю Safari / IOS в моем js и либо устанавливаю источник звука opus или mp3 в зависимости от результата.Я пытался использовать m4a в качестве формата файла, но он не воспроизводился, несмотря на то, что браузер поддерживает m4a?
Сохраняются следующие проблемы:
Метод .pause()
не работает с аудиоэлементом, он просто воспроизводится с начала дорожки снова, когда пользователь возобновляет воспроизведение.
Попытка установить .currentTime, чтобы позволить пользователю пропустить дорожку, ничего не делает в сафари.Однако он читает currentTime в качестве установки позиции игровой головки.
Когда функция animate () (которая вызывается рекурсивно с помощью requestAnimationFrame) работает очень медленно, прежде чем начать что-либо воспроизводить, в течение минутызадержка, то же самое на ios, но не так сильно, и ios не страдает от других проблем.
Число поли на сцене составляет приблизительно 250 тыс., что довольно много, однако было бы странно, если бы поли-счет на холстепроигрывал звук медленно, несмотря на другие проблемы со звуком, в то время как requestAnimationFrame не работает.
Извините за неаккуратный код, у меня не было много времени, чтобы написать это:
const playTrack = (trackNumber) => {
audio.src = `assets/audio/${trackNumber}.${fileType}`;
audio.load();
audio.play();
};
audio.ontimeupdate = () => {
const left = audio.currentTime * segment;
playHead.style.width = `${left}px`;
};
playbar.addEventListener("click", (e) => {
const pos = e.x - container.left;
audio.currentTime = pos / segment;
}, false);
tracks.forEach(track => {
track.addEventListener("click", (e) => {
e.preventDefault();
//pause or load
if (!audio.paused && nowPlaying === track) {
//pause track
audio.pause();
track.children[0].classList.remove('fa-pause');
track.children[0].classList.add('fa-play');
} else if (audio.paused && nowPlaying === track) {
//play track
audio.play();
track.children[0].classList.remove('fa-play');
track.children[0].classList.add('fa-pause');
} else {
//load and play track
instructions.style.display = "none";
trackNumber = parseInt(track.getAttribute('data-value'), 10);
playTrack(trackNumber);
nowPlaying = track;
iconFlick(track);
}
trackDuration = duration[trackNumber];
segment = width / trackDuration;
if (clickFirst === 0) {
clickFirst = 10;
setupNodes(audio)
}
trackGlobal = track;
});
const setupNodes = (audio) => {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const source = audioCtx.createMediaElementSource(audio);
analyser = audioCtx.createAnalyser();
source.connect(analyser);
analyser.fftSize = 256;
bufferLength = analyser.frequencyBinCount;
dataArray = new Uint8Array(bufferLength);
audioBegin = 1;
analyser.connect(audioCtx.destination);
};
Веб-сайт, который я создаю, находится здесь, содержит полный исходный код: https://www.missed.flights/
пожалуйста, дайте мне знать, если вы заметите что-нибудь, это поставило меня в тупик.