zwfm-encoder

command module
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 17, 2025 License: MIT Imports: 21 Imported by: 0

README

ZuidWest FM Encoder

Audio streaming software for ZuidWest FM and Radio Rucphen. Stream audio from a Raspberry Pi to multiple SRT destinations simultaneously. Built for broadcast environments with real-time monitoring and web-based configuration.

Raspberry Pi and SRT logo

Features

  • Multi-output streaming - Send to multiple SRT servers with different codecs simultaneously
  • Real-time VU meters - Peak hold (1.5s) with Peak/RMS toggle, clip detection, updated via WebSocket
  • Silence detection - Alerts via webhook, email, or file log when audio drops below threshold
  • Web interface - Configure outputs, select audio input, monitor levels
  • Auto-recovery - Automatic reconnection with configurable retry limits per output
  • Multiple codecs - MP3, MP2, OGG Vorbis, or uncompressed WAV per output
  • Update notifications - Alerts when new versions are available
  • Single binary - Web interface embedded, minimal runtime dependencies

Requirements

Installation

  1. Install Raspberry Pi OS Trixie Lite (64-bit)
  2. Configure HiFiBerry following the official guide
  3. Run the installer as root:
sudo su
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/oszuidwest/zwfm-encoder/main/deploy/install.sh)"

The web interface will be available at http://<raspberry-pi-ip>:8080

Default credentials: admin / encoder

Audio Input

Connect the digital output of your audio processor to the HiFiBerry input.

Requirements:

  • 48 kHz sample rate
  • 16-bit depth
  • SPDIF format preferred (AES/EBU may work but is not guaranteed)

Codecs

Codec Encoder Bitrate
MP3 libmp3lame 320 kbit/s
MP2 libtwolame 384 kbit/s
OGG libvorbis ~500 kbit/s (Q10)
WAV pcm_s16le Uncompressed

Silence Detection

Monitors audio levels and sends alerts when silence is detected or recovered. Uses hysteresis to prevent alert flapping:

Setting Default Range Description
Threshold -40 dB -60 to 0 Audio level below which silence is detected
Duration 15 s 1-300 Seconds of silence before alerting
Recovery 5 s 1-60 Seconds of audio before considering recovered

Alerting options (can use multiple simultaneously):

  • Webhook - POST request to a URL on silence start and recovery
  • Email - SMTP notification to configured recipients on silence start and recovery
  • File Log - Append JSON Lines to a local file for each silence event

Configure via the web interface under Settings → Alerts.

Configuration

Configuration is stored in /etc/encoder/config.json:

{
  "web_port": 8080,
  "web_user": "admin",
  "web_password": "encoder",
  "audio_input": "default:CARD=sndrpihifiberry",
  "silence_threshold": -40,
  "silence_duration": 15,
  "silence_recovery": 5,
  "silence_webhook": "https://example.com/alert",
  "silence_log_path": "/var/log/encoder/silence.jsonl",
  "email_smtp_host": "smtp.example.com",
  "email_smtp_port": 587,
  "email_username": "alerts@example.com",
  "email_password": "secret",
  "email_recipients": "admin@example.com, tech@example.com",
  "outputs": [
    {
      "id": "output-1",
      "host": "srt.example.com",
      "port": 9000,
      "streamid": "studio",
      "password": "secret",
      "codec": "mp3",
      "max_retries": 99
    }
  ]
}

Architecture

flowchart LR
    subgraph Input
        A[Audio Source<br>S/PDIF]
    end

    subgraph Capture
        B[arecord<br>Raw PCM]
    end

    subgraph Distribution
        C[Go Distributor<br>Level Metering<br>Silence Detection]
    end

    subgraph Encoding
        D1[FFmpeg MP3]
        D2[FFmpeg MP2]
        D3[FFmpeg OGG]
    end

    subgraph Output
        E1[SRT Server 1]
        E2[SRT Server 2]
        E3[SRT Server 3]
    end

    subgraph Monitoring
        F[Web Interface<br>WebSocket]
    end

    subgraph Alerts
        G1[Webhook]
        G2[Email]
        G3[File Log]
    end

    A --> B --> C
    C --> D1 --> E1
    C --> D2 --> E2
    C --> D3 --> E3
    C -.->|levels| F
    C -.->|silence| G1
    C -.->|silence| G2
    C -.->|silence| G3

On Linux, arecord captures audio from ALSA with minimal CPU overhead. The Go distributor calculates RMS/peak audio levels directly from the PCM stream, runs silence detection, and fans out the audio to multiple FFmpeg encoder processes. Each encoder streams to its own SRT destination. Audio levels are sent to the web interface via WebSocket, and silence events trigger configured alerts.

On macOS (for development), FFmpeg with AVFoundation is used for capture instead of arecord.

Post-installation

Optional cleanup to reduce attack surface:

# Disable WiFi
echo "dtoverlay=disable-wifi" >> /boot/firmware/config.txt

# Remove unnecessary packages
apt remove bolt bluez ntfs-3g rsyslog telnet

SRT Resources

License

MIT License - See LICENSE.md

Documentation

Overview

Package main implements an audio streaming encoder that captures audio from digital input and streams to multiple SRT destinations.

Usage:

encoder [-config path/to/config.json]

If -config is not specified, the encoder looks for config.json in the same directory as the binary.

Directories

Path Synopsis
internal
audio
Package audio provides audio processing utilities including level metering and silence detection.
Package audio provides audio processing utilities including level metering and silence detection.
config
Package config provides application configuration management.
Package config provides application configuration management.
encoder
Package encoder provides the audio capture and encoding engine.
Package encoder provides the audio capture and encoding engine.
notify
Package notify provides notification services for silence alerts.
Package notify provides notification services for silence alerts.
output
Package output manages FFmpeg output processes for streaming.
Package output manages FFmpeg output processes for streaming.
server
Package server provides the HTTP server and WebSocket handler for the web interface.
Package server provides the HTTP server and WebSocket handler for the web interface.
types
Package types provides shared type definitions used across the encoder.
Package types provides shared type definitions used across the encoder.
util
Package util provides shared utility functions used across the encoder.
Package util provides shared utility functions used across the encoder.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL