120 lines
4.4 KiB
JavaScript
120 lines
4.4 KiB
JavaScript
const { RoonExtension } = require('roon-kit');
|
|
const fs = require('fs');
|
|
const { exec } = require('child_process');
|
|
|
|
const lyricsScriptPath = "/home/teraflops/.config/waybar/scripts/get_lyrics.py";
|
|
|
|
function log(msg) {
|
|
const timestamp = new Date().toISOString();
|
|
const fullMsg = `[${timestamp}] ${msg}`;
|
|
console.log(fullMsg);
|
|
fs.appendFileSync('/tmp/roon_debug.log', fullMsg + '\n');
|
|
}
|
|
|
|
const extension = new RoonExtension({
|
|
description: {
|
|
extension_id: 'roon-kit-now-playing',
|
|
display_name: "Roon Kit Now Playing",
|
|
display_version: "0.2.0",
|
|
publisher: 'roon-kit',
|
|
email: 'stevenic@microsoft.com',
|
|
website: 'https://github.com/Stevenic/roon-kit'
|
|
},
|
|
RoonApiBrowse: 'not_required',
|
|
RoonApiImage: 'required',
|
|
RoonApiTransport: 'required',
|
|
subscribe_outputs: false,
|
|
subscribe_zones: true,
|
|
log_level: 'none'
|
|
});
|
|
|
|
function cleanTitle(title) {
|
|
return title.replace(/^[A-Za-z0-9]{1,3}\s+/, '').replace(/[$#@!%^&*(){}\[\]<>?/\\|`~]/g, '').trim();
|
|
}
|
|
|
|
function getLyrics(artist, title, callback) {
|
|
const cmd = `python3 ${lyricsScriptPath} "${artist}" "${title}"`;
|
|
log(`🎤 Ejecutando: ${cmd}`);
|
|
exec(cmd, (error, stdout, stderr) => {
|
|
if (error) {
|
|
log(`❌ Error en getLyrics: ${stderr}`);
|
|
callback("Letras no disponibles.");
|
|
} else {
|
|
const lyrics = stdout.trim();
|
|
log(`✅ Letras obtenidas (${lyrics.length} chars)`);
|
|
callback(lyrics || "Letras no encontradas.");
|
|
}
|
|
});
|
|
}
|
|
|
|
extension.on("subscribe_zones", async (core, response, body) => {
|
|
log("🔄 Evento subscribe_zones recibido");
|
|
log(JSON.stringify(body, null, 2));
|
|
|
|
const changedZones = body.zones_changed ?? [];
|
|
const addedZones = body.zones_added ?? [];
|
|
const removedZones = body.zones_removed ?? [];
|
|
|
|
if (removedZones.length > 0) {
|
|
log("🧹 Zona eliminada, limpiando /tmp/waybar_roon_info.json");
|
|
fs.writeFileSync('/tmp/waybar_roon_info.json', JSON.stringify({ text: '', tooltip: '' }));
|
|
exec("/usr/bin/pkill -RTMIN+3 waybar");
|
|
}
|
|
|
|
for (const zone of [...addedZones, ...changedZones]) {
|
|
log(`🎧 Zona: ${zone.display_name}, estado: ${zone.state}`);
|
|
if (zone.state === 'playing') {
|
|
const track = cleanTitle(zone.now_playing?.one_line?.line1 || '');
|
|
const artist = zone.now_playing?.one_line?.line2 || '';
|
|
const album = zone.now_playing?.three_line?.line3 || '';
|
|
|
|
log(`🎵 Reproduciendo: ${track} - ${artist} (${album})`);
|
|
|
|
getLyrics(artist, track, async (lyrics) => {
|
|
const displayText = `${track} - ${artist}`;
|
|
const tooltip = `🎵 ${track}\n👤 ${artist}\n💿 ${album}\n\n${lyrics}`;
|
|
|
|
const data = {
|
|
text: displayText,
|
|
tooltip: tooltip
|
|
};
|
|
|
|
log(`✍️ Escribiendo JSON para Waybar: ${JSON.stringify(data)}`);
|
|
fs.writeFileSync('/tmp/waybar_roon_info.json', JSON.stringify(data));
|
|
exec("/usr/bin/pkill -RTMIN+3 waybar");
|
|
|
|
const image_key = zone.now_playing?.image_key;
|
|
if (image_key) {
|
|
try {
|
|
const imageData = await core.services.RoonApiImage.get_image(image_key, { width: 300, height: 300 });
|
|
const coverPath = '/tmp/roon_album_cover.jpg';
|
|
fs.writeFileSync(coverPath, imageData.image);
|
|
exec(`notify-send -i ${coverPath} "Now Playing" "${displayText}"`);
|
|
log("✅ Notificación enviada con carátula");
|
|
} catch (error) {
|
|
log(`⚠️ Error obteniendo imagen: ${error}`);
|
|
exec(`notify-send "Now Playing" "${displayText}"`);
|
|
}
|
|
} else {
|
|
exec(`notify-send "Now Playing" "${displayText}"`);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
extension.start_discovery();
|
|
extension.set_status('Esperando conexión al Core de Roon...');
|
|
log("🔍 Buscando Core...");
|
|
|
|
(async () => {
|
|
const core = await extension.get_core();
|
|
if (core) {
|
|
log("✅ Core emparejado correctamente");
|
|
extension.set_status('Emparejado con el Core de Roon');
|
|
} else {
|
|
log("❌ No se emparejó con ningún Core");
|
|
}
|
|
})();
|
|
|