phoboslab / jsmpeg

MPEG1 Video Decoder in JavaScript
MIT License
6.3k stars 1.43k forks source link

about progress bar #419

Closed kikyouink closed 8 months ago

kikyouink commented 8 months ago

Is there a way to implement a progress bar feature? I know that setting currentTime can control the current progress, but how can I listen to the current progress of the video to make the progress bar change? use setTimeout?

phoboslab commented 8 months ago

You could use the onVideoDecode callback for that purpose. The current time already comes in the second parameter.

var player = new JSMpeg.Player('file.ts', {
    onVideoDecode: function(decoder, elapsedTime) {
        console.log('time', elapsedTime);
    }
});

A progress bar is a bit more difficult. Because of the nature of MPEG1, we do not know the total length of a video before actually loading all parts. For static video (not streaming) the presentation time stamp (PTS) of each packet is collected as soon as it's loaded. The last PTS of the file is the total length. So reading from the collected timestamps:

let totalTime = player.video.timestamps.at(-1)?.time;

Again, by the nature of MPEG1, this last PTS is only the last PTS loaded so far. So, to actually get the full video length, you have to make sure the whole file is loaded first. You can set progressive: false to load the video in a single chunk and use the onSourceCompleted callback to get the PTS as stated above.

If you don't want to load the full file at once, you either have to supply the full video duration separately (e.g. get the duration from ffmpeg on your server, or store it elsewhere), or only show a progress bar for the already loaded duration.