1

imagine i have a video file and i want to build a blob URL from that file then play it in a html page, so far i tried this but i could not make it work ...

var files = URL.createObjectURL(new Blob([someVideoFile], {type: "video/mp4"}));
document.getElementById(videoId).setAttribute("src", files);//video tag id
document.getElementById(videoPlayer).load();//this is source tag id
document.getElementById(videoPlayer).play();//this is source tag id

it gives me a blob URL but wont play the video... am i doing something wrong? i am pretty new to electron so excuse me if my code is not good enough

i saw the similar questions mentioned in comments but they dont work for me as they dont work for others in those pages....

fardad
  • 29
  • 1
  • 9

2 Answers2

1

I know this is an old question, but it still deserves a working answer.

In order to play a video in the renderer context, you're on the right track: you can use a blob url and assign it as the video source. Except, a local filepath is not a valid url, which is why your current code doesn't work.

Unfortunately, in electron, currently there are only 3 ways to generate a blob from a file in the renderer context:

  • Have the user drag it into the window, and use the drag-and-drop API
  • Have the user select it via a file input: <input type="file">
  • Read the entire file with the 'fs' module, and generate a Blob from it

The third option (the only one without user input) can be done as long as nodeIntegration is enabled or if it is done in a non-sandboxed preloader. For accomplishing this via streaming vs. loading the entire file at once, the following module can be used:

// fileblob.js
const fs = require('fs');

// convert system file into blob
function fileToBlob(path, {bufferSize=64*1024, mimeType='aplication/octet-stream'}={}) {
    return new Promise((resolve,reject) => {
        // create incoming stream from file
        const stream = fs.createReadStream(path, {highWaterMark:bufferSize});

        // initialize empty blob
        var blob = new Blob([], {type:mimeType});

        stream.on('data', buffer => {
            // append each chunk to blob by building new blob concatenating new chunk
            blob = new Blob([blob, buffer], {type:mimeType});
        });
        stream.on('close', () => {
            // resolve with resulting blob
            resolve(blob);
        });
    });
}

// convert blob into system file
function blobToFile(blob,path, {bufferSize=64*1024}={}) {
    return new Promise((resolve,reject) => {
        // create outgoing stream to file
        const stream = fs.createWriteStream(path);

        stream.on('ready', async () => {
            // iterate chunks at a time
            for(let i=0; i<blob.size; i+=bufferSize) {
                // read chunk
                let slice = await blob.slice(i, i+bufferSize).arrayBuffer();

                // write chunk
                if(!stream.write(new Uint8Array(slice))) {
                    // wait for next drain event
                    await new Promise(resolve => stream.once('drain', resolve));
                }
            }

            // close file and resolve
            stream.on('close', () => resolve());
            stream.close();
        });
    });
}

module.exports = {
    fileToBlob,
    blobToFile,
};

Then, in a preloader or the main context with nodeIntegration enabled, something like the following would load the file into a blob and use it for the video player:

const {fileToBlob} = require('./fileblob');

fileToBlob("E:/nodeJs/test/app/downloads/clips/test.mp4", {mimeType:"video/mp4"}).then(blob => {
    var url = URL.createObjectURL(blob);
    document.getElementById(videoId).setAttribute("src", url);
    document.getElementById(videoPlayer).load();
    document.getElementById(videoPlayer).play();
});

Again, unfortunately this is slow for large files. We're still waiting for a better solution from electron:

Codesmith
  • 5,779
  • 5
  • 38
  • 50
0

Try

 video.src = window.URL.createObjectURL(vid);

For more details please refer to this answer

Mayank Kumar Chaudhari
  • 16,027
  • 10
  • 55
  • 122