diff --git a/configs/main.js.example b/configs/main.js.example index 769bdc30..0f38a51c 100644 --- a/configs/main.js.example +++ b/configs/main.js.example @@ -118,6 +118,9 @@ module.exports = { //max thumb dimensions (square) in px. images smaller than this are not thumbnailed thumbSize: 250, + //0-100 percent through a video to try taking video thumbnails from, to remedy black first frames or fade-ins + videoThumbPercentage: 5, + /* extra mime types for files to be uploaded as attachments (no thumbnails) e.g. text files/archives NOTE: appropriate extensions will need to be added to nginx configuration, and uncommend the provided "other files" section which includes an example configuration for .txt files to match this default config. diff --git a/helpers/files/videothumbnail.js b/helpers/files/videothumbnail.js index db4987d6..ff839e3d 100644 --- a/helpers/files/videothumbnail.js +++ b/helpers/files/videothumbnail.js @@ -2,7 +2,7 @@ const ffmpeg = require('fluent-ffmpeg') , { thumbSize } = require(__dirname+'/../../configs/main.js') , uploadDirectory = require(__dirname+'/uploadDirectory.js'); -module.exports = (file, geometry, frames) => { +module.exports = (file, geometry, timestamp) => { return new Promise((resolve, reject) => { ffmpeg(`${uploadDirectory}/file/${file.filename}`) @@ -13,7 +13,7 @@ module.exports = (file, geometry, frames) => { return reject(err); }) .screenshots({ - timestamps: [(frames === 'N/A' ? 0 : '1%')],//1% should remedy black first frames or fade-ins + timestamps: [timestamp], count: 1, filename: `thumb-${file.hash}${file.thumbextension}`, folder: `${uploadDirectory}/file/`, diff --git a/models/forms/makepost.js b/models/forms/makepost.js index 781c1775..3541d516 100644 --- a/models/forms/makepost.js +++ b/models/forms/makepost.js @@ -3,7 +3,7 @@ const path = require('path') , { createHash, randomBytes } = require('crypto') , randomBytesAsync = require('util').promisify(randomBytes) - , { remove, pathExists } = require('fs-extra') + , { remove, pathExists, stat: fsStat } = require('fs-extra') , uploadDirectory = require(__dirname+'/../../helpers/files/uploadDirectory.js') , Mongo = require(__dirname+'/../../db/db.js') , Socketio = require(__dirname+'/../../socketio.js') @@ -24,7 +24,8 @@ const path = require('path') , timeUtils = require(__dirname+'/../../helpers/timeutils.js') , deletePosts = require(__dirname+'/deletepost.js') , spamCheck = require(__dirname+'/../../helpers/checks/spamcheck.js') - , { checkRealMimeTypes, thumbSize, thumbExtension, postPasswordSecret, strictFiltering } = require(__dirname+'/../../configs/main.js') + , { checkRealMimeTypes, thumbSize, thumbExtension, videoThumbPercentage, + postPasswordSecret, strictFiltering } = require(__dirname+'/../../configs/main.js') , buildQueue = require(__dirname+'/../../queue.js') , dynamicResponse = require(__dirname+'/../../helpers/dynamic.js') , { buildThread } = require(__dirname+'/../../helpers/tasks.js'); @@ -274,7 +275,19 @@ module.exports = async (req, res, next) => { await moveUpload(file, processedFile.filename, 'file'); } if (!existsThumb) { - await videoThumbnail(processedFile, processedFile.geometry, videoData.streams[0].nb_frames); + const numFrames = videoData.streams[0].nb_frames; + if (numFrames === 'N/A' && subtype === 'webm') { + await videoThumbnail(processedFile, processedFile.geometry, videoThumbPercentage+'%'); + let videoThumbStat = null; + try { + videoThumbStat = await fsStat(`${uploadDirectory}/file/thumb-${processedFile.hash}${processedFile.thumbextension}`); + } catch (err) { /*ENOENT, the thumb failed to create. No need to handle this.*/ } + if (!videoThumbStat || videoThumbStat.size === 0) { + await videoThumbnail(processedFile, processedFile.geometry, 0); + } + } else { + await videoThumbnail(processedFile, processedFile.geometry, ((numFrames === 'N/A' || numFrames <= 1) ? 0 : videoThumbPercentage+'%')); + } } break; }