71 lines
2.0 KiB
JavaScript
71 lines
2.0 KiB
JavaScript
import WebSocket from "ws";
|
|
import { connect } from "mqtt";
|
|
import secrets from "./secrets.mjs";
|
|
|
|
let ws;
|
|
const wsConnect = () => {
|
|
ws = new WebSocket(secrets.wsUrl);
|
|
ws.on("close", () => {
|
|
console.log(`${new Date().toString()}: Websocket closed unexpectedly`);
|
|
ws = undefined;
|
|
setTimeout(wsConnect, 10000); // Retry after 10 seconds
|
|
});
|
|
ws.on("error", () => {
|
|
console.log(`${new Date().toString()}: Error on websocket`);
|
|
ws = undefined;
|
|
setTimeout(wsConnect, 10000); // Retry after 10 seconds
|
|
});
|
|
ws.on("message", wsOnMsg);
|
|
}
|
|
do {
|
|
wsConnect();
|
|
} while(!ws);
|
|
|
|
const client = connect(secrets.mqttUrl, {
|
|
username: secrets.mqttUser,
|
|
password: secrets.mqttPass,
|
|
protocol: "ws",
|
|
reconnectPeriod: 10000, // Retry after 10 seconds
|
|
});
|
|
|
|
function metaFromMetadata(metadata) {
|
|
const meta = {
|
|
title: metadata.name,
|
|
album: metadata.album.name,
|
|
artist: metadata.artist.map(artist => artist.name)
|
|
};
|
|
const cover = metadata.album.coverGroup.image.find(image => image.size.toLowerCase() === "default");
|
|
if (cover) {
|
|
meta.cover = `https://i.scdn.co/image/${cover.fileId.toLowerCase()}`;
|
|
}
|
|
|
|
return meta;
|
|
}
|
|
|
|
function wsOnMsg(data) {
|
|
if (!client.connected) return;
|
|
|
|
const parsed = JSON.parse(data);
|
|
let message = {};
|
|
|
|
switch (parsed.event) {
|
|
case "trackChanged":
|
|
case "playbackResumed":
|
|
message.playbackState = "PLAYING";
|
|
case "metadataAvailable":
|
|
if (parsed.track) message = {...message, ...metaFromMetadata(parsed.track)};
|
|
break;
|
|
case "playbackPaused":
|
|
message.playbackState = "PAUSED";
|
|
break;
|
|
case "sessionCleared":
|
|
case "playbackEnded":
|
|
case "inactiveSession":
|
|
case "connectionDropped":
|
|
default:
|
|
message.playbackState = "STOPPED";
|
|
break;
|
|
}
|
|
|
|
client.publish(secrets.mqttTopic, JSON.stringify(message));
|
|
}; |