Skip to content

Deploying uStreamer

Introduction

uStreamer (pronounced micro-streamer) is a lightweight, high-performance MJPEG video streaming server designed for embedded systems and Raspberry Pi devices. Unlike heavier streaming solutions, uStreamer focuses on minimal latency and resource efficiency, making it ideal for applications like 3D printer cameras, security monitoring, and remote observation systems.

Written in C with minimal dependencies, uStreamer captures video from V4L2 devices (like USB cameras or Raspberry Pi cameras) and streams it via HTTP. The project emerged from the PiKVM project’s need for a reliable, low-latency streaming solution.

Key highlights of uStreamer:

  • Ultra-Low Latency: Optimized for real-time monitoring with minimal delay
  • Lightweight: Minimal CPU and memory usage, perfect for embedded systems
  • Hardware Acceleration: Supports GPU encoding on Raspberry Pi
  • MJPEG Streaming: Universal format compatible with all browsers
  • Snapshot API: Capture still images via HTTP endpoint
  • Multiple Clients: Handle many simultaneous viewers efficiently
  • V4L2 Support: Works with USB cameras and CSI cameras
  • Resolution Control: Dynamic resolution and frame rate adjustment
  • GPIO Integration: Optional GPIO control for camera accessories
  • REST API: Programmatic control and status monitoring
  • Open Source: Licensed under GPL-3.0

This guide walks through deploying uStreamer on Klutch.sh using Docker, configuring video capture, and setting up streaming endpoints.

Why Deploy uStreamer on Klutch.sh

Deploying uStreamer on Klutch.sh provides several advantages for video streaming applications:

Simplified Deployment: Klutch.sh automatically builds and deploys your uStreamer configuration. Push to GitHub, and your stream server deploys automatically.

HTTPS by Default: Klutch.sh provides automatic SSL certificates, enabling secure video streaming without manual certificate management.

GitHub Integration: Connect your configuration repository directly from GitHub. Updates trigger automatic redeployments.

Scalable Resources: Allocate CPU and memory based on stream resolution and viewer count.

Environment Variable Management: Configure streaming parameters through Klutch.sh’s environment variable system.

Custom Domains: Assign a custom domain for clean streaming URLs.

Always-On Availability: Your stream server remains accessible 24/7 for continuous monitoring applications.

Note: For camera streaming, uStreamer typically runs directly on the device with the camera attached. This guide covers deploying uStreamer on Klutch.sh for scenarios where you’re relaying streams or building stream infrastructure.

Prerequisites

Before deploying uStreamer on Klutch.sh, ensure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your configuration
  • Basic familiarity with Docker and video streaming concepts
  • A video source (USB camera, IP camera, or stream relay scenario)

Understanding uStreamer Architecture

uStreamer is designed for simplicity and performance:

V4L2 Capture: Interfaces with Video4Linux2 devices to capture video frames directly from hardware.

JPEG Encoding: Compresses frames to JPEG format, optionally using hardware acceleration on supported platforms.

HTTP Server: Built-in web server that delivers MJPEG streams and static snapshots to clients.

Stream Multiplexing: Efficiently serves the same stream to multiple clients without re-encoding.

Stream Endpoints

EndpointDescription
/streamLive MJPEG video stream
/snapshotSingle JPEG frame capture
/stateJSON status and statistics
/Simple web viewer (if enabled)

Preparing Your Repository

To deploy uStreamer on Klutch.sh, create a GitHub repository containing your configuration.

Repository Structure

ustreamer-deploy/
├── Dockerfile
├── start.sh
├── README.md
└── .dockerignore

Creating the Dockerfile

Create a Dockerfile for uStreamer:

FROM debian:bookworm-slim AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libevent-dev \
libjpeg-dev \
libbsd-dev \
git \
&& rm -rf /var/lib/apt/lists/*
# Clone and build uStreamer
WORKDIR /build
RUN git clone --depth 1 https://github.com/pikvm/ustreamer.git .
RUN make
FROM debian:bookworm-slim
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
libevent-2.1-7 \
libjpeg62-turbo \
libbsd0 \
v4l-utils \
&& rm -rf /var/lib/apt/lists/*
# Copy built binary
COPY --from=builder /build/ustreamer /usr/local/bin/ustreamer
COPY --from=builder /build/ustreamer-dump /usr/local/bin/ustreamer-dump
# Copy start script
COPY start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh
# Create non-root user
RUN useradd -m -s /bin/bash streamer
USER streamer
# Environment variables
ENV HOST=0.0.0.0
ENV PORT=8080
ENV DEVICE=/dev/video0
ENV RESOLUTION=1280x720
ENV FPS=30
ENV FORMAT=MJPEG
# Expose streaming port
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/state || exit 1
# Start uStreamer
CMD ["/usr/local/bin/start.sh"]

Start Script

Create a start.sh script for flexible configuration:

#!/bin/bash
# Parse resolution
WIDTH=$(echo $RESOLUTION | cut -d'x' -f1)
HEIGHT=$(echo $RESOLUTION | cut -d'x' -f2)
# Build uStreamer command
exec ustreamer \
--host=${HOST:-0.0.0.0} \
--port=${PORT:-8080} \
--device=${DEVICE:-/dev/video0} \
--resolution=${RESOLUTION:-1280x720} \
--desired-fps=${FPS:-30} \
--format=${FORMAT:-MJPEG} \
--quality=${QUALITY:-80} \
--workers=${WORKERS:-3} \
--drop-same-frames=${DROP_FRAMES:-30} \
${EXTRA_ARGS}

Creating the .dockerignore File

Create a .dockerignore file:

.git
.github
*.md
LICENSE
.gitignore
*.log
.DS_Store

Environment Variables Reference

VariableRequiredDefaultDescription
HOSTNo0.0.0.0Bind address for HTTP server
PORTNo8080HTTP server port
DEVICENo/dev/video0Video capture device
RESOLUTIONNo1280x720Capture resolution (WxH)
FPSNo30Target frames per second
FORMATNoMJPEGCapture format (MJPEG, YUYV, etc.)
QUALITYNo80JPEG quality (1-100)
WORKERSNo3Encoder worker threads
DROP_FRAMESNo30Drop identical frames threshold
EXTRA_ARGSNo-Additional uStreamer arguments

Deploying uStreamer on Klutch.sh

Once your repository is prepared, follow these steps to deploy:

    Push Your Repository to GitHub

    Initialize your repository and push to GitHub:

    Terminal window
    git init
    git add Dockerfile start.sh .dockerignore
    git commit -m "Initial uStreamer configuration"
    git remote add origin https://github.com/yourusername/ustreamer-deploy.git
    git push -u origin main

    Create a New Project on Klutch.sh

    Navigate to the Klutch.sh dashboard and create a new project. Name it something descriptive like “ustreamer” or “camera-stream”.

    Create a New App

    Within your project, create a new app. Connect your GitHub account and select your uStreamer repository.

    Configure HTTP Traffic

    uStreamer serves streams over HTTP:

    • Select HTTP as the traffic type
    • Set the internal port to 8080

    Set Environment Variables

    Configure streaming parameters:

    VariableValue
    RESOLUTION1280x720 (or your preferred resolution)
    FPS30 (or your preferred frame rate)
    QUALITY80 (JPEG quality)

    Deploy Your Application

    Click Deploy to start the build process. Klutch.sh will:

    • Build uStreamer from source
    • Create the container image
    • Start the streaming server
    • Provision an HTTPS certificate

    Access Your Stream

    Once deployed, access:

    • Live stream: https://your-app.klutch.sh/stream
    • Snapshot: https://your-app.klutch.sh/snapshot
    • Status: https://your-app.klutch.sh/state

Stream Configuration

Resolution Options

Common resolution settings:

ResolutionUse Case
640x480Low bandwidth, many viewers
1280x720HD quality, balanced
1920x1080Full HD, high bandwidth
3840x21604K (requires powerful hardware)

Quality Settings

Balance quality and bandwidth:

QualityBandwidthUse Case
50-60LowMobile networks
70-80MediumGeneral use
85-95HighLocal networks

Frame Rate Considerations

  • 30 FPS: Standard for most monitoring
  • 15-20 FPS: Reduced bandwidth for limited connections
  • 60 FPS: Smooth motion for fast-moving subjects

Viewing the Stream

Browser Viewing

Access the stream directly in any web browser at /stream. Most browsers natively support MJPEG streams.

HTML Embedding

Embed the stream in web pages:

<img src="https://your-app.klutch.sh/stream" alt="Live Stream" />

OBS Integration

Add the stream as a media source in OBS using the stream URL.

VLC Playback

Open the stream URL directly in VLC Media Player for external viewing.

Production Best Practices

Security Recommendations

  • Authentication: Consider adding a reverse proxy with authentication for private streams
  • HTTPS: Always use HTTPS for public-facing streams
  • Access Control: Restrict access to trusted viewers when necessary

Performance Optimization

  • Resolution Matching: Use native camera resolution when possible
  • Hardware Encoding: Leverage GPU acceleration on supported platforms
  • Worker Threads: Adjust worker count based on CPU availability
  • Frame Dropping: Enable frame dropping for identical frames to save bandwidth

Bandwidth Management

  • Quality Adjustment: Lower quality for bandwidth-limited scenarios
  • Resolution Scaling: Reduce resolution for many concurrent viewers
  • Frame Rate Reduction: Lower FPS for slow connections

Troubleshooting Common Issues

No Video Output

Symptoms: Stream endpoint returns errors or blank output.

Solutions:

  • Verify video device is accessible
  • Check device permissions
  • Confirm camera is not in use by another process
  • Review uStreamer logs for errors

High Latency

Symptoms: Significant delay between action and stream display.

Solutions:

  • Enable frame dropping
  • Reduce quality setting
  • Lower resolution
  • Check network bandwidth

Connection Refused

Symptoms: Cannot connect to stream endpoints.

Solutions:

  • Verify container is running
  • Check port configuration
  • Confirm health check is passing
  • Review network settings

Poor Image Quality

Symptoms: Stream appears blocky or artifacts visible.

Solutions:

  • Increase JPEG quality setting
  • Check lighting conditions
  • Verify camera focus
  • Consider higher resolution

Additional Resources

Conclusion

Deploying uStreamer on Klutch.sh provides a lightweight, efficient video streaming solution for monitoring and observation applications. The combination of uStreamer’s minimal resource footprint and Klutch.sh’s deployment simplicity means you can set up reliable video streaming without complex infrastructure.

Whether you’re monitoring 3D printers, security cameras, or any other video source, uStreamer on Klutch.sh delivers low-latency streaming accessible from any web browser.