Install Node.js via nodeenv (pip); use web client
nodeenv is a Python package that downloads a pre-built Node.js binary — no apt repos, no compilation, guaranteed to work in python:3.12-slim. The 'node' binary is linked into /usr/local/bin so yt-dlp can find it. With Node.js available the web client works fully (37 formats) and can solve YouTube's n-challenge that every other approach was failing on. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,13 @@ RUN apt-get update && apt-get install -y ffmpeg gosu && rm -rf /var/lib/apt/list
|
|||||||
|
|
||||||
COPY backend/requirements.txt ./backend/requirements.txt
|
COPY backend/requirements.txt ./backend/requirements.txt
|
||||||
RUN pip install --no-cache-dir -r backend/requirements.txt && pip install --no-cache-dir -U yt-dlp
|
RUN pip install --no-cache-dir -r backend/requirements.txt && pip install --no-cache-dir -U yt-dlp
|
||||||
|
|
||||||
|
# nodeenv downloads a pre-built Node.js binary via pip — no apt repos needed.
|
||||||
|
# yt-dlp needs 'node' in PATH to solve YouTube's n-challenge (JS obfuscation).
|
||||||
|
RUN pip install --no-cache-dir nodeenv && \
|
||||||
|
nodeenv --prebuilt /opt/node && \
|
||||||
|
ln -sf /opt/node/bin/node /usr/local/bin/node
|
||||||
|
|
||||||
RUN echo "--cache-dir /data/yt-dlp-cache" > /etc/yt-dlp.conf
|
RUN echo "--cache-dir /data/yt-dlp-cache" > /etc/yt-dlp.conf
|
||||||
|
|
||||||
COPY backend/ ./backend/
|
COPY backend/ ./backend/
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ def ytdlp_test(
|
|||||||
"yt-dlp",
|
"yt-dlp",
|
||||||
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||||
"--dump-json", "--no-download", "--no-playlist",
|
"--dump-json", "--no-download", "--no-playlist",
|
||||||
"--extractor-args", "youtube:player_client=web_embedded",
|
"--extractor-args", "youtube:player_client=web",
|
||||||
*cookie_args,
|
*cookie_args,
|
||||||
],
|
],
|
||||||
capture_output=True, text=True, timeout=30,
|
capture_output=True, text=True, timeout=30,
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ def fetch_video_metadata(video_id: str) -> dict | None:
|
|||||||
base_cmd = [
|
base_cmd = [
|
||||||
"yt-dlp", url,
|
"yt-dlp", url,
|
||||||
"--dump-json", "--no-download", "--no-playlist",
|
"--dump-json", "--no-download", "--no-playlist",
|
||||||
"--extractor-args", "youtube:player_client=web_embedded",
|
"--extractor-args", "youtube:player_client=web",
|
||||||
]
|
]
|
||||||
stdout, stderr, code = _run([*base_cmd, *cookie_args], timeout=30)
|
stdout, stderr, code = _run([*base_cmd, *cookie_args], timeout=30)
|
||||||
if code != 0:
|
if code != 0:
|
||||||
@@ -567,7 +567,7 @@ def start_download(
|
|||||||
"--no-part", "--no-mtime",
|
"--no-part", "--no-mtime",
|
||||||
"-o", output_template,
|
"-o", output_template,
|
||||||
"--newline", "--progress", "--no-colors",
|
"--newline", "--progress", "--no-colors",
|
||||||
"--extractor-args", "youtube:player_client=web_embedded",
|
"--extractor-args", "youtube:player_client=web",
|
||||||
*cookie_args,
|
*cookie_args,
|
||||||
],
|
],
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
|
|||||||
Reference in New Issue
Block a user