Skip to content

Instantly share code, notes, and snippets.

@mharsch
Last active January 31, 2017 17:12
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mharsch/5144208 to your computer and use it in GitHub Desktop.
Save mharsch/5144208 to your computer and use it in GitHub Desktop.
transcode video streams using node.js Streams and avconv (aka ffmpeg)

The avconv utility can be made to work in 'the Unix way' by specifying stdin and/or stdout instead of filenames for the input and output respectively. See: http://libav.org/avconv.html#pipe

Example:

cat input.ts | avconv -i pipe:0 -f mp4 -movflags frag_keyframe pipe:1 | cat > output.mp4

Using node's require('child_process').spawn(), we can pipe streams of video data through avconv's stdin and stdout and thus Stream All The Things.

var fs = require('fs');
var child = require('child_process');

var input_file = fs.createReadStream('./input.ts');
var output_file = fs.createWriteStream('./output.mp4');

var args = ['-i', 'pipe:0', '-f', 'mp4', '-movflags', 'frag_keyframe', 'pipe:1'];
var trans_proc = child.spawn('avconv', args, null);

input_file.pipe(trans_proc.stdin);
trans_proc.stdout.pipe(output_file);

trans_proc.stderr.on('data', function (data) {
	console.log(data.toString());
});
@manast
Copy link

manast commented Mar 12, 2013

ok. This should fit nicely in navcodec, I will take a look at it asap.

@manast
Copy link

manast commented Mar 12, 2013

The biggest problem right now is that the open function in navcodec returns a Media object with some metadata, but using streams this is not easy. So for the stream support I will probably need to have a separate API...

@manast
Copy link

manast commented Mar 12, 2013

Defining an output as stream is on the other hand quite easy.

@mharsch
Copy link
Author

mharsch commented Mar 15, 2013

Here are a couple random notes:
1.) child_process.spawn() blocks the event loop while the child process is forking. This may not be a big deal here, but see node-spawn-async by @davepacheco for details.

2.) Experimentation has led me to switch from avconv(1) to ffmpeg(1) from ffmpeg.org. For some reason, avconv(1) can't seem to keep up with realtime encoding from mpegts/mpeg-2 to mp4/h.264 when using a udp stream as the source.

@mablae
Copy link

mablae commented Apr 3, 2013

Great! I am going to use this in tvheadendWebplayer. Did you try out the current master of avconv?

@muammar
Copy link

muammar commented Aug 24, 2016

Thanks for the ffmpeg command. Just what I was looking for. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment