import path from "node:path"; import commandExists from "command-exists"; import type { Metadata } from "music-server-shared/types"; export const coverRegex = process.env.COVER_REGEX === undefined ? /(cover)|(folder).(png|jpg)$/i : ""; export const musicRoot = process.env.MUSIC_ROOT || ""; export const mediaInfoDisabled = !!process.env.DISABLE_MEDIAINFO || false; if (musicRoot === "") { console.error("Please define the environment variable MUSIC_ROOT"); process.exit(1); } export const [username, password] = process.env.AUTH ? Buffer.from(process.env.AUTH, "base64").toString().split(":", 2) : [undefined, undefined]; export const authTokens = new Map(); //clear outdated tokens once a day setInterval( () => { for (const [token, endDate] of authTokens.entries()) { if (endDate.getTime() < Date.now()) authTokens.delete(token); } }, 1000 * 60 * 60 * 24, ); if (!path.isAbsolute(musicRoot)) { console.error(`Music root ${musicRoot} is not absolute`); process.exit(1); } export const excludeExtension = process.env.EXCLUDE_EXTENSION === undefined ? ["txt", "log", "nfo", "m3u", "htm", "html"] : process.env.EXCLUDE_EXTENSION.split(","); if (!commandExists.sync("ffmpeg")) { console.error("Required command ffmpeg not found in PATH"); process.exit(1); } if (!commandExists.sync("tar")) { console.error("Required command tar not found in PATH"); process.exit(1); } if (!commandExists.sync("avifenc")) { console.error("Required command avifenc not found in PATH"); process.exit(1); } export const mediaTypes = ["audio", "video"]; export const allowedTypes = [...mediaTypes, "image"]; export const fileTypeCache = new Map(); export const probeCache = new Map(); export const generatedPlaylistIds = new Map(); export class PathInfo { constructor(public mimeType: string) {} } export class ServerError { constructor( public status: number, public error: string, ) {} }