【发布时间】:2019-07-06 23:42:25
【问题描述】:
我正在构建一个网站,其中有一个 HTML5 音频元素,我使用 javascript 根据用户点击的曲目动态更新源。这由网络音频 API 包装,该 API 执行 fft 并使用它来控制三个 js 中的场景。
该网站在 chrome 和 firefox 中可以正常工作,但在 safari 中音频非常有问题。
第一个问题是 safari 不会接受源作为音频的子节点,如果您动态更新它,您必须将 src 放在音频标签中。我正在检查我的 js 中的 safari/IOS,并根据结果设置 opus 或 mp3 音频源。我尝试使用 m4a 作为文件格式,但它无法播放,尽管浏览器支持 m4a?
持续存在的问题是:
.pause() 方法不适用于音频元素,它只是在用户恢复播放时再次从曲目的开头播放。
尝试设置 .currentTime 以允许用户跳过曲目在 safari 中没有任何作用。但是它正在读取 currentTime 作为它设置播放头的位置。
当 animate() 函数(使用 requestAnimationFrame 递归调用)运行时,它在开始播放之前非常慢,超过一分钟的延迟,在 ios 上相同,但没有那么严重,并且 ios 不会遇到其他问题.
场景中的多边形数量约为 250k,这是相当高的,但是如果画布上的多边形数量使音频播放速度变慢,那就很奇怪了,尽管 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);
};
如果你发现了什么,请告诉我,这让我很难过。
【问题讨论】:
标签: javascript html html5-audio web-audio-api