Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the currentTime in HTML5 audio object when audio file is online?

I have a JavaScript audio player with skip forward/back 10 second buttons. I do this by setting the currentTime of my audio element:

function Player(skipTime)
{
    this.skipTime = skipTime;
    this.waitLoad = false;

    // initialise main narration audio
    this.narration = new Audio(getFileName(dynamicNarration));
    this.narration.preload = "auto";
    this.narration.addEventListener('canplaythrough', () => { this.loaded();       });
    this.narration.addEventListener('timeupdate',     () => { this.seek();         });
    this.narration.addEventListener('ended',          () => { this.ended();        });
    this.narration.addEventListener('waiting',        () => { this.audioWaiting(); });
    this.narration.addEventListener('playing',        () => { this.loaded();       });
}

Player.prototype = {
    rew: function rew()
    {
        if (!this.waitLoad) {
            this.skip(-this.skipTime);
        }
    },

    ffw: function ffw()
    {
        if (!this.waitLoad) {
            this.skip(this.skipTime);
        }
    },

    skip: function skip(amount)
    {
        const curTime = this.narration.currentTime;
        const newTime = curTime + amount;
        console.log(`Changing currentTime (${curTime}) to ${newTime}`);
        this.narration.currentTime = newTime;
        console.log(`Result: currentTime = ${this.narration.currentTime}`);
    },

    loaded: function loaded()
    {
        if (this.waitLoad) {
            this.waitLoad = false;
            playButton.removeClass('loading');
        }
    },

    audioWaiting: function audioWaiting()
    {
        if (!this.waitLoad) {
            this.waitLoad = true;
            playButton.addClass('loading');
        }
    },
}

(I'm including here some of the event listeners I'm attaching because previously I'd debugged a similar problem as being down to conflicts in event listeners. Having thoroughly debugged event listeners this time though, I don't think that's the root of the problem.)

Though this all works fine on my local copy, when I test an online version I get the following results:

  • Chrome: resets play position to 0. Final console line reads Result: currentTime = 0.
  • Safari: doesn't change play position at all. Final console.log line gives a value for currentTime equal to newTime (even though the play position actually doesn't change).
  • Firefox: skipping forward works; skipping backwards interrupts the audio for a few seconds, then it starts playing again from a couple of seconds before where the playhead had been. In both cases, final console.log line gives a value for currentTime equal to newTime

The issue must have something to do with the way audio is loaded. I have tried adding another console log line to show the start and end values for buffered.

In Chrome it goes up to 2 seconds after current play position. In Safari it goes up to ~170 seconds, and in Firefox it seems to buffer the full audio length.

However, in each case the start of the buffered object is 0.

Does anyone have any idea what might be going wrong?

like image 609
Igid Avatar asked Sep 02 '18 14:09

Igid


1 Answers

There are some requirements to properly load an audio file and use the properties. Your response while serving the file needs to have the following headers.

accept-ranges: bytes

Content-Length: BYTE_LENGTH_OF_YOUR_FILE

Content-Range: bytes 0-BYTE_LENGTH_OF_YOUR_FILE/BYTE_LENGTH_OF_YOUR_FILE

content-type: audio/mp3

My colleagues and I have been struggling over this for a few days and finally this worked

Image of Response header for an audio file

like image 52
Yuvaraj Mani Avatar answered Oct 19 '22 19:10

Yuvaraj Mani