简体   繁体   中英

Playing audio file while downloading it in Audio web API

so, what am trying to do is to play audio file while am downloading it , the problem that am facing is the audio player play the audio but only after it finish the download, here is my code:

audio tag

<audio controls preload="all" muted="muted" > </audio>

this is my JS

var audio = document.querySelector('audio');
var assetURL = 'url/audios/file';
var token = 'Bearer token'
var mimeCodec = 'audio/wav';

var mediaSource = new MediaSource; 
audio.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
function sourceOpen(_) {
    const playPromise = audio.play();
    console.log(this.readyState); 
    var mediaSource = this;
    var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
    fetchAB(assetURL, function (buf) {
        sourceBuffer.addEventListener('updateend', function (_) {
            mediaSource.endOfStream();
            audio.play();
            console.log(mediaSource.readyState); // ended
        });
        sourceBuffer.appendBuffer(buf);
    });
};
function fetchAB(url, cb) {
    console.log(url);
    var xhr = new XMLHttpRequest;
    xhr.open('get', url);
    xhr.setRequestHeader('Authorization', token);
    xhr.responseType = 'arraybuffer';
    xhr.onload = function () {
        cb(xhr.response);
    };
    xhr.send();
}; 

am not really sure how to do it, any help will be appreciate it

You cannot partially play an audiofile using the Web Audio API. You should create an <audio> element and set its src-attribute to load the file, that approach will let you stream a file.

const audio = document.createElement('audio');
audio.src = 'file.wav';
audio.play();

However, your example shows you're setting headers when loading the file, that is not going to work with the above approach so you should get rid of that (although seems to be a way to circumvent it: Send custom HTTP request header with HTML5 audio tag )

I think you can simplify you code to this:

var audio = new Audio('file.wav');

var promise = audio.play();

// Older browsers may not return promise
if (promise)
    promise.catch(function() { 
        // Couldn't play audio for some reason
    });

The built-in Audio class supports buffering and playback will start as soon as possible, without waiting for whole file to be downloaded.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM