# MediaBridge -- SRT Gateway (Rust)

MediaBridge is a custom-built SRT gateway designed to act as the **data
plane** of a future professional streaming control platform.

This repository contains the **Rust-based SRT gateway**, built directly
on top of the Haivision SRT library, compiled from source inside Docker.

------------------------------------------------------------------------

# 🎯 Project Goal

MediaBridge aims to become:

-   A professional **SRT routing gateway**
-   A multi-stream publish/play relay
-   A future **control-plane + data-plane streaming platform**
-   A foundation for:
    -   Monitoring (RTT, packet loss, bitrate)
    -   Licensing
    -   Multi-tenant management
    -   Web preview (SRT → WebRTC)

This current version focuses exclusively on the **core SRT data-plane
logic**.

------------------------------------------------------------------------

# 🚀 Current Capabilities

## ✅ Custom SRT Build

-   Compiles **libSRT from source**
-   Rust FFI bindings via `bindgen`
-   Fully containerized with Docker

## ✅ Publish / Play Gateway

Supports two streamID formats:

### MediaBridge format

    mb:publish/<key>
    mb:play/<key>

Example:

    mb:publish/live/alpha
    mb:play/live/alpha

### Standard SRT hashbang format

    #!::m=publish,r=<key>
    #!::m=play,r=<key>

------------------------------------------------------------------------

## ✅ Stream Rules

-   One publisher per key
-   Publish policy is per stream (`publisher_strategy`: `replace` or `reject`)
-   Player limit is per stream (`max_players`, with `-1` = unlimited)
-   Max allowed bitrate is per stream (`max_bps`, in kbps)
-   Ring buffer relay (in-memory)

------------------------------------------------------------------------

## ✅ Allowlist Protection

Only stream entries defined in:

    config/allowlist.json

are accepted.

Expected allowlist entry format:

```json
{
  "allowed": [
    {
      "stream_id": "live/alpha",
      "publisher_strategy": "replace",
      "max_players": -1,
      "max_bps": 10000
    }
  ]
}
```

If the allowlist is empty → all streams are denied.

------------------------------------------------------------------------

## ✅ Health API (liveness/readiness)

MediaBridge now exposes dedicated health endpoints:

    GET /health/live
    GET /health/ready
    GET /health   (alias of /health/ready)
    GET /metrics
    GET /stats
    GET /stats/flows/{flowId}
    GET /stats/flows/{flowId}/publish
    GET /stats/flows/{flowId}/players
    GET /stats/flows/{flowId}/players/{connId}

Default bind:

    0.0.0.0:8080

Response format follows the current API health-check style (`status`,
`version`, `releaseId`, `serviceId`, `checks`) with statuses:

    pass | warn | fail

`/health/live` checks process liveness only.
`/health/ready` checks runtime readiness (allowlist, listener, SRT runtime,
flows, memory) and returns:

-   HTTP 200 for `pass` or `warn`
-   HTTP 503 for `fail`

`/metrics` returns Prometheus text format (`text/plain; version=0.0.4`).
Example metrics:

    mediabridge_ready 1
    mediabridge_active_flows 3
    mediabridge_stalled_flows 0
    mediabridge_active_connections 4
    mediabridge_accept_errors_total 0

`/stats` returns one unique object per flow (`flowId`) with links.
`/stats/flows/{flowId}` returns detailed data for one flow only.
`flowId` in path must be URL-encoded (example: `live/alpha` -> `live%2Falpha`).

Useful environment variables:

    HEALTH_BIND=0.0.0.0:8080
    SERVICE_ID=mediabridge
    SERVICE_DESCRIPTION=SRT gateway
    RELEASE_ID=dev
    STALLED_FLOW_MS=5000
    MEMORY_WARN_PERCENT=80
    MEMORY_FAIL_PERCENT=95
    STATS_SRT_HOST=127.0.0.1
    STATS_SRT_LATENCY_MS=80

------------------------------------------------------------------------

# 📦 Project Structure

    mediabridge-srt-rust/
    ├── Dockerfile
    ├── docker-compose.yml
    ├── Cargo.toml
    ├── build.rs
    ├── wrapper.h
    ├── config/
    │   └── allowlist.json
    └── src/
        ├── main.rs
        └── srt.rs

------------------------------------------------------------------------

# 🐳 How to Run

## 1️⃣ Build and start

    docker compose up --build

The gateway will listen on:

    UDP 9000
    TCP 8080 (health HTTP)

------------------------------------------------------------------------

# 🎥 Testing Locally

## Publish with OBS

Set OBS Output → SRT:

### MediaBridge format

    srt://127.0.0.1:9000?mode=caller&latency=120&streamid=mb:publish/live/alpha

### Or SRT standard format

    srt://127.0.0.1:9000?mode=caller&latency=120&streamid=#!::m=publish,r=live/alpha

------------------------------------------------------------------------

## Play with VLC

Open network stream:

### MediaBridge format

    srt://127.0.0.1:9000?mode=caller&latency=120&streamid=mb:play/live/alpha

### Or SRT standard format

    srt://127.0.0.1:9000?mode=caller&latency=120&streamid=#!::m=play,r=live/alpha

If VLC shows black screen, try increasing latency to 200--400.

------------------------------------------------------------------------

## FFmpeg / ffplay quick test (PowerShell)

Set stream URLs once:

    $tx = "srt://127.0.0.1:9000?mode=caller&transtype=live&latency=80&streamid=mb:publish/live/alpha"
    $rx = "srt://127.0.0.1:9000?mode=caller&latency=80&streamid=mb:play/live/alpha"

Read/play the SRT stream:

    ffplay -fflags nobuffer -flags low_delay -framedrop $rx

Send a test stream:

    ffmpeg -re -f lavfi -i "testsrc2=size=1280x720:rate=60" `
      -c:v libx264 -preset ultrafast -tune zerolatency `
      -g 60 -keyint_min 60 -bf 0 -pix_fmt yuv420p `
      -f mpegts `
      $tx

Measure end-to-end latency with the provided PowerShell script:

    .\srt-latency-meter.ps1

Or with explicit URLs:

    .\srt-latency-meter.ps1 -PublishUrl $tx -PlayUrl $rx -Fps 60

Check health:

    curl http://127.0.0.1:8080/health/live
    curl http://127.0.0.1:8080/health/ready
    curl http://127.0.0.1:8080/metrics
    curl http://127.0.0.1:8080/stats
    curl http://127.0.0.1:8080/stats/flows/live%2Falpha

------------------------------------------------------------------------

# 🔮 Future Roadmap

## 🔜 Core Improvements

-   SRT statistics (RTT, packet loss, bitrate)
-   Stream state detection (LIVE / OFFLINE / DEGRADED)
-   JSON structured logging

## 🔜 Configuration Improvements

-   Reload allowlist without restart
    -   HTTP endpoint OR
    -   File hot-reload when modified

## 🔜 Security

-   Passphrase per stream
-   IP ACL
-   Bitrate limits

## 🔜 Product Evolution

-   Control plane (Node.js)
-   Multi-tenant system
-   Licensing enforcement
-   Web preview (SRT → WebRTC)

------------------------------------------------------------------------

# 🧠 Current Status

MediaBridge currently implements:

-   A stable Rust-based SRT relay
-   Custom streamID parsing
-   Allowlist protection
-   Publisher replacement logic
-   Docker-based reproducible build

This is the foundation of the future MediaBridge platform.
