Quantcast
Channel: Active questions tagged youtube-api - Stack Overflow
Viewing all articles
Browse latest Browse all 3831

YouTube video fetching fails in Docker with "python not found" and unplayable content errors

$
0
0

I'm building a YouTube video info. fetcher using Remix, Node.js, and yt-dlp. It works locally, but fails in Docker with several issues (see output below):

  • Python not found when trying to use yt-dlp via Python
  • YouTube API returns "UNPLAYABLE" content status
  • Fallback to youtube-dl-exec is too slow

Output

GET /?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DZyF-pmNfnH0 200 - - 17100.357 msPlayer API response for ZyF-pmNfnH0 (attempt 1): {"status": 200,"hasStreamingData": false,"playabilityStatus": "UNPLAYABLE","reason": "This content isn't available."}Python yt-dlp error: Error: Command failed: python /app/yt_dlp_temp.py "https://www.youtube.com/watch?v=ZyF-pmNfnH0"/bin/sh: 1: python: not found

What I've tried

  • Different YouTube API endpoints (ANDROID, WEB)
  • Multiple fallback strategies
  • Various yt-dlp configurations

Questions

  1. How can I fix the "python not found" error in Docker?
  2. Why does the YouTube API return UNPLAYABLE status when the video is available?
  3. How can I improve performance to match sites like y2mate?

Code

api.info.ts (main route handler):

// app/routes/api.info.tsimport { json, type LoaderFunctionArgs } from "@remix-run/node";import youtubedl from "youtube-dl-exec";import { fetchWithPythonYtDlp } from "~/lib/yt-dlp-wrapper";export async function loader({ request }: LoaderFunctionArgs) {  const url = new URL(request.url);  const videoUrl = url.searchParams.get("url");  try {    const videoId = extractVideoId(videoUrl);    let info;    try {      info = await fetchVideoInfo(videoId);      if (info.formats.length === 0) throw new Error(`Format array is empty`);    } catch (error) {      console.warn(`Player API failed, falling back to yt-dlp:`, error);      try {        info = await fetchWithPythonYtDlp(videoUrl);      } catch (error) {        console.warn(`Falling back to youtube-dl-exec:`, error);        info = await fetchVideoInfoFallback(videoId, videoUrl);      }    }    return json({ success: true, data: info });  } catch (error) {    return json({ error: "Failed to fetch video info" }, { status: 500 });  }}

yt-dlp-wrapper.ts (Python fallback):

// ~/lib/yt-dlp-wrapper.tsimport { exec } from "child_process";import { promisify } from "util";import fs from "fs";const execPromise = promisify(exec);export async function fetchWithPythonYtDlp(videoUrl: string) {  const pythonScript = `import yt_dlpimport jsonimport sysvideo_url = sys.argv[1]ydl_opts = {'quiet': True, 'skip_download': True}with yt_dlp.YoutubeDL(ydl_opts) as ydl:    info = ydl.extract_info(video_url, download=False)print(json.dumps(info))`;  fs.writeFileSync("yt_dlp_temp.py", pythonScript);  const { stdout } = await execPromise(`python yt_dlp_temp.py "${videoUrl}"`);  return JSON.parse(stdout);}

Dockerfile

# ---------- Stage 1: Build ----------FROM node:18-bullseye-slim AS builder# Install yt-dlp for build phase (if needed)RUN apt-get update && apt-get install -y python3 python3-pip && rm -rf /var/lib/apt/lists/*RUN pip3 install --no-cache-dir yt-dlp# Set working directoryWORKDIR /app# Copy and install dependenciesCOPY package*.json ./RUN npm install# Copy all source filesCOPY . .# Build Remix appRUN npm run build# ---------- Stage 2: Runtime ----------FROM node:18-bullseye-slim# Install only runtime dependenciesRUN apt-get update && \    apt-get install -y ffmpeg python3 python3-pip && \    rm -rf /var/lib/apt/lists/*# Install yt-dlp (needed at runtime)RUN pip3 install --no-cache-dir yt-dlp# Set working directoryWORKDIR /app# Copy package files and install only prod depsCOPY package*.json ./RUN npm install --omit=dev# Copy only built + required app files from builder stageCOPY --from=builder /app/build ./buildCOPY --from=builder /app/public ./publicCOPY --from=builder /app/app ./appCOPY --from=builder /app/remix.config.js ./remix.config.js# Expose port and start the appEXPOSE 3000CMD ["npm", "run", "start"]

Viewing all articles
Browse latest Browse all 3831

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>