feat: refactor preview to support random fragment extraction
This commit is contained in:
parent
c2dbbe6396
commit
22f9eb4dff
|
@ -2,7 +2,7 @@ const jetpack = require('fs-jetpack');
|
|||
const path = require('path');
|
||||
const sharp = require('sharp');
|
||||
const ffmpeg = require('fluent-ffmpeg');
|
||||
const previewUtil = require('./PreviewUtil');
|
||||
const previewUtil = require('./videoPreview/FragmentPreview');
|
||||
|
||||
const log = require('./Log');
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
const ffmpeg = require('fluent-ffmpeg');
|
||||
const probe = require('ffmpeg-probe');
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
const getRandomInt = (min, max) => {
|
||||
const minInt = Math.ceil(min);
|
||||
const maxInt = Math.floor(max);
|
||||
|
||||
// eslint-disable-next-line no-mixed-operators
|
||||
return Math.floor(Math.random() * (maxInt - minInt + 1) + minInt);
|
||||
};
|
||||
|
||||
const getStartTime = (vDuration, fDuration, ignoreBeforePercent, ignoreAfterPercent) => {
|
||||
// by subtracting the fragment duration we can be sure that the resulting
|
||||
// start time + fragment duration will be less than the video duration
|
||||
const safeVDuration = vDuration - fDuration;
|
||||
|
||||
// if the fragment duration is longer than the video duration
|
||||
if (safeVDuration <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return getRandomInt(ignoreBeforePercent * safeVDuration, ignoreAfterPercent * safeVDuration);
|
||||
};
|
||||
|
||||
module.exports = async opts => {
|
||||
const {
|
||||
log = noop,
|
||||
|
||||
// general output options
|
||||
quality = 2,
|
||||
width,
|
||||
height,
|
||||
input,
|
||||
output,
|
||||
|
||||
fragmentDurationSecond = 3,
|
||||
ignoreBeforePercent = 0.25,
|
||||
ignoreAfterPercent = 0.75
|
||||
} = opts;
|
||||
|
||||
const info = await probe(input);
|
||||
|
||||
let { duration } = info.format;
|
||||
duration = parseInt(duration, 10);
|
||||
|
||||
const startTime = getStartTime(duration, fragmentDurationSecond, ignoreBeforePercent, ignoreAfterPercent);
|
||||
|
||||
const result = { startTime, duration };
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
let scale = null;
|
||||
|
||||
if (width && height) {
|
||||
result.width = width | 0;
|
||||
result.height = height | 0;
|
||||
scale = `scale=${width}:${height}`;
|
||||
} else if (width) {
|
||||
result.width = width | 0;
|
||||
result.height = ((info.height * width) / info.width) | 0;
|
||||
scale = `scale=${width}:-1`;
|
||||
} else if (height) {
|
||||
result.height = height | 0;
|
||||
result.width = ((info.width * height) / info.height) | 0;
|
||||
scale = `scale=-1:${height}`;
|
||||
} else {
|
||||
result.width = info.width;
|
||||
result.height = info.height;
|
||||
}
|
||||
|
||||
return ffmpeg()
|
||||
.input(input)
|
||||
.inputOptions([`-ss ${startTime}`])
|
||||
.outputOptions(['-vsync', 'vfr'])
|
||||
.outputOptions(['-q:v', quality, '-vf', scale])
|
||||
.outputOptions([`-t ${fragmentDurationSecond}`])
|
||||
.noAudio()
|
||||
.output(output)
|
||||
.on('start', cmd => log && log({ cmd }))
|
||||
.on('end', resolve)
|
||||
.on('error', reject)
|
||||
.run();
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
|
@ -1,8 +1,6 @@
|
|||
const ffmpeg = require('fluent-ffmpeg');
|
||||
const probe = require('ffmpeg-probe');
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
module.exports = async opts => {
|
||||
|
@ -61,7 +59,7 @@ module.exports = async opts => {
|
|||
ffmpeg(input)
|
||||
.outputOptions(['-vsync', 'vfr'])
|
||||
.outputOptions(['-q:v', quality, '-vf', filter])
|
||||
.outputOption('-an')
|
||||
.noAudio()
|
||||
.outputFormat('webm')
|
||||
.output(output)
|
||||
.on('start', cmd => log && log({ cmd }))
|
|
@ -1,13 +1,13 @@
|
|||
// $basePink: #EC1A55;
|
||||
$base-1: #292e39;
|
||||
$base-2: #2E3440;
|
||||
$base-3: #3B4252;
|
||||
$base-4: #434C5E;
|
||||
$base-5: #4C566A;
|
||||
$base-2: #2e3440;
|
||||
$base-3: #3b4252;
|
||||
$base-4: #434c5e;
|
||||
$base-5: #4c566a;
|
||||
|
||||
$background: #1e2430;
|
||||
$backgroundAccent: #20222b;
|
||||
$backgroundAccentLighter: #53555E;
|
||||
$backgroundAccentLighter: #53555e;
|
||||
$backgroundLight1: #f5f6f8;
|
||||
|
||||
// customize navbar
|
||||
|
@ -23,16 +23,15 @@ $input-hover-color: $textColor;
|
|||
|
||||
$basePink: #ff015b;
|
||||
$basePinkHover: rgb(196, 4, 71);
|
||||
$baseBlue: #30A9ED;
|
||||
$baseBlue: #30a9ed;
|
||||
$baseBlueHover: rgb(21, 135, 201);
|
||||
|
||||
$uploaderDropdownColor: #797979;
|
||||
|
||||
$boxShadow: 0 10px 15px rgba(4,39,107,0.2);
|
||||
$boxShadow: 0 10px 15px rgba(4, 39, 107, 0.2);
|
||||
$boxShadowLight: rgba(15, 17, 21, 0.35) 0px 6px 9px 0px;
|
||||
|
||||
// pagination
|
||||
|
||||
$pagination-color: $defaultTextColor;
|
||||
|
||||
$pagination-focus-color: $textColorHighlight;
|
||||
|
@ -46,3 +45,8 @@ $pagination-hover-border-color: $textColorHighlight;
|
|||
|
||||
$pagination-current-background-color: $base-3;
|
||||
$pagination-current-border-color: $base-2;
|
||||
|
||||
// loading
|
||||
|
||||
$loading-background: rgba(0, 0, 0, 0.8);
|
||||
$loading-background: rgba(40, 40, 40, 0.66);
|
||||
|
|
Loading…
Reference in New Issue