-1

i'm still new to node so bear with me.

i have images stored in mongo gridfs. how do i resize the image stream? i'm trying to use ffmpeg. here's my method:

exports.read = function (req, res) {
var db = mongoose.connection.db;
var id = new ObjectID(req.params.imageId);
var store = new GridStore(db, id, 'r', {root: 'fs'});

store.open(function (err, store) {
    if (err) return err;

    res.header("Content-Type", store.metadata['Content Type']);
    res.header("Content-Disposition", "attachment; filename='" + store.filename + "'");

    new ffmpeg()
        .input(store.stream(true))
        .size('650x365')
        .output('/temp/screenshot.png')
        .run();

    store.stream(true).pipe(res)
});
};

but i'm getting an error:

Error: ffmpeg exited with code 1: pipe:0: Invalid data found when processing input.

what am i doing wrong?

CurlyFro
  • 1,862
  • 4
  • 22
  • 39

1 Answers1

2

You're piping a GridStore stream to res before ffmpeg can finish running, which could cause all kinds of unpredictable results. Also, the stream that you're piping to res is the from your GridStore and not the output from ffmpeg. So, even if ffmpeg did run correctly, you'd end up getting the original image and not the resized one.

It's been a while since I've used GridStore and ffmpeg so I'm a little rusty, but I took a quick look at the docs and I think you want something like this:

Note: I'm assuming you're using fluent-ffmpeg

store.open(function (err, store) {
    if (err) return err; // !! NOTE: This return won't do anything... you should handle the error condition differently !!

    res.header("Content-Type", store.metadata['Content Type']);
    res.header("Content-Disposition", "attachment; filename='" + store.filename + "'");

    ffmpeg() // You shouldn't need "new" here
        .input(store.stream(true))
        .size('650x365')
        .pipe(res);
});

That code is streaming the output from ffmpeg directly to res which eliminates the need for the temporary file and simplifies things quite a bit.

Note: I don't recommend taking this approach on anything but a prototype or extremely low traffic site. The overhead of resizing the image on each request is going to be large; you should be caching the resized image and returning that.

Mike S
  • 41,895
  • 11
  • 89
  • 84
  • thanks Mike S. i'm still prototyping and trying to figure things out. thanks again for your advice. – CurlyFro Sep 13 '14 at 01:22