sorry for doing this.
This commit is contained in:
parent
5fc82a8bc7
commit
b3db294485
106 changed files with 86 additions and 259 deletions
|
@ -1,619 +0,0 @@
|
|||
var socket;
|
||||
|
||||
Vue.component('footer-player', {
|
||||
template: '#footer-player'
|
||||
});
|
||||
|
||||
// vue instance
|
||||
var app = new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
screen: "player",
|
||||
player: {
|
||||
currentMediaItem: {},
|
||||
songActions: false,
|
||||
lyrics: {},
|
||||
lyricsMediaItem: {},
|
||||
lyricsDebug: {
|
||||
current: 0,
|
||||
start: 0,
|
||||
end: 0
|
||||
},
|
||||
queue: {},
|
||||
lowerPanelState: "controls",
|
||||
userInteraction: false
|
||||
},
|
||||
queue: {
|
||||
temp: []
|
||||
},
|
||||
artistPage: {
|
||||
data: {},
|
||||
editorsNotes: false
|
||||
},
|
||||
albumPage: {
|
||||
data: {},
|
||||
editorsNotes: false
|
||||
},
|
||||
search: {
|
||||
query: "",
|
||||
results: [],
|
||||
state: 0,
|
||||
tab: "all",
|
||||
searchType: "applemusic",
|
||||
trackSelect: false,
|
||||
selected: {},
|
||||
queue: {},
|
||||
lastPage: "search",
|
||||
lastY: 0
|
||||
},
|
||||
lastPage: "player",
|
||||
connectedState: 0,
|
||||
url: window.location.hostname,
|
||||
mode: "default",
|
||||
// url: "localhost",
|
||||
},
|
||||
methods: {
|
||||
searchScroll(e) {
|
||||
this.search.lastY = e.target.scrollTop;
|
||||
},
|
||||
musicKitAPI(method, id, params) {
|
||||
socket.send(
|
||||
JSON.stringify({
|
||||
action: "musickit-api",
|
||||
method: method,
|
||||
id: id,
|
||||
params: params
|
||||
})
|
||||
)
|
||||
},
|
||||
resetPlayerUI() {
|
||||
this.player.lowerPanelState = "controls";
|
||||
},
|
||||
musicAppVariant() {
|
||||
if (navigator.userAgent.match(/Android/i)) {
|
||||
return "Apple Music";
|
||||
} else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
|
||||
return "Music";
|
||||
} else {
|
||||
if (navigator.userAgent.indexOf('Mac') > 0) {
|
||||
return 'Music';
|
||||
} else if (navigator.userAgent.indexOf('Win') > 0) {
|
||||
return 'Apple Music Electron';
|
||||
} else {
|
||||
return 'Apple Music Electron';
|
||||
}
|
||||
}
|
||||
},
|
||||
checkOrientation() {
|
||||
// check orientation of device
|
||||
if (window.innerHeight > window.innerWidth) {
|
||||
return 'portrait'
|
||||
} else {
|
||||
return 'landscape';
|
||||
}
|
||||
},
|
||||
checkPlatformMD() {
|
||||
// check if platfom is desktop or mobile
|
||||
if (navigator.userAgent.match(/Android/i)) {
|
||||
return "mobile";
|
||||
} else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
|
||||
return "mobile";
|
||||
} else {
|
||||
if (navigator.userAgent.indexOf('Mac') > 0) {
|
||||
return 'desktop';
|
||||
} else if (navigator.userAgent.indexOf('Win') > 0) {
|
||||
return 'desktop';
|
||||
} else {
|
||||
return 'desktop';
|
||||
}
|
||||
}
|
||||
},
|
||||
checkPlatform() {
|
||||
if (navigator.userAgent.match(/Android/i)) {
|
||||
return "android";
|
||||
} else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
|
||||
return "ios";
|
||||
} else {
|
||||
if (navigator.userAgent.indexOf('Mac') > 0) {
|
||||
return 'mac';
|
||||
} else if (navigator.userAgent.indexOf('Win') > 0) {
|
||||
return 'win';
|
||||
} else {
|
||||
return 'linux';
|
||||
}
|
||||
}
|
||||
},
|
||||
artworkPlaying() {
|
||||
if (this.player.currentMediaItem.status) {
|
||||
return
|
||||
} else {
|
||||
return ["paused"]
|
||||
}
|
||||
},
|
||||
setAutoplay(value) {
|
||||
socket.send(JSON.stringify({
|
||||
"action": "set-autoplay",
|
||||
"autoplay": value
|
||||
}));
|
||||
this.getCurrentMediaItem()
|
||||
if (value) {
|
||||
setTimeout(() => {
|
||||
this.getQueue()
|
||||
}, 1000)
|
||||
} else {
|
||||
this.getQueue()
|
||||
}
|
||||
},
|
||||
seekTo(time, adjust = true) {
|
||||
if (adjust) {
|
||||
time = parseInt(time / 1000)
|
||||
}
|
||||
socket.send(JSON.stringify({
|
||||
action: "seek",
|
||||
time: time
|
||||
}));
|
||||
},
|
||||
setVolume(volume) {
|
||||
socket.send(JSON.stringify({
|
||||
action: "volume",
|
||||
volume: volume
|
||||
}));
|
||||
},
|
||||
getQueue() {
|
||||
socket.send(JSON.stringify({
|
||||
action: "get-queue"
|
||||
}))
|
||||
},
|
||||
play() {
|
||||
socket.send(JSON.stringify({
|
||||
action: "play"
|
||||
}))
|
||||
},
|
||||
pause() {
|
||||
socket.send(JSON.stringify({
|
||||
action: "pause"
|
||||
}))
|
||||
},
|
||||
next() {
|
||||
socket.send(JSON.stringify({
|
||||
action: "next"
|
||||
}))
|
||||
},
|
||||
previous() {
|
||||
socket.send(JSON.stringify({
|
||||
action: "previous"
|
||||
}))
|
||||
},
|
||||
searchArtist() {
|
||||
this.search.query = this.player.currentMediaItem.artistName;
|
||||
this.screen = "search";
|
||||
this.searchQuery();
|
||||
},
|
||||
trackSelect(song) {
|
||||
this.search.selected = song;
|
||||
this.search.trackSelect = true
|
||||
},
|
||||
clearSelectedTrack() {
|
||||
this.search.selected = {}
|
||||
this.search.trackSelect = false
|
||||
},
|
||||
getArtworkColor(hex) {
|
||||
return `#${hex}`
|
||||
},
|
||||
playMediaItemById(id, kind = "song") {
|
||||
socket.send(JSON.stringify({
|
||||
action: "play-mediaitem",
|
||||
id: id,
|
||||
kind: kind
|
||||
}))
|
||||
this.screen = "player";
|
||||
},
|
||||
playNext(type, id) {
|
||||
socket.send(JSON.stringify({
|
||||
action: "play-next",
|
||||
type: type,
|
||||
id: id
|
||||
}))
|
||||
},
|
||||
playLater(type, id) {
|
||||
socket.send(JSON.stringify({
|
||||
action: "play-later",
|
||||
type: type,
|
||||
id: id
|
||||
}))
|
||||
},
|
||||
searchQuery() {
|
||||
if (this.search.query.length == 0) {
|
||||
this.search.state = 0;
|
||||
return;
|
||||
}
|
||||
this.search.state = 1;
|
||||
var actionType = "search"
|
||||
if (this.search.searchType == "library") {
|
||||
actionType = "library-search"
|
||||
}
|
||||
socket.send(JSON.stringify({
|
||||
"action": actionType,
|
||||
"term": this.search.query,
|
||||
"limit": 20
|
||||
}))
|
||||
},
|
||||
quickSearch() {
|
||||
var search = prompt("Search for a song", "")
|
||||
if (search == null || search == "") {
|
||||
return
|
||||
}
|
||||
|
||||
socket.send(JSON.stringify({
|
||||
action: "quick-play",
|
||||
term: search
|
||||
}))
|
||||
},
|
||||
parseTime(value) {
|
||||
var minutes = Math.floor(value / 60000);
|
||||
var seconds = ((value % 60000) / 1000).toFixed(0);
|
||||
return minutes + ":" + (seconds < 10 ? '0' : '') + seconds;
|
||||
},
|
||||
parseTimeDecimal(value) {
|
||||
var minutes = Math.floor(value / 60000);
|
||||
var seconds = ((value % 60000) / 1000).toFixed(0);
|
||||
return minutes + "." + (seconds < 10 ? '0' : '') + seconds;
|
||||
},
|
||||
hmsToSecondsOnly(str) {
|
||||
var p = str.split(':'),
|
||||
s = 0,
|
||||
m = 1;
|
||||
|
||||
while (p.length > 0) {
|
||||
s += m * parseInt(p.pop(), 10);
|
||||
m *= 60;
|
||||
}
|
||||
|
||||
return s;
|
||||
},
|
||||
getCurrentTime() {
|
||||
return parseFloat(this.hmsToSecondsOnly(this.parseTime(this.player.currentMediaItem.durationInMillis - this.player.currentMediaItem.remainingTime)));
|
||||
},
|
||||
percentage(partial, full) {
|
||||
return (100 * partial) / full
|
||||
},
|
||||
getLyricBGStyle(start, end) {
|
||||
var currentTime = this.getCurrentTime();
|
||||
var duration = this.player.currentMediaItem.durationInMillis
|
||||
var start2 = this.hmsToSecondsOnly(start)
|
||||
var end2 = this.hmsToSecondsOnly(end)
|
||||
var currentProgress = ((100 * (currentTime)) / (end2))
|
||||
// check if currenttime is between start and end
|
||||
this.player.lyricsDebug.start = start2
|
||||
this.player.lyricsDebug.end = end2
|
||||
this.player.lyricsDebug.current = currentTime
|
||||
if (currentTime >= start2 && currentTime <= end2) {
|
||||
return {
|
||||
"--bgSpeed": `${(end2 - start2)}s`
|
||||
}
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
getLyricClass(start, end) {
|
||||
var currentTime = this.getCurrentTime();
|
||||
// check if currenttime is between start and end
|
||||
if (currentTime >= start && currentTime <= end) {
|
||||
setTimeout(() => {
|
||||
if (document.querySelector(".lyric-line.active")) {
|
||||
document.querySelector(".lyric-line.active").scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "center"
|
||||
})
|
||||
}
|
||||
}, 200)
|
||||
return "active"
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
},
|
||||
getAlbumArtUrl(size = 600) {
|
||||
if (this.player.currentMediaItem.artwork) {
|
||||
return `url("${this.player.currentMediaItem.artwork.url.replace('{w}', size).replace('{h}', size)}")`;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
getAlbumArtUrlList(url, size = 64) {
|
||||
return `url("${url.replace('{w}', size).replace('{h}', size)}")`;
|
||||
},
|
||||
searchTabClass(tab) {
|
||||
if (tab == this.search.tab) {
|
||||
return "active";
|
||||
}
|
||||
},
|
||||
searchTypeClass(type) {
|
||||
if (type == this.search.searchType) {
|
||||
return "active";
|
||||
}
|
||||
},
|
||||
getQueuePositionClass(position) {
|
||||
if (this.player.queue["_position"] == position) {
|
||||
return ["playing", "passed"]
|
||||
} else if (this.player.queue["_position"] > position) {
|
||||
return ["passed"]
|
||||
}
|
||||
},
|
||||
showSearch(reset = false) {
|
||||
if(reset) {
|
||||
this.search.lastPage = "search"
|
||||
}
|
||||
switch(this.search.lastPage) {
|
||||
case "search":
|
||||
this.screen = "search"
|
||||
break;
|
||||
case "album":
|
||||
this.screen = "album-page"
|
||||
break;
|
||||
case "artist":
|
||||
this.screen = "artist-page"
|
||||
break;
|
||||
case "playlist":
|
||||
this.screen = "playlist-page"
|
||||
break;
|
||||
}
|
||||
},
|
||||
showArtistByName(name) {
|
||||
this.musicKitAPI("search", name, {types: "artists"})
|
||||
},
|
||||
showAlbum(id) {
|
||||
this.search.lastPage = "album"
|
||||
this.screen = "album-page"
|
||||
this.musicKitAPI("album", id, {})
|
||||
},
|
||||
showArtist(id) {
|
||||
this.search.lastPage = "artist"
|
||||
this.screen = "artist-page"
|
||||
this.musicKitAPI("artist", id, {include: "songs,playlists,albums"})
|
||||
},
|
||||
showQueue() {
|
||||
this.queue.temp = this.player["queue"]["_queueItems"]
|
||||
this.screen = "queue"
|
||||
this.getQueue()
|
||||
},
|
||||
queueMove(evt) {
|
||||
console.log(evt)
|
||||
console.log(`new: ${evt.moved.newIndex} old: ${evt.moved.oldIndex}`)
|
||||
this.queue.temp.splice(evt.moved.newIndex, 0, this.queue.temp.splice(evt.moved.oldIndex, 1)[0])
|
||||
socket.send(JSON.stringify({
|
||||
action: "queue-move",
|
||||
from: evt.moved.oldIndex,
|
||||
to: evt.moved.newIndex
|
||||
}))
|
||||
this.getQueue()
|
||||
return true
|
||||
},
|
||||
repeat() {
|
||||
socket.send(JSON.stringify({
|
||||
action: "repeat"
|
||||
}))
|
||||
this.getCurrentMediaItem()
|
||||
},
|
||||
shuffle() {
|
||||
socket.send(JSON.stringify({
|
||||
action: "shuffle"
|
||||
}))
|
||||
this.getCurrentMediaItem()
|
||||
},
|
||||
setShuffle(val) {
|
||||
socket.send(JSON.stringify({
|
||||
action: "set-shuffle",
|
||||
shuffle: val
|
||||
}))
|
||||
this.getCurrentMediaItem()
|
||||
},
|
||||
getMediaPalette(data) {
|
||||
var palette = {
|
||||
'--bgColor': `#${data['artwork']['bgColor']}`,
|
||||
'--textColor1': `#${data['artwork']['textColor1']}`,
|
||||
'--textColor2': `#${data['artwork']['textColor2']}`,
|
||||
'--textColor3': `#${data['artwork']['textColor3']}`,
|
||||
'--textColor4': `#${data['artwork']['textColor4']}`
|
||||
}
|
||||
return palette
|
||||
},
|
||||
playAlbum(id, shuffle = false) {
|
||||
if(shuffle) {
|
||||
this.setShuffle(true)
|
||||
}else{
|
||||
this.setShuffle(false)
|
||||
}
|
||||
this.playMediaItemById(id, 'album');
|
||||
},
|
||||
getLyrics() {
|
||||
socket.send(JSON.stringify({
|
||||
action: "get-lyrics",
|
||||
}))
|
||||
},
|
||||
showLyrics() {
|
||||
this.getLyrics()
|
||||
this.screen = "lyrics"
|
||||
},
|
||||
showLyricsInline() {
|
||||
this.getLyrics()
|
||||
this.player.lowerPanelState = "lyrics"
|
||||
},
|
||||
parseLyrics() {
|
||||
var xml = this.stringToXml(this.player.lyricsMediaItem.ttml)
|
||||
var json = xmlToJson(xml);
|
||||
this.player.lyrics = json
|
||||
},
|
||||
stringToXml(st) {
|
||||
// string to xml
|
||||
var xml = (new DOMParser()).parseFromString(st, "text/xml");
|
||||
return xml;
|
||||
},
|
||||
canShowSearchTab(tab) {
|
||||
if (tab == this.search.tab || this.search.tab == "all") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
getCurrentMediaItem() {
|
||||
socket.send(JSON.stringify({
|
||||
action: "get-currentmediaitem"
|
||||
}))
|
||||
},
|
||||
setStreamerOverlay() {
|
||||
document.body.classList.add("streamer-overlay")
|
||||
},
|
||||
setMode(mode) {
|
||||
switch(mode) {
|
||||
default:
|
||||
this.screen = "player"
|
||||
break;
|
||||
case "miniplayer":
|
||||
this.screen = "miniplayer"
|
||||
break;
|
||||
}
|
||||
},
|
||||
connect() {
|
||||
let self = this;
|
||||
this.connectedState = 0;
|
||||
if (this.url === "") {
|
||||
this.url = prompt("Host IP", "localhost")
|
||||
}
|
||||
socket = new WebSocket(`ws://${this.url}:26369`);
|
||||
socket.onopen = (e) => {
|
||||
console.log(e);
|
||||
console.log('connected');
|
||||
app.connectedState = 1;
|
||||
if(getParameterByName("mode")) {
|
||||
self.setMode(getParameterByName("mode"))
|
||||
}else{
|
||||
self.setMode("default")
|
||||
}
|
||||
self.clearSelectedTrack()
|
||||
}
|
||||
|
||||
socket.onclose = (e) => {
|
||||
console.log(e);
|
||||
console.log('disconnected');
|
||||
app.connectedState = 2;
|
||||
}
|
||||
|
||||
socket.onerror = (e) => {
|
||||
console.log(e);
|
||||
console.log('error');
|
||||
app.connectedState = 2;
|
||||
}
|
||||
|
||||
socket.onmessage = (e) => {
|
||||
const response = JSON.parse(e.data);
|
||||
switch (response.type) {
|
||||
default:
|
||||
console.log(response);
|
||||
break;
|
||||
case "musickitapi.search":
|
||||
self.showArtist(response.data["artists"][0]["id"]);
|
||||
break;
|
||||
case "musickitapi.album":
|
||||
if(self.screen == "album-page") {
|
||||
self.albumPage.data = response.data
|
||||
}
|
||||
break;
|
||||
case "musickitapi.artist":
|
||||
if(self.screen == "artist-page") {
|
||||
self.artistPage.data = response.data
|
||||
}
|
||||
break;
|
||||
case "queue":
|
||||
self.player.queue = response.data;
|
||||
self.queue.temp = response.data["_queueItems"];
|
||||
self.$forceUpdate()
|
||||
break;
|
||||
case "lyrics":
|
||||
self.player.lyrics = response.data;
|
||||
self.$forceUpdate()
|
||||
break;
|
||||
case "searchResultsLibrary":
|
||||
self.search.results = response.data;
|
||||
self.search.state = 2;
|
||||
break;
|
||||
case "searchResults":
|
||||
self.search.results = response.data;
|
||||
self.search.state = 2;
|
||||
break;
|
||||
case "playbackStateUpdate":
|
||||
if (!self.player.userInteraction) {
|
||||
self.updatePlaybackState(response.data)
|
||||
}
|
||||
break;
|
||||
}
|
||||
// console.log(e.data);
|
||||
}
|
||||
},
|
||||
updatePlaybackState(mediaitem) {
|
||||
var lyricsDisplayed = this.screen == "lyrics" || this.player.lowerPanelState == "lyrics"
|
||||
if (this.player.currentMediaItem["isrc"] != mediaitem["isrc"]) {
|
||||
if (lyricsDisplayed) {
|
||||
this.getLyrics()
|
||||
}
|
||||
if (this.screen == "queue") {
|
||||
this.getQueue()
|
||||
}
|
||||
}
|
||||
this.player.currentMediaItem = mediaitem
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
function getParameterByName(name, url) {
|
||||
if (!url) url = window.location.href;
|
||||
name = name.replace(/[\[\]]/g, '\\$&');
|
||||
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
|
||||
results = regex.exec(url);
|
||||
if (!results) return null;
|
||||
if (!results[2]) return '';
|
||||
return decodeURIComponent(results[2].replace(/\+/g, ' '));
|
||||
}
|
||||
|
||||
function xmlToJson(xml) {
|
||||
|
||||
// Create the return object
|
||||
var obj = {};
|
||||
|
||||
if (xml.nodeType == 1) { // element
|
||||
// do attributes
|
||||
if (xml.attributes.length > 0) {
|
||||
obj["@attributes"] = {};
|
||||
for (var j = 0; j < xml.attributes.length; j++) {
|
||||
var attribute = xml.attributes.item(j);
|
||||
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
|
||||
}
|
||||
}
|
||||
} else if (xml.nodeType == 3) { // text
|
||||
obj = xml.nodeValue;
|
||||
}
|
||||
|
||||
// do children
|
||||
if (xml.hasChildNodes()) {
|
||||
for (var i = 0; i < xml.childNodes.length; i++) {
|
||||
var item = xml.childNodes.item(i);
|
||||
var nodeName = item.nodeName;
|
||||
if (typeof (obj[nodeName]) == "undefined") {
|
||||
obj[nodeName] = xmlToJson(item);
|
||||
} else {
|
||||
if (typeof (obj[nodeName].push) == "undefined") {
|
||||
var old = obj[nodeName];
|
||||
obj[nodeName] = [];
|
||||
obj[nodeName].push(old);
|
||||
}
|
||||
obj[nodeName].push(xmlToJson(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
window.onresize = function () {
|
||||
app.resetPlayerUI()
|
||||
}
|
||||
|
||||
app.connect()
|
Loading…
Add table
Add a link
Reference in a new issue