Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream file to html video player as it's being downloaded in Electron using fs

  • I'm currently trying to use the HTML video player to stream a file from the file system in Electron.

  • I would like to start streaming as the file is downloading.

  • I'm not sure if my current plan will work (or if this is even possible).

The plan

  • Create a readble stream from the file that updates as the file is downloaded
  • Generate a blob url from that stream
  • Use that blob url as the video source

Where I think this is currently failing is that I generate a blob url after the first chunk is read, but any chunks after that aren't included in the blob url.

This is about what I would like to do (I know this code will not work)

const file = GrowingFile.open(downloadPath) // provides a readable stream for a file

let chunks = [];
file.on('data', (chunk) => {
  chunks.push(chunk);
  const blob = new Blob(chunks);
  const url = URL.createObjectURL(blob);

  video.src = url // continuously update the video src with a new blob url
})

My main question is:

Is there a way to push to a blob list after a url has been generated from it and continue to use the same blob url?

like image 874
sss Avatar asked Oct 02 '18 19:10

sss


1 Answers

What you want can be accomplished via MediaSource SourceBuffer. I will point out that it is important you know the codec of the video/audio stream otherwise the video will not load.

You will have to convert the blob to a buffer.

let blob = null;
let mimeCodec = 'video/webm; codecs="vorbis,vp8"';
let video = document.getElementById("video");
let mediasource = new MediaSource();
let sourceBuffer = null;
let chunks = [];
let pump = function(){
    if(chunks[0]){
        let chunk = chunks[0];
        delete chunks[0];
        sourceBuffer.appendBuffer(chunk);
        chunk = null;
    }
};
mediaSource.addEventListener('sourceopen', function(_){
    sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
    sourceBuffer.addEventListener('updateend', () => {
        if(chunks[0])
            pump();
    }, false);
});
video.src = URL.createObjectURL(mediaSource);
video.play();

let reader = new FileReader();
reader.onload = function(event) {
    chunks[chunks.length] = new Uint8Array(event.target.result);
    pump();
};
reader.readAsArrayBuffer(blob);
like image 84
Jgillett7674 Avatar answered Nov 06 '22 08:11

Jgillett7674