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?

sss
  • 618
  • 1
  • 8
  • 20
  • Using the `file://` protocol directly does not work or you want some kind of work in your data? – E. Zacarias Oct 02 '18 at 20:02
  • 1
    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. – sss Oct 02 '18 at 20:11
  • You might find it easier to use something like: http://v1-6-2.shaka-player-demo.appspot.com/docs/tutorial-offline.html (although that would require you to use MPEG-DASH) – colde Oct 05 '18 at 20:33

1 Answers1

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);
Jgillett7674
  • 112
  • 4