diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4544fa7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,55 @@ +FROM node:20-alpine AS base + +# Install dependencies needed for yt-dlp and ffmpeg +RUN apk add --no-cache \ + python3 \ + ffmpeg \ + ca-certificates \ + && wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O /usr/local/bin/yt-dlp \ + && chmod a+rx /usr/local/bin/yt-dlp + +# Set environment variables +ENV YT_DLP_PATH=/usr/local/bin/yt-dlp +ENV FFMPEG_PATH=/usr/bin/ffmpeg + +# Install dependencies only when needed +FROM base AS deps +WORKDIR /app + +COPY package.json package-lock.json* ./ +RUN npm ci + +# Build the application +FROM base AS builder +WORKDIR /app + +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +RUN npm run build + +# Production image +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV=production + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +# Create downloads directories +RUN mkdir -p /app/downloads /app/public/downloads \ + && chown -R nextjs:nodejs /app + +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +CMD ["node", "server.js"] diff --git a/docs/configuration.md b/docs/configuration.md index 24e6c68..afeabba 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -37,14 +37,19 @@ which yt-dlp ### Optional Configuration #### FFMPEG_PATH -**Optional - Reserved for future use** +**Optional - For custom ffmpeg location** -Full path to ffmpeg executable (currently not used, but reserved for future configuration). +Full path to the ffmpeg executable. Passed to yt-dlp via `--ffmpeg-location` flag. Only needed if ffmpeg is not in your system PATH. ```bash FFMPEG_PATH=/usr/local/bin/ffmpeg ``` +**When to set this:** +- ffmpeg is not installed via package manager +- ffmpeg is in a custom location (e.g., Docker, Coolify deployments) +- You're using a standalone ffmpeg binary + ## Configuration Examples ### Example 1: yt-dlp in Custom Location diff --git a/lib/youtube.ts b/lib/youtube.ts index 65d3ded..897b585 100644 --- a/lib/youtube.ts +++ b/lib/youtube.ts @@ -13,6 +13,12 @@ function getYtDlpPath(): string { return process.env.YT_DLP_PATH || 'yt-dlp'; } +// Get ffmpeg location flag for yt-dlp (optional) +function getFfmpegLocationFlag(): string { + const ffmpegPath = process.env.FFMPEG_PATH; + return ffmpegPath ? `--ffmpeg-location "${ffmpegPath}"` : ''; +} + const DOWNLOADS_DIR = path.join(process.cwd(), 'downloads'); const PUBLIC_DOWNLOADS_DIR = path.join(process.cwd(), 'public', 'downloads'); @@ -102,19 +108,21 @@ export async function downloadVideo( const outputPath = path.join(DOWNLOADS_DIR, `${fileId}.%(ext)s`); const finalPath = path.join(PUBLIC_DOWNLOADS_DIR, `${fileId}.${outputExt}`); - // Get yt-dlp path at runtime + // Get yt-dlp path and ffmpeg location at runtime const ytDlpPath = getYtDlpPath(); + const ffmpegFlag = getFfmpegLocationFlag(); console.log('[downloadVideo] Using yt-dlp path:', ytDlpPath); + if (ffmpegFlag) console.log('[downloadVideo] Using ffmpeg location flag:', ffmpegFlag); // Download with yt-dlp - let command = `"${ytDlpPath}" -f "${ytDlpFormat}" -o "${outputPath}" "${url}"`; + let command = `"${ytDlpPath}" ${ffmpegFlag} -f "${ytDlpFormat}" -o "${outputPath}" "${url}"`; if (formatType === 'audio' && format === 'mp3') { // For MP3, we need to extract audio and convert - command = `"${ytDlpPath}" -f "bestaudio[ext=m4a]/bestaudio" -x --audio-format mp3 --audio-quality 0 -o "${outputPath}" "${url}"`; + command = `"${ytDlpPath}" ${ffmpegFlag} -f "bestaudio[ext=m4a]/bestaudio" -x --audio-format mp3 --audio-quality 0 -o "${outputPath}" "${url}"`; } else if (formatType === 'audio' && format === 'wav') { // For WAV, extract and convert - command = `"${ytDlpPath}" -f "bestaudio[ext=m4a]/bestaudio" -x --audio-format wav -o "${outputPath}" "${url}"`; + command = `"${ytDlpPath}" ${ffmpegFlag} -f "bestaudio[ext=m4a]/bestaudio" -x --audio-format wav -o "${outputPath}" "${url}"`; } // Increase maxBuffer for downloads as well diff --git a/next.config.ts b/next.config.ts index e9ffa30..68a6c64 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + output: "standalone", }; export default nextConfig;