Node-fluent-ffmpeg: write mp4 to stream

Created on 3 Feb 2015  路  5Comments  路  Source: fluent-ffmpeg/node-fluent-ffmpeg

I have a strange isssue when converting a file to an mp4 stream and sending it out via express.
The following code works with vlc but if I try to add it to a <video> element in a browser the encoding starts but after a few seconds the browser closes the stream.
Idon*t now if these is an issue of fluent-ffmeg or express but thanks for any hints

This is the output:

file starting
Processing: 4.4418372838431095% done
Processing: 8.214935198486385% done
Processing: 12.22033205190434% done
an error happened: Output stream closed
ffmpeg stdout: undefined
ffmpeg stderr: undefined

This is the code

`````` javascript
app.get('/video/:filename', function(req, res) {
var pathToMovie = jsonobj[req.params.filename];
res.writeHead(206, { "Content-Type":"video/mp4"});
console.log("encoding movie",pathToMovie );
var outStream = fs.createWriteStream(__dirname + '/player/moviestream.mp4');
var readstream = 0;
var proc = ffmpeg(pathToMovie)
.audioCodec('aac')
.videoCodec('libx264')
.addOption('-strict', 'experimental')
.addOption('-movflags', 'faststart')
.toFormat('flv')
.size('640x480').autopad()
// setup event handlers
.on('end', function() {
console.log('file has been converted succesfully');
})
.on('progress', function(progress) {
console.log('Processing: ' + progress.percent + '% done');
})
.on('error', function(err,stdout,stderr) {
console.log('an error happened: ' + err.message);
console.log('ffmpeg stdout: ' + stdout);
console.log('ffmpeg stderr: ' + stderr);
})
.on('start', function() {
console.log('file starting');
});
var ffstream = proc.pipe(res);

});```
``````

Needs info

Most helpful comment

Can I ask real quick if I understand this right; Streaming as mp4 is impossible because it needs to set file / stream headers (I assume something like the length of the video) before the stream starts? If so, is there any way to generate a stream that can be read by the native <video> element and not via flash?

All 5 comments

I think the problem is in the way browsers do requests.
Can you log the requests done by the browser when trying to play the video ?

I think the problem of the server part ist solved by this gist:
https://gist.github.com/lleo/8614403
ok so far

but what is a bit strange to me:
none of your samples for piping a mp4 to a write stream seem to work for me:

code from the docs

fmpeg(__dirname +'/player/movie.mp4')
    .videoCodec('libx264')
    .audioCodec('libmp3lame')
    .size('320x240')
    .on('error', function(err,stdout,stderr) {
        console.log('an error happened: ' + err.message);
        console.log('ffmpeg stdout: ' + stdout);
        console.log('ffmpeg stderr: ' + stderr);
    })
    .on('end', function() {
        console.log('Processing finished !');
    })
    .on('progress', function(progress) {
        console.log('Processing: ' + progress.percent + '% done');
    })
    .pipe(outStream, { end: true });

produces:

an error happened: ffmpeg exited with code 1: pipe:1: Invalid argument
Unable to find a suitable output format for 'pipe:1'

if i add a format:

fmpeg(__dirname +'/player/movie.mp4')
    .videoCodec('libx264')
    .audioCodec('libmp3lame')
    .size('320x240')
    .format('mp4')
    .on('error', function(err,stdout,stderr) {
        console.log('an error happened: ' + err.message);
        console.log('ffmpeg stdout: ' + stdout);
        console.log('ffmpeg stderr: ' + stderr);
    })
    .on('end', function() {
        console.log('Processing finished !');
    })
    .on('progress', function(progress) {
        console.log('Processing: ' + progress.percent + '% done');
    })
    .pipe(outStream, { end: true });

produces:

an error happened: ffmpeg exited with code 1: Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
[mp4 @ 0x7fae138d3a00] muxer does not support non seekable output

Yeah, unfortunately that example is flawed. As you pointed out a format specification is missing. But you may not use mp4 when outputting to a stream, as mp4 requires a seekable output (it needs to go back after having written the video file to write the file header).

Oh yeah that was obvious!
Thanks for the answers, I will close the issue

Can I ask real quick if I understand this right; Streaming as mp4 is impossible because it needs to set file / stream headers (I assume something like the length of the video) before the stream starts? If so, is there any way to generate a stream that can be read by the native <video> element and not via flash?

Was this page helpful?
0 / 5 - 0 ratings