Snippets

Kees van Bemmel Video Thumbnail Generation

Created by Kees van Bemmel

File index.js Added

  • Ignore whitespace
  • Hide word diff
+/*
+ * Author: Incentro Cloud
+ */
+
+'use strict';
+
+const gcs = require('@google-cloud/storage')();
+const path = require('path');
+const fs = require('fs');
+
+const ffmpeg = require('fluent-ffmpeg');
+const ffmpeg_static = require('ffmpeg-static');
+const ffprobe_static = require('ffprobe-static');
+
+// Set the ffmpeg path to use the deployed binaries
+const binPath = path.resolve(__dirname, 'ffmpeg');
+ffmpeg.setFfmpegPath(ffmpeg_static.path);
+ffmpeg.setFfprobePath(ffprobe_static.path);
+
+exports.videoGenerateThumbnail = function videoGenerateThumbnail(event) {
+    const pubsubMessage = event.data;
+    const messageData = Buffer.from(pubsubMessage.data, 'base64').toString();
+
+    const dataObject = JSON.parse(messageData);
+    const bucket = dataObject.file.bucket;
+    const filename = dataObject.file.name;
+    const assetid = dataObject.assetid;
+
+    const file = gcs.bucket(bucket).file(filename);
+
+    console.log('Processing file: ' + filename + ' for assetid ' + assetid);
+
+    var justFile = path.basename(filename);
+    var destinationPath = '/tmp/' + justFile;
+
+    return Promise.resolve()
+        .then(() => {
+            console.log('downloading video file...')
+
+            return downloadFile(file, filename, destinationPath);
+        }).then(() => {
+
+            console.log('extracting thumbnail from video')
+            return generateThumbnail(destinationPath, bucket, filename);
+        }).catch((err) => {
+            return Promise.reject(err);
+        });
+};
+
+function generateThumbnail(fileName, thumbnailBucketName, gcsfilename) {
+    return new Promise((resolve, reject) => {
+        ffmpeg(fileName)
+            .on('end', function () {
+                console.log('extracted thumbnail');
+                resolve();
+            })
+            .screenshots({
+                timestamps: ['50%'],
+                filename: 'thumbnail.png',
+                size: '500x?',
+                folder: '/tmp/'
+            });
+    }).then(() => {
+        console.log('Uploading thumbnail to GCS: gs://' + thumbnailBucketName + "/" + gcsfilename + "/thumbnail.png");
+        return uploadFile(gcs.bucket(thumbnailBucketName), '/tmp/thumbnail.png', gcsfilename + "/thumbnail.png");
+    }).then(() => {
+        //make file public so the front-end can serve the image
+        console.log("making thumbnail public");
+        return gcs.bucket(thumbnailBucketName).file(gcsfilename + "/thumbnail.png").makePublic();
+    }).then(() => {         
+        fs.unlinkSync('/tmp/thumbnail.png');
+        console.log('cleanup successful!');
+        return Promise.resolve();
+    });
+}
+
+function uploadFile(bucket, source, destfilename) {
+    return new Promise((resolve, reject) => {
+    var file = bucket.file(destfilename);
+        fs.createReadStream(source)
+          .pipe(file.createWriteStream({ validation: false }))
+          .on('error', function(err) {
+            console.log("error: " + err);
+            reject(err);
+          })
+          .on('finish', function() {
+            console.log("done uploading: " + destfilename);
+            resolve(destfilename);// The file upload is complete.
+        });
+    });
+}
+
+function downloadFile(file, fileName, destinationPath) {
+    return new Promise((resolve, reject) => {
+        var onlyPath = path.dirname(destinationPath);
+        if (!fs.existsSync(onlyPath)) {
+            fs.mkdirSync(onlyPath);
+        }
+        file.download({
+            destination: destinationPath
+        }).then((error) => {
+            if (error.length > 0) {
+                reject(error);
+            } else {
+                resolve(destinationPath);
+            }
+        })
+    });
+}
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.