v3.0.0/src/api/utils/ThumbUtil.js

106 lines
3.2 KiB
JavaScript

const jetpack = require('fs-jetpack');
const path = require('path');
const sharp = require('sharp');
const ffmpeg = require('fluent-ffmpeg');
const previewUtil = require('./videoPreview/FragmentPreview');
const log = require('./Log');
class ThumbUtil {
static imageExtensions = ['.jpg', '.jpeg', '.gif', '.png', '.webp'];
static videoExtensions = ['.webm', '.mp4', '.wmv', '.avi', '.mov'];
static thumbPath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, 'thumbs');
static squareThumbPath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, 'thumbs', 'square');
static videoPreviewPath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, 'thumbs', 'preview');
static generateThumbnails(filename) {
const ext = path.extname(filename).toLowerCase();
const output = `${filename.slice(0, -ext.length)}.png`;
const previewOutput = `${filename.slice(0, -ext.length)}.webm`;
// eslint-disable-next-line max-len
if (ThumbUtil.imageExtensions.includes(ext)) return ThumbUtil.generateThumbnailForImage(filename, output);
// eslint-disable-next-line max-len
if (ThumbUtil.videoExtensions.includes(ext)) return ThumbUtil.generateThumbnailForVideo(filename, previewOutput);
return null;
}
static async generateThumbnailForImage(filename, output) {
const filePath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, filename);
const file = await jetpack.readAsync(filePath, 'buffer');
await sharp(file)
.resize(64, 64)
.toFormat('png')
.toFile(path.join(ThumbUtil.squareThumbPath, output));
await sharp(file)
.resize(225, null)
.toFormat('png')
.toFile(path.join(ThumbUtil.thumbPath, output));
}
static async generateThumbnailForVideo(filename, output) {
const filePath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER, filename);
ffmpeg(filePath)
.thumbnail({
timestamps: [0],
filename: '%b.png',
folder: ThumbUtil.squareThumbPath,
size: '64x64'
})
.on('error', error => log.error(error.message));
ffmpeg(filePath)
.thumbnail({
timestamps: [0],
filename: '%b.png',
folder: ThumbUtil.thumbPath,
size: '150x?'
})
.on('error', error => log.error(error.message));
try {
await previewUtil({
input: filePath,
width: 150,
output: path.join(ThumbUtil.videoPreviewPath, output),
log: log.debug
});
} catch (e) {
log.error(e);
}
}
static getFileThumbnail(filename) {
if (!filename) return null;
const ext = path.extname(filename).toLowerCase();
const isImage = ThumbUtil.imageExtensions.includes(ext);
const isVideo = ThumbUtil.videoExtensions.includes(ext);
if (isImage) return { thumb: `${filename.slice(0, -ext.length)}.webp` };
if (isVideo) {
return {
thumb: `${filename.slice(0, -ext.length)}.png`,
preview: `${filename.slice(0, -ext.length)}.webm`
};
}
return null;
}
static async removeThumbs({ thumb, preview }) {
if (thumb) {
await jetpack.removeAsync(path.join(ThumbUtil.thumbPath, thumb));
await jetpack.removeAsync(path.join(ThumbUtil.squareThumbPath, thumb));
}
if (preview) {
await jetpack.removeAsync(path.join(ThumbUtil.videoPreviewPath, preview));
}
}
}
module.exports = ThumbUtil;