簡體   English   中英

Safari 使用 HTML5 音頻標簽表現得很奇怪

[英]Safari behaving very weirdy with HTML5 audio tag

我正在構建一個站點,其中有一個 HTML5 音頻元素,我在其中使用 javascript 根據用戶單擊的軌道動態更新源。 這是由 web 音頻 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);
};

如果你發現了什么,請告訴我,這讓我很難過。

如果您不使用<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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM