You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ass/thumbnails.js

87 lines
2.8 KiB

const ffmpeg = require('ffmpeg-static');
const Jimp = require('jimp');
const shell = require('any-shell-escape');
const { exec } = require('child_process');
const { path } = require('./utils');
const { diskFilePath } = require('./config.json');
// Thumbnail parameters
const THUMBNAIL = {
QUALITY: 75,
WIDTH: 200 * 2,
HEIGHT: 140 * 2,
}
/**
* Builds a safe escaped ffmpeg command
* @param {String} src Path to the input file
* @param {String} dest Path of the output file
* @returns {String} The command to execute
*/
function getCommand(src, dest) {
return shell([
ffmpeg, '-y',
'-v', (process.env.NODE_ENV === 'production' ? 'error' : 'debug'), // Log level
'-i', src, // Input file
'-ss', '00:00:01.000', // Timestamp of frame to grab
'-frames:v', '1', // Number of frames to grab
'-s', `${THUMBNAIL.WIDTH}x${THUMBNAIL.HEIGHT}`, // Dimensions of output file
dest // Output file
]);
}
/**
* Builds a thumbnail filename
* @param {String} oldName The original filename
* @returns {String} The filename for the thumbnail
*/
function getNewName(oldName) {
return oldName.concat('.thumbnail.jpg');
}
/**
* Builds a path to the thumbnails
* @param {String} oldName The original filename
* @returns {String} The path to the thumbnail
*/
function getNewNamePath(oldName) {
return path(diskFilePath, 'thumbnails/', getNewName(oldName));
}
/**
* Extracts an image from a video file to use as a thumbnail, using ffmpeg
* @param {*} file The video file to pull a frame from
*/
function getVideoThumbnail(file) {
return new Promise((resolve, reject) => exec(
getCommand(file.path, getNewNamePath(file.randomId)),
(err) => (err ? reject(err) : resolve())
));
}
/**
* Generates a thumbnail for the provided image
* @param {*} file The file to generate a thumbnail for
*/
function getImageThumbnail(file) {
return new Promise((resolve, reject) =>
Jimp.read(file.path)
.then((image) => image
.quality(THUMBNAIL.QUALITY)
.resize(THUMBNAIL.WIDTH, THUMBNAIL.HEIGHT, Jimp.RESIZE_BICUBIC)
.write(getNewNamePath(file.randomId)))
.then(resolve)
.catch(reject));
}
/**
* Generates a thumbnail
* @param {*} file The file to generate a thumbnail for
* @returns The thumbnail filename (NOT the path)
*/
module.exports = (file) =>
new Promise((resolve, reject) =>
(file.is.video ? getVideoThumbnail : file.is.image ? getImageThumbnail : () => Promise.resolve())(file)
.then(() => resolve((file.is.video || file.is.image) ? getNewName(file.randomId) : file.is.audio ? 'views/ass-audio-icon.png' : 'views/ass-file-icon.png'))
.catch(reject));