I am trying to setup canvas animation convertion to video with FFMPEG.wasm. The idea is to generate a bunch of images with canvas.toDataURL() then send them to a Node server to generate a video. Everything works perfectly with preuploaded images I am pulling from the public directory for testing, however when I try to send a bunch (or a single) of images created with canvas.toDataURL() I get the following error:
RuntimeError: abort(Error: ENAMETOOLONG: name too long, open 'data:image/png;base64, ...
I tried to replace canvas.toDataURL() with canvas.getContext('2d').getImageData(), however this didn't help either. Below is a cut code I am using:
front:
async function fetchData() {
const response = await fetch('/api/record-canvas', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ image: here_goes_the_canvas_data }),
});
}
backend:
await ffmpeg.load();
ffmpeg.FS('writeFile', `001.png`, await fetchFile(image));
await ffmpeg.run('-loop', '1', '-i', '001.png', '-c:v', 'libx264', '-t', '30', '-pix_fmt', 'yuv420p', 'out.mp4');
await fs.promises.writeFile('out.mp4', ffmpeg.FS('readFile', 'out.mp4'));
The code above is simplified to make a video of a single image looping it for 30 seconds. Again, works great with preuploaded image, however not with the canvas data.
For those who ran into the same problem, this is the solution I came up with:
dataURL must be jpeg (for example, canvas.toDataURL('image/jpeg') ).
You must cast it to a buffer value (eg Buffer.from(image.split(',')[1], 'base64') before passing it to FFMPEG's fetchFile function.
The answers are long and difficult to understand.