Search code examples
firebaseffmpeggoogle-cloud-functions

Can you call out to FFMPEG in a Firebase Cloud Function


Per the Firebase Cloud Functions documentation, you can leverage ImageMagick from within a cloud function: https://firebase.google.com/docs/functions/use-cases

Is it possible do something similar but call out to FFMPEG instead of ImageMagick? While thumbnailing images is great, I'd also like the capability to append incoming images to a video file stored out on Firebase Storage.


Solution

  • Update: ffmpeg is now preinstalled in the Cloud Functions environment. For a complete list of preinstalled packages, check out https://cloud.google.com/functions/docs/reference/system-packages.

    Note As of April 2023, google does not offer ffmpeg as a pre-installed package for cloud functions with the latest version of Ubuntu (v22.04). So make sure you pick a runtime environment that uses Ubuntu (v18.04) in order to have ffmpeg pre-installed on your cloud function. You can find a complete list of runtime environments that use Ubuntu (v18.04) available here.

    Note: you only have disk write access at /tmp/.

    Option 1: use ffmpeg-fluent npm module

    This module abstracts the ffmpeg command line options with an easy to use Node.js module.

    const ffmpeg = require('fluent-ffmpeg');
    
    let cmd = ffmpeg('example.mp4')
        .clone()
        .size('300x300')
        .save('/tmp/smaller-file.mp4')
        .on('end', () => {
          // Finished processing the video.
          console.log('Done');
    
          // E.g. return the resized video:
          res.sendFile('/tmp/smaller-file.mp4');
        });
    

    Full code on GitHub

    Option 2: invoke the ffmpeg binary directly

    Because ffmpeg is already installed, you can invoke the binary and its command line options via a shell process.

    const { exec } = require("child_process");
    
    exec("ffmpeg -i example.mp4", (error, stdout, stderr) => {
      //ffmpeg logs to stderr, but typically output is in stdout.
      console.log(stderr);
    });
    

    Full code on GitHub

    Option 3: upload your own binary

    If you need a specific version of ffmpeg, you can include an ffmpeg binary as part of the upload and then run a shell command using something like child_process.exec. You'll need an ffmpeg binary that's compiled for the target platform (Ubuntu).

    File listing with pre-compiled ffmpeg binary

    ./
    ../
    index.js
    ffmpeg
    

    index.js

    const { exec } = require("child_process");
    
    exec("ffmpeg -i example.mp4", (error, stdout, stderr) => {
      //ffmpeg logs to stderr, but typically output is in stdout.
      console.log(stderr);
    });
    

    I've included two full working examples on GitHub. The examples are for Google Cloud Functions (not specifically Cloud Functions for Firebase).