Sign inSign up

lancer1977/busey-box

By lancer1977

Updated 4 months ago

Headless RTMP Video Server

Image
0

784

lancer1977/busey-box repository overview

Busey-Box: Raspberry Pi RTMP Broadcaster

A Python-based RTMP broadcaster for Raspberry Pi that streams video playlists to Twitch with dynamic overlays and "Now Playing" text.

Features

  • Playlist-based streaming: Define video playlists in JSON manifests
  • Dynamic text overlays: Real-time "Now Playing" updates during streaming
  • Watermark support: Add watermarks with customizable positioning
  • Hardware acceleration: Supports multiple encoders (Raspberry Pi, NVIDIA, Intel QSV, or CPU)
  • Automatic looping: Continuous playlist playback with optional shuffle
  • FFmpeg-powered: Professional streaming quality with configurable bitrates

Current Status

Web Interface Available: Access the control panel at http://localhost:8080 to manage streams, playlists, and overlays through a modern web UI.

Project Structure

/opt/rpi-broadcaster/
├── app/
│   ├── runner.py           # Main playlist runner
│   └── run_ffmpeg.sh       # FFmpeg streaming script
├── config/
│   └── overlays/           # Overlay presets (watermark, text)
│       └── default.json
├── media/
│   └── shows/              # Show directories with video files
│       └── my-show-01/
│           ├── manifest.json
│           └── video/
├── state/
│   ├── current.json        # Current playback state
│   └── now_playing.txt     # Dynamic text file for FFmpeg
└── systemd/
    └── rpi-broadcaster.service

Busey-Box automatically generates example configurations for your hardware when you first run it!

# 1. Clone and start
git clone https://github.com/lancer1977/Busey-Box.git
cd Busey-Box
docker compose up -d

# 2. Container creates hardware-specific examples in ./config/examples/
# Read the guide:
cat ./config/examples/README.txt

# 3. Choose and copy your config
cp ./config/examples/YOUR-HARDWARE.json ./config/config.json

# 4. Add your Twitch stream key
nano ./config/config.json
# Replace YOUR_TWITCH_STREAM_KEY_HERE with your key from:
# https://dashboard.twitch.tv/settings/stream

# 5. Restart and start streaming!
docker compose restart

That's it! The container automatically creates optimized configs for:

  • Raspberry Pi 4 & 5
  • PC/Server (CPU encoding)
  • NVIDIA GPU
  • AMD GPU
  • Intel QuickSync

📖 See Auto-Generated Configs Guide for more details.

Alternative: Traditional Installation

Automated setup (for non-Docker installations):

cd Busey-Box
./setup.sh

The setup script will:

  • Install all dependencies
  • Create directory structure
  • Install systemd services (broadcaster + web interface)
  • Create configuration templates
  • Set up Twitch credential files

After setup:

  1. Verify installation: ./verify-install.sh
  2. Edit ~/.buseybox/config.json with your Twitch stream key and media directory
  3. Start services: sudo systemctl start rpi-broadcaster rpi-broadcaster-web
  4. Access web UI: http://localhost:8080

Note: The installer uses a Python virtual environment (.venv) to avoid PEP 668 errors on Debian Bookworm/Raspberry Pi OS. See PEP668-FIX.md for details.

Docker (Headless)

Yes — Busey-Box runs headless in Docker (FFmpeg + runner + web API, no desktop/GUI required).

1) Prepare config
cp config.json.example config.json

Edit config.json and set your Twitch stream key. For easiest container compatibility, set:

"video_codec": "libx264"

(You can still try h264_v4l2m2m on Raspberry Pi with extra device mapping; see below.)

2) Start with Docker Compose
docker compose -f docker-compose.local.yml up -d --build

Open the web UI at: http://localhost:8080

3) Volume layout used by compose
  • ./config.json/config/config.json (Twitch + app settings)
  • ./media/shows/opt/rpi-broadcaster/media/shows (your playlists/videos)
  • ./state/opt/rpi-broadcaster/state (runtime state + now_playing)
  • ./config/overlays/opt/rpi-broadcaster/config/overlays (overlay presets)
4) Raspberry Pi hardware encoding notes

If you want Pi hardware encode in container (h264_v4l2m2m), you may need to expose /dev/video* devices and group permissions in docker-compose.yml (commented examples are included). If hardware encoding fails, switch back to libx264.

5) Useful Docker commands
docker compose -f docker-compose.local.yml logs -f
docker compose -f docker-compose.local.yml restart
docker compose -f docker-compose.local.yml down
6) Local helper scripts
# Build local image
./scripts/docker-build-local.sh

# Build + run local stack
./scripts/docker-up-local.sh

# Stop local stack
./scripts/docker-down.sh

If port 8080 is already used on your host:

HOST_PORT=8081 ./scripts/docker-up-local.sh

Then open http://localhost:8081.

7) Docker Hub workflow (lancer1977/busey-box)
# Build and push image (set TAG to a release version)
TAG=v0.1.0 ./scripts/docker-publish.sh

# Deploy from Docker Hub image
TAG=v0.1.0 ./scripts/docker-deploy-hub.sh

You can also deploy with compose directly:

TAG=v0.1.0 docker compose -f docker-compose.hub.yml up -d

Manual Installation

If you prefer manual installation or need customization:

  1. Install dependencies:

    sudo apt update
    sudo apt install ffmpeg python3-full python3-venv
    
  2. Set up configuration:

    mkdir -p ~/.buseybox
    cp config.json.example ~/.buseybox/config.json
    nano ~/.buseybox/config.json  # Add your stream key and configure paths
    chmod 600 ~/.buseybox/config.json
    
  3. Create directory structure and virtual environment:

    sudo mkdir -p /opt/rpi-broadcaster/{app,config/overlays,media/shows,state,logs}
    sudo cp -r app/* /opt/rpi-broadcaster/app/
    sudo cp -r config/* /opt/rpi-broadcaster/config/
    sudo chown -R $USER:$USER /opt/rpi-broadcaster
    
    # Create virtual environment
    python3 -m venv /opt/rpi-broadcaster/.venv
    /opt/rpi-broadcaster/.venv/bin/pip install --upgrade pip
    /opt/rpi-broadcaster/.venv/bin/pip install -r /opt/rpi-broadcaster/app/requirements.txt
    
  4. Install systemd services:

    sudo cp systemd/*.service /etc/systemd/system/
    sudo systemctl daemon-reload
    sudo systemctl enable rpi-broadcaster rpi-broadcaster-web
    sudo systemctl start rpi-broadcaster rpi-broadcaster-web
    

Usage

Access the control panel at http://localhost:8080 (or http://your-pi-ip:8080 remotely).

Features:

  • 🎬 Start/stop streaming with one click
  • 📋 Browse and select shows/playlists
  • ⏭️ Skip to next/previous video
  • 🎯 Jump to specific video in playlist
  • 🎨 Change overlay presets on the fly
  • 📊 Real-time status monitoring
  • 🔄 Auto-refreshing "Now Playing" display
Creating a Show/Playlist
  1. Create a show directory:

    mkdir -p /opt/rpi-broadcaster/media/shows/my-show/video
    
  2. Add video files to the video/ subdirectory

  3. Create a manifest.json:

    {
      "name": "my-show",
      "loop": true,
      "shuffle": false,
      "overlayPreset": "default",
      "playlist": [
        {
          "path": "video/intro.mp4",
          "title": "Show Intro"
        },
        {
          "path": "video/episode01.mp4",
          "title": "Episode 1"
        }
      ]
    }
    
Controlling Playback

Via Web Interface (easiest):

  • Navigate to http://localhost:8080
  • Use the control panel to start/stop and manage playlists

Via REST API:

# Get status
curl http://localhost:8080/api/status

# Start streaming
curl -X POST http://localhost:8080/api/control/start

# Stop streaming
curl -X POST http://localhost:8080/api/control/stop

# Select a show
curl -X POST http://localhost:8080/api/control/select-show \
  -H "Content-Type: application/json" \
  -d '{"show_dir": "/opt/rpi-broadcaster/media/shows/my-show"}'

# Jump to video index
curl -X POST http://localhost:8080/api/control/jump \
  -H "Content-Type: application/json" \
  -d '{"index": 2}'

# Next/previous video
curl -X POST http://localhost:8080/api/control/next
curl -X POST http://localhost:8080/api/control/previous

Via JSON file (manual): Edit /opt/rpi-broadcaster/state/current.json:

{
  "running": true,
  "show_dir": "/opt/rpi-broadcaster/media/shows/my-show",
  "index": 0,
  "overlay_preset": "default"
}

The runner script monitors this file and automatically applies changes.

Customizing Overlays

Edit /opt/rpi-broadcaster/config/overlays/default.json:

{
  "name": "default",
  "description": "Watermark bottom-right + dynamic Now Playing text top-left",
  "watermark": {
    "enabled": true,
    "path": "overlays/watermark.png",
    "x": "W-w-20",
    "y": "H-h-20",
    "alpha": 0.9
  },
  "dynamic_text": {
    "enabled": true,
    "textfile": "/opt/rpi-broadcaster/state/now_playing.txt",
    "x": 24,
    "y": 24,
    "font_size": 36,
    "box": true,
    "boxborderw": 12
  },
  "video": {
    "scale_w": 1280,
    "scale_h": 720,
    "fps": 30
  }
}

How It Works

  1. runner.py monitors /opt/rpi-broadcaster/state/current.json
  2. When running: true, it reads the show's manifest.json
  3. For each playlist item:
    • Updates /opt/rpi-broadcaster/state/now_playing.txt with the title
    • Launches run_ffmpeg.sh with the video file and overlay preset
    • Waits for FFmpeg to complete
    • Advances to next item (or loops if configured)
  4. FFmpeg uses drawtext=textfile=...:reload=1 to display live-updating "Now Playing" text

Dynamic Text Overlay

The "Now Playing" feature uses FFmpeg's drawtext filter with reload=1:

  • FFmpeg reads /opt/rpi-broadcaster/state/now_playing.txt every frame
  • runner.py updates this file atomically when switching videos
  • No need to restart FFmpeg - text updates live during the stream

See DYNAMIC-TEXT.md for technical details.

Environment Variables

Set in /etc/systemd/system/rpi-broadcaster.service or export before running:

  • VIDEO_CODEC: Default h264_v4l2m2m (Pi 4 hardware encoder) or libx264 (software fallback)
  • VBITRATE: Video bitrate (default: 3000k for 720p30)
  • ABITRATE: Audio bitrate (default: 160k)
  • FPS: Frame rate (default: 30)
  • GOP: Keyframe interval (default: 120)
  • FONTFILE: Path to TTF font for text overlay (optional but recommended)
  • TWITCH_INGEST: Twitch ingest server (default: live.twitch.tv)

Troubleshooting

Check service status:

sudo systemctl status rpi-broadcaster
sudo systemctl status rpi-broadcaster-web
journalctl -u rpi-broadcaster -f
journalctl -u rpi-broadcaster-web -f

Test web interface manually:

cd /opt/rpi-broadcaster/app
python3 web_server.py
# Access at http://localhost:8080

Test streaming manually:

# Configuration is loaded automatically from ~/.buseybox/config.json

# Test with a single video
cd /opt/rpi-broadcaster/app
./run_ffmpeg.sh /path/to/video.mp4 /opt/rpi-broadcaster/config/overlays/default.json

Common issues:

  • No video codec: Install FFmpeg with hardware support or change video_codec in config.json to libx264
  • Permission denied: Ensure the service user has read access to media files
  • Stream key invalid: Verify ~/.buseybox/config.json contains correct key and is readable
  • Videos not found: Check that media.root_dir in config.json points to correct location
  • PEP 668 error (Debian Bookworm): The installer uses a virtual environment to avoid this. If you see this error, ensure python3-venv is installed and re-run setup.sh

Configuration

Main Configuration File

All settings are stored in ~/.buseybox/config.json (user-specific, no sudo required):

{
  "twitch": {
    "stream_key": "YOUR_TWITCH_STREAM_KEY_HERE",
    "ingest_server": "live.twitch.tv"
  },
  "media": {
    "root_dir": "/opt/rpi-broadcaster/media/shows"
  },
  "streaming": {
    "video_codec": "libx264",
    "video_bitrate": "3000k",
    "audio_bitrate": "160k",
    "fps": 30,
    "gop": 120,
    "resolution": {
      "width": 1280,
      "height": 720
    }
  },
  "web": {
    "port": 8080,
    "host": "0.0.0.0"
  }
}
📚 Configuration Resources

🎯 Quick Start - Choose Your Hardware:

Your SystemCopy This Config
Raspberry Pi 4cp docs/examples/config-raspberry-pi-4.json ~/.buseybox/config.json
Raspberry Pi 5cp docs/examples/config-raspberry-pi-5.json ~/.buseybox/config.json
PC/Server (CPU)cp docs/examples/config-pc-cpu.json ~/.buseybox/config.json
NVIDIA GPUcp docs/examples/config-nvidia-rtx.json ~/.buseybox/config.json
AMD GPUcp docs/examples/config-amd-vaapi.json ~/.buseybox/config.json
Intel QuickSynccp docs/examples/config-intel-quicksync.json ~/.buseybox/config.json

Then edit the file and add your Twitch stream key!

📖 Full Documentation:

💾 All Example Configs (in docs/examples/):

  • Hardware-optimized: Pi 4, Pi 5, PC CPU, NVIDIA, AMD, Intel
  • Quality presets: Low bandwidth, High quality, 60fps
  • Includes detailed notes and requirements for each
Quick Configuration Notes
  • Get your stream key: https://dashboard.twitch.tv/settings/stream
  • Video codec: Use libx264 (software, works everywhere) or h264_v4l2m2m (Raspberry Pi hardware)
  • Bitrate recommendations: 720p = 2500-4000k, 1080p = 4500-6000k
  • Legacy support: Scripts will check ~/.buseybox/twitch.env as fallback for backwards compatibility

Future Enhancements

  • Web interface on port 8080 for remote playlist control
  • REST API for programmatic control
  • WebSocket support for real-time updates (currently polling)
  • Stream health monitoring (bitrate, dropped frames)
  • Playlist scheduling and automation
  • Multi-platform streaming (YouTube, Facebook, etc.)
  • User authentication for web interface
  • Mobile-responsive design improvements
  • Playlist editor in web UI

License

MIT License - see LICENSE file for details.

Tag summary

Content type

Image

Digest

sha256:f2f3e9905

Size

238.2 MB

Last updated

4 months ago

docker pull lancer1977/busey-box