feat: 쿠키 파일 기반 설정(YOUTUBE_COOKIE_PATH)+리졸버 URL 설정화, 다음곡 프리페치로 재생지연 단축, ytresolver 리포 포함, 쿠키 재발급 스크립트, README 상세화

This commit is contained in:
tkrmagid
2026-09-11 02:34:55 +09:00
parent e198c5244a
commit 56bea22e4a
7 changed files with 472 additions and 21 deletions

View File

@@ -1,6 +1,22 @@
import "dotenv/config";
import { ColorResolvable, Colors } from "discord.js";
import { join } from "node:path";
import { existsSync, readFileSync } from "node:fs";
/**
* Netscape 형식 쿠키 파일(cookies.txt)을 "name=value; name=value" 헤더 문자열로 변환한다.
* youtubei.js/YoutubeMusic 검색은 쿠키 헤더 문자열을 쓰고, yt-dlp 리졸버는 Netscape 파일을 그대로 쓴다.
*/
function cookieFileToHeader(path: string): string {
const lines = readFileSync(path, "utf8").split(/\r?\n/);
const pairs: string[] = [];
for (const line of lines) {
if (!line || line.startsWith("#")) continue;
const p = line.split("\t");
if (p.length >= 7 && p[5]) pairs.push(`${p[5]}=${p[6] ?? ""}`);
}
return pairs.join("; ");
}
export const Config = {
debug: process.env.DEBUG?.trim()?.toLocaleLowerCase() === "true",
@@ -62,13 +78,34 @@ export const Config = {
}
},
// Netscape 쿠키 파일 경로. 리졸버(yt-dlp)와 봇(YoutubeMusic 검색)이 공유하는 단일 쿠키 소스.
// 기본값은 컨테이너 내 /db/ytcookie.txt (= 호스트 /root/bot/db/ytcookie.txt, db 볼륨 마운트).
youtubeCookiePath: process.env.YOUTUBE_COOKIE_PATH?.trim() || "/db/ytcookie.txt",
_youtube_cookie: process.env.YOUTUBE_COOKIE?.trim(),
_youtube_cookie_cache: undefined as string | undefined,
/**
* 쿠키 헤더 문자열. 우선순위:
* 1) YOUTUBE_COOKIE (인라인 문자열, 하위호환)
* 2) YOUTUBE_COOKIE_PATH 의 Netscape 파일을 헤더 문자열로 변환
* 둘 다 없으면 예외.
*/
get youtube_cookie() {
if (!this._youtube_cookie) throw new ReferenceError("YOUTUBE_COOKIE is missing");
if (this._youtube_cookie.startsWith('"')) this._youtube_cookie = this._youtube_cookie.slice(1,-1);
return this._youtube_cookie;
if (this._youtube_cookie) {
if (this._youtube_cookie.startsWith('"')) this._youtube_cookie = this._youtube_cookie.slice(1,-1);
return this._youtube_cookie;
}
// 파일에서 매번 새로 읽되(쿠키 갱신 반영), 파싱 결과는 캐시
if (existsSync(this.youtubeCookiePath)) {
this._youtube_cookie_cache = cookieFileToHeader(this.youtubeCookiePath);
return this._youtube_cookie_cache;
}
throw new ReferenceError("YOUTUBE_COOKIE / YOUTUBE_COOKIE_PATH 둘 다 없습니다");
},
// yt-dlp 오디오 리졸버(ytresolver) 주소. 리졸버는 봇/쿠키와 같은 .5 호스트에 co-located.
ytresolverUrl: (process.env.YTRESOLVER_URL?.trim() || "http://192.168.10.5:8779").replace(/\/+$/, ""),
proxyUrl: process.env.PROXY_URL?.trim() || "",
_redis: {