mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 13:04:23 +00:00
load additional data from file now possible
This commit is contained in:
@@ -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 ) {
|
||||
|
||||
@@ -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' );
|
||||
} )
|
||||
} );
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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' );
|
||||
}
|
||||
this.sendUpdate( 'songQueue' );
|
||||
},
|
||||
control( action ) {
|
||||
if ( action === 'play' ) {
|
||||
|
||||
Reference in New Issue
Block a user