mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 04:54:23 +00:00
almost finished
This commit is contained in:
@@ -11,7 +11,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" />
|
<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>
|
</head>
|
||||||
<body>
|
<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 class="content" id="app">
|
||||||
<div v-if="hasLoaded" style="width: 100%">
|
<div v-if="hasLoaded" style="width: 100%">
|
||||||
<div class="current-song-wrapper">
|
<div class="current-song-wrapper">
|
||||||
@@ -27,17 +27,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="song-list-wrapper">
|
<div class="song-list-wrapper">
|
||||||
<div v-for="song in songQueue" class="song-list">
|
<div v-for="song in songQueue" class="song-list">
|
||||||
<span class="material-symbols-outlined song-image" v-if="!song.hasCoverArt && ( playingSong.filename !== song.filename || isPlaying )">music_note</span>
|
|
||||||
<img v-else-if="song.hasCoverArt && ( playingSong.filename !== song.filename || isPlaying ) && song.coverArtOrigin === 'api'" :src="song.coverArtURL" class="song-image">
|
|
||||||
<img v-else-if="song.hasCoverArt && ( playingSong.filename !== song.filename || isPlaying ) && song.coverArtOrigin !== 'api'" :src="'/getSongCover?filename=' + song.filename" class="song-image">
|
|
||||||
<div v-if="playingSong.filename === song.filename && isPlaying" class="playing-symbols">
|
|
||||||
<div class="playing-symbols-wrapper">
|
|
||||||
<div class="playing-bar" id="bar-1"></div>
|
|
||||||
<div class="playing-bar" id="bar-2"></div>
|
|
||||||
<div class="playing-bar" id="bar-3"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="material-symbols-outlined pause-icon" v-if="!isPlaying && playingSong.filename === song.filename">pause</span>
|
|
||||||
<div class="song-details-wrapper">
|
<div class="song-details-wrapper">
|
||||||
<h3>{{ song.title }}</h3>
|
<h3>{{ song.title }}</h3>
|
||||||
<p>{{ song.artist }}</p>
|
<p>{{ song.artist }}</p>
|
||||||
|
|||||||
@@ -48,52 +48,18 @@ body {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playing-bar {
|
|
||||||
height: 60%;
|
|
||||||
background-color: white;
|
|
||||||
width: 10%;
|
|
||||||
border-radius: 50px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bar-1 {
|
|
||||||
animation: music-playing 0.9s infinite ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bar-2 {
|
|
||||||
animation: music-playing 0.9s infinite ease-in-out;
|
|
||||||
animation-delay: 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bar-3 {
|
|
||||||
animation: music-playing 0.9s infinite ease-in-out;
|
|
||||||
animation-delay: 0.6s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes music-playing {
|
|
||||||
0% {
|
|
||||||
transform: scaleY( 1 );
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: scaleY( 0.5 );
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: scaleY( 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.song-list-wrapper {
|
.song-list-wrapper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
margin-bottom: 5%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.song-list {
|
.song-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
@@ -107,6 +73,7 @@ body {
|
|||||||
display: block;
|
display: block;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
width: 65%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.song-list .song-image {
|
.song-list .song-image {
|
||||||
@@ -128,22 +95,20 @@ body {
|
|||||||
|
|
||||||
.current-song-wrapper {
|
.current-song-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 55vh;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 0.5%;
|
margin-bottom: 2%;
|
||||||
margin-top: 0.25%;
|
margin-top: 1%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-song {
|
.current-song {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-top: 1vh;
|
margin-top: 1vh;
|
||||||
padding: 1vh;
|
padding: 1vh;
|
||||||
|
max-width: 80%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: rgba( 0, 0, 0, 0.4 );
|
background-color: rgba( 0, 0, 0, 0.4 );
|
||||||
}
|
}
|
||||||
@@ -157,19 +122,27 @@ body {
|
|||||||
font-size: 30vh !important;
|
font-size: 30vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#canvas {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
background-color: rgba( 0, 0, 0, 0 );
|
background-color: rgba( 0, 0, 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#progress {
|
#progress, #progress::-webkit-progress-bar {
|
||||||
background-color: rgba(45, 28, 145);
|
background-color: rgba(45, 28, 145);
|
||||||
|
color: rgba(45, 28, 145);
|
||||||
width: 30vw;
|
width: 30vw;
|
||||||
border: none;
|
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 {
|
.mode-selector-wrapper {
|
||||||
@@ -199,3 +172,8 @@ body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.time-until {
|
||||||
|
width: 30%;
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
@@ -11,8 +11,6 @@ createApp( {
|
|||||||
pos: 0,
|
pos: 0,
|
||||||
queuePos: 0,
|
queuePos: 0,
|
||||||
colourPalette: [],
|
colourPalette: [],
|
||||||
startTime: 0,
|
|
||||||
offsetTime: 0,
|
|
||||||
progressBar: 0,
|
progressBar: 0,
|
||||||
timeTracker: null,
|
timeTracker: null,
|
||||||
};
|
};
|
||||||
@@ -54,11 +52,13 @@ createApp( {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
startTimeTracker () {
|
startTimeTracker () {
|
||||||
this.startTime = new Date().getTime();
|
|
||||||
this.timeTracker = setInterval( () => {
|
this.timeTracker = setInterval( () => {
|
||||||
this.pos = this.playingSong.startTime - new Date().getTime() / 1000;
|
this.pos = ( new Date().getTime() - this.playingSong.startTime ) / 1000 + this.oldPos;
|
||||||
this.progressBar = ( this.pos / this.playingSong.duration ) * 1000;
|
this.progressBar = ( this.pos / this.playingSong.duration ) * 1000;
|
||||||
}, 75 );
|
if ( isNaN( this.progressBar ) ) {
|
||||||
|
this.progressBar = 0;
|
||||||
|
}
|
||||||
|
}, 100 );
|
||||||
},
|
},
|
||||||
stopTimeTracker () {
|
stopTimeTracker () {
|
||||||
clearInterval( this.timeTracker );
|
clearInterval( this.timeTracker );
|
||||||
@@ -79,13 +79,11 @@ createApp( {
|
|||||||
this.songs = data.data.songQueue ?? [];
|
this.songs = data.data.songQueue ?? [];
|
||||||
this.pos = data.data.pos ?? 0;
|
this.pos = data.data.pos ?? 0;
|
||||||
this.oldPos = data.data.pos ?? 0;
|
this.oldPos = data.data.pos ?? 0;
|
||||||
this.startTime = new Date().getTime();
|
|
||||||
this.progressBar = this.pos / this.playingSong.duration * 1000;
|
this.progressBar = this.pos / this.playingSong.duration * 1000;
|
||||||
this.queuePos = data.data.queuePos ?? 0;
|
this.queuePos = data.data.queuePos ?? 0;
|
||||||
} else if ( data.type === 'pos' ) {
|
} else if ( data.type === 'pos' ) {
|
||||||
this.pos = data.data;
|
this.pos = data.data;
|
||||||
this.oldPos = data.data;
|
this.oldPos = data.data;
|
||||||
this.startTime = new Date().getTime();
|
|
||||||
this.progressBar = data.data / this.playingSong.duration * 1000;
|
this.progressBar = data.data / this.playingSong.duration * 1000;
|
||||||
} else if ( data.type === 'isPlaying' ) {
|
} else if ( data.type === 'isPlaying' ) {
|
||||||
this.isPlaying = data.data;
|
this.isPlaying = data.data;
|
||||||
@@ -102,12 +100,18 @@ createApp( {
|
|||||||
this.hasLoaded = true;
|
this.hasLoaded = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
|
||||||
source.addEventListener( 'error', function( e ) {
|
source.addEventListener( 'error', function( e ) {
|
||||||
if ( e.eventPhase == EventSource.CLOSED ) source.close();
|
if ( e.eventPhase == EventSource.CLOSED ) source.close();
|
||||||
|
|
||||||
if ( e.target.readyState == EventSource.CLOSED ) {
|
if ( e.target.readyState == EventSource.CLOSED ) {
|
||||||
console.log( 'disconnected' );
|
console.log( 'disconnected' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTimeout( () => {
|
||||||
|
self.connect();
|
||||||
|
}, 1000 );
|
||||||
}, false );
|
}, false );
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,13 +19,14 @@ app.use( session( {
|
|||||||
resave: false,
|
resave: false,
|
||||||
} ) );
|
} ) );
|
||||||
|
|
||||||
|
const conf = JSON.parse( fs.readFileSync( path.join( __dirname + '/config/config.json' ) ) );
|
||||||
|
|
||||||
// TODO: Import from config
|
// TODO: Import from config
|
||||||
const remoteURL = 'http://localhost:3000';
|
const remoteURL = conf.connectionURL ?? 'http://localhost:3000';
|
||||||
let hasConnected = false;
|
let hasConnected = false;
|
||||||
|
|
||||||
const connect = () => {
|
const connect = () => {
|
||||||
if ( authKey !== '' ) {
|
if ( authKey !== '' && conf.doConnect ) {
|
||||||
axios.post( remoteURL + '/connect', { 'authKey': authKey } ).then( res => {
|
axios.post( remoteURL + '/connect', { 'authKey': authKey } ).then( res => {
|
||||||
if ( res.status === 200 ) {
|
if ( res.status === 200 ) {
|
||||||
console.log( '[ BACKEND INTEGRATION ] Connection successful' );
|
console.log( '[ BACKEND INTEGRATION ] Connection successful' );
|
||||||
@@ -42,10 +43,7 @@ const connect = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let authKey = '';
|
let authKey = conf.authKey ?? '';
|
||||||
try {
|
|
||||||
authKey = '' + fs.readFileSync( path.join( __dirname + '/config/authKey.txt' ) );
|
|
||||||
} catch( err ) {};
|
|
||||||
|
|
||||||
connect();
|
connect();
|
||||||
|
|
||||||
@@ -69,8 +67,8 @@ app.get( '/', ( request, response ) => {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
app.get( '/openSongs', ( req, res ) => {
|
app.get( '/openSongs', ( req, res ) => {
|
||||||
res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' );
|
// res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' );
|
||||||
// res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' );
|
res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' );
|
||||||
// res.send( { 'data': dialog.showOpenDialogSync( { properties: [ 'openDirectory' ], title: 'Open music library folder' } ) } );
|
// res.send( { 'data': dialog.showOpenDialogSync( { properties: [ 'openDirectory' ], title: 'Open music library folder' } ) } );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@@ -119,6 +117,24 @@ app.get( '/mainNotifier', ( req, res ) => {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
const sendUpdate = ( update ) => {
|
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 ) {
|
for ( let client in connectedClients ) {
|
||||||
connectedClients[ client ].write( 'data: ' + JSON.stringify( { 'type': update, 'data': currentDetails[ update ] } ) + '\n\n' );
|
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
|
// Check if connected and if not, try to authenticate with data from authKey file
|
||||||
|
|
||||||
if ( hasConnected ) {
|
if ( hasConnected ) {
|
||||||
if ( update === 'pos' ) {
|
if ( update === 'isPlaying' ) {
|
||||||
return;
|
axios.post( remoteURL + '/statusUpdate', { 'type': 'playingSong', 'data': currentDetails[ 'playingSong' ], 'authKey': authKey } ).catch( err => {
|
||||||
} else if ( update === 'playingSong' ) {
|
console.error( err );
|
||||||
currentDetails[ update ][ 'startTime' ] === new Date().getTime();
|
} );
|
||||||
|
|
||||||
|
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 => {
|
axios.post( remoteURL + '/statusUpdate', { 'type': update, 'data': currentDetails[ update ], 'authKey': authKey } ).catch( err => {
|
||||||
if ( res.status !== 200 ) {
|
|
||||||
console.log( res );
|
|
||||||
}
|
|
||||||
} ).catch( err => {
|
|
||||||
console.error( err );
|
console.error( err );
|
||||||
} );
|
} );
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -156,19 +156,27 @@ body {
|
|||||||
font-size: 30vh !important;
|
font-size: 30vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#canvas {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
background-color: rgba( 0, 0, 0, 0 );
|
background-color: rgba( 0, 0, 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#progress {
|
#progress, #progress::-webkit-progress-bar {
|
||||||
background-color: rgba(45, 28, 145);
|
background-color: rgba(45, 28, 145);
|
||||||
|
color: rgba(45, 28, 145);
|
||||||
width: 30vw;
|
width: 30vw;
|
||||||
border: none;
|
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 {
|
.mode-selector-wrapper {
|
||||||
|
|||||||
@@ -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" />
|
<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>
|
</head>
|
||||||
<body>
|
<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 class="content" id="app">
|
||||||
<div v-if="hasLoaded" style="width: 100%">
|
<div v-if="hasLoaded" style="width: 100%">
|
||||||
<div class="current-song-wrapper">
|
<div class="current-song-wrapper">
|
||||||
@@ -64,7 +64,6 @@
|
|||||||
<div class="beat"></div>
|
<div class="beat"></div>
|
||||||
<div class="beat-manual"></div>
|
<div class="beat-manual"></div>
|
||||||
</div>
|
</div>
|
||||||
<canvas id="canvas"></canvas>
|
|
||||||
</div>
|
</div>
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
<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>
|
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
|
||||||
|
|||||||
@@ -11,11 +11,8 @@ createApp( {
|
|||||||
pos: 0,
|
pos: 0,
|
||||||
queuePos: 0,
|
queuePos: 0,
|
||||||
colourPalette: [],
|
colourPalette: [],
|
||||||
startTime: 0,
|
|
||||||
offsetTime: 0,
|
|
||||||
progressBar: 0,
|
progressBar: 0,
|
||||||
timeTracker: null,
|
timeTracker: null,
|
||||||
timeCorrector: null,
|
|
||||||
visualizationSettings: 'mic',
|
visualizationSettings: 'mic',
|
||||||
micAnalyzer: null,
|
micAnalyzer: null,
|
||||||
beatDetected: false,
|
beatDetected: false,
|
||||||
@@ -59,20 +56,16 @@ createApp( {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
startTimeTracker () {
|
startTimeTracker () {
|
||||||
this.startTime = new Date().getTime();
|
|
||||||
this.timeTracker = setInterval( () => {
|
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;
|
this.progressBar = ( this.pos / this.playingSong.duration ) * 1000;
|
||||||
}, 75 );
|
if ( isNaN( this.progressBar ) ) {
|
||||||
|
this.progressBar = 0;
|
||||||
this.timeCorrector = setInterval( () => {
|
}
|
||||||
this.pos = this.oldPos + ( new Date().getTime() - this.startTime ) / 1000;
|
}, 100 );
|
||||||
this.progressBar = ( this.pos / this.playingSong.duration ) * 1000;
|
|
||||||
}, 5000 );
|
|
||||||
},
|
},
|
||||||
stopTimeTracker () {
|
stopTimeTracker () {
|
||||||
clearInterval( this.timeTracker );
|
clearInterval( this.timeTracker );
|
||||||
clearInterval( this.timeCorrector );
|
|
||||||
this.oldPos = this.pos;
|
this.oldPos = this.pos;
|
||||||
},
|
},
|
||||||
getImageData() {
|
getImageData() {
|
||||||
@@ -109,7 +102,6 @@ createApp( {
|
|||||||
this.songs = data.data.songQueue ?? [];
|
this.songs = data.data.songQueue ?? [];
|
||||||
this.pos = data.data.pos ?? 0;
|
this.pos = data.data.pos ?? 0;
|
||||||
this.oldPos = data.data.pos ?? 0;
|
this.oldPos = data.data.pos ?? 0;
|
||||||
this.startTime = new Date().getTime();
|
|
||||||
this.progressBar = this.pos / this.playingSong.duration * 1000;
|
this.progressBar = this.pos / this.playingSong.duration * 1000;
|
||||||
this.queuePos = data.data.queuePos ?? 0;
|
this.queuePos = data.data.queuePos ?? 0;
|
||||||
this.getImageData().then( palette => {
|
this.getImageData().then( palette => {
|
||||||
@@ -122,7 +114,6 @@ createApp( {
|
|||||||
} else if ( data.type === 'pos' ) {
|
} else if ( data.type === 'pos' ) {
|
||||||
this.pos = data.data;
|
this.pos = data.data;
|
||||||
this.oldPos = data.data;
|
this.oldPos = data.data;
|
||||||
this.startTime = new Date().getTime();
|
|
||||||
this.progressBar = data.data / this.playingSong.duration * 1000;
|
this.progressBar = data.data / this.playingSong.duration * 1000;
|
||||||
} else if ( data.type === 'isPlaying' ) {
|
} else if ( data.type === 'isPlaying' ) {
|
||||||
this.isPlaying = data.data;
|
this.isPlaying = data.data;
|
||||||
@@ -147,12 +138,19 @@ createApp( {
|
|||||||
this.hasLoaded = true;
|
this.hasLoaded = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
|
||||||
source.addEventListener( 'error', function( e ) {
|
source.addEventListener( 'error', function( e ) {
|
||||||
if ( e.eventPhase == EventSource.CLOSED ) source.close();
|
if ( e.eventPhase == EventSource.CLOSED ) source.close();
|
||||||
|
|
||||||
if ( e.target.readyState == EventSource.CLOSED ) {
|
if ( e.target.readyState == EventSource.CLOSED ) {
|
||||||
console.log( 'disconnected' );
|
console.log( 'disconnected' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Notify about disconnect
|
||||||
|
setTimeout( () => {
|
||||||
|
self.connect();
|
||||||
|
}, 1000 );
|
||||||
}, false );
|
}, false );
|
||||||
},
|
},
|
||||||
handleBackground() {
|
handleBackground() {
|
||||||
@@ -206,6 +204,7 @@ createApp( {
|
|||||||
this.setVisualization();
|
this.setVisualization();
|
||||||
},
|
},
|
||||||
setVisualization () {
|
setVisualization () {
|
||||||
|
if ( Object.keys( this.playingSong ).length > 0 ) {
|
||||||
if ( this.visualizationSettings === 'bpm' ) {
|
if ( this.visualizationSettings === 'bpm' ) {
|
||||||
if ( this.playingSong.bpm && this.isPlaying ) {
|
if ( this.playingSong.bpm && this.isPlaying ) {
|
||||||
$( '.beat' ).show();
|
$( '.beat' ).show();
|
||||||
@@ -229,6 +228,9 @@ createApp( {
|
|||||||
} catch ( err ) {}
|
} catch ( err ) {}
|
||||||
this.micAudioHandler();
|
this.micAudioHandler();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.log( 'not playing yet' );
|
||||||
|
}
|
||||||
},
|
},
|
||||||
micAudioHandler () {
|
micAudioHandler () {
|
||||||
const audioContext = new ( window.AudioContext || window.webkitAudioContext )();
|
const audioContext = new ( window.AudioContext || window.webkitAudioContext )();
|
||||||
@@ -288,9 +290,9 @@ createApp( {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.connect();
|
this.connect();
|
||||||
if ( this.visualizationSettings === 'mic' ) {
|
// if ( this.visualizationSettings === 'mic' ) {
|
||||||
this.micAudioHandler();
|
// this.micAudioHandler();
|
||||||
}
|
// }
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
isPlaying( value ) {
|
isPlaying( value ) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="playback-pos-info">
|
<div class="playback-pos-info">
|
||||||
<div style="margin-right: auto;">{{ playbackPosBeautified }}</div>
|
<div style="margin-right: auto;">{{ playbackPosBeautified }}</div>
|
||||||
<div>{{ durationBeautified }}</div>
|
<div @click="toggleShowMode()" style="cursor: pointer;">{{ durationBeautified }}</div>
|
||||||
</div>
|
</div>
|
||||||
<sliderView :active="audioLoaded" :position="playbackPos" :duration="playingSong.duration" @pos="( p ) => { setPos( p ) }"
|
<sliderView :active="audioLoaded" :position="playbackPos" :duration="playingSong.duration" @pos="( p ) => { setPos( p ) }"
|
||||||
name="player"></sliderView>
|
name="player"></sliderView>
|
||||||
@@ -142,6 +142,7 @@ export default {
|
|||||||
hasLoadedSongs: false,
|
hasLoadedSongs: false,
|
||||||
isShowingFancyView: false,
|
isShowingFancyView: false,
|
||||||
notifier: null,
|
notifier: null,
|
||||||
|
isShowingRemainingTime: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
@@ -208,6 +209,22 @@ export default {
|
|||||||
}
|
}
|
||||||
}, 300 );
|
}, 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 ) {
|
sendUpdate( update ) {
|
||||||
let data = {};
|
let data = {};
|
||||||
if ( update === 'pos' ) {
|
if ( update === 'pos' ) {
|
||||||
@@ -250,14 +267,27 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.playbackPosBeautified += secondCount;
|
this.playbackPosBeautified += secondCount;
|
||||||
}
|
}
|
||||||
}, 0.02 );
|
|
||||||
this.progressTracker = setInterval( () => {
|
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( 'pos' );
|
||||||
}, 5000 );
|
|
||||||
this.sendUpdate( 'isPlaying' );
|
this.sendUpdate( 'isPlaying' );
|
||||||
} else if ( action === 'pause' ) {
|
} else if ( action === 'pause' ) {
|
||||||
this.$emit( 'update', { 'type': 'playback', 'status': false } );
|
this.$emit( 'update', { 'type': 'playback', 'status': false } );
|
||||||
musicPlayer.pause();
|
musicPlayer.pause();
|
||||||
|
this.sendUpdate( 'pos' );
|
||||||
try {
|
try {
|
||||||
clearInterval( this.progressTracker );
|
clearInterval( this.progressTracker );
|
||||||
clearInterval( this.notifier );
|
clearInterval( this.notifier );
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
gaöwovwef89voawö8p9 odövefw8öoaewpf89wec
|
|
||||||
5
frontend/src/config/config.json
Normal file
5
frontend/src/config/config.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"connectionURL": "http://localhost:3000",
|
||||||
|
"authKey": "gaöwovwef89voawö8p9 odövefw8öoaewpf89wec",
|
||||||
|
"doConnect": true
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user