load additional data from file now possible

This commit is contained in:
2023-11-18 13:26:49 +01:00
parent 2f57ce7257
commit bfde5cd0ac
4 changed files with 69 additions and 39 deletions

View File

@@ -138,7 +138,13 @@ const sendUpdate = ( update ) => {
connectedClients[ client ].write( 'data: ' + JSON.stringify( { 'type': 'pos', 'data': currentDetails[ 'pos' ] } ) + '\n\n' );
}
} else if ( update === 'playingSong' ) {
currentDetails[ update ][ 'startTime' ] = new Date().getTime();
if ( !currentDetails[ 'playingSong' ] ) {
currentDetails[ 'playingSong' ] = {};
}
currentDetails[ 'playingSong' ][ 'startTime' ] = new Date().getTime();
for ( let client in connectedClients ) {
connectedClients[ client ].write( 'data: ' + JSON.stringify( { 'type': 'pos', 'data': currentDetails[ 'pos' ] } ) + '\n\n' );
}
} else if ( update === 'isPlaying' ) {
currentDetails[ 'playingSong' ][ 'startTime' ] = new Date().getTime();
for ( let client in connectedClients ) {

View File

@@ -8,6 +8,8 @@
*/
const path = require( 'path' );
const fs = require( 'fs' );
const csv = require( 'csv-parser' );
const dialog = require( 'electron' ).dialog;
const analyzeFile = ( filepath ) => {
@@ -27,6 +29,8 @@ const analyzeFile = ( filepath ) => {
} );
} else if ( filepath.includes( '.json' ) ) {
resolve( JSON.parse( fs.readFileSync( filepath ) ) );
} else {
reject( 'NO_CSV_OR_JSON_FILE' );
}
} );
}
@@ -58,14 +62,22 @@ module.exports = ( app ) => {
title: 'Open file with additional data on the songs',
filters: [
{
name: 'CSV', extensions: [ '.csv' ],
name: 'JSON', extensions: [ '.json' ]
name: 'All supported files (.csv, .json)',
extensions: [ 'csv', 'json' ],
},
{
name: 'JSON',
extensions: [ 'json' ],
},
{
name: 'CSV',
extensions: [ 'csv' ],
}
]
} );
],
} )[ 0 ];
analyzeFile( filepath ).then( analyzedFile => {
res.send( analyzeFile );
} ).catch( err => {
res.send( analyzedFile );
} ).catch( () => {
res.status( 500 ).send( 'no csv / json file' );
} )
} );

View File

@@ -40,18 +40,19 @@
<div class="player-wrapper">
<div class="player">
<div class="controls">
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" @click="control( 'previous' )">skip_previous</span>
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" @click="control( 'replay10' )">replay_10</span>
<span class="material-symbols-outlined control-icon" :class="hasFinishedInit ? 'active': 'inactive'" @click="control( 'previous' )">skip_previous</span>
<span class="material-symbols-outlined control-icon" :class="hasFinishedInit ? 'active': 'inactive'" @click="control( 'replay10' )">replay_10</span>
<span class="material-symbols-outlined control-icon play-pause" v-if="!isPlaying && hasSelectedPlaylist" @click="control( 'play' )">play_arrow</span>
<span class="material-symbols-outlined control-icon play-pause" v-else-if="isPlaying && hasSelectedPlaylist" @click="control( 'pause' )">pause</span>
<span class="material-symbols-outlined control-icon play-pause" style="cursor: default;" v-else>play_disabled</span>
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" @click="control( 'forward10' )">forward_10</span>
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" @click="control( 'next' )" style="margin-right: 1vw;">skip_next</span>
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" v-if="!isShuffleEnabled" @click="control( 'shuffleOn' )">shuffle</span>
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" v-else @click="control( 'shuffleOff' )">shuffle_on</span>
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" v-if="repeatMode === 'off'" @click="control( 'repeatOne' )">repeat</span>
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" v-else-if="repeatMode === 'one'" @click="control( 'repeatAll' )">repeat_one_on</span>
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" v-else-if="repeatMode === 'all'" @click="control( 'repeatOff' )">repeat_on</span>
<span class="material-symbols-outlined control-icon" :class="hasFinishedInit ? 'active': 'inactive'" @click="control( 'forward10' )">forward_10</span>
<span class="material-symbols-outlined control-icon" :class="hasFinishedInit ? 'active': 'inactive'" @click="control( 'next' )" style="margin-right: 1vw;">skip_next</span>
<span class="material-symbols-outlined control-icon" :class="hasFinishedInit ? 'active': 'inactive'" v-if="!isShuffleEnabled" @click="control( 'shuffleOn' )">shuffle</span>
<span class="material-symbols-outlined control-icon" :class="hasFinishedInit ? 'active': 'inactive'" v-else @click="control( 'shuffleOff' )">shuffle_on</span>
<span class="material-symbols-outlined control-icon" :class="hasFinishedInit ? 'active': 'inactive'" v-if="repeatMode === 'off'" @click="control( 'repeatOne' )">repeat</span>
<span class="material-symbols-outlined control-icon" :class="hasFinishedInit ? 'active': 'inactive'" v-else-if="repeatMode === 'one'" @click="control( 'repeatAll' )">repeat_one_on</span>
<span class="material-symbols-outlined control-icon" :class="hasFinishedInit ? 'active': 'inactive'" v-else-if="repeatMode === 'all'" @click="control( 'repeatOff' )">repeat_on</span>
<span class="material-symbols-outlined control-icon" :class="hasSelectedPlaylist ? 'active': 'inactive'" @click="getAdditionalSongInfo()" title="Load additional song information">upload</span>
<div class="control-icon" id="settings">
<span class="material-symbols-outlined">info</span>
<div id="showIP">
@@ -62,7 +63,7 @@
</div>
<div class="song-info">
<div class="song-info-wrapper">
<img v-if="hasSelectedPlaylist" :src="playingSong.coverArtURL" class="image">
<img v-if="hasFinishedInit" :src="playingSong.coverArtURL" class="image">
<span class="material-symbols-outlined image" v-else>music_note</span>
<div class="name">
<h3>{{ playingSong.title ?? 'No song selected' }}</h3>
@@ -76,8 +77,8 @@
</div>
<div class="slider">
<progress id="progress-slider" class="progress-slider" :value="sliderProgress" max="1000" @mousedown="( e ) => { setPos( e ) }"
:class="hasSelectedPlaylist ? '' : 'slider-inactive'"></progress>
<div v-if="hasSelectedPlaylist" id="slider-knob" @mousedown="( e ) => { startMove( e ) }"
:class="hasFinishedInit ? '' : 'slider-inactive'"></progress>
<div v-if="hasFinishedInit" id="slider-knob" @mousedown="( e ) => { startMove( e ) }"
:style="'left: ' + ( parseInt( originalPos ) + parseInt( sliderPos ) ) + 'px;'">
<div id="slider-knob-style"></div>
</div>

View File

@@ -22,7 +22,8 @@ const app = Vue.createApp( {
localIP: '',
hasLoadedPlaylists: false,
isPreparingToPlay: false,
filenameForAdditionalInfo: '',
additionalSongInfo: {},
hasFinishedInit: false,
// slider
offset: 0,
@@ -69,23 +70,12 @@ const app = Vue.createApp( {
this.musicKit.shuffleMode = MusicKit.PlayerShuffleMode.off;
this.musicKit.addEventListener( 'nowPlayingItemDidChange', ( e ) => {
this.control( 'play' );
this.hasFinishedInit = true;
// Assemble this.playingSong
// TODO: Also add additional items to queue if there are new
// items that weren't previously shown (limitation of MusicKitJS).
if ( e.item ) {
this.playingSong = {
'artist': e.item.attributes.artistName,
'title': e.item.attributes.name,
'year': e.item.attributes.releaseDate,
// Think about bpm analysis
// 'bpm': metadata[ 'common' ][ 'bpm' ],
'genre': e.item.attributes.genreNames,
'duration': Math.round( e.item.attributes.durationInMillis / 1000 ),
'filename': this.songQueue[ this.musicKit.nowPlayingItemIndex ].filename,
'coverArtOrigin': 'api',
'hasCoverArt': true,
'queuePos': this.musicKit.nowPlayingItemIndex,
}
this.playingSong = this.songQueue[ this.musicKit.nowPlayingItemIndex ];
let url = e.item.attributes.artwork.url;
url = url.replace( '{w}', e.item.attributes.artwork.width );
url = url.replace( '{h}', e.item.attributes.artwork.height );
@@ -144,18 +134,38 @@ const app = Vue.createApp( {
} else return false;
},
getAdditionalSongInfo() {
// TODO: Implement
if ( this.filenameForAdditionalInfo ) {
if ( Object.keys( this.additionalSongInfo ).length < 1 ) {
fetch( '/apple-music/getAdditionalData' ).then( res => {
if ( res.status === 200 ) {
res.json().then( json => {
this.additionalSongInfo = json;
this.handleAdditionalData();
} );
}
} );
}
},
handleAdditionalData () {
if ( Object.keys( this.additionalSongInfo ).length > 0 ) {
for ( let item in this.songQueue ) {
if ( this.additionalSongInfo[ item ] ) {
for ( let d in this.additionalSongInfo[ item ] ) {
if ( !this.songQueue[ item ][ d ] ) {
this.songQueue[ item ][ d ] = this.additionalSongInfo[ item ][ d ];
}
}
}
}
this.playingSong = this.songQueue[ this.musicKit.nowPlayingItemIndex ];
this.sendUpdate( 'songQueue' );
this.sendUpdate( 'playingSong' );
}
},
selectPlaylist( id ) {
this.isPreparingToPlay = true;
this.musicKit.setQueue( { playlist: id } ).then( () => {
try {
this.control( 'play' );
this.loadPlaylist();
// TODO: Load additional data from file
this.hasSelectedPlaylist = true;
this.isPreparingToPlay = false;
} catch( err ) {
@@ -251,8 +261,9 @@ const app = Vue.createApp( {
url = url.replace( '{w}', songQueue[ item ].attributes.artwork.width );
url = url.replace( '{h}', songQueue[ item ].attributes.artwork.height );
this.songQueue[ item ][ 'coverArtURL' ] = url;
}
this.handleAdditionalData();
this.sendUpdate( 'songQueue' );
}
},
control( action ) {
if ( action === 'play' ) {