mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 13:04:23 +00:00
578 lines
26 KiB
JavaScript
578 lines
26 KiB
JavaScript
const app = Vue.createApp( {
|
|
data() {
|
|
return {
|
|
musicKit: null,
|
|
isLoggedIn: false,
|
|
config: {
|
|
'devToken': '',
|
|
'userToken': ''
|
|
},
|
|
playlists: {},
|
|
hasSelectedPlaylist: false,
|
|
songQueue: {},
|
|
queuePos: 0,
|
|
pos: 0,
|
|
playingSong: {},
|
|
isPlaying: false,
|
|
isShuffleEnabled: false,
|
|
repeatMode: 'off',
|
|
playbackPosBeautified: '',
|
|
durationBeautified: '',
|
|
isShowingRemainingTime: false,
|
|
localIP: '',
|
|
hasLoadedPlaylists: false,
|
|
isPreparingToPlay: false,
|
|
additionalSongInfo: {},
|
|
hasFinishedInit: false,
|
|
|
|
// For use with playlists that are partially from apple music and
|
|
// local drive
|
|
isUsingCustomPlaylist: false,
|
|
rawLoadedPlaylistData: {},
|
|
|
|
// slider
|
|
offset: 0,
|
|
isDragging: false,
|
|
sliderPos: 0,
|
|
originalPos: 0,
|
|
sliderProgress: 0,
|
|
active: false,
|
|
}
|
|
},
|
|
methods: {
|
|
logInto() {
|
|
if ( !this.musicKit.isAuthorized ) {
|
|
this.musicKit.authorize().then( () => {
|
|
this.isLoggedIn = true;
|
|
this.initMusicKit();
|
|
} );
|
|
} else {
|
|
this.musicKit.authorize().then( () => {
|
|
this.isLoggedIn = true;
|
|
this.initMusicKit();
|
|
} );
|
|
}
|
|
},
|
|
initMusicKit () {
|
|
fetch( '/getAppleMusicDevToken' ).then( res => {
|
|
if ( res.status === 200 ) {
|
|
res.text().then( token => {
|
|
// MusicKit global is now defined
|
|
MusicKit.configure( {
|
|
developerToken: token,
|
|
app: {
|
|
name: 'MusicPlayer',
|
|
build: '2'
|
|
},
|
|
storefrontId: 'CH',
|
|
} ).then( () => {
|
|
this.config.devToken = token;
|
|
this.musicKit = MusicKit.getInstance();
|
|
if ( this.musicKit.isAuthorized ) {
|
|
this.isLoggedIn = true;
|
|
this.config.userToken = this.musicKit.musicUserToken;
|
|
}
|
|
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).
|
|
// TODO: Load from disk and stop MusicKit playback if next item in queue is
|
|
// to be loaded from disk
|
|
// TODO: Consideration: array with offsets to check if songs is correct
|
|
if ( e.item ) {
|
|
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 );
|
|
this.playingSong[ 'coverArtURL' ] = url;
|
|
this.queuePos = this.musicKit.nowPlayingItemIndex;
|
|
this.sendUpdate( 'playingSong' );
|
|
this.sendUpdate( 'pos' );
|
|
this.sendUpdate( 'isPlaying' );
|
|
this.sendUpdate( 'queuePos' );
|
|
setTimeout( () => {
|
|
this.sendUpdate( 'pos' );
|
|
}, 500 );
|
|
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;
|
|
}
|
|
}
|
|
} );
|
|
this.apiGetRequest( 'https://api.music.apple.com/v1/me/library/playlists', this.playlistHandler );
|
|
} );
|
|
} );
|
|
}
|
|
} );
|
|
},
|
|
playlistHandler ( data ) {
|
|
if ( data.status === 'ok' ) {
|
|
const d = data.data.data;
|
|
this.playlist = {};
|
|
for ( let el in d ) {
|
|
this.playlists[ d[ el ].id ] = {
|
|
title: d[ el ].attributes.name,
|
|
id: d[ el ].id,
|
|
playParams: d[ el ].attributes.playParams,
|
|
}
|
|
}
|
|
this.hasLoadedPlaylists = true;
|
|
}
|
|
},
|
|
apiGetRequest( url, callback ) {
|
|
if ( this.config.devToken != '' && this.config.userToken != '' ) {
|
|
fetch( url, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Authorization': `Bearer ${ this.config.devToken }`,
|
|
'Music-User-Token': this.config.userToken
|
|
}
|
|
} ).then( res => {
|
|
if ( res.status === 200 ) {
|
|
res.json().then( json => {
|
|
try {
|
|
callback( { 'status': 'ok', 'data': json } );
|
|
} catch( err ) {}
|
|
} );
|
|
} else {
|
|
try {
|
|
callback( { 'status': 'error', 'error': res.status } );
|
|
} catch( err ) {}
|
|
}
|
|
} );
|
|
} else return false;
|
|
},
|
|
getAdditionalSongInfo() {
|
|
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 ];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// TODO: update all those items to use custom queue manager for queue pos
|
|
this.playingSong = this.songQueue[ this.queuePos ];
|
|
this.sendUpdate( 'songQueue' );
|
|
this.sendUpdate( 'playingSong' );
|
|
}
|
|
},
|
|
selectPlaylist( id ) {
|
|
this.isPreparingToPlay = true;
|
|
this.musicKit.setQueue( { playlist: id } ).then( () => {
|
|
try {
|
|
this.loadPlaylist();
|
|
this.hasSelectedPlaylist = true;
|
|
this.isPreparingToPlay = false;
|
|
} catch( err ) {
|
|
this.hasSelectedPlaylist = false;
|
|
console.error( err );
|
|
alert( 'We were unable to play. Please ensure that DRM (yeah sorry it is Apple Music, we cannot do anything about that) is enabled and working' );
|
|
}
|
|
} ).catch( err => {
|
|
console.error( 'ERROR whilst settings Queue', err );
|
|
} );
|
|
},
|
|
handleDrag( e ) {
|
|
if ( this.isDragging ) {
|
|
if ( 0 < this.originalPos + e.screenX - this.offset && this.originalPos + e.screenX - this.offset < document.getElementById( 'progress-slider' ).clientWidth - 5 ) {
|
|
this.sliderPos = e.screenX - this.offset;
|
|
this.calcProgressPos();
|
|
}
|
|
}
|
|
},
|
|
startMove( e ) {
|
|
this.offset = e.screenX;
|
|
this.isDragging = true;
|
|
document.getElementById( 'drag-support' ).classList.add( 'drag-support-active' );
|
|
},
|
|
stopMove() {
|
|
this.originalPos += parseInt( this.sliderPos );
|
|
this.isDragging = false;
|
|
this.offset = 0;
|
|
this.sliderPos = 0;
|
|
document.getElementById( 'drag-support' ).classList.remove( 'drag-support-active' );
|
|
this.calcPlaybackPos();
|
|
},
|
|
setPos ( e ) {
|
|
if ( this.hasSelectedPlaylist ) {
|
|
this.originalPos = e.offsetX;
|
|
this.calcProgressPos();
|
|
this.calcPlaybackPos();
|
|
this.musicKit.seekToTime( this.pos );
|
|
this.sendUpdate( 'pos' );
|
|
}
|
|
},
|
|
calcProgressPos() {
|
|
this.sliderProgress = Math.ceil( ( this.originalPos + parseInt( this.sliderPos ) ) / ( document.getElementById( 'progress-slider' ).clientWidth - 5 ) * 1000 );
|
|
},
|
|
calcPlaybackPos() {
|
|
this.pos = Math.round( ( this.originalPos + parseInt( this.sliderPos ) ) / ( document.getElementById( 'progress-slider' ).clientWidth - 5 ) * this.playingSong.duration );
|
|
},
|
|
sendUpdate( update ) {
|
|
let data = {};
|
|
let up = update;
|
|
if ( update === 'pos' ) {
|
|
data = this.pos;
|
|
} else if ( update === 'playingSong' ) {
|
|
data = this.playingSong;
|
|
} else if ( update === 'isPlaying' ) {
|
|
data = this.isPlaying;
|
|
} else if ( update === 'songQueue' ) {
|
|
data = this.songQueue;
|
|
} else if ( update === 'queuePos' ) {
|
|
this.queuePos = this.musicKit.nowPlayingItemIndex >= 0 ? this.musicKit.nowPlayingItemIndex : 0;
|
|
data = this.queuePos;
|
|
} else if ( update === 'posReset' ) {
|
|
data = 0;
|
|
up = 'pos';
|
|
}
|
|
let fetchOptions = {
|
|
method: 'post',
|
|
body: JSON.stringify( { 'type': up, 'data': data } ),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'charset': 'utf-8'
|
|
},
|
|
};
|
|
fetch( 'http://localhost:8081/statusUpdate', fetchOptions ).catch( err => {
|
|
console.error( err );
|
|
} );
|
|
},
|
|
loadPlaylist() {
|
|
const songQueue = this.musicKit.queue.items;
|
|
for ( let item in songQueue ) {
|
|
this.songQueue[ item ] = {
|
|
'artist': songQueue[ item ].attributes.artistName,
|
|
'title': songQueue[ item ].attributes.name,
|
|
'year': songQueue[ item ].attributes.releaseDate,
|
|
'genre': songQueue[ item ].attributes.genreNames,
|
|
'duration': Math.round( songQueue[ item ].attributes.durationInMillis / 1000 ),
|
|
'filename': songQueue[ item ].id,
|
|
'coverArtOrigin': 'api',
|
|
'hasCoverArt': true,
|
|
'queuePos': item,
|
|
'origin': 'apple-music',
|
|
}
|
|
let url = songQueue[ item ].attributes.artwork.url;
|
|
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' ) {
|
|
if( !this.musicKit || !this.isPlaying ) {
|
|
this.musicKit.play().then( () => {
|
|
this.sendUpdate( 'pos' );
|
|
} ).catch( err => {
|
|
console.log( 'player failed to start' );
|
|
console.log( err );
|
|
} );
|
|
} else {
|
|
this.musicKit.pause().then( () => {
|
|
this.musicKit.play().catch( err => {
|
|
console.log( 'player failed to start' );
|
|
console.log( err );
|
|
} );
|
|
} );
|
|
}
|
|
this.isPlaying = true;
|
|
try {
|
|
clearInterval( this.progressTracker );
|
|
} catch( err ) {};
|
|
this.progressTracker = setInterval( () => {
|
|
this.pos = parseInt( this.musicKit.currentPlaybackTime );
|
|
|
|
const minuteCount = Math.floor( this.pos / 60 );
|
|
this.playbackPosBeautified = minuteCount + ':';
|
|
if ( ( '' + minuteCount ).length === 1 ) {
|
|
this.playbackPosBeautified = '0' + minuteCount + ':';
|
|
}
|
|
const secondCount = Math.floor( this.pos - minuteCount * 60 );
|
|
if ( ( '' + secondCount ).length === 1 ) {
|
|
this.playbackPosBeautified += '0' + secondCount;
|
|
} else {
|
|
this.playbackPosBeautified += secondCount;
|
|
}
|
|
|
|
if ( this.isShowingRemainingTime ) {
|
|
const minuteCounts = Math.floor( ( this.playingSong.duration - this.pos ) / 60 );
|
|
this.durationBeautified = '-' + String( minuteCounts ) + ':';
|
|
if ( ( '' + minuteCounts ).length === 1 ) {
|
|
this.durationBeautified = '-0' + minuteCounts + ':';
|
|
}
|
|
const secondCounts = Math.floor( ( this.playingSong.duration - this.pos ) - minuteCounts * 60 );
|
|
if ( ( '' + secondCounts ).length === 1 ) {
|
|
this.durationBeautified += '0' + secondCounts;
|
|
} else {
|
|
this.durationBeautified += secondCounts;
|
|
}
|
|
}
|
|
}, 200 );
|
|
this.sendUpdate( 'pos' );
|
|
this.sendUpdate( 'isPlaying' );
|
|
} else if ( action === 'pause' ) {
|
|
this.musicKit.pause();
|
|
this.sendUpdate( 'pos' );
|
|
try {
|
|
clearInterval( this.progressTracker );
|
|
clearInterval( this.notifier );
|
|
} catch ( err ) {};
|
|
this.isPlaying = false;
|
|
this.sendUpdate( 'isPlaying' );
|
|
} else if ( action === 'replay10' ) {
|
|
this.musicKit.seekToTime( this.musicKit.currentPlaybackTime > 10 ? musicPlayer.player.currentPlaybackTime - 10 : 0 );
|
|
this.pos = this.musicKit.currentPlaybackTime;
|
|
this.sendUpdate( 'pos' );
|
|
} else if ( action === 'forward10' ) {
|
|
if ( this.musicKit.currentPlaybackTime < ( this.playingSong.duration - 10 ) ) {
|
|
this.musicKit.seekToTime( this.musicKit.currentPlaybackTime + 10 );
|
|
this.pos = this.musicKit.currentPlaybackTime;
|
|
this.sendUpdate( 'pos' );
|
|
// Get currently playing song and get duration from there
|
|
} else {
|
|
if ( this.repeatMode !== 'one' ) {
|
|
this.control( 'next' );
|
|
} else {
|
|
this.musicKit.seekToTime( 0 );
|
|
this.pos = this.musicKit.currentPlaybackTime;
|
|
this.sendUpdate( 'pos' );
|
|
}
|
|
}
|
|
} else if ( action === 'reset' ) {
|
|
clearInterval( this.progressTracker );
|
|
this.pos = 0;
|
|
this.musicKit.seekToTime( 0 );
|
|
this.sendUpdate( 'pos' );
|
|
} else if ( action === 'next' ) {
|
|
this.musicKit.skipToNextItem().then( () => {
|
|
this.sendUpdate( 'queuePos' );
|
|
this.pos = 0;
|
|
this.sendUpdate( 'posReset' );
|
|
} );
|
|
} else if ( action === 'previous' ) {
|
|
if ( this.pos > 3 ) {
|
|
this.pos = 0;
|
|
this.musicKit.seekToTime( 0 ).then( () => {
|
|
this.sendUpdate( 'pos' );
|
|
this.sendUpdate( 'queuePos' );
|
|
this.control( 'play' );
|
|
} );
|
|
} else {
|
|
this.musicKit.skipToPreviousItem().then( () => {
|
|
this.sendUpdate( 'queuePos' );
|
|
this.pos = 0;
|
|
this.sendUpdate( 'posReset' );
|
|
} );
|
|
}
|
|
} else if ( action === 'shuffleOff' ) {
|
|
this.isShuffleEnabled = false;
|
|
this.musicKit.shuffleMode = MusicKit.PlayerShuffleMode.off;
|
|
this.loadPlaylist();
|
|
} else if ( action === 'shuffleOn' ) {
|
|
this.musicKit.shuffleMode = MusicKit.PlayerShuffleMode.songs;
|
|
this.isShuffleEnabled = true;
|
|
this.loadPlaylist();
|
|
} else if ( action === 'repeatOne' ) {
|
|
this.repeatMode = 'one';
|
|
this.musicKit.repeatMode = MusicKit.PlayerRepeatMode.one;
|
|
} else if ( action === 'repeatAll' ) {
|
|
this.musicKit.repeatMode = MusicKit.PlayerRepeatMode.all;
|
|
this.repeatMode = 'all';
|
|
} else if ( action === 'repeatOff' ) {
|
|
this.musicKit.repeatMode = MusicKit.PlayerRepeatMode.none;
|
|
this.repeatMode = 'off';
|
|
}
|
|
},
|
|
play( song, specificID ) {
|
|
let foundSong = specificID ?? 0;
|
|
if ( !specificID ) {
|
|
for ( let s in this.songQueue ) {
|
|
if ( this.songQueue[ s ] === song ) {
|
|
foundSong = s;
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: Update as well
|
|
this.musicKit.changeToMediaItem( this.musicKit.queue.items[ foundSong ] ).then( () => {
|
|
this.sendUpdate( 'queuePos' );
|
|
this.pos = 0;
|
|
this.sendUpdate( 'posReset' );
|
|
} ).catch( ( err ) => {
|
|
console.log( err );
|
|
} );
|
|
},
|
|
toggleShowMode() {
|
|
this.isShowingRemainingTime = !this.isShowingRemainingTime;
|
|
},
|
|
exportCurrentPlaylist() {
|
|
let fetchOptions = {
|
|
method: 'post',
|
|
body: JSON.stringify( this.songQueue ),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'charset': 'utf-8'
|
|
},
|
|
};
|
|
fetch( '/savePlaylist', fetchOptions ).then( res => {
|
|
if ( res.status === 200 ) {
|
|
console.log( 'saved' );
|
|
}
|
|
} );
|
|
},
|
|
selectPlaylistFromDisk() {
|
|
this.isPreparingToPlay = true;
|
|
let playlistSongs = [];
|
|
fetch( '/loadPlaylist' ).then( res => {
|
|
res.json().then( data => {
|
|
this.rawLoadedPlaylistData = data;
|
|
for ( let song in data ) {
|
|
if ( data[ song ].origin === 'apple-music' ) {
|
|
playlistSongs.push( data[ song ].filename );
|
|
}
|
|
}
|
|
this.musicKit.setQueue( { songs: playlistSongs } ).then( () => {
|
|
this.isUsingCustomPlaylist = true;
|
|
try {
|
|
this.loadCustomPlaylist();
|
|
this.hasSelectedPlaylist = true;
|
|
this.isPreparingToPlay = false;
|
|
} catch( err ) {
|
|
this.hasSelectedPlaylist = false;
|
|
console.error( err );
|
|
alert( 'We were unable to play. Please ensure that DRM (yeah sorry it is Apple Music, we cannot do anything about that) is enabled and working' );
|
|
}
|
|
} ).catch( err => {
|
|
console.error( 'ERROR whilst settings Queue', err );
|
|
} );
|
|
} );
|
|
} );
|
|
},
|
|
loadCustomPlaylist() {
|
|
const songQueue = this.musicKit.queue.items;
|
|
let offset = 0;
|
|
( async() => {
|
|
for ( let item in this.rawLoadedPlaylistData ) {
|
|
if ( this.rawLoadedPlaylistData[ item ].origin === 'apple-music' ) {
|
|
this.songQueue[ item ] = {
|
|
'artist': songQueue[ item - offset ].attributes.artistName,
|
|
'title': songQueue[ item - offset ].attributes.name,
|
|
'year': songQueue[ item - offset ].attributes.releaseDate,
|
|
'genre': songQueue[ item - offset ].attributes.genreNames,
|
|
'duration': Math.round( songQueue[ item - offset ].attributes.durationInMillis / 1000 ),
|
|
'filename': songQueue[ item - offset ].id,
|
|
'coverArtOrigin': 'api',
|
|
'hasCoverArt': true,
|
|
'queuePos': item,
|
|
'origin': 'apple-music',
|
|
}
|
|
let url = songQueue[ item - offset ].attributes.artwork.url;
|
|
url = url.replace( '{w}', songQueue[ item - offset ].attributes.artwork.width );
|
|
url = url.replace( '{h}', songQueue[ item - offset ].attributes.artwork.height );
|
|
this.songQueue[ item ][ 'coverArtURL' ] = url;
|
|
} else {
|
|
offset += 1;
|
|
const queryParameters = {
|
|
term: ( this.rawLoadedPlaylistData[ item ].artist ?? '' ) + ' ' + ( this.rawLoadedPlaylistData[ item ].title ?? '' ),
|
|
types: [ 'songs' ],
|
|
};
|
|
// TODO: Make sure that playback duration is correct (get from backend with analysis?)
|
|
// TODO: Make storefront adjustable
|
|
const result = await this.musicKit.api.music( '/v1/catalog/ch/search', queryParameters );
|
|
if ( result.data ) {
|
|
if ( result.data.results.songs ) {
|
|
const dat = result.data.results.songs.data[ 0 ]
|
|
this.songQueue[ item ] = {
|
|
'artist': dat.attributes.artistName,
|
|
'title': dat.attributes.name,
|
|
'year': dat.attributes.releaseDate,
|
|
'genre': dat.attributes.genreNames,
|
|
'duration': Math.round( dat.attributes.durationInMillis / 1000 ),
|
|
'filename': this.rawLoadedPlaylistData[ item ].filename,
|
|
'coverArtOrigin': 'api',
|
|
'hasCoverArt': true,
|
|
'queuePos': item,
|
|
'origin': 'apple-music',
|
|
}
|
|
let url = dat.attributes.artwork.url;
|
|
url = url.replace( '{w}', dat.attributes.artwork.width );
|
|
url = url.replace( '{h}', dat.attributes.artwork.height );
|
|
this.songQueue[ item ][ 'coverArtURL' ] = url;
|
|
}
|
|
}
|
|
}
|
|
this.handleAdditionalData();
|
|
this.sendUpdate( 'songQueue' );
|
|
}
|
|
} )();
|
|
}
|
|
},
|
|
watch: {
|
|
pos() {
|
|
if ( !this.isDragging ) {
|
|
this.sliderProgress = Math.ceil( this.pos / this.playingSong.duration * 1000 + 2 );
|
|
this.originalPos = Math.ceil( this.pos / this.playingSong.duration * ( document.getElementById( 'progress-slider' ).scrollWidth - 5 ) );
|
|
}
|
|
}
|
|
},
|
|
created() {
|
|
document.addEventListener( 'keydown', ( e ) => {
|
|
if ( e.key === ' ' ) {
|
|
e.preventDefault();
|
|
if ( !this.isPlaying ) {
|
|
this.control( 'play' );
|
|
} else {
|
|
this.control( 'pause' );
|
|
}
|
|
} else if ( e.key === 'ArrowRight' ) {
|
|
e.preventDefault();
|
|
this.control( 'next' );
|
|
} else if ( e.key === 'ArrowLeft' ) {
|
|
e.preventDefault();
|
|
this.control( 'previous' );
|
|
}
|
|
} );
|
|
if ( !window.MusicKit ) {
|
|
document.addEventListener( 'musickitloaded', () => {
|
|
self.initMusicKit();
|
|
} );
|
|
} else {
|
|
this.initMusicKit();
|
|
}
|
|
fetch( '/getLocalIP' ).then( res => {
|
|
if ( res.status === 200 ) {
|
|
res.text().then( ip => {
|
|
this.localIP = ip;
|
|
} );
|
|
}
|
|
} );
|
|
},
|
|
} ).mount( '#app' ); |