almost finished

This commit is contained in:
2023-11-09 21:06:41 +01:00
parent 5037663fd5
commit 6bbc97f2c3
10 changed files with 167 additions and 133 deletions

View File

@@ -19,13 +19,14 @@ app.use( session( {
resave: false,
} ) );
const conf = JSON.parse( fs.readFileSync( path.join( __dirname + '/config/config.json' ) ) );
// TODO: Import from config
const remoteURL = 'http://localhost:3000';
const remoteURL = conf.connectionURL ?? 'http://localhost:3000';
let hasConnected = false;
const connect = () => {
if ( authKey !== '' ) {
if ( authKey !== '' && conf.doConnect ) {
axios.post( remoteURL + '/connect', { 'authKey': authKey } ).then( res => {
if ( res.status === 200 ) {
console.log( '[ BACKEND INTEGRATION ] Connection successful' );
@@ -42,10 +43,7 @@ const connect = () => {
}
};
let authKey = '';
try {
authKey = '' + fs.readFileSync( path.join( __dirname + '/config/authKey.txt' ) );
} catch( err ) {};
let authKey = conf.authKey ?? '';
connect();
@@ -69,8 +67,8 @@ app.get( '/', ( request, response ) => {
} );
app.get( '/openSongs', ( req, res ) => {
res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' );
// res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' );
// res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' );
res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' );
// res.send( { 'data': dialog.showOpenDialogSync( { properties: [ 'openDirectory' ], title: 'Open music library folder' } ) } );
} );
@@ -119,6 +117,24 @@ app.get( '/mainNotifier', ( req, res ) => {
} );
const sendUpdate = ( update ) => {
if ( update === 'pos' ) {
currentDetails[ 'playingSong' ][ 'startTime' ] = new Date().getTime();
for ( let client in connectedClients ) {
connectedClients[ client ].write( 'data: ' + JSON.stringify( { 'type': 'playingSong', 'data': currentDetails[ 'playingSong' ] } ) + '\n\n' );
}
} else if ( update === 'playingSong' ) {
currentDetails[ update ][ 'startTime' ] = new Date().getTime();
} else if ( update === 'isPlaying' ) {
currentDetails[ 'playingSong' ][ 'startTime' ] = new Date().getTime();
for ( let client in connectedClients ) {
connectedClients[ client ].write( 'data: ' + JSON.stringify( { 'type': 'playingSong', 'data': currentDetails[ 'playingSong' ] } ) + '\n\n' );
}
for ( let client in connectedClients ) {
connectedClients[ client ].write( 'data: ' + JSON.stringify( { 'type': 'pos', 'data': currentDetails[ 'pos' ] } ) + '\n\n' );
}
}
for ( let client in connectedClients ) {
connectedClients[ client ].write( 'data: ' + JSON.stringify( { 'type': update, 'data': currentDetails[ update ] } ) + '\n\n' );
}
@@ -126,16 +142,20 @@ const sendUpdate = ( update ) => {
// Check if connected and if not, try to authenticate with data from authKey file
if ( hasConnected ) {
if ( update === 'pos' ) {
return;
} else if ( update === 'playingSong' ) {
currentDetails[ update ][ 'startTime' ] === new Date().getTime();
if ( update === 'isPlaying' ) {
axios.post( remoteURL + '/statusUpdate', { 'type': 'playingSong', 'data': currentDetails[ 'playingSong' ], 'authKey': authKey } ).catch( err => {
console.error( err );
} );
axios.post( remoteURL + '/statusUpdate', { 'type': 'pos', 'data': currentDetails[ 'pos' ], 'authKey': authKey } ).catch( err => {
console.error( err );
} );
} else if ( update === 'pos' ) {
axios.post( remoteURL + '/statusUpdate', { 'type': 'playingSong', 'data': currentDetails[ 'playingSong' ], 'authKey': authKey } ).catch( err => {
console.error( err );
} );
}
axios.post( remoteURL + '/statusUpdate', { 'type': update, 'data': currentDetails[ update ], 'authKey': authKey } ).then( res => {
if ( res.status !== 200 ) {
console.log( res );
}
} ).catch( err => {
axios.post( remoteURL + '/statusUpdate', { 'type': update, 'data': currentDetails[ update ], 'authKey': authKey } ).catch( err => {
console.error( err );
} );
} else {

View File

@@ -156,19 +156,27 @@ body {
font-size: 30vh !important;
}
#canvas {
display: none;
}
#app {
background-color: rgba( 0, 0, 0, 0 );
}
#progress {
#progress, #progress::-webkit-progress-bar {
background-color: rgba(45, 28, 145);
color: rgba(45, 28, 145);
width: 30vw;
border: none;
border-radius: 50px;
border-radius: 0px;
accent-color: white;
-webkit-appearance: none;
appearance: none;
}
#progress::-moz-progress-bar {
background-color: white;
}
#progress::-webkit-progress-value {
background-color: white !important;
}
.mode-selector-wrapper {

View File

@@ -12,7 +12,7 @@
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
</head>
<body>
<div class="info">Designed and developed by Janis Hutz https://janishutz.com</div>
<div class="info">Designed and developed by Janis Hutz <a href="https://janishutz.com" target="_blank" style="text-decoration: none; color: white;">https://janishutz.com</a></div>
<div class="content" id="app">
<div v-if="hasLoaded" style="width: 100%">
<div class="current-song-wrapper">
@@ -64,7 +64,6 @@
<div class="beat"></div>
<div class="beat-manual"></div>
</div>
<canvas id="canvas"></canvas>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

View File

@@ -11,11 +11,8 @@ createApp( {
pos: 0,
queuePos: 0,
colourPalette: [],
startTime: 0,
offsetTime: 0,
progressBar: 0,
timeTracker: null,
timeCorrector: null,
visualizationSettings: 'mic',
micAnalyzer: null,
beatDetected: false,
@@ -59,20 +56,16 @@ createApp( {
},
methods: {
startTimeTracker () {
this.startTime = new Date().getTime();
this.timeTracker = setInterval( () => {
this.pos += 0.075;
this.pos = ( new Date().getTime() - this.playingSong.startTime ) / 1000 + this.oldPos;
this.progressBar = ( this.pos / this.playingSong.duration ) * 1000;
}, 75 );
this.timeCorrector = setInterval( () => {
this.pos = this.oldPos + ( new Date().getTime() - this.startTime ) / 1000;
this.progressBar = ( this.pos / this.playingSong.duration ) * 1000;
}, 5000 );
if ( isNaN( this.progressBar ) ) {
this.progressBar = 0;
}
}, 100 );
},
stopTimeTracker () {
clearInterval( this.timeTracker );
clearInterval( this.timeCorrector );
this.oldPos = this.pos;
},
getImageData() {
@@ -109,7 +102,6 @@ createApp( {
this.songs = data.data.songQueue ?? [];
this.pos = data.data.pos ?? 0;
this.oldPos = data.data.pos ?? 0;
this.startTime = new Date().getTime();
this.progressBar = this.pos / this.playingSong.duration * 1000;
this.queuePos = data.data.queuePos ?? 0;
this.getImageData().then( palette => {
@@ -122,7 +114,6 @@ createApp( {
} else if ( data.type === 'pos' ) {
this.pos = data.data;
this.oldPos = data.data;
this.startTime = new Date().getTime();
this.progressBar = data.data / this.playingSong.duration * 1000;
} else if ( data.type === 'isPlaying' ) {
this.isPlaying = data.data;
@@ -146,6 +137,8 @@ createApp( {
source.onopen = () => {
this.hasLoaded = true;
};
let self = this;
source.addEventListener( 'error', function( e ) {
if ( e.eventPhase == EventSource.CLOSED ) source.close();
@@ -153,6 +146,11 @@ createApp( {
if ( e.target.readyState == EventSource.CLOSED ) {
console.log( 'disconnected' );
}
// TODO: Notify about disconnect
setTimeout( () => {
self.connect();
}, 1000 );
}, false );
},
handleBackground() {
@@ -206,28 +204,32 @@ createApp( {
this.setVisualization();
},
setVisualization () {
if ( this.visualizationSettings === 'bpm' ) {
if ( this.playingSong.bpm && this.isPlaying ) {
$( '.beat' ).show();
$( '.beat' ).css( 'animation-duration', 60 / this.playingSong.bpm );
$( '.beat' ).css( 'animation-delay', this.pos % ( 60 / this.playingSong.bpm * this.pos ) + this.playingSong.bpmOffset - ( 60 / this.playingSong.bpm * this.pos / 2 ) );
} else {
if ( Object.keys( this.playingSong ).length > 0 ) {
if ( this.visualizationSettings === 'bpm' ) {
if ( this.playingSong.bpm && this.isPlaying ) {
$( '.beat' ).show();
$( '.beat' ).css( 'animation-duration', 60 / this.playingSong.bpm );
$( '.beat' ).css( 'animation-delay', this.pos % ( 60 / this.playingSong.bpm * this.pos ) + this.playingSong.bpmOffset - ( 60 / this.playingSong.bpm * this.pos / 2 ) );
} else {
$( '.beat' ).hide();
}
try {
clearInterval( this.micAnalyzer );
} catch ( err ) {}
} else if ( this.visualizationSettings === 'off' ) {
$( '.beat' ).hide();
try {
clearInterval( this.micAnalyzer );
} catch ( err ) {}
} else if ( this.visualizationSettings === 'mic' ) {
$( '.beat-manual' ).hide();
try {
clearInterval( this.micAnalyzer );
} catch ( err ) {}
this.micAudioHandler();
}
try {
clearInterval( this.micAnalyzer );
} catch ( err ) {}
} else if ( this.visualizationSettings === 'off' ) {
$( '.beat' ).hide();
try {
clearInterval( this.micAnalyzer );
} catch ( err ) {}
} else if ( this.visualizationSettings === 'mic' ) {
$( '.beat-manual' ).hide();
try {
clearInterval( this.micAnalyzer );
} catch ( err ) {}
this.micAudioHandler();
} else {
console.log( 'not playing yet' );
}
},
micAudioHandler () {
@@ -288,9 +290,9 @@ createApp( {
},
mounted() {
this.connect();
if ( this.visualizationSettings === 'mic' ) {
this.micAudioHandler();
}
// if ( this.visualizationSettings === 'mic' ) {
// this.micAudioHandler();
// }
},
watch: {
isPlaying( value ) {

View File

@@ -31,7 +31,7 @@
</div>
<div class="playback-pos-info">
<div style="margin-right: auto;">{{ playbackPosBeautified }}</div>
<div>{{ durationBeautified }}</div>
<div @click="toggleShowMode()" style="cursor: pointer;">{{ durationBeautified }}</div>
</div>
<sliderView :active="audioLoaded" :position="playbackPos" :duration="playingSong.duration" @pos="( p ) => { setPos( p ) }"
name="player"></sliderView>
@@ -142,6 +142,7 @@ export default {
hasLoadedSongs: false,
isShowingFancyView: false,
notifier: null,
isShowingRemainingTime: false,
}
},
components: {
@@ -208,6 +209,22 @@ export default {
}
}, 300 );
},
toggleShowMode() {
this.isShowingRemainingTime = !this.isShowingRemainingTime;
if ( !this.isShowingRemainingTime ) {
const minuteCounts = Math.floor( this.playingSong.duration / 60 );
this.durationBeautified = String( minuteCounts ) + ':';
if ( ( '' + minuteCounts ).length === 1 ) {
this.durationBeautified = '0' + minuteCounts + ':';
}
const secondCounts = Math.floor( this.playingSong.duration - minuteCounts * 60 );
if ( ( '' + secondCounts ).length === 1 ) {
this.durationBeautified += '0' + secondCounts;
} else {
this.durationBeautified += secondCounts;
}
}
},
sendUpdate( update ) {
let data = {};
if ( update === 'pos' ) {
@@ -250,14 +267,27 @@ export default {
} else {
this.playbackPosBeautified += secondCount;
}
}, 0.02 );
this.progressTracker = setInterval( () => {
this.sendUpdate( 'pos' );
}, 5000 );
if ( this.isShowingRemainingTime ) {
const minuteCounts = Math.floor( ( this.playingSong.duration - this.playbackPos ) / 60 );
this.durationBeautified = '-' + String( minuteCounts ) + ':';
if ( ( '' + minuteCounts ).length === 1 ) {
this.durationBeautified = '-0' + minuteCounts + ':';
}
const secondCounts = Math.floor( ( this.playingSong.duration - this.playbackPos ) - minuteCounts * 60 );
if ( ( '' + secondCounts ).length === 1 ) {
this.durationBeautified += '0' + secondCounts;
} else {
this.durationBeautified += secondCounts;
}
}
}, 20 );
this.sendUpdate( 'pos' );
this.sendUpdate( 'isPlaying' );
} else if ( action === 'pause' ) {
this.$emit( 'update', { 'type': 'playback', 'status': false } );
musicPlayer.pause();
this.sendUpdate( 'pos' );
try {
clearInterval( this.progressTracker );
clearInterval( this.notifier );

View File

@@ -1 +0,0 @@
gaöwovwef89voawö8p9 odövefw8öoaewpf89wec

View File

@@ -0,0 +1,5 @@
{
"connectionURL": "http://localhost:3000",
"authKey": "gaöwovwef89voawö8p9 odövefw8öoaewpf89wec",
"doConnect": true
}