Add Node.js to backend Dockerfile and enhance downloader
Added Node.js installation to the backend Dockerfile to support yt-dlp's JavaScript runtime. Updated downloader API to bypass SSL verification in Docker, improved error reporting, and convert video thumbnails to data URLs to avoid mixed content issues. In the frontend, improved Dockerfile.prod install process and added new service routes for drone and web services in App.tsx.
This commit is contained in:
@@ -2,6 +2,7 @@ FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies including Node.js for yt-dlp JavaScript runtime
|
||||
RUN apt update && apt install -y \
|
||||
weasyprint \
|
||||
libcairo2 \
|
||||
@@ -9,7 +10,13 @@ RUN apt update && apt install -y \
|
||||
libpango-1.0-0 \
|
||||
libgobject-2.0-0 \
|
||||
ffmpeg \
|
||||
ca-certificates
|
||||
ca-certificates \
|
||||
curl \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt install -y nodejs \
|
||||
&& update-ca-certificates \
|
||||
&& apt clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
23
backend/thirdparty/downloader/views.py
vendored
23
backend/thirdparty/downloader/views.py
vendored
@@ -6,6 +6,8 @@ import tempfile
|
||||
import os
|
||||
import shutil
|
||||
import mimetypes
|
||||
import base64
|
||||
import urllib.request
|
||||
|
||||
from rest_framework import serializers
|
||||
from rest_framework.views import APIView
|
||||
@@ -95,12 +97,13 @@ class Downloader(APIView):
|
||||
|
||||
ydl_options = {
|
||||
"quiet": True,
|
||||
"no_check_certificates": True, # Bypass SSL verification in Docker
|
||||
}
|
||||
try:
|
||||
with yt_dlp.YoutubeDL(ydl_options) as ydl:
|
||||
info = ydl.extract_info(url, download=False)
|
||||
except Exception:
|
||||
return Response({"error": "Failed to retrieve video info"}, status=400)
|
||||
except Exception as e:
|
||||
return Response({"error": f"Failed to retrieve video info: {str(e)}"}, status=400)
|
||||
|
||||
formats = info.get("formats", []) or []
|
||||
|
||||
@@ -128,11 +131,24 @@ class Downloader(APIView):
|
||||
|
||||
audio_resolutions = [f"{b}kbps" for b in sorted(bitrates, reverse=True)]
|
||||
|
||||
# Convert thumbnail to data URL to avoid mixed content issues (HTTPS thumbnail on HTTP site)
|
||||
thumbnail_url = info.get("thumbnail")
|
||||
thumbnail_data_url = None
|
||||
if thumbnail_url:
|
||||
try:
|
||||
with urllib.request.urlopen(thumbnail_url, timeout=10) as response:
|
||||
image_data = response.read()
|
||||
content_type = response.headers.get('Content-Type', 'image/jpeg')
|
||||
thumbnail_data_url = f"data:{content_type};base64,{base64.b64encode(image_data).decode('utf-8')}"
|
||||
except Exception:
|
||||
# If thumbnail fetch fails, just use the original URL
|
||||
thumbnail_data_url = thumbnail_url
|
||||
|
||||
return Response(
|
||||
{
|
||||
"title": info.get("title"),
|
||||
"duration": info.get("duration"),
|
||||
"thumbnail": info.get("thumbnail"),
|
||||
"thumbnail": thumbnail_data_url,
|
||||
"video_resolutions": video_resolutions,
|
||||
"audio_resolutions": audio_resolutions,
|
||||
},
|
||||
@@ -305,6 +321,7 @@ class Downloader(APIView):
|
||||
"merge_output_format": ext, # container
|
||||
"outtmpl": outtmpl, # temp dir
|
||||
"quiet": True,
|
||||
"no_check_certificates": True, # Bypass SSL verification in Docker
|
||||
"max_filesize": settings.DOWNLOADER_MAX_SIZE_BYTES,
|
||||
"socket_timeout": settings.DOWNLOADER_TIMEOUT,
|
||||
"postprocessors": [],
|
||||
|
||||
Reference in New Issue
Block a user