Skip to the content.

CastCaster

CI Gem License Ruby

Unified live streaming management platform.

Manage RTMP/HLS streaming with Nginx, per-channel FFmpeg tasks, and Docker-based deployment. Each channel spawns independent containers for relay, adaptive transcoding, snapshot, or test — isolated and scalable.

Quick Start

# Install and initialize
gem install castcaster
castcaster init

# Add a test channel
castcaster channel add --name demo

# Generate compose.yml and start
castcaster deploy
docker compose up -d

Open http://localhost:8080/channel/demo — click play to see timestamp video.

Source Types

# Test — internal test stream (default)
castcaster channel add --name demo

# Pull — relay from external RTMP source
castcaster channel add --name relay --source-type rtmp_pull --source rtmp://example.com/live/stream

# Pull + adaptive transcoding
castcaster channel add --name news \
  --source-type rtmp_pull \
  --source rtmp://example.com/live/stream \
  --transcode 720p,480p

# Pull + snapshot
castcaster channel add --name camera \
  --source-type http_pull \
  --source http://example.com/stream \
  --snapshot 5

# Push — external OBS/FFmpeg pushes to CastCaster
castcaster channel add --name mychannel --source-type rtmp_push
# OBS: rtmp://host:1935/live/mychannel

Architecture

Browser───:80 ──→ Traefik (optional) ──→ nginx :8080
                   │                       ├── /hls/live/* → HLS segments
                   │                       ├── /api/*      → proxy → webui:8081
                   │                       ├── /           → proxy → webui:8081
                   │                       └── RTMP :1935  → RTMP ingest
                   │
                   └── :443 (HTTPS, via Let's Encrypt)

FFmpeg containers (per channel):
  test-<name>    → teststream.sh (internal test pattern)
  relay-<name>   → relay.sh (RTMP/HTTP pull relay)
  adaptive-<name>→ adaptive.sh (multi-bitrate transcode)
  snapshot-<name>→ snapshot.sh (periodic thumbnail)

Requirements

Docker Images

Image Source Purpose
ghcr.io/lax/castcaster-nginx Local build Nginx (RTMP + HLS + proxy)
ghcr.io/lax/castcaster-webui Local build Web management UI
ghcr.io/lax/castcaster-ffmpeg Local build FFmpeg relay/transcode/snapshot
traefik:v3.0 Docker Hub Reverse proxy + SSL (optional)

Commands

init

Initialize project in current directory.

castcaster init

Creates: castcaster.yml, castcaster.token, channels/, hls/, logs/, data/.

channel add

Default is test — generates a timestamp video with zero external dependencies.

# Test — internal test stream
castcaster channel add --name demo

# Pull — relay from external RTMP source
castcaster channel add --name relay \
  --source-type rtmp_pull \
  --source rtmp://example.com/live/stream

# Pull — relay from HTTP source
castcaster channel add --name radio \
  --source-type http_pull \
  --source http://example.com/stream

# Pull + adaptive transcoding
castcaster channel add --name news \
  --source-type http_pull \
  --source http://example.com/stream \
  --transcode 720p,480p,360p

# Pull + snapshot
castcaster channel add --name camera \
  --source-type http_pull \
  --source http://example.com/stream \
  --snapshot 5

# Push — external OBS/FFmpeg pushes to CastCaster
castcaster channel add --name mychannel --source-type rtmp_push
# OBS: rtmp://host:1935/live/mychannel

channel list / start / stop / rm / update

castcaster channel list
castcaster channel start news
castcaster channel stop news
castcaster channel rm radio
castcaster channel update news --source-type rtmp_pull --source rtmp://example.com/new

config

Preview generated nginx config.

castcaster config

deploy

Generate compose.yml (and optional Traefik config).

castcaster deploy                       # Docker Compose (default)
castcaster deploy --with-traefik        # + Traefik SSL
castcaster deploy --mode swarm          # Docker Swarm

doctor

Check system environment.

Ruby           ruby 3.4.1
Docker         Docker version 28.4.0
Compose        Docker Compose version v2.39.3
nginx          available
ffmpeg         available
webui          available
config.yml     ok (engine: nginx-rtmp)

Channel Tasks

Each channel spawns independent containers based on config:

Task Container Name Trigger Description
Test castcaster-test-<name> test (default) Internal timestamp video
Relay castcaster-relay-<name> rtmp_pull / http_pull / srt Relay external source → nginx
Adaptive castcaster-adaptive-<name> --transcode Multi-bitrate transcoding (replaces relay)
Snapshot castcaster-snapshot-<name> --snapshot Periodic thumbnail capture
(none) rtmp_push OBS/FFmpeg pushes directly, no container

Containers are tagged with Docker labels:

labels:
  "castcaster/channel": "news"
  "castcaster/task": "adaptive"

Transcode Presets

Profile Bitrate Resolution Audio
360p 512k 640×360 64k
480p 1024k 854×480 96k
576p 1248k 1024×576 96k
720p 2048k 1280×720 128k
1080p 3000k 1920×1080 128k

Web Management UI

http://localhost:8080

Note: Start/stop actions are managed via CLI (castcaster channel start/stop) for security reasons.

Configuration

# castcaster.yml
engine: nginx-rtmp
hls_fragment: 6
hls_window: 60
domain: stream.example.com        # for Traefik SSL
acme_email: admin@example.com
enable_traefik: false

Deployment Modes

Docker Compose (default)

castcaster deploy
docker compose up -d

Docker Compose + Traefik

castcaster deploy --with-traefik
docker compose up -d

Traefik provides Let’s Encrypt HTTPS, sits in front of nginx.

Docker Swarm

castcaster deploy --mode swarm
docker stack deploy -c docker-stack.yml castcaster

Development

Branch Description
dev Active development
main Product release branch

Only Docker needed — no Ruby installation required:

# Build CLI image
make cli-build

# Create and start a test project
make dev TARGET=/tmp/my-project

# View logs
make dev-logs TARGET=/tmp/my-project

# Stop all services
make dev-down TARGET=/tmp/my-project

# Run tests (unit + integration) in container
make test

# Quick syntax check in container
make syntax

Build from source (Ruby only)

git clone https://github.com/Lax/castcaster.git
cd castcaster
gem build castcaster.gemspec
gem install castcaster-*.gem

Test

make test                     # Run all tests in Docker container
make syntax                   # Ruby syntax check in Docker container
make check                    # Full: syntax + test + gem build

Or with Ruby locally:

rake test                     # Run all tests (unit)
rake syntax                   # Ruby syntax check
rake                          # Default: syntax + test

Project structure

castcaster/
├── lib/castcaster/           ← Ruby source
│   ├── cli.rb                ← CLI commands (Thor)
│   ├── channel.rb            ← Channel model + CRUD
│   ├── channel_cli.rb        ← Channel subcommands
│   ├── config.rb             ← Configuration load/save
│   ├── deploy.rb             ← Deployment generator
│   ├── deploy/               ← Compose/Swarm deployers
│   ├── engines/              ← Streaming engine configs
│   ├── ffmpeg_profiles.rb    ← Transcode presets
│   └── version.rb            ← Version constant
├── templates/                ← ERB/Tera templates
│   ├── nginx-rtmp/           ← Nginx config template
│   └── deploy/               ← Deployment templates
├── docker/                   ← Docker image sources
│   ├── cli/                  ← CLI tool container
│   ├── nginx/
│   ├── ffmpeg/
│   └── webui/
├── bin/                      ← CLI entry point
├── test/                     ← Minitest suite
├── examples/README.md         ← Example documentation
└── examples/clock-demo/       ← CLI-generated project with clock source

License

MIT

Homepage: https://castcaster.mib.cc