CurbSoftware TECH INNOVATIONS
Start a route →

Product · Open Source · Video Tooling

video-hls

Own the path from source video to adaptive streaming

video-hls cover

video-hls turns a folder of ordinary video files into adaptive-bitrate HTTP Live Streaming packages without putting a video SaaS between you and your own media. Drop a source into video/, run one script, and the output is a portable directory containing a master playlist, synchronized quality variants, segments, and a machine-readable record of how the package was produced.

It handles the difficult transcoding and packaging work while leaving storage, delivery, player choice, and access policy under your control.

Why own the transcoding step?

Hosted video platforms are excellent when a project needs managed live streaming, DRM, viewer analytics, automatic transcription, or a global delivery product with minimal operations. For a library of finished videos, however, their per-minute storage and delivery model can turn a solved encoding job into a permanent bill.

video-hls takes a narrower position: encode the library correctly, publish ordinary static files, and serve them from infrastructure you already understand. The result can live in Amazon S3, Cloudflare R2, Backblaze B2, DigitalOcean Spaces, nginx, or any compatible origin behind a CDN. Every URI inside the package is relative, so the same directory can move between buckets, prefixes, and hosts without rewriting its playlists.

HLS also changes how viewers consume the file. A phone does not need to pull the same 1080p asset as a desktop, and someone who watches thirty seconds should not transfer an entire long-form MP4. The player fetches short segments from the rendition that currently fits the screen and connection, then changes tiers as throughput changes.

One command, a complete package

git clone https://github.com/CurbSoftware/video-hls.git
cd video-hls
cp .env.example .env
./run.sh --check
cp ~/Videos/talk.mp4 video/
./run.sh

The default configuration works without a GPU. ./run.sh --check goes further than listing encoders compiled into FFmpeg: it performs a live probe so the report distinguishes hardware paths that are genuinely usable on the machine from encoders whose drivers or devices are unavailable.

For each source, the pipeline probes its dimensions, frame rate, and audio streams; removes ladder tiers taller than the source; computes a shared keyframe interval from the frame rate and segment duration; encodes each rendition; packages without re-encoding; validates the result; and publishes the completed directory atomically. Failed work remains available for retry, while successful sources and subtitle sidecars can be archived automatically.

Correctness at the switching points

Adaptive streaming only feels seamless when every rendition cuts at compatible timestamps. video-hls locks the keyframe interval to fps × HLS_TIME across the ladder, which gives the packager common boundaries for every quality tier. The player can move between 360p, 720p, and 1080p without landing between keyframes and stuttering.

The pipeline also reads CODECS metadata back from the encoded files instead of guessing it. Audio is advertised only when the source actually has audio. H.264 with AAC uses MPEG-TS by default, while HEVC, AV1, or Opus select fragmented MP4/CMAF because those combinations do not belong in MPEG-TS. These details separate a stream that happens to play in VLC from one browsers can negotiate reliably.

Hardware acceleration is optional. Automatic selection probes NVENC, Intel QSV, VAAPI, and VideoToolbox before falling back to software encoders. H.264, HEVC, and AV1 are available, but compatibility remains an explicit operator choice: H.264 reaches the widest set of browsers, while newer codecs trade reach and encode time for smaller output.

Publishing and protecting the files

The generated package is static, but production delivery still needs correct HTTP behavior. Playlists should use application/vnd.apple.mpegurl; transport-stream segments use video/mp2t; fragmented segments use video/iso.segment; initialization MP4s use video/mp4; and subtitles use text/vtt. Cross-origin players also need GET and HEAD allowed by the origin's CORS policy.

Paid libraries can authorize a whole video prefix with signed cookies, place an edge-token check in a Cloudflare Worker or nginx, or generate viewer-specific playlist URLs. Prefix authorization is usually simpler because one playback requests a master playlist, a variant playlist, and many segments.

That protection is access control, not DRM. It prevents casual link sharing, but it cannot stop an authorized viewer from saving the bytes they receive. Widevine, PlayReady, and FairPlay require encryption and license infrastructure that this project deliberately does not pretend to provide.

A focused tool, not a hosted platform

video-hls is for video on demand. It does not provide live ingest, managed analytics, automatic captions, thumbnail storyboards, a player, DRM, or a global CDN. Those are good reasons to choose a hosted platform when the product needs them.

For teams with finished media, existing storage, and a preference for files they can move and inspect, the project supplies the missing middle: repeatable encoding, honest manifests, aligned variants, and output that stays yours. It is released under the MIT License and can be used, modified, and shipped commercially with the copyright notice retained.

What it does

  • Adaptive-bitrate ladders with aligned keyframes and segment boundaries
  • Automatic codec, accelerator, container, audio, and subtitle handling
  • Atomic, resumable batch processing with safe source archiving
  • Portable static output for any object store, web server, or CDN

Route intake · RTE-01

Start a route

Tell us what your operation runs on and where it hurts. We reply within two business days.

Complete the spam check to send your route.