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

1

10
  • 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?

Undies answered 2/10, 2018 at 19:57 Comment(3)
Using the file:// protocol directly does not work or you want some kind of work in your data?Calvin
using file:// only works if the file is completely downloaded. I need to request it right when something is written so I can begin streaming as soon as possible.Undies
You might find it easier to use something like: v1-6-2.shaka-player-demo.appspot.com/docs/tutorial-offline.html (although that would require you to use MPEG-DASH)Gonion
O
4

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);
Oxpecker answered 2/10, 2018 at 20:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.