我正在建立一个网站,我有一个HTML5音频元素,我使用javascript动态更新源,具体取决于用户点击的轨道。这是由web音频API封装的,它执行fft并使用它来控制三个js中的场景。
该网站在chrome和firefox中正常工作,但在safari中,音频非常有问题。
第一个问题是safari不接受源作为音频的子节点,如果你动态更新它,你必须把src放在音频标签中。我正在检查我的js中的safari / IOS,并根据结果设置opus或mp3音频源。我尝试使用m4a作为文件格式,但它不会播放,尽管浏览器支持m4a?
持续存在的问题是:
.pause()
方法不适用于音频元素,它只是在用户恢复播放时再次从轨道的开头播放。
尝试设置.current时间以允许用户跳过轨道在Safari中没有任何作用。但是它正在读取当前时间作为设置播放头的位置。
当animate()函数(使用requestAnimationFrame以递归方式调用)运行时,它在开始播放任何内容之前非常缓慢,超过一分钟延迟,在ios上相同但不严重且ios不会遇到其他问题。
场景上的多边形数量大约是250k,这是非常高的,但是如果画布上的polycount使得音频播放速度很慢会很奇怪,尽管在requestAnimationFrame未运行时音频存在其他问题。
请原谅邋code的代码我没有太多时间写这个:
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/
如果你发现任何事情,请告诉我,这让我很难过。
如果你不使用<audio>
标签,你可能会有更好的运气和更多的控制。如果你想要那些控件,你需要自己制作播放按钮和滑块。并使用Web Audio API自行下载和解码并播放曲目。
var url = "whatever.mp3";
var source = audioCtx.createBufferSource();
var buffers = {};
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function () {
audioCtx.decodeAudioData(request.response, function (buffer) {
source.buffer = buffer;
source.connect(audioCtx.destination);
source.start(audioCtx.currentTime);
// save this for later, so you can replay it without downloading
buffers[url] = buffer;
}, function () {
console.warn("error loading sound url: " + url);
});
}
request.send();