Can you call out to FFMPEG in a Firebase Cloud Function

ffmpeg is not preinstalled (pretty much just ImageMagick); to see exactly what's installed check out the Dockerfile here: https://github.com/GoogleCloudPlatform/nodejs-docker/blob/master/runtime-image/Dockerfile.

However, you can upload arbitrary binaries when you upload your code using gcloud beta functions deploy because everything in the current directory (except node_modules) is uploaded.

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

Option 1: use ffmpeg-static npm module

ffmpeg-static is an npm module that builds the correct ffmpeg binary based on the current system during npm install. Since Cloud Functions builds your code in the cloud, it'll build the correct ffmpeg binary.

https://github.com/eugeneware/ffmpeg-static

You can see it in action in the Cloud Functions for Firebase examples repo.

const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');

var cmd = ffmpeg('/tmp/video.avi')
  .setFfmpegPath(ffmpeg_static.path)
  .videoBitrate(1024)
  .videoCodec('divx')
  .format('avi')
  .on('end', () => {
    // ...
  })
  .on('error', err => {
    console.error(err);
  })
  .save('/tmp/file-out.avi');

(Thanks Daniel Lessa for pointing out this module in his answer.)

Option 2: upload your own binary

You could include an ffmpeg binary as part of the upload and then run a shell command using something like child_process.exec. You'll need the ffmpeg binary that's compiled for the target platform (Debian/jessie).

File listing with pre-compiled ffmpeg binary

./
../
index.js
ffmpeg

Then run for example gcloud beta functions deploy myFunc --trigger-http

index.js

var exec = require('child_process').exec;
var cmd = 'ffmpeg -i /tmp/myvideo.mp4 /tmp/image-%d.jpg';

exec(cmd, function(error, stdout, stderr) {
  // command output is in stdout
});

While you technically can run FFMPEG on a Firebase Functions instance, you will quickly hit the small quota limits.

As per this answer, you can instead use Functions to trigger a request to GCP's more powerful App Engine or Compute Engine services. The App Engine process can grab the file from the same bucket, handle the transcoding, and upload the finished file back to the bucket. If you check the other answers at the link, one user posted a sample repo that does just that.


Use the lib https://github.com/eugeneware/ffmpeg-static

const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');


let cmd = ffmpeg.('filePath.mp4')
   .setFfmpegPath(ffmpeg_static.path)
   .setInputFormat('mp4')
   .output('outputPath.mp4')
   ...
   ...
   .run()