shared.ts
⎇
Raw
1import path from "node:path";
2import commandExists from "command-exists";
3import type { Metadata } from "music-server-shared/types";
4import { parseArgs } from "node:util";
5
6export const coverRegex = process.env.COVER_REGEX === undefined ? /(cover)|(folder).(png|jpg)$/i : "";
7export const musicRoot = process.env.MUSIC_ROOT || "";
8export const mediaInfoDisabled = !!process.env.DISABLE_MEDIAINFO || false;
9if (musicRoot === "") {
10 console.error("Please define the environment variable MUSIC_ROOT");
11 process.exit(1);
12}
13
14export const [username, password] = process.env.AUTH
15 ? Buffer.from(process.env.AUTH, "base64").toString().split(":", 2)
16 : [undefined, undefined];
17
18export const authTokens = new Map<string, Date>();
19
20//clear outdated tokens once a day
21setInterval(
22 () => {
23 for (const [token, endDate] of authTokens.entries()) {
24 if (endDate.getTime() < Date.now()) authTokens.delete(token);
25 }
26 },
27 1000 * 60 * 60 * 24,
28);
29
30if (!path.isAbsolute(musicRoot)) {
31 console.error(`Music root ${musicRoot} is not absolute`);
32 process.exit(1);
33}
34
35export const excludeExtension =
36 process.env.EXCLUDE_EXTENSION === undefined
37 ? ["txt", "log", "nfo", "m3u", "htm", "html"]
38 : process.env.EXCLUDE_EXTENSION.split(",");
39
40if (!commandExists.sync("ffmpeg")) {
41 console.error("Required command ffmpeg not found in PATH");
42 process.exit(1);
43}
44if (!commandExists.sync("tar")) {
45 console.error("Required command tar not found in PATH");
46 process.exit(1);
47}
48if (!commandExists.sync("avifenc")) {
49 console.error("Required command avifenc not found in PATH");
50 process.exit(1);
51}
52
53export const { values: args } = parseArgs({
54 args: Bun.argv,
55 options: {
56 serve: {
57 type: "string",
58 },
59 },
60 strict: true,
61 allowPositionals: true,
62});
63
64if (!args.serve) {
65 console.error("Missing --serve, set it to the directory containing the frontend code");
66 process.exit(1);
67}
68
69export const mediaTypes = ["audio", "video"];
70export const allowedTypes = [...mediaTypes, "image"];
71
72export const fileTypeCache = new Map<string, string>();
73export const probeCache = new Map<string, Metadata>();
74export const generatedPlaylistIds = new Map<string, string[]>();
75
76export class PathInfo {
77 constructor(public mimeType: string) {}
78}
79
80export class ServerError {
81 constructor(
82 public status: number,
83 public error: string,
84 ) {}
85}
86