mirror of
https://github.com/spacedeck/spacedeck-open.git
synced 2025-12-16 18:07:31 +01:00
Merge pull request #162 from arillo/feature/convert-percentage
add video conversion progress
This commit is contained in:
10
Gulpfile.js
10
Gulpfile.js
@@ -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()
|
||||||
})
|
});
|
||||||
@@ -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));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -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
@@ -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;
|
||||||
@@ -319,10 +330,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.video {
|
.video {
|
||||||
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%;
|
||||||
}
|
}
|
||||||
@@ -496,32 +531,31 @@ body.present-mode {
|
|||||||
.artifact-zone {
|
.artifact-zone {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 -->
|
||||||
|
|||||||
Reference in New Issue
Block a user