Merge pull request #162 from arillo/feature/convert-percentage

add video conversion progress
This commit is contained in:
banglashi
2021-02-06 01:13:22 +01:00
committed by GitHub
6 changed files with 164 additions and 16180 deletions

View File

@@ -1,13 +1,15 @@
const gulp = require('gulp') const gulp = require('gulp');
const sass = require('gulp-sass') const sass = require('gulp-sass');
const concat = require('gulp-concat') const concat = require('gulp-concat');
const cleanCSS = require('gulp-clean-css');
gulp.task('styles', function(done) { gulp.task('styles', function(done) {
gulp.src('styles/**/*.scss') gulp.src('styles/**/*.scss')
.pipe(sass({ .pipe(sass({
errLogToConsole: true errLogToConsole: true
})) }))
.pipe(cleanCSS())
.pipe(gulp.dest('./public/stylesheets/')) .pipe(gulp.dest('./public/stylesheets/'))
.pipe(concat('style.css')) .pipe(concat('style.css'))
done() done()
}) });

View File

@@ -50,6 +50,8 @@ const convertableAudioTypes = [
"audio/x-hx-aac-adts", "audio/x-hx-aac-adts",
"audio/aac"]; "audio/aac"];
// ffmpeg progress
var duration = 0, time = 0, progress = 0;
function getDuration(localFilePath, callback){ function getDuration(localFilePath, callback){
exec.execFile("ffprobe", ["-show_format", "-of", "json", localFilePath], function(error, stdout, stderr) { exec.execFile("ffprobe", ["-show_format", "-of", "json", localFilePath], function(error, stdout, stderr) {
@@ -58,6 +60,40 @@ function getDuration(localFilePath, callback){
}); });
} }
function getConversionProgress(content){
// get duration of source
var matches = (content) ? content.match(/Duration: (.*?), start:/) : [];
if( matches && matches.length>0 ){
var rawDuration = matches[1];
// convert rawDuration from 00:00:00.00 to seconds.
var ar = rawDuration.split(":").reverse();
duration = parseFloat(ar[0]);
if (ar[1]) duration += parseInt(ar[1]) * 60;
if (ar[2]) duration += parseInt(ar[2]) * 60 * 60;
}
// get the time
matches = content.match(/time=(.*?) bitrate/g);
if( matches && matches.length>0 ){
var rawTime = matches.pop();
// needed if there is more than one match
if (Array.isArray(rawTime)){
rawTime = rawTime.pop().replace('time=','').replace(' bitrate','');
} else {
rawTime = rawTime.replace('time=','').replace(' bitrate','');
}
// convert rawTime from 00:00:00.00 to seconds.
ar = rawTime.split(":").reverse();
time = parseFloat(ar[0]);
if (ar[1]) time += parseInt(ar[1]) * 60;
if (ar[2]) time += parseInt(ar[2]) * 60 * 60;
//calculate the progress
progress = Math.round((time/duration) * 100);
}
return progress;
}
function createWaveform(fileName, localFilePath, callback){ function createWaveform(fileName, localFilePath, callback){
var filePathImage = localFilePath + "-" + (new Date().getTime()) + ".png"; var filePathImage = localFilePath + "-" + (new Date().getTime()) + ".png";
@@ -135,7 +171,7 @@ function convertVideo(fileName, filePath, codec, callback, progressCallback) {
ff.stderr.on('data', function (data) { ff.stderr.on('data', function (data) {
console.log('[ffmpeg-video] stderr: ' + data); console.log('[ffmpeg-video] stderr: ' + data);
if (progressCallback) { if (progressCallback) {
progressCallback(data); progressCallback(getConversionProgress(""+data));
} }
}); });

View File

@@ -4,7 +4,8 @@
"private": true, "private": true,
"scripts": { "scripts": {
"start": "node spacedeck.js", "start": "node spacedeck.js",
"dev": "nodemon spacedeck.js" "dev": "nodemon spacedeck.js",
"styles": "gulp styles"
}, },
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
@@ -23,9 +24,6 @@
"file-type": "^7.6.0", "file-type": "^7.6.0",
"glob": "7.1.1", "glob": "7.1.1",
"gm": "^1.23.1", "gm": "^1.23.1",
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-sass": "^4.0.2",
"helmet": "^3.5.0", "helmet": "^3.5.0",
"i18n-2": "0.6.3", "i18n-2": "0.6.3",
"log-timestamp": "latest", "log-timestamp": "latest",
@@ -51,6 +49,10 @@
"ws": "3.3.1" "ws": "3.3.1"
}, },
"devDependencies": { "devDependencies": {
"gulp": "^4.0.2",
"gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.6.1",
"gulp-sass": "^4.0.2",
"nodemon": "^2.0.6" "nodemon": "^2.0.6"
}, },
"main": "app.js", "main": "app.js",

File diff suppressed because one or more lines are too long

View File

@@ -11,10 +11,12 @@
max-height: 100%; max-height: 100%;
} }
&.hide-text .text { opacity: 0 } &.hide-text .text {
opacity: 0;
}
&.locked.selected { &.locked.selected {
box-shadow: 0px 0px 0px 3px rgba(0,0,0,0.5) !important; box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.5) !important;
} }
.placeholder { .placeholder {
@@ -26,7 +28,9 @@
} }
} }
&.artifact-text.text-blank [contentEditable=true]:not(.text-editing) p:first-child::after { &.artifact-text.text-blank
[contentEditable="true"]:not(.text-editing)
p:first-child::after {
content: "Double click to edit"; content: "Double click to edit";
opacity: 0.25; opacity: 0.25;
} }
@@ -79,7 +83,6 @@
// padding-right: 20px; margin-right: -20px; // padding-right: 20px; margin-right: -20px;
//> * {pointer-events: auto; } //> * {pointer-events: auto; }
} }
&:not(.artifact-text) { &:not(.artifact-text) {
@@ -142,7 +145,9 @@
li { li {
margin-top: 0; margin-top: 0;
margin-bottom: 0.5em; margin-bottom: 0.5em;
&:last-child {margin-bottom: 0em !important; } &:last-child {
margin-bottom: 0em !important;
}
} }
h1 { h1 {
@@ -179,10 +184,14 @@
p { p {
margin-top: 0; margin-top: 0;
margin-bottom: 0.5em; // compatibility to old system margin-bottom: 0.5em; // compatibility to old system
&:last-child {margin-bottom: 0em !important; } &:last-child {
margin-bottom: 0em !important;
}
} }
a {pointer-events: none; } a {
pointer-events: none;
}
ol { ol {
padding: 0; padding: 0;
@@ -247,7 +256,7 @@
} }
.oembed, .oembed,
div[class*='oembed-'] { div[class*="oembed-"] {
height: 100%; height: 100%;
.play { .play {
position: absolute; position: absolute;
@@ -290,7 +299,9 @@
} }
} }
.title {font-size: 20px; } .title {
font-size: 20px;
}
.image { .image {
height: auto; height: auto;
top: 0; top: 0;
@@ -323,6 +334,7 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
background-size: cover; background-size: cover;
background-color: black;
&.playing { &.playing {
video { video {
@@ -359,10 +371,8 @@
.btn { .btn {
margin-top: 20px; margin-top: 20px;
} }
} }
} }
// FIXME: fix later // FIXME: fix later
@@ -381,8 +391,8 @@
height: 100%; height: 100%;
.timeline { .timeline {
position: absolute; position: absolute;
left:0; left: 0;
top:0; top: 0;
width: 100%; width: 100%;
bottom: 54px; bottom: 54px;
background-size: 100% 100%; background-size: 100% 100%;
@@ -391,7 +401,7 @@
overflow: hidden; overflow: hidden;
.tl-current-time { .tl-current-time {
height:100%; height: 100%;
background: white; background: white;
opacity: 0.5; opacity: 0.5;
border-right: 1px solid #888; border-right: 1px solid #888;
@@ -427,12 +437,11 @@
.btn { .btn {
margin-top: 20px; margin-top: 20px;
} }
} }
.tl-title { .tl-title {
margin-left:10px; margin-left: 10px;
max-width: 55%; max-width: 55%;
overflow: hidden; overflow: hidden;
display: inline-block; display: inline-block;
@@ -454,19 +463,41 @@
height: 100%; height: 100%;
} }
&.bold { font-weight: bold;} &.bold {
&.italic { font-style: italic;} font-weight: bold;
&.underline { text-decoration: underline;} }
&.strike { text-decoration: line-through;} &.italic {
font-style: italic;
}
&.underline {
text-decoration: underline;
}
&.strike {
text-decoration: line-through;
}
&.align-top .text-cell {vertical-align: top;} &.align-top .text-cell {
&.align-middle .text-cell {vertical-align: middle;} vertical-align: top;
&.align-bottom .text-cell {vertical-align: bottom;} }
&.align-middle .text-cell {
vertical-align: middle;
}
&.align-bottom .text-cell {
vertical-align: bottom;
}
&.align-left { text-align: left; } &.align-left {
&.align-center { text-align: center; } text-align: left;
&.align-right { text-align: right; } }
&.align-justify { text-align: justify; } &.align-center {
text-align: center;
}
&.align-right {
text-align: right;
}
&.align-justify {
text-align: justify;
}
audio { audio {
width: 100%; width: 100%;
@@ -481,10 +512,14 @@
font-size: 36px; font-size: 36px;
&.artifact-zone { &.artifact-zone {
background-color: rgba(0,0,0,0.05); background-color: rgba(0, 0, 0, 0.05);
border-radius: 10px; border-radius: 10px;
&:after {display: none; } &:after {
.shape {display: none; } display: none;
}
.shape {
display: none;
}
.zone { .zone {
height: 100%; height: 100%;
} }
@@ -498,30 +533,29 @@ body.present-mode {
} }
.artifact { .artifact {
cursor: default !important; cursor: default !important;
.text a { pointer-events: auto !important; } .text a {
pointer-events: auto !important;
}
} }
} }
} }
body:not(.present-mode) { body:not(.present-mode) {
#space { #space {
.Medium { .Medium {
cursor: text; cursor: text;
} }
.artifact { .artifact {
&.selected.text-editing, &.selected.text-editing,
&.text-editing { &.text-editing {
cursor: text; cursor: text;
&:before { &:before {
border: 1px solid rgba(255,255,255,0.25); border: 1px solid rgba(255, 255, 255, 0.25);
} }
&:after { &:after {
border: 1px dotted rgba(40,140,215,0.5); border: 1px dotted rgba(40, 140, 215, 0.5);
background-color: transparent !important; background-color: transparent !important;
} }
} }
@@ -535,24 +569,27 @@ body:not(.present-mode) {
} }
&:not(.artifact-vector):after { &:not(.artifact-vector):after {
border: 1px solid rgba(40,140,215,1); border: 1px solid rgba(40, 140, 215, 1);
// overlay color removed for now (messes with colors) // overlay color removed for now (messes with colors)
//background-color: rgba(40,140,215,0.35); //background-color: rgba(40,140,215,0.35);
} }
} }
} }
} }
} }
.mouse-scribble, .tool-scribble, .tool-line, .tool-arrow { .mouse-scribble,
.tool-scribble,
.tool-line,
.tool-arrow {
cursor: crosshair !important; cursor: crosshair !important;
.artifact { .artifact {
pointer-events: none !important; pointer-events: none !important;
} }
.artifact:after, .artifact:before { .artifact:after,
.artifact:before {
display: none !important; display: none !important;
} }
} }
@@ -566,21 +603,27 @@ body:not(.present-mode) {
} }
.artifact.state-idle { .artifact.state-idle {
.progress, .progress-text { .progress,
.progress-text {
display: none; display: none;
} }
} }
.artifact.state-processing, .artifact.state-uploading { .artifact.state-processing,
.artifact.state-uploading {
.progress { .progress {
height: 100%; height: 100%;
padding: 10px; padding: 4px;
background-color: $blue;
opacity: 0.9; opacity: 0.9;
text-align: center;
font-size: 14px; font-size: 14px;
} }
.progress-container {
background: $white;
width: 100%;
height: 100%;
padding-left: 10px;
padding-top: 10px;
}
.progress-text { .progress-text {
text-align: center; text-align: center;
padding: 8px; padding: 8px;
@@ -593,43 +636,48 @@ body:not(.present-mode) {
color: #888; color: #888;
font-size: 10px; font-size: 10px;
} }
video, audio, .tl-controls, .timeline { video,
audio,
.tl-controls,
.timeline {
display: none; display: none;
} }
background-color: white; background-color: white;
} }
.state-processing .spinner { .state-processing .spinner {
opacity: 1; opacity: 1;
background-image: url('/images/hourglass.gif'); background-image: url("/images/hourglass.gif");
} }
.state-uploading .spinner { .state-uploading .spinner {
opacity: 0.8; opacity: 0.8;
background-image: url('/images/hourglass.gif'); background-image: url("/images/hourglass.gif");
} }
.state-idle .spinner { .state-idle .spinner {
display: none; display: none;
} }
.artifact.image { .artifact.image {
background-color: transparent; background-color: transparent;
&.state-loading { background-color: rgba(40,140,215,0.05);} &.state-loading {
&.state-processing { background-color: rgba(107,195,111,0.05);} background-color: rgba(40, 140, 215, 0.05);
}
&.state-processing {
background-color: rgba(107, 195, 111, 0.05);
}
} }
.spinner { .spinner {
height:44px; height: 44px;
width:44px; width: 44px;
position:absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
margin: -22px; margin: -22px;
border-radius:100%; border-radius: 100%;
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
} }

View File

@@ -156,8 +156,13 @@
<source v-for="rep in a.view.payload_alternatives" v-bind:src="rep.payload_uri" v-bind:type="rep.mime" /> <source v-for="rep in a.view.payload_alternatives" v-bind:src="rep.payload_uri" v-bind:type="rep.mime" />
<source v-if="a.view.payload_uri && a.view.mime" v-bind:src="a.view.payload_uri" v-bind:type="a.view.mime" /> <source v-if="a.view.payload_uri && a.view.mime" v-bind:src="a.view.payload_uri" v-bind:type="a.view.mime" />
</video> </video>
<div class="spinner"></div> <div class="progress" v-bind:style="{width: a.description+'%'}">
<div class="progress" v-bind:style="{width: a.view.progress+'%'}">{{a.description}}</div> <div class="progress-container">
<h3>
{{a.description}}%
</h3>
</div>
</div>
</div> </div>
<!-- audio --> <!-- audio -->