running ffmpeg via nodejs error

15,324

Solution 1

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');
});

Solution 2

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'))
Share:
15,324

Related videos on Youtube

Greyhammer
Author by

Greyhammer

IT Network Admin that is trying to learn new things, and hoping to develop some coding skills that will make me more marketable and possibly open new doors for me. Currently trying to automate a few daily tasks and make my workflow more efficient, but once I learn enough, I'll write things that can benefit others as well.

Updated on July 28, 2022

Comments

  • Greyhammer
    Greyhammer almost 2 years

    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.

  • Greyhammer
    Greyhammer over 7 years
    The double quotes on your var cmd = '"/home/ubuntu/bin/ffmpeg"'; caused errors. I removed them and it worked great. Thanks
  • God Himself
    God Himself over 4 years
    almost. make sure to set the encoding to read the output proc.stderr.setEncoding("utf8")