Question

Is possible to create and download a video file only on the client side?

Suppose that we have an animated canvas like in this JSFIDDLE. Please see this snippet:

...
var stop = false;
setTimeout(function () {
    stop = true;
}, 1860);
...
if (!stop) { requestAnimationFrame( draw, 10 ); }

So, my animation duration is 1860ms.

We can generate text files for download, I know that we can generate images from canvas, but is possible to render and download a video file?

Would adding sound possible?

Was it helpful?

Solution

Disclaimer: I haven't done this myself so all the information I am providing is only what I have found by researching

In theory, yes it is possible but not easy or practical.

Overview

So basically you are looking at having more-or-less a video encoder in-browser which can take the images you get form the canvas and convert it to video.

I had a few concerns first whether it was possible to actually do this, mainly:

  • Is there a limit on Blob size? According to the W3C Blob spec, there doesn't seem to be.
  • How the browser will handle the amount of memory required to do encoding?

In your circumstance, the animation duration is short enough that I do not believe that memory will be an issue (at least in terms of storing the images and video).

Let's get encoding!

I mentioned that you are basically having a video encoder. There are really two options for this, either build your own encoder or hope that someone has built some sort of encoder already.

An awesome answer on GameDev (and later found something similar on StackOverflow) explains that FFmpeg can create a video slideshow from images.

For those who don't know, FFmpeg is a free software project that produces libraries and programs for handling multimedia data

I know what you might be thinking, how is FFmpeg going to help me, that isn't JavaScript... right?

Well, before today I would have thought the same thing until I found videoconverter.js which apparently is a working copy of FFmpeg in JavaScript!

What's the catch?

Well, the FFmpeg JS file is kind of large weighing in at ~6MB gzipped (or ~24 MB uncompressed). The browser memory footprint is bound to be quite large!

I will note I am also making a few big assumption here:

  • That the FFmpeg JS can actually read an image blob so we can build the video slideshow
  • That FFmpeg JS actually supports all the same functions as the standard FFmpeg application

Besides FFmpeg, what is another way?

You can pick the format of video you want to output and write your own encoder!

To get you started, you could look at the spec for AVI (Audio Video Interlaced) or possibly Theora. You would be writing the information to a blob like you did in your text download example.

This stuff really is out of my skill set so I will leave the finer details of this up to you.

This isn't practical! This is a mountain of effort for a small video!

I said from the beginning that it wasn't going to be easy. What @ShivanDragon mentioned in the comments is the way I would personally go about it. Pass the images off to a server, get it generated and then downloaded.

There are some reasons why you might want it in-browser but I really don't see it being practical.

Edit: Hang on! I also asked whether sound is possible!

Whoops, I missed that part! Yes, adding sound is definitely possible though will add even more complexity into the mix. You can add audio as a second input file for FFmpeg which will insert it into the output video.

In terms of making your own video encoder, it will add a decent amount of extra effort for adding an audio stream. Probably best place to start is another few links to specs for audio like Vorbis or WAV.

Licensed under: CC-BY-SA with attribution
scroll top