Reputation: 51
I have a Node API that accepts video files uploaded via client-side FormData. The result is a req.file
object:
{
fieldname: 'media',
originalname: 'IMG_6288.MOV',
encoding: '7bit',
mimetype: 'video/quicktime',
buffer: <Buffer 00 00 00 14 66 74 79 70 71 74 20 20 00 00 00 00 71 74 20 20 00 00 00 08 77 69 64 65 01 ed db 13 6d 64 61 74 21 20 03 40 68 1c 21 4e e6 ff f9 80 e7 ff ... 32390609 more bytes>,
size: 32390659
}
I am trying to create a thumbnail image from a given frame in the video file. However, almost everything I find on thumbnail generation (i.e. ffmpeg) requires a path in order to process the video, which is not provided.
Is there a way to create a thumbnail image without the file path? Perhaps from the provided buffer, either directly or by converting it into a stream first?
TIA for your help
Upvotes: 1
Views: 2520
Reputation: 3876
I got it workin with the following code.
This is not perfect and throws sometimes a EPIPE
error, because ffmpeg close stdin to fast, but its working & a solid base for your use case:
const { exec } = require("child_process");
const fs = require("fs");
// this (data) is your input file, that you pipe into ffmepg
const data = fs.readFileSync("./input.avi");
console.log("input data read, size:", data.length);
const ffmpeg = exec(`ffmpeg -ss 00:10:00 -y -f avi -i pipe: -vframes 1 output.jpg`);
ffmpeg.on("error", (err) => {
console.log("FFMEPG-ERROR", err)
});
ffmpeg.on("close", (code) => {
console.log("ffmepg exited", code);
});
ffmpeg.stdin.on("error", (err) => {
if (err.code === "EPIPE") {
// ignore EPIPE error
// throws sometimes a EPIPE error, ignore as long ffmpeg exit with code 0
} else {
console.log("ffmepg stdin error", err);
}
});
ffmpeg.stdin.write(data);
Basicly spawn ffmepg, to read from stdin, -i pipe:
or -i -
, and start pumping data into stdin.
To test the ffmpeg command, you can ran the command below.
This creates a thumbnail at 10sec of the input data.
Keep in mind to adjust the file type (-f
option) to match your input data, since ffmepg cant autodetect it when it reads from stdin.
The -y
flag is to override a allready existing output file.
cat input.avi | ffmpeg -ss 00:10:00 -y -f avi -i pipe: -vframes 1 output.jpg
Some people mention to use -ss
as the first option to seek faster, but it has no effect on my test. You can read here more: https://stackoverflow.com/a/27573049/5781499
Let me know if you need any furthur help.
Upvotes: 4