aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZephyrrus <[email protected]>2020-07-02 23:42:44 +0300
committerZephyrrus <[email protected]>2020-07-02 23:42:44 +0300
commit22f9eb4dff9ee03b5ec655db2204050ffe7a7771 (patch)
tree74a18e6887b90062d470b41c406d0ec146dc7360
parentfeat: refactor account to use vuex, fix small presentational components (diff)
downloadhost.fuwn.me-22f9eb4dff9ee03b5ec655db2204050ffe7a7771.tar.xz
host.fuwn.me-22f9eb4dff9ee03b5ec655db2204050ffe7a7771.zip
feat: refactor preview to support random fragment extraction
-rw-r--r--src/api/utils/ThumbUtil.js2
-rw-r--r--src/api/utils/videoPreview/FragmentPreview.js87
-rw-r--r--src/api/utils/videoPreview/FrameIntervalPreview.js (renamed from src/api/utils/PreviewUtil.js)4
-rw-r--r--src/site/assets/styles/_colors.scss22
4 files changed, 102 insertions, 13 deletions
diff --git a/src/api/utils/ThumbUtil.js b/src/api/utils/ThumbUtil.js
index 5cfd9c0..2931d3b 100644
--- a/src/api/utils/ThumbUtil.js
+++ b/src/api/utils/ThumbUtil.js
@@ -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');
diff --git a/src/api/utils/videoPreview/FragmentPreview.js b/src/api/utils/videoPreview/FragmentPreview.js
new file mode 100644
index 0000000..8815392
--- /dev/null
+++ b/src/api/utils/videoPreview/FragmentPreview.js
@@ -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;
+};
diff --git a/src/api/utils/PreviewUtil.js b/src/api/utils/videoPreview/FrameIntervalPreview.js
index bf3a480..75f6d2b 100644
--- a/src/api/utils/PreviewUtil.js
+++ b/src/api/utils/videoPreview/FrameIntervalPreview.js
@@ -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 }))
diff --git a/src/site/assets/styles/_colors.scss b/src/site/assets/styles/_colors.scss
index a141447..b8861d2 100644
--- a/src/site/assets/styles/_colors.scss
+++ b/src/site/assets/styles/_colors.scss
@@ -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;
@@ -45,4 +44,9 @@ $pagination-hover-color: $textColorHighlight;
$pagination-hover-border-color: $textColorHighlight;
$pagination-current-background-color: $base-3;
-$pagination-current-border-color: $base-2; \ No newline at end of file
+$pagination-current-border-color: $base-2;
+
+// loading
+
+$loading-background: rgba(0, 0, 0, 0.8);
+$loading-background: rgba(40, 40, 40, 0.66);