diff --git a/package.json b/package.json index 1bd7dd1..65f35ce 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,11 @@ "register-scheme": "^0.0.2", "vlc.js": "^3.2.7" }, + "overrides": { + "node-fetch@2.x": { + "whatwg-url": "14.x" + } + }, "devDependencies": { "@types/node": "^22.12.0" }, diff --git a/src/rpc/format.js b/src/rpc/format.js index fa30f68..2439e53 100755 --- a/src/rpc/format.js +++ b/src/rpc/format.js @@ -2,11 +2,9 @@ * Description: Decides what information to display based on the nature of the media (video, music, etc) */ -const fs = require("fs"); const log = require("../helpers/lager.js"); const cl = require("../helpers/configLoader.js"); const config = cl.getOrInit("config.js"); -const axios = require("axios"); const { debug } = require("console"); let staticOverridesFetcher = new (require("./staticOverridesFetcher.js"))( @@ -17,6 +15,7 @@ let bandcampFetcher = new (require("./bandcampFetcher.js"))(); let coverartarchiveFetcher = new (require("./coverartarchiveFetcher.js"))(); let songTitle = null; let selectedStream = null; +let bitsPerSample = null; // These functions, 'fetchers', provide uniform inteface for simple access to the APIs // They take VLC metadata as the argument and on success return object containing @@ -136,14 +135,42 @@ module.exports = async (status) => { const { meta } = status.information.category; + let season = meta.seasonNumber; + let episode = meta.episodeNumber; + let showname = meta.showName || ""; // fallback to VLC title if available + + if (season === undefined && episode === undefined) { + const filename = meta.filename || ""; + // Try matching SxxEyy or Exx + const match = + filename.match(/S(\d{1,2})E(\d{1,2})/i) || filename.match(/E(\d{1,2})/i); + + if (match) { + if (match.length === 3) { + season = parseInt(match[1], 10); + episode = parseInt(match[2], 10); + } else if (match.length === 2) { + episode = parseInt(match[1], 10); + } + + // Extract showname as everything before the match + showname = filename + .slice(0, match.index) + .replace(/[\._-]+$/, "") // remove trailing dots, underscores, or dashes + .replace(/[\._]/g, " ") // replace remaining dots/underscores with space + .trim(); + } + } + // Select VLC stream to fetch track information (wip for attatched mode) if (config.rpc.detached) { - selectedStream = - status.information.category["Stream 'audio/0'"] ?? - status.information.category["Stream 'video/1'"] ?? - (status.information.category["Stream 0"]?.Frame_rate - ? status.information.category["Stream 1"] - : status.information.category["Stream 0"]) ?? + const streams = Object.values(status.information.category); + + // Find the first audio stream + selectedStream = streams.find((stream) => stream.Type === "Audio") ?? null; + bitsPerSample = + selectedStream?.Bits_per_sample ?? + selectedStream?.Decoded_bits_per_sample ?? null; } @@ -207,13 +234,12 @@ module.exports = async (status) => { } } ); - // Format songTitle for Bit rate and Sample Rate if (config.rpc.enableSampleRate && selectedStream) { - songTitle = `${meta.title || meta.filename || "Playing something.."} [${ - selectedStream["Bits_per_sample"] - } Bits, ${selectedStream["Sample_rate"].slice(0, 2)}kHz]`; + songTitle = `${ + meta.title || meta.filename || "Playing something.." + } [${bitsPerSample} Bits, ${selectedStream["Sample_rate"].slice(0, 2)}kHz]`; } else { songTitle = meta.title || meta.filename || "Playing something.."; } @@ -249,14 +275,14 @@ module.exports = async (status) => { output.largeImageKey = "youtube"; output.largeImageText = meta.url; } - if (meta.showName) { + if (showname) { // if a tv show - output.details = meta.showName; + output.details = showname; } - if (meta.episodeNumber) { - output.state = `Episode ${meta.episodeNumber}`; - if (meta.seasonNumber) { - output.state += ` - Season ${meta.seasonNumber}`; + if (episode) { + output.state = `Episode ${episode}`; + if (season && season !== 1) { + output.state += ` - Season ${season}`; } } else if (display_artist) { output.state = display_artist;