This project provides:
- A Telegram bot (
/create-> photo -> YouTube URL -> generated video). - A reusable REST API for future website integration.
- In-memory async jobs with ffmpeg + yt-dlp processing.
- Accepts one photo + one public YouTube URL.
- Telegram guided UX with inline choices (source mode + output duration).
- Accepts audio source from either YouTube URL or uploaded video.
- Extracts audio with
yt-dlp. - Creates MP4 matching source image dimensions (odd dimensions padded by +1 pixel for compatibility).
- Max source duration is configurable (default: 10 minutes).
- API key protected endpoints.
- Swagger docs at
/docs. - Immediate temporary file cleanup after delivery/download.
- Node.js 20+
ffmpeginstalled and available in PATH (or setFFMPEG_PATH)ffprobeinstalled and available in PATH (or setFFPROBE_PATH)yt-dlpinstalled and available in PATH (or setYTDLP_PATH)
- Install dependencies:
npm install
- Create env file:
cp .env.example .env
- Set required values in
.env:API_KEYTELEGRAM_BOT_TOKEN(optional if API-only)- Optional
yt-dlpstability settings:YTDLP_JS_RUNTIMES=nodeYTDLP_EXTRACTOR_ARGS=youtube:player_client=android,webYTDLP_RETRY_EXTRACTOR_ARGS=youtube:player_client=tv,iosYTDLP_COOKIES_FILE=/absolute/path/to/cookies.txt(if 403 continues)
- Optional upload limits:
MAX_UPLOADED_SOURCE_FILE_BYTES=209715200
- Start in dev mode:
npm run start:dev
Base path: /v1/media-jobs
POST /v1/media-jobs- Multipart fields:
photo(file)youtubeUrl(string)
- Returns:
{ "jobId": "...", "status": "queued" }
- Multipart fields:
GET /v1/media-jobs/:jobId- Returns current status and error details if failed.
GET /v1/media-jobs/:jobId/result- Streams final MP4 when ready.
- Cleans generated file after successful download.
All API calls require header: x-api-key: <API_KEY>.
- Send
/create. - Pick source mode (
YouTube URLorUpload Video). - Send image (document preferred for exact dimensions).
- Send audio source (URL or video/document).
- Pick output duration (
15s,30s,60s,Full). - Bot edits one status message through progress and sends final video.
npm testdocker compose up --build- Session state and jobs are in memory (reset on restart).
- Output/result files are stored in
STORAGE_DIR(default./tmp) and cleaned after delivery.