Skip to content

Commit

Permalink
Merge pull request #395 from /issues/388
Browse files Browse the repository at this point in the history
Issues/388 thumbnail creation for images videos
  • Loading branch information
dennis-learningpool committed Jul 1, 2014
2 parents 5ab535b + 3f23704 commit 9bdf96c
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 13 deletions.
98 changes: 85 additions & 13 deletions lib/assetmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ var path = require('path'),
configuration = require('./configuration'),
formidable = require('formidable'),
probe = require('node-ffprobe'),
IncomingForm = formidable.IncomingForm;
IncomingForm = formidable.IncomingForm,
FFMpeg = require('fluent-ffmpeg');

/**
* CONSTANTS
*/

var MODNAME = 'assetmanager',
WAITFOR = 'contentmanager'
STREAM_BUFFER_SIZE = 64 * 1024;
WAITFOR = 'contentmanager',
STREAM_BUFFER_SIZE = 64 * 1024,
THUMBNAIL_WIDTH = '?',
THUMBNAIL_HEIGHT = '48',
DEFAULT_THUMBNAIL_IMAGE = 'none';

// errors
function AssetNotFoundError (message, assetID) {
Expand Down Expand Up @@ -78,6 +82,7 @@ exports = module.exports = {
rest.get('/asset/query', instance.queryAssets.bind(instance));
rest.get('/asset/:id', instance.getAsset.bind(instance));
rest.get('/asset/serve/:id', instance.serveAsset.bind(instance));
rest.get('/asset/thumb/:id', instance.assetThumb.bind(instance));
rest.delete('/asset/:id', instance.deleteAsset.bind(instance));

preloader.emit('preloadChange', MODNAME, app.preloadConstants.COMPLETE);
Expand Down Expand Up @@ -252,6 +257,7 @@ exports = module.exports = {
description: fields.description,
repository: repository,
path: storedFile.path,
thumbnailPath: DEFAULT_THUMBNAIL_IMAGE,
size: storedFile.size,
directory: directory,
isDirectory: false,
Expand Down Expand Up @@ -291,23 +297,53 @@ exports = module.exports = {
// Derive assetType and (if available) store extra metadata depending on the type of file uploaded
switch (storedFile.type.split('/')[0]) {
case 'image':
asset.assetType = 'image';
asset.metadata = probeData ? {width: probeData.streams[0].width, height: probeData.streams[0].height} : null;
break;
asset.assetType = 'image';
asset.metadata = probeData ? {width: probeData.streams[0].width, height: probeData.streams[0].height} : null;
var imageThumbnailPath = asset.path.substr(0, asset.path.lastIndexOf(fileExt)) + '_thumb' + fileExt ;
new FFMpeg({ source: asset.path })
.withSize(THUMBNAIL_WIDTH + 'x' + THUMBNAIL_HEIGHT)
.keepPixelAspect(true)
.on('error', function (err) {
// keep default thumbnail, but log error
logger.log('error', 'Failed to create thumbnail: ' + err.message);
return doCreate(asset);
})
.on('end', function () {
asset.thumbnailPath = imageThumbnailPath;
return doCreate(asset);
})
.saveToFile(imageThumbnailPath);
return; // return is important!

case 'video':
asset.assetType = 'video';
asset.metadata = probeData ? {duration: probeData.streams[0].duration, width: probeData.streams[0].width, height: probeData.streams[0].height} : null;
break;
asset.assetType = 'video';
asset.metadata = probeData ? {duration: probeData.streams[0].duration, width: probeData.streams[0].width, height: probeData.streams[0].height} : null;
var pathToDir = asset.path.substr(0, asset.path.lastIndexOf('/'));
new FFMpeg({ source : asset.path })
.withSize(THUMBNAIL_WIDTH + 'x' + THUMBNAIL_HEIGHT)
.on('error', function (err) {
// keep default thumbnail, but log error
logger.log('error', 'Failed to create thumbnail: ' + err.message);
return doCreate(asset);
})
.on('end', function (filenames) {
// hmmm - do we keep the original file name? should we rename?
if (filenames && filenames.length) {
asset.thumbnailPath = path.join(pathToDir, filenames[0]);
}
return doCreate(asset);
})
.takeScreenshots(1, pathToDir);
return; // return is important!

case 'audio':
asset.assetType = 'audio';
asset.metadata = probeData ? {duration: probeData.streams[0].duration} : null;
asset.assetType = 'audio';
asset.metadata = probeData ? {duration: probeData.streams[0].duration} : null;
break;

default:
asset.assetType = 'other';
asset.metadata = null;
asset.assetType = 'other';
asset.metadata = null;
break;
}

Expand Down Expand Up @@ -532,6 +568,42 @@ exports = module.exports = {
});
},

/**
* serves the thumb for an asset - one at a time!
*
* @param {object} req
* @param {object} res
* @param {callback} next
*/

assetThumb: function (req, res, next) {
this.retrieveAsset({ _id: req.params.id }, function (error, assetRecs) {
if (error) {
return next(error);
}

// record was not found
if (!assetRecs || assetRecs.length !== 1) {
res.statusCode = 404;
return res.end();
}

var assetRec = assetRecs[0];
filestorage.getStorage(assetRec.repository, function (error, storage) {
if (error) {
return next(error);
}

storage.createReadStream(assetRec.thumbnailPath, { bufferSize: STREAM_BUFFER_SIZE }, function (stream) {
stream.pipe(res);
stream.on('end', function () {
return res.end();
});
});
});
});
},

/**
* responder for delete requests
*
Expand Down
4 changes: 4 additions & 0 deletions lib/dml/schema/system/asset.schema
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
"type": "string",
"required": "true"
},
"thumbnailPath": {
"type": "string",
"required": "true"
},
"repository": {
"type": "string",
"required": "true"
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"connect-mongodb": "1.1.x",
"consolidate": "0.10.0",
"express": "3.4.0",
"fluent-ffmpeg": "1.7.1",
"formidable": "~1.0.14",
"handlebars-form-helpers": "0.1.3",
"hbs": "2.4.0",
Expand Down

0 comments on commit 9bdf96c

Please sign in to comment.