I'm trying to run ffmpeg from node, and I'm getting an error. Here is the code
var exec = require('child_process').exec;
var cmd = '/home/ubuntu/bin/ffmpeg -i /home/ubuntu/input.flv -s 640x480 -y -codec:a aac -b:a 44.1k -r 15 -b:v 1000k -codec:v h264 -f mp4 /home/ubuntu/output.mp4';
exec(cmd, function(err, stdout, stderr) {
if (err) console.log('err:\n' + err);
if (stderr) console.log('stderr:\n' + stderr);
console.log('stdout:\n' + stdout);
});
When I run this node script, I get the following errors:
err:
Error: Command failed: /home/ubuntu/bin/ffmpeg -i /home/ubuntu/input.flv -s 640x480 -y -codec:a aac -b:a 44.1k -r 15 -b:v 1000k -codec:v h264 -f mp4 /home/ubuntu/output.mp4
ffmpeg version N-83323-g126e965 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
configuration: --prefix=/home/ubuntu/ffmpeg_build --pkg-config-flags=--static --extra-cflags=-I/home/ubuntu/ffmpeg_build/include --extra-ldflags=-L/home/ubuntu/ffmpeg_build/lib --bindir=/home/ubuntu/bin --enable-gpl --enable-libopus --enable-libvpx --enable-libvorbis --enable-libmp3lame --enable-libfdk-aac --enable-libx264 --enable-nonfree
libavutil 55. 45.100 / 55. 45.100
libavcodec 57. 75.100 / 57. 75.100
libavformat 57. 66.101 / 57. 66.101
libavdevice 57. 2.100 / 57. 2.100
libavfilter 6. 72.100 / 6. 72.100
libswscale 4. 3.101 / 4. 3.101
libswresample 2. 4.100 / 2. 4.100
libpostproc 54. 2.100 / 54. 2.100
/home/ubuntu/input.flv: Invalid data found when processing input
stderr:
ffmpeg version N-83323-g126e965 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
configuration: --prefix=/home/ubuntu/ffmpeg_build --pkg-config-flags=--static --extra-cflags=-I/home/ubuntu/ffmpeg_build/include --extra-ldflags=-L/home/ubuntu/ffmpeg_build/lib --bindir=/home/ubuntu/bin --enable-gpl --enable-libopus --enable-libvpx --enable-libvorbis --enable-libmp3lame --enable-libfdk-aac --enable-libx264 --enable-nonfree
libavutil 55. 45.100 / 55. 45.100
libavcodec 57. 75.100 / 57. 75.100
libavformat 57. 66.101 / 57. 66.101
libavdevice 57. 2.100 / 57. 2.100
libavfilter 6. 72.100 / 6. 72.100
libswscale 4. 3.101 / 4. 3.101
libswresample 2. 4.100 / 2. 4.100
libpostproc 54. 2.100 / 54. 2.100
/home/ubuntu/input.flv: Invalid data found when processing input
stdout:
But when I run
/home/ubuntu/bin/ffmpeg -i /home/ubuntu/input.flv -s 640x480 -y -codec:a aac -b:a 44.1k -r 15 -b:v 1000k -codec:v h264 -f mp4 /home/ubuntu/output.mp4
straight in the terminal, It works flawlessly. I think it has to do with how node runs the command but all my google searching has returned zero useful results. Any help is greatly appreciated.
This is not related to the async nature of node. Node process always waits for spawned child processes (created with both spawn and exec).
I suggest you to use spawn
with ffmpeg due to number of reasons :
spawn
handles the arguments in a different way than how exec does. It starts the process itself and passes the argument array to the process. exec
however takes the whole command as a string and passes it to a shell process. This may lead to some escaping errors.
ffmpeg is most of the time a "long running" process. It is better to parse its output while it is still running. exec does not give the output until the process finishes.
ffmpeg could produce large amounts of output data. This can cause problems with exec
as it starts the process with a limited buffer. (As Aikon has mentioned above). spawn
passes the data as chunks in real time using streams.
Example with your cmd/args :
var spawn = require('child_process').spawn;
var cmd = '/home/ubuntu/bin/ffmpeg';
var args = [
'-y',
'-i', '/home/ubuntu/input.flv',
'-s', '640x480',
'-codec:a', 'aac',
'-b:a', '44.1k',
'-r', '15',
'-b:v', '1000k',
'-c:v','h264',
'-f', 'mp4', '/home/ubuntu/output.mp4'
];
var proc = spawn(cmd, args);
proc.stdout.on('data', function(data) {
console.log(data);
});
proc.stderr.setEncoding("utf8")
proc.stderr.on('data', function(data) {
console.log(data);
});
proc.on('close', function() {
console.log('finished');
});
Based on the other answer:
runCommand.js
:
var spawn = require('child_process').spawn;
module.exports = (cmd, args, onData, onFinish) => {
var proc = spawn(cmd, args.split(' '));
proc.stdout.on('data', onData);
proc.stderr.setEncoding("utf8")
proc.stderr.on('data', err => console.log(err) );
proc.on('close', onFinish);
}
main.js
:
runCommand('ffmpeg', '-y -f concat -i list.txt -c copy output-final.mp4',
data => console.log(data), () => console.log('finished'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With