High-performance automated highlight capture for live broadcasts.
Stream Clipper is a production-ready utility designed to capture and process highlights from live broadcasts. By leveraging yt-dlp for stream manifest resolution and FFmpeg for segmented recording, it provides a seamless way to generate high-quality .mp4 clips from active live streams.
The application avoids unreliable VOD-based scraping options by pre-resolving broadcasts to direct HLS manifest URLs. It then captures video directly from the stream's live edge or oldest available DVR frames, utilizing highly resilient reconnection parameters designed for modern live infrastructure.
- Broad Platform Support: Native handling for YouTube, Twitch, and Kick with handle-to-stream resolution.
- Live Preview: Real-time stream embedding in the UI to confirm the broadcast status before triggering a capture.
- Dynamic Quality Profiles: Targeted scaling down to Low (360p), Medium (720p), or up to High (1080p) resolutions.
- Reliable Job Management: Powered by a persistent
better-sqlite3engine running under Write-Ahead Logging (WAL) mode for fast, concurrent status tracking. - Instant Distribution: Fully integrated one-click mirror uploads to Catbox, qu.ax, and Videy directly from the client interface.
- Multi-Layered Security: Mandatory 32-character API key enforcement split into admin and browser tiers, Server-Side Request Forgery (SSRF) guards restricting stream target hosts, strict UUID validation, and an in-memory IP rate limiter segmented by route.
- Production Infrastructure: Includes turn-key automation scripts for multi-stage system deployments, Nginx reverse proxy management, Let's Encrypt SSL configuration, and custom Fail2ban brute-force protection.
├── clipper.js # Core Express app server, security middlewares & clipping router
├── ecosystem.config.js # PM2 cluster configuration for forks, restart rules & logging paths
├── deploy.sh # Fully automated production package installation, Nginx, and SSL script
├── harden.sh # Server security setup deploying custom Fail2ban jail blocks and UFW rules
├── public/ # Web client directory containing frontend application code
│ ├── clipper.html # Main operational web dashboard template
│ ├── clipper.css # Fully responsive grid custom layouts with dark mode variables [cite: 2]
│ ├── script.js # Client-side validation, iframe embeds, and asynchronous polling logic
│ └── clips/ # Production storage directory for completed .mp4 clips
├── logs/ # System log destination managing active PM2 standard out and error streams
├── temp/ # Temporary working directory for staging incoming stream fragments
└── .env # Critical environment variable configuration file [cite: 1]Stream Clipper includes automated management scripts optimized for a clean installation on Ubuntu or Debian environments.
Run the deployment routine as root to install all runtime packages (Node.js 20, FFmpeg, yt-dlp, Nginx, Certbot), mirror app targets, and configure Let's Encrypt SSL tracking:
# 1. Execute production deploy automation bash deploy.sh
bash harden.sh
The application will refuse to start if a CLIPPER_API_KEY containing at least 32 characters is missing from the environment. You can generate a cryptographically secure 32-character hex key string by running:
node -e "require('crypto').randomBytes(32).toString('hex')|0 && process.stdout.write(require('crypto').randomBytes(32).toString('hex'))"Configure the following variables within your local .env file:
| Variable | Description | Default |
|---|---|---|
CLIPPER_API_KEY |
Required. Security authentication credential for server/admin mutating requests. Must be at least 32 characters. | None |
CLIPPER_BROWSER_KEY |
Separate browser-facing key provided to the frontend payload. Falls back to CLIPPER_API_KEY if omitted. |
CLIPPER_API_KEY |
MAX_CLIP_SECONDS |
Maximum allowable duration ceiling for a single captured clip request. | 300 |
DEFAULT_CLIP_SECS |
Standard recording duration utilized if an explicit runtime length is not requested by the user. | 60 |
MAX_CONCURRENT_JOBS |
The maximum number of background resolution, capture, and encoding instances allowed to run simultaneously. | 5 |
CLIP_MAX_AGE_HOURS |
How long to keep completed clip files on disk before auto-deleting them to maintain bounded disk usage. | 2 |
DB_PATH |
The relative or absolute filesystem directory path mapped to host the tracking SQLite database file. | ./clipper.db |
YOUTUBE_API_KEY |
Optional YouTube Data API v3 token used to perform rapid handle-to-live channel resource resolutions. | None |
CATBOX_USERHASH |
Optional hash key used to tie web dashboard Catbox file uploads permanently to a custom repository account. | None |
VIDEY_API_KEYVIDEY_API_SECRET |
Videy provider API credentials required to authorize remote mirror clip uploads to videy.co. | None |
RATE_LIMIT_WINDOW_MS |
The time window duration for the built-in core API memory-backed IP rate limiter (in milliseconds). | 60000 (1 min) |
RATE_LIMIT_MAX_CLIPS |
The maximum number of new clip creation jobs an IP can start per rate limit window. | 5 |
RATE_LIMIT_MAX_POLLS |
The maximum number of status polling requests an IP can make per rate limit window. | 300 |
CLIP_OUTPUT_DIR |
Target destination directory where final structured highlight MP4 recordings are written. | ./public/clips |
CLIP_TEMP_DIR |
Scratch workspace where raw un-transcoded live data streams are buffered. | ./temp |
KICK_API_BASE |
Base API route domain used when communicating with Kick platform interfaces. | https://api.kick.com |
KICK_AUTH_BASE |
Authentication credential service endpoint used during Kick verification transactions. | https://id.kick.com |
KICK_CLIENT_ID |
Optional OAuth Client identifier for Kick developer API validation rules. | None |
KICK_CLIENT_SECRET |
Optional App Client Secret string associated with proprietary Kick API pipelines. | None |
Licensed under GNU GENERAL PUBLIC LICENSE