Strom (Swedish for "stream") is a visual, web-based interface for creating and managing GStreamer media pipelines. Design complex media flows without writing code.
Visual pipeline editor showing a simple test flow
- Visual Pipeline Editor - Node-based graph editor in your browser
- Real-time Control - Start, stop, and monitor pipelines via REST API or WebSocket
- Element Discovery - Browse and configure any installed GStreamer element
- Reusable Blocks - Create custom components from element groups (e.g., AES67 receiver)
- gst-launch Import/Export - Import existing
gst-launch-1.0commands or export flows to gst-launch syntax - SAP/AES67 Discovery - Browse and monitor network audio streams via SAP announcements
- PTP Clock Monitoring - View PTP synchronization status and statistics per domain
- Media File Browser - Manage media files for playlist playback
- System Monitoring - Real-time CPU, memory, and GPU usage graphs in the topbar
- Authentication - Secure with session login or API keys (optional)
- Auto-restart - Pipelines survive server restarts
- Native or Web - Run as desktop app or web service
- MCP Integration - Control pipelines with AI assistants (Claude, etc.)
- CI/CD - Automated testing, building, and releases for Linux, Windows, macOS, and ARM64
- Dynamic Pad Linking - Automatic handling of runtime-created pads (decodebin, demuxers)
- Automatic Tee Insertion - Fan-out outputs without manual configuration
- Pad Properties - Configure per-pad properties (e.g., volume/mute on audiomixer inputs)
- Debug Graphs - Generate SVG visualizations of running pipelines
- WebSocket/SSE - Real-time state updates and pipeline events
Get started with Strom instantly on Open Source Cloud - no installation required!
Deploy Strom with just a few clicks - perfect for testing, demos, or production workloads.
curl -sSL https://raw.githubusercontent.com/Eyevinn/strom/main/install.sh | bashThe interactive installer detects your OS, downloads the latest release, and installs GStreamer dependencies.
For CI/CD or scripted installs, use environment variables:
curl -sSL https://raw.githubusercontent.com/Eyevinn/strom/main/install.sh | AUTO_INSTALL=true GSTREAMER_INSTALL_TYPE=minimal bashAvailable options: AUTO_INSTALL, GSTREAMER_INSTALL_TYPE (full/minimal), SKIP_GSTREAMER, SKIP_GRAPHVIZ, INSTALL_DIR, VERSION.
After installation, run strom and open http://localhost:8080 in your browser.
Download the latest release for your platform from GitHub Releases:
# Linux
wget https://github.com/Eyevinn/strom/releases/latest/download/strom-v*-linux-x86_64
chmod +x strom-v*-linux-x86_64
./strom-v*-linux-x86_64
# macOS
# Download and run the macOS binary
# Windows
# Download and run the .exe fileOpen your browser to http://localhost:8080 to access the web UI.
# Pull and run the latest version
docker pull eyevinntechnology/strom:latest
docker run -p 8080:8080 -v $(pwd)/data:/data eyevinntechnology/strom:latest
# Or build locally
docker build -t strom .
docker run -p 8080:8080 -v $(pwd)/data:/data stromAccess the web UI at http://localhost:8080
# Install GStreamer
sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav \
gstreamer1.0-tools libnice-dev gstreamer1.0-nice graphviz
# Install Rust and tools
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown
cargo install trunk# Production mode (web UI at http://localhost:8080)
cargo run --release
# Development with hot reload
cargo run # Backend on :8080 (Terminal 1)
cd frontend && trunk serve # Frontend on :8095 (Terminal 2)
# Headless mode (API only)
cargo run --release -- --headlessOnce Strom is running:
- Open
http://localhost:8080in your browser - Browse available GStreamer elements in the palette
- Drag elements onto the canvas to create your pipeline
- Connect elements by dragging from output pads to input pads
- Configure element properties in the inspector panel
- Click "Start" to launch your pipeline
For API usage, visit http://localhost:8080/swagger-ui for interactive documentation.
Strom includes automated CI/CD pipelines for continuous integration, testing, and releases:
On every push to main and pull requests, automated checks run:
- Format Check - Ensures code follows Rust formatting standards
- Clippy Linting - Static analysis for backend, MCP server, and frontend (WASM)
- Test Suite - Runs all tests for backend and MCP server
- Multi-platform Builds - Builds binaries for Linux, Windows, and macOS
When a version tag is pushed (e.g., v0.1.0):
- Cross-platform Binaries - Automatically builds for Linux, Windows, and macOS
- GitHub Releases - Creates release with binaries and generated release notes
- Docker Publishing - Publishes multi-platform images (amd64/arm64) to Docker Hub
Pre-built multi-architecture Docker images are available (amd64 and arm64):
docker pull eyevinntechnology/strom:latest
docker pull eyevinntechnology/strom:0.2.6 # Specific version┌─────────────────────────────────┐
│ Frontend (egui → WebAssembly) │
│ - Visual flow editor │
│ - Element palette │
│ - Property inspector │
└────────────┬────────────────────┘
│ REST + WebSocket/SSE
┌────────────▼────────────────────┐
│ Backend (Rust + Axum) │
│ - Flow manager │
│ - GStreamer integration │
│ - Block registry (AES67, ...) │
│ - Storage (JSON or PostgreSQL) │
└─────────────────────────────────┘
Workspace Members:
strom-types- Shared domain models and API typesstrom- Server with GStreamer pipeline managementstrom-frontend- egui UI (compiles to WASM or native)strom-mcp-server- Model Context Protocol server for AI integration
Flows
GET/POST/DELETE /api/flows- Manage pipeline configurationsPOST /api/flows/:id/start- Start pipelinePOST /api/flows/:id/stop- Stop pipeline
Elements
GET /api/elements- List available GStreamer elementsGET /api/elements/:name- Get element details and properties
Blocks
GET/POST/DELETE /api/blocks- Manage reusable component definitionsGET /api/blocks/categories- List block categories
Real-time
GET /api/events- Server-Sent Events streamWS /api/ws- WebSocket connection
See OpenAPI docs at /swagger-ui when server is running.
Strom supports importing and exporting pipelines using standard gst-launch-1.0 syntax, making it easy to convert existing command-line pipelines to visual flows.
Import:
- Paste any
gst-launch-1.0command directly into the import dialog - Supports multiline pipelines with backslash continuations
- Handles element references for complex pipelines (e.g.,
name=mux ... mux.) - Automatically strips command prefixes and flags (
-v,-e, etc.)
Export:
- Convert visual flows back to
gst-launch-1.0syntax - Useful for documentation, sharing, or running pipelines outside Strom
Example - Import a test pipeline:
gst-launch-1.0 -v videotestsrc is-live=true ! x264enc ! mp4mux name=mux ! filesink location=test.mp4 audiotestsrc is-live=true ! lamemp3enc ! mux.API Endpoints:
POST /api/gst-launch/parse- Parse gst-launch string to flowPOST /api/gst-launch/export- Export flow to gst-launch string
Configure Strom using config files, command-line arguments, or environment variables.
Settings are applied in this order (highest to lowest priority):
- Command-line arguments
- Environment variables
- Local config file (
.strom.tomlin current directory) - User config file (
~/.config/strom/config.tomlon Linux) - Default values
Create a .strom.toml file in your project directory:
# Copy the example config
cp .strom.toml.example .strom.toml
# Edit with your settings
nano .strom.tomlSee .strom.toml.example for all available options and documentation.
# Server
--port 8080 # or STROM_SERVER_PORT=8080
# Storage - PostgreSQL (recommended for production)
--database-url postgresql://user:pass@localhost/strom # or STROM_STORAGE_DATABASE_URL=...
# Storage - JSON files (default)
--data-dir /path/to/data # or STROM_STORAGE_DATA_DIR=/path/to/data
--flows-path /custom/flows.json # or STROM_STORAGE_FLOWS_PATH=/custom/flows.json
--blocks-path /custom/blocks.json # or STROM_STORAGE_BLOCKS_PATH=/custom/blocks.json
# Logging
RUST_LOG=infoPostgreSQL (Recommended for production):
- Set
STROM_DATABASE_URLto use PostgreSQL for flow storage - Supports multiple isolated instances sharing one PostgreSQL server
- Automatic schema migrations on startup
- See docs/POSTGRESQL.md for setup guide
JSON Files (Default):
- Used when
STROM_DATABASE_URLis not set - Simple file-based storage
Default storage locations:
- Docker:
./data/(current directory) - Linux:
~/.local/share/strom/ - Windows:
%APPDATA%\strom\ - macOS:
~/Library/Application Support/strom/
Note: Individual file paths (--flows-path, --blocks-path) override --data-dir.
Strom supports two authentication methods to protect your installation:
Perfect for web UI access with username/password login.
Setup:
# Generate a password hash
cargo run -- hash-password
# Or with Docker:
docker run eyevinntechnology/strom:latest hash-password
# Enter your desired password when prompted
# Copy the generated hashConfigure environment variables:
export STROM_ADMIN_USER="admin"
export STROM_ADMIN_PASSWORD_HASH='$2b$12$...' # Use single quotes to preserve special characters
# Run Strom
cargo run --releaseUsage:
- Navigate to
http://localhost:8080 - Login with your configured username and password
- Session persists for 24 hours of inactivity
- Click "Logout" button in the top-right to end session
Perfect for programmatic access, scripts, and CI/CD.
Setup:
export STROM_API_KEY="your-secret-api-key-here"
# Run Strom
cargo run --releaseUsage:
# All API requests must include the Authorization header
curl -H "Authorization: Bearer your-secret-api-key-here" \
http://localhost:8080/api/flowsYou can enable both authentication methods simultaneously:
# Enable both session and API key authentication
export STROM_ADMIN_USER="admin"
export STROM_ADMIN_PASSWORD_HASH='$2b$12$...'
export STROM_API_KEY="your-secret-api-key-here"
cargo run --releaseUsers can then:
- Login via web UI with username/password
- Access API with Bearer token
docker run -p 8080:8080 \
-e STROM_ADMIN_USER="admin" \
-e STROM_ADMIN_PASSWORD_HASH='$2b$12$...' \
-e STROM_API_KEY="your-api-key" \
-v $(pwd)/data:/data \
eyevinntechnology/strom:latestAuthentication is disabled by default if no credentials are configured. To run without authentication (development only):
# Simply run without setting auth environment variables
cargo run --releaseWhen authentication is enabled, all API endpoints except the following require authentication:
GET /health- Health checkPOST /api/login- Login endpointPOST /api/logout- Logout endpointGET /api/auth/status- Check auth status- Static assets (frontend files)
Create reusable components from element groups:
Inputs:
- Media Player - File and playlist playback with position tracking, loop support, and decode/passthrough modes
- AES67 Input - Receives AES67/Ravenna audio via RTP multicast using SDP
- WHEP Input - Receives audio/video via WebRTC WHEP protocol
- DeckLink Video/Audio Input - Captures from Blackmagic DeckLink SDI/HDMI cards
- Inter Input - Subscribes to streams from other flows (inter-pipeline routing)
Outputs:
- AES67 Output - Sends AES67/Ravenna audio via RTP multicast with SDP generation
- WHIP Output - Sends audio via WebRTC WHIP protocol
- MPEG-TS/SRT Output - Muxes audio/video to MPEG Transport Stream over SRT
- DeckLink Video/Audio Output - Outputs to Blackmagic DeckLink SDI/HDMI cards
- Inter Output - Publishes streams for other flows to consume
Processing:
- Video Encoder - H.264/H.265/AV1/VP9 with automatic hardware acceleration (NVENC, QSV, VA-API, AMF, software)
- Video Format - Resolution, framerate, and pixel format conversion
- Audio Format - Sample rate, channels, and PCM format conversion (supports surround sound)
- Video Compositor - Multi-input compositing with GPU (OpenGL) and CPU backends
Analysis:
- Audio Meter - RMS and peak level monitoring per channel
Custom blocks can also be created via JSON or API.
See docs/BLOCKS_IMPLEMENTATION.md and docs/VIDEO_ENCODER_BLOCK.md for details.
Enable AI assistants to manage pipelines:
# Start MCP server
cd mcp-server
cargo run
# Configure in Claude Desktop
# See mcp-server/README.mdExample: "Create a flow that encodes video to H.264 and streams via SRT"
# Clone the repository
git clone https://github.com/Eyevinn/strom.git
cd strom
# Install GStreamer dependencies
sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav \
gstreamer1.0-tools libnice-dev gstreamer1.0-nice graphviz
# Install Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown
cargo install trunk
# Install git hooks for automated checks
./scripts/install-hooks.shStrom includes comprehensive tests to ensure quality and reliability.
# Run all tests across the workspace
cargo test --workspace
# Run tests with output
cargo test --workspace -- --nocapture
# Run tests for specific package
cargo test --package strom
cargo test --package strom-mcp-server
cargo test --package strom-types# Run a specific test by name
cargo test test_name
# Run tests matching a pattern
cargo test pipeline
# Run integration tests only
cargo test --test '*'# Format code (required before committing)
cargo fmt --all
# Check formatting without modifying files
cargo fmt --all -- --check
# Run linter (Clippy)
cargo clippy --workspace -- -D warnings
# Lint specific packages
cargo clippy --package strom --all-targets --all-features -- -D warnings
cargo clippy --package strom-frontend --target wasm32-unknown-unknown -- -D warnings# Build frontend for development
cd frontend
trunk serve
# Build frontend for production
trunk build --release
# Check frontend compiles for WASM
cargo check --package strom-frontend --target wasm32-unknown-unknownTo test Strom manually:
-
Start the backend:
cargo run --package strom
-
Access the UI: Open
http://localhost:8080in your browser -
Test a simple pipeline:
- Add a
videotestsrcelement - Add an
autovideosinkelement - Connect them and click "Start"
- You should see a test pattern window
- Add a
-
Test the API:
# List all flows curl http://localhost:8080/api/flows # Get available elements curl http://localhost:8080/api/elements # View API documentation open http://localhost:8080/swagger-ui
# Build Docker image locally
docker build -t strom:test .
# Run and test
docker run -p 8080:8080 strom:test
# Test with custom data directory
docker run -p 8080:8080 -v $(pwd)/test-data:/data strom:testThe git hooks run these checks automatically before each commit:
- Code formatting (
cargo fmt) - Linting (
cargo clippy) - Tests (
cargo test)
If any check fails, the commit is blocked until issues are resolved.
strom/
├── types/ # Shared types (flows, elements, blocks, API)
├── backend/ # Axum server + GStreamer integration
│ └── src/
│ ├── api/ # REST endpoints
│ ├── gst/ # Pipeline management
│ └── blocks/ # Block registry and built-ins
├── frontend/ # egui UI (WASM/native)
├── mcp-server/ # AI assistant integration
└── docs/ # Documentation
├── BLOCKS_IMPLEMENTATION.md
├── CONTRIBUTING.md
└── TODO.md
Some GStreamer elements cause segfaults during introspection and are automatically skipped:
- GES elements (gesdemux, gessrc)
- HLS elements (hlssink*, hlsdemux*)
- Certain aggregator elements require special handling
See docs/PAD_TEMPLATE_CRASH_FIX.md and docs/MPEGTSMUX_DEADLOCK_FIX.md for technical details.
MIT OR Apache-2.0