zwfm-encoder

command module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Dec 29, 2025 License: MIT Imports: 22 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.5 s) 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

Platform Support

Platform Status Audio Capture
Linux (Raspberry Pi) Primary arecord (ALSA)
macOS Development only FFmpeg (AVFoundation)
Windows Experimental FFmpeg (DirectShow)

Linux on Raspberry Pi is the primary supported platform. macOS support exists for local development. Windows support is experimental and not recommended for production use.

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
  • Stereo (2 channels)
  • S/PDIF format preferred (AES/EBU compatibility not guaranteed)

Codecs

Codec Encoder Bitrate Notes
MP3 libmp3lame 320 kbit/s
MP2 libtwolame 384 kbit/s Uses psymodel 4
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 to 300 Seconds of silence before alerting
Recovery 5 s 1 to 60 Seconds of audio before recovery

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 on production systems. For development, use the -config flag to specify a custom path, or place config.json next to the binary.

{
  "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[S/PDIF Audio]
    end

    subgraph Capture
        B[arecord]
    end

    subgraph Processing
        C[Distributor]
        SD[Silence Detector]
        SN[Silence Notifier]
    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[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 -.-> SD -.-> SN
    SN -.-> G1
    SN -.-> G2
    SN -.-> G3
    C -.->|levels| F

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 and Windows, FFmpeg handles audio capture (AVFoundation and DirectShow respectively).

Component Architecture
graph TB
    subgraph External Processes
        ARECORD[arecord]
        FFM1[FFmpeg 1]
        FFM2[FFmpeg 2]
        FFM3[FFmpeg n]
    end

    subgraph Go Application
        subgraph Engine
            ENCODER[Encoder]
            DIST[Distributor]
            OUTMGR[Output Manager]
        end

        subgraph Audio
            METER[Level Metering]
            SILENCE[Silence Detector]
        end

        subgraph Notifications
            NOTIFIER[Silence Notifier]
            WEBHOOK[Webhook]
            EMAIL[Email]
            FLOG[File Log]
        end

        subgraph HTTP
            SERVER[Server]
            WS[WebSocket]
        end
    end

    subgraph Outputs
        SRT1[SRT Server 1]
        SRT2[SRT Server 2]
        SRT3[SRT Server n]
    end

    ARECORD ==>|PCM| ENCODER
    ENCODER ==> DIST
    DIST ==> OUTMGR
    OUTMGR ==>|PCM| FFM1
    OUTMGR ==>|PCM| FFM2
    OUTMGR ==>|PCM| FFM3
    FFM1 ==>|SRT| SRT1
    FFM2 ==>|SRT| SRT2
    FFM3 ==>|SRT| SRT3

    DIST -.-> METER
    DIST -.-> SILENCE
    DIST -.->|levels| WS
    SILENCE -.-> NOTIFIER
    NOTIFIER -.-> WEBHOOK
    NOTIFIER -.-> EMAIL
    NOTIFIER -.-> FLOG
    SERVER -.-> ENCODER

Legend: ══► PCM/audio stream | ┄┄► control/data

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

Encoder is an audio streaming application 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