Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

41 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Pipeline Controller

Professional GStreamer-based broadcast playout system (channel-in-a-box) for Linux – with an HTML5 web interface, oGraf graphics engine, and plugin system.

Node.js GStreamer Platform oGraf License


πŸ“Ί What is Pipeline Controller?

Pipeline Controller is a complete broadcast playout system built on the open-source framework GStreamer. It enables professional on-air operations through a modern, fully browser-based web interface β€” designed for 24/7 channel-in-a-box operations. image

Features at a glance

  • 🎬 dynamic configureable amount of independent media players (MXF, MP4, MOV, TS, …)
  • 🎚️ Master pipeline with compositor, video switcher, and audio mixing
  • πŸ”Š Flexible audio routing with multiple groups, channel matrices, and 5.1 upmix
  • πŸ“Š EBU R128 loudness normalization per audio group
  • ✨ oGraf HTML5 graphics engine (EBU standard) via Puppeteer/Chromium with templates
  • πŸ“‹ Playlist engine with transitions (cut, v-fade, cut-fade, fade-cut, X-fade) and event children
  • 🧩 Asset Panel for one-click commercial breaks with auto-return (interrupt / break / live modes)
  • ⏱️ Counter Strip showing all time-critical events of the current hour at a glance
  • πŸŽ™οΈ Voiceover engine with fade-in/out and program ducking
  • πŸ”Œ Plugin system running in isolated worker threads (crash-safe playout)
  • πŸ” Optional Bearer-token authentication with role-based access (admin/editor/grafiker/viewer)
  • 🌐 Full REST API, SSE event stream, and HTTPS support
  • πŸ• PTP clock support (IEEE 1588 / SMPTE 2110) and DST-safe scheduling
  • 🌍 Bilingual UI (English / German) with light/dark mode
  • πŸ“Ί Multi-channel supervisor β€” run several independent channels/playlists per host (e.g. a main channel + a sign-language variant), each with its own data dir/port, with a central dashboard
  • πŸ”— ChannelBus cross-channel triggers β€” send NEXT/NEXT_LIVE/JUMP/CUT commands between channels (or hosts), including playlist-item-bound trigger children with frame-accurate pre-roll
  • πŸ”² DVE / Squeeze β€” squeeze the program/live video into a positioned box (or squeeze an image/oGraf overlay over full-screen video), with green-screen auto-detection and chroma-key transparency for frame graphics
  • πŸ“€ Additional outputs β€” any number of extra downconverted network outputs (RTMP/SRT/UDP/file) or DeckLink SDI/HDMI hardware sinks, independent of the main program path
  • πŸ“‘ DMF/MXL live sources β€” EBU/AMWA Media eXchange Layer shared-memory flows as live sources (real mxlsrc/mxlsink GStreamer plugin), with in-UI feed discovery/selection
  • πŸ“Ί SCTE-35 splice cue generator β€” generate SCTE-35 splice_insert/splice_null as MPEG-TS/UDP, triggered by playlist events, classification (commercial/promo), block_start/block_end events, or manual cue from the UI
  • ⚠️ Transition timing validation β€” automatic warnings when clips are too short for configured crossfade/fade transitions (πŸ”€βš  badge on playlist event + toast in editor)
  • πŸ”‡ Audio Preset Resilience β€” automatic fallback when a clip has fewer audio channels than the selected preset requires: static pre-cue check (before playout) and live EBU-silence detection (during playout, hot-swap without interruption). Global fallback chain + optional per-event override, both configurable via an interactive drag-and-drop chip builder in the UI
  • πŸ”€ Per-Track Audio Silence Fallback β€” when a specific audio group (e.g. 5.1 surround) is detected silent while a fallback group (e.g. stereo program) carries signal, only that group's routing matrix is hot-patched without affecting other groups. Automatic up-/downmix (LoRo / LtRt / sum) when channel counts differ. Restores to the original preset matrix when audio returns
  • πŸŽ›οΈ Stream Deck WebHID β€” direct hardware button surface control from the browser (Chrome/Edge, no drivers needed). Fully dynamic pages for playlist control, live source switching, asset playback, oGraf take/takeout, SCTE-35 cues, and branding selection. Plugin-extensible: any plugin can register its own Stream Deck page

πŸš€ Quick Start

Option 1: Installer Package (recommended for production / remote installs)

Native Node.js installation β€” no AppImage required:

# On a target machine: download & install
tar -xzf PipelineController-1.0.1.tar.gz
cd PipelineController-1.0.1
bash install.sh          # ⚠️ never with sudo!

# Start
bash ~/pipeline-controller/start.sh
# or as systemd user-service (if enabled during install)
systemctl --user start pipeline-controller

The installer verifies Node.js β‰₯ 18, all required GStreamer plugins (intervideosrc, interaudiosrc, compositor, …), installs missing dependencies via apt-get, sets up runtime directories, and configures settings.json paths correctly for the target machine.

Option 2: AppImage

chmod +x PipelineController-x86_64.AppImage

# IMPORTANT: extract the AppImage (do not run it directly!)
./PipelineController-x86_64.AppImage --appimage-extract
cd squashfs-root
./AppRun

⚠️ Important: The AppImage must be extracted β€” the oGraf graphics engine (Puppeteer/Chromium) requires access to the real filesystem and cannot run from a FUSE-mounted AppImage.

Option 3: From source

# Node.js β‰₯ 18 required
nvm install 20 && nvm use 20

sudo apt install build-essential libgstreamer1.0-dev \
  libgstreamer-plugins-base1.0-dev \
  gstreamer1.0-{tools,plugins-base,plugins-good,plugins-bad,plugins-ugly,libav,x,alsa,gl} \
  pulseaudio

npm install
node server.js

Then open in your browser: http://localhost:3000

Option 4: Multi-channel (several playlists on one host)

node supervisor.js channels.json

Opens a dashboard at http://localhost:3099 listing all configured channels, each running as its own isolated server.js process (own port, own data dir). See Multi-Channel Operation in the manual.


πŸ“‹ System Requirements

Component Requirement
Operating System Linux x86_64, kernel β‰₯ 5.4 (Debian 12 / Ubuntu 22.04 recommended)
Node.js β‰₯ 18
GStreamer β‰₯ 1.22 (with plugins-bad for intervideosrc, compositor, …)
X11 display Required for ximagesink (use fakesink for headless)
Audio PulseAudio (recommended) or ALSA
Python 3 Only required for the Marina Sync plugin
RAM β‰₯ 2 GB (4 GB recommended)

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Web UI (HTML5 SPA Β· DE / EN)                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ REST + SSE  (HTTP / HTTPS)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Node.js Server (server.js)                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Playlist Engine  β”‚ Graphics Engine β”‚  Voiceover    β”‚   β”‚
β”‚  β”‚  Audio Router     β”‚ Plugin Host     β”‚  Media Lib    β”‚   β”‚
β”‚  β”‚  Auth + Roles     β”‚ User Log        β”‚  Asset Engine β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ gst-kit (native bindings)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  GStreamer Pipelines                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ Player 1 β”‚  β”‚ Player 2 β”‚  β”‚ Player 3 β”‚β†’β”‚  Master    β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  Pipeline  β”‚ β”‚
β”‚                                              β”‚ (Compositor)β”‚ β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                       β”‚ + Switcher β”‚ β”‚
β”‚  β”‚ oGraf (Chromium) │──────────────────────→│ + AudioMix β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                   β–Ό
                                    Video Sink + Audio Sinks

Master Pipeline (actual GStreamer element graph)

Auto-generated graph of the running master pipeline (compositor, video switcher, audio mixer/router, sinks):

Pipeline element graph


🎨 oGraf Graphics Engine

Pipeline Controller is built on the EBU oGraf standard for HTML5 broadcast graphics.

Playlist Variables

Graphics can pull live data from the playlist using a powerful variable syntax β€” automatically resolved when the graphic appears on screen:

{{next[class(movie)]:title}}                  β†’ next movie's title
{{next[title(News)]:starttime|unixms}}        β†’ countdown target as Unix ms
{{current:classifcolor}}                      β†’ dynamic accent color
{{next2[class(movie)]:starttime|HH:MM}}       β†’ 2nd next movie's start time

Numeric formats (unix, unixms, countdown, countdownms) return real JS numbers β€” perfect for template fields of type integer or number. An interactive {{…}}-builder is available in the UI for every text/number field.

See the manual for the full syntax.


πŸ”Œ Plugin System

Plugins run in isolated worker threads β€” a plugin crash has no impact on the running playout.

Plugin Description Default
πŸ“ File Transfer Manager Automatic FTP/FTPS/local transfer & cache management βœ… enabled
πŸŽ›οΈ Broadcast Controller Control external routers (SW-P-08, EVS Cerebrum, HTTP, TCP) disabled
πŸ“Ί SCTE-35 Cue Generator Generate SCTE-35 splice cues as MPEG-TS/UDP from playlist events, classifications, or manual trigger disabled
πŸ›₯️ Marina Sync Auto-sync playlist from Pebble Beach Marina (.mpl watchfolder, on-air resume) disabled
πŸ“‘ SNMP Monitor Monitor broadcast devices via SNMP v1/v2c/v3 disabled
πŸ’¬ Subtitle FAB Live subtitle control via FAB Subtitle Server disabled

Custom plugins can be developed in just a few lines of code – see plugin development in the manual.


πŸ” User Management

Optional role-based access control with Bearer tokens. Disabled by default β€” enable it under Settings β†’ Users when the system is reachable from untrusted networks.

Role Access
admin Full access β€” user management, all settings, plugins
editor Playlist control, media library, plugin management
grafiker Graphics only (oGraf templates, take/out, hotkeys)
viewer Read-only β€” live state, SSE stream, no actions

All login, logout, and write operations are logged to a JSONL audit log (configurable path). Passwords are stored as SHA-256 hashes.


πŸ“‘ REST API & SSE

Full control via HTTP β€” for example:

# Start the master pipeline
curl -X POST http://localhost:3000/api/master/start

# Cue a clip
curl -X POST http://localhost:3000/api/player/1/cue \
  -H "Content-Type: application/json" \
  -d '{"file":"news.mxf","som":"00:00:00:00","eom":"00:05:30:00"}'

# Show a graphic
curl -X POST http://localhost:3000/api/grafik/show \
  -H "Content-Type: application/json" \
  -d '{"template":"lower-third","data":{"headline":"Max Mustermann"}}'

Real-time updates via Server-Sent Events:

const es = new EventSource('http://localhost:3000/events');
es.addEventListener('audio-level', e => {
  const { levels } = JSON.parse(e.data);
  // levels: { "pgm-stereo": { rms: -18.5, peak: -14.2 }, ... }
});

Full API reference: Manual β†’ REST API


πŸ”’ HTTPS / TLS (optional)

Enable HTTPS as a parallel server port via settings.json or environment variables:

HTTPS_KEY=/path/to/key.pem \
HTTPS_CERT=/path/to/cert.pem \
HTTPS_PORT=3443 \
node server.js

The plain HTTP port stays active in parallel (useful for local access).


πŸ“ Project Structure

pipeline-controller/
β”œβ”€β”€ server.js               # Main server (one process = one channel)
β”œβ”€β”€ supervisor.js           # Multi-channel supervisor + dashboard
β”œβ”€β”€ channels.json           # Multi-channel config (id/dataDir/port per channel)
β”œβ”€β”€ ui.html                 # Web interface (SPA)
β”œβ”€β”€ settings.json           # Settings (auto-generated)
β”œβ”€β”€ audio_config.json       # Audio groups + presets + clock
β”œβ”€β”€ plugins.json            # Plugin configurations
β”œβ”€β”€ users.json              # Users (SHA-256 password hashes)
β”œβ”€β”€ lib/                    # Backend modules
β”‚   β”œβ”€β”€ MasterPipeline.js
β”‚   β”œβ”€β”€ PlayerPipeline.js
β”‚   β”œβ”€β”€ AudioRouter.js
β”‚   β”œβ”€β”€ PlaylistEngine.js
β”‚   β”œβ”€β”€ GrafixEngine.js
β”‚   β”œβ”€β”€ VoiceoverEngine.js
β”‚   β”œβ”€β”€ ChannelBus.js       # Cross-channel/cross-host trigger bus
β”‚   β”œβ”€β”€ OutputEngine.js     # Additional downconvert/Cleanfeed/DeckLink outputs
β”‚   β”œβ”€β”€ GreenZoneDetect.js  # Green-screen box detection + chroma-key transparency
β”‚   β”œβ”€β”€ MxlSource.js        # DMF/MXL flow discovery (mxl-info wrapper)
β”‚   └── ...
β”œβ”€β”€ releases/               # Build artifacts (AppImage, tar.gz) β€” git-ignored, distributed via GitHub Releases
β”œβ”€β”€ plugins/                # Plugin system
β”‚   β”œβ”€β”€ broadcast-controller/
β”‚   β”œβ”€β”€ file-transfer-manager/
β”‚   β”œβ”€β”€ marina-sync/
β”‚   β”œβ”€β”€ scte35/
β”‚   └── ...
β”œβ”€β”€ scripts/
β”‚   └── install-mxl.sh      # Builds libmxl + gst-mxl-rs (mxlsrc/mxlsink) from source
β”œβ”€β”€ env/mxl.env              # DMF/MXL plugin paths (auto-generated by install-mxl.sh)
β”œβ”€β”€ templates/grafik/       # oGraf templates
β”œβ”€β”€ media/                  # Media files
β”œβ”€β”€ playlists/              # Saved playlists
β”œβ”€β”€ images/                 # Still images
β”œβ”€β”€ channelbranding/        # Branding overlays
└── asrun/                  # As-run logs (daily, txt)

πŸ“š Documentation


πŸ› οΈ Tech Stack

Component Version License
GStreamer 1.22+ LGPL 2.0+
Node.js 18+ MIT
Puppeteer 24+ Apache 2.0
gst-kit 0.2.5+ MIT
basic-ftp latest MIT
EBU oGraf v1 Open Standard

⚠️ Note on Codecs

gst-plugins-bad and gst-plugins-ugly include decoders for partly license-restricted formats (H.264, MPEG-2, AC-3, DTS). For commercial use with these codecs, licensing fees may apply. For testing and non-commercial use, the open-source implementations may be used freely.


πŸ› Bug Reports & Feature Requests

Please file issues via GitHub Issues. For bug reports, please include:

  • Linux distribution & version
  • GStreamer version (gst-launch-1.0 --version)
  • Node.js version (node --version)
  • Output of GST_DEBUG=*:2 node server.js 2> gst_debug.log
  • Relevant parts of settings.json (paths, video/audio sinks)

πŸ“„ License

The foundation (GStreamer, Node.js, Chromium, npm packages) is open source. The application-specific code is released under the terms defined in the LICENSE file.


Screenshots

Playlist Event Editor:
image

Player Section:
image

Ograf Editor: image

Manual Record:
image

Assets:
image

Pipeline Controller
Broadcast Playout System Β· GStreamer 1.22+ Β· Node.js 18+ Β· EBU oGraf
24/7 channel-in-a-box Β· Linux Β· Open-Source-based

About

Professional gstreamer based SMPTE 2110 ready tv broadcast channel in the box

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages