68 lines
1.8 KiB
JavaScript
68 lines
1.8 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", () => {
|
||
|
ws = undefined;
|
||
|
setTimeout(wsConnect, 10000); // Retry after 10 seconds
|
||
|
});
|
||
|
ws.on("error", () => {
|
||
|
ws = undefined;
|
||
|
setTimeout(wsConnect, 10000); // Retry after 10 seconds
|
||
|
});
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
ws.on("message", (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));
|
||
|
});
|