Enhance Dockerfile and API for yt-dlp integration

- Install Deno as a JavaScript runtime for yt-dlp in the Dockerfile.
- Add configuration for yt-dlp to support cookies and JavaScript runtime selection.
- Update API to handle cookies for YouTube bot detection and allow specifying the JavaScript runtime.
- Introduce new environment variables for cookie management and JavaScript runtime configuration in README.
This commit is contained in:
Peter Meier
2025-12-22 12:58:09 +01:00
parent eb32dd1064
commit a8f822807d
3 changed files with 69 additions and 8 deletions

View File

@@ -56,8 +56,23 @@ export const POST: APIRoute = async ({ request }) => {
// Format aus Request Header (optional, Standard: MP4)
const format = request.headers.get("x-format") || "mp4";
// Cookie-Unterstützung für YouTube Bot-Erkennung
const cookiesFile = process.env.YT_DLP_COOKIES;
const cookiesFromBrowser = process.env.YT_DLP_COOKIES_FROM_BROWSER;
// JavaScript Runtime für yt-dlp (Standard: deno)
const jsRuntime = process.env.YT_DLP_JS_RUNTIME || "deno";
// Zuerst Video-Informationen abrufen, um den Dateinamen zu erhalten
const videoInfo = await ytDlpWrap.getVideoInfo(url);
// getVideoInfo verwendet intern yt-dlp mit --dump-json
// Deno wird beim eigentlichen Download verwendet
const videoInfoOptions: string[] = [];
if (cookiesFile) {
videoInfoOptions.push("--cookies", cookiesFile);
} else if (cookiesFromBrowser) {
videoInfoOptions.push("--cookies-from-browser", cookiesFromBrowser);
}
const videoInfo = await ytDlpWrap.getVideoInfo(url, videoInfoOptions);
const title = videoInfo.title || "Video";
// Dateiendung bestimmen
@@ -72,12 +87,13 @@ export const POST: APIRoute = async ({ request }) => {
const filename = `${title}.${ext}`;
// Format-String für yt-dlp
// Für "best": Kein Format-String = yt-dlp wählt automatisch bestes Format und merged
const formatString =
format === "mp4"
? "bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo[ext=mp4]+bestaudio/best[ext=mp4]/best"
: format === "audio"
? "bestaudio[ext=m4a]/bestaudio[ext=mp3]/bestaudio"
: "best";
: undefined; // undefined = yt-dlp wählt automatisch bestes Format
if (streamOnly) {
// STREAM-MODUS: Datei temporär speichern, streamen, dann löschen
@@ -91,12 +107,24 @@ export const POST: APIRoute = async ({ request }) => {
url,
"-o",
tempFilePath,
"-f",
formatString,
"--no-mtime",
"--no-playlist",
"--js-runtimes",
jsRuntime,
];
// Cookie-Unterstützung hinzufügen
if (cookiesFile) {
execArgs.push("--cookies", cookiesFile);
} else if (cookiesFromBrowser) {
execArgs.push("--cookies-from-browser", cookiesFromBrowser);
}
// Format nur hinzufügen wenn definiert
if (formatString) {
execArgs.push("-f", formatString);
}
if (format === "mp4") {
execArgs.push("--merge-output-format", "mp4");
} else if (format === "audio") {
@@ -184,12 +212,24 @@ export const POST: APIRoute = async ({ request }) => {
url,
"-o",
outputPath,
"-f",
formatString,
"--no-mtime",
"--no-playlist",
"--js-runtimes",
jsRuntime,
];
// Cookie-Unterstützung hinzufügen
if (cookiesFile) {
execArgs.push("--cookies", cookiesFile);
} else if (cookiesFromBrowser) {
execArgs.push("--cookies-from-browser", cookiesFromBrowser);
}
// Format nur hinzufügen wenn definiert
if (formatString) {
execArgs.push("-f", formatString);
}
if (format === "mp4") {
execArgs.push("--merge-output-format", "mp4");
} else if (format === "audio") {