Datarhei - Dragon Fork: fork of datarhei/core with native WebRTC (WHEP) egress for low-latency streaming. Built with Pion.
Find a file
ZGaetano b1057756d2
Some checks failed
ci / race tests (push) Blocked by required conditions
ci / WebRTC smoke (5-viewer fanout) (push) Blocked by required conditions
ci / WebRTC latency p95 gate (push) Blocked by required conditions
ci / vet + build (push) Has been cancelled
fix(whip): rewrite lifecycle hooks — correct port allocation, clean FFmpeg RTP input legs
2026-05-09 16:33:35 -04:00
.forgejo/workflows feat(ci): add Docker image publish workflow on tag push (closes #12) 2026-05-06 16:00:32 -04:00
.github Add linux/arm/v8 build 2026-03-16 09:28:04 +01:00
app fix(whip): rewrite lifecycle hooks — correct port allocation, clean FFmpeg RTP input legs 2026-05-09 16:33:35 -04:00
cmd/webrtc-poc feat(webrtc): add -rtp-host flag + TrueNAS Docker deploy 2026-04-17 09:05:37 -04:00
config fix(config): preserve WebRTC section in Config.Clone() 2026-04-17 15:26:11 -04:00
core/webrtc feat(core/webrtc): add IngestPeer for WHIP publish side (issue #16) 2026-05-09 16:20:09 -04:00
deploy fix(docker): chmod apply-overlay.sh before execution (exit 126) 2026-05-09 16:25:28 -04:00
docs docs: add upstream rebase policy (closes #13) 2026-05-06 15:55:00 -04:00
encoding/json Add v16.7.2 2022-05-13 19:26:45 +02:00
ffmpeg Add looping_runtime to avstream status 2023-05-05 12:03:48 +02:00
glob Fix memfs concurrent read and write performance 2024-03-15 15:25:25 +01:00
http Merge branch 'm5-branding-release' into m2-webrtc-core-integration 2026-05-03 12:26:39 +00:00
internal Update dependencies 2024-01-12 12:35:07 +01:00
io Fix memfs concurrent read and write performance 2024-03-15 15:25:25 +01:00
log Add WithLevel() to Logger interface 2024-05-29 15:51:51 +02:00
math/rand Fix concurrent accesses 2024-03-15 11:45:50 +01:00
monitor Fix typo in test name 2024-03-14 12:03:38 +01:00
net Fix tests 2023-04-26 09:50:09 +02:00
playout Add v16.7.2 2022-05-13 19:26:45 +02:00
process Fix race condition 2024-01-15 10:42:08 +01:00
prometheus test(prometheus): add WebRTC snapshot collector unit tests 2026-05-06 15:56:43 -04:00
psutil Fix #10 2023-04-11 15:04:31 +02:00
restream feat(restream): extend ProcessHooks with OnInputStart for WHIP ingest input legs 2026-05-09 16:32:03 -04:00
rtmp Don't report EOF as error in RTMP server, update dependency 2024-05-29 16:33:32 +02:00
service Add logging for service 2022-12-27 09:47:59 +01:00
session Fix require positive persist interval 2024-01-12 15:37:51 +01:00
src/misc/Logo Update rsLogo component to import from local images directory 2026-05-03 23:26:20 -04:00
srt Add support for SRTv4 clients 2024-01-12 15:38:32 +01:00
test chore: create test/load/results/ directory for load test reports 2026-05-06 16:04:13 -04:00
update Don't use deprecated functions from io/ioutil 2022-08-18 10:27:33 +03:00
vendor feat(webrtc): add ICE config helper (Configuration + SettingEngine) 2026-04-17 08:46:27 -04:00
.dockerignore Add v16.8.0 2022-06-03 17:21:52 +02:00
.editorconfig Add v16.7.2 2022-05-13 19:26:45 +02:00
.gitignore Merge branch 'm4-latency-gate' into m2-webrtc-core-integration 2026-05-03 12:26:21 +00:00
build.sh Add v16.7.2 2022-05-13 19:26:45 +02:00
CHANGELOG.md docs: update CHANGELOG for v0.2 backlog work (closes #11, #12, #13, #14) 2026-05-06 16:03:09 -04:00
CREDITS feat(branding): Dragon Fork identity for v0.1.0-dragonfork release 2026-05-03 12:22:25 +00:00
Dockerfile Add ubuntu build for vod branch 2024-09-24 11:47:25 +02:00
Dockerfile.bundle Mod exposes ports 2022-09-29 10:10:05 +02:00
Dockerfile.test Mod updates build-files 2023-02-23 10:17:39 +01:00
go.mod feat(webrtc): add ICE config helper (Configuration + SettingEngine) 2026-04-17 08:46:27 -04:00
go.sum feat(webrtc): add ICE config helper (Configuration + SettingEngine) 2026-04-17 08:46:27 -04:00
LICENSE Add v16.8.0 2022-06-03 17:21:52 +02:00
main.go Use config locations for import and ffmigrage 2023-01-03 11:45:10 +01:00
Makefile Bump version to 16.15.0, update changelog 2024-04-03 14:27:58 +02:00
mime.types Add v16.7.2 2022-05-13 19:26:45 +02:00
NOTES.md docs: add Dragon Fork WebRTC egress design spec and M1 plan 2026-04-17 08:40:05 -04:00
NOTICE feat(branding): Dragon Fork identity for v0.1.0-dragonfork release 2026-05-03 12:22:25 +00:00
README.md docs: update README quick-start with Prometheus/Grafana and Docker publish 2026-05-06 16:04:02 -04:00
run.sh Add test if import and migrate script exist 2024-04-04 11:10:10 +02:00
SECURITY.md Create SECURITY.md 2022-06-01 22:48:21 +02:00

Datarhei — Dragon Fork

A fork of datarhei/core that adds a native WebRTC (WHEP) egress path. Everything upstream Datarhei already does — RTMP / SRT / RTSP ingest, FFmpeg process orchestration, HLS / DASH outputs, S3 mounts, the HTTP API and Swagger UI — works unchanged. WebRTC sits alongside as another output type, opt-in per process.

publisher (OBS / FFmpeg / SRT) ──▶  datarhei Core  ──▶  WebRTC peers
            │                            │   (15 viewers per stream)
            │                            ├──▶ HLS / DASH (existing)
            │                            ├──▶ RTMP relay (existing)
            └──▶ ingest (RTMP / SRT / …) └──▶ recording (existing)

Sub-second glass-to-glass on a LAN over WHEP, no SFU dependencies, single binary, single Docker image.

Status: v0.2 in progress (last work 2026-05-06). Full GUI bundled (Restreamer UI + Wild Dragon WebRTC admin). Prometheus + Grafana observability stack shipped. Live deploy running on TrueNAS since 2026-04-17.

What this fork adds

  • webrtc.* config block alongside rtmp.* and srt.*, with the same CORE_* env-var binding pattern.
  • Per-process webrtc.enabled toggle on the existing process config. Once true, Core auto-injects two RTP output legs (video + audio), allocates UDP ports, and the WHEP endpoint is live.
  • POST /api/v3/whep/{processID} — WebRTC-HTTP Egress Protocol subscribe; SDP offer in, SDP answer out. JWT-protected by the existing Core auth.
  • DELETE /api/v3/whep/{processID}/{resourceID} — idempotent teardown.
  • PATCH …/{resourceID} — trickle ICE.
  • Bundled GUI — the upstream Restreamer React UI is built into the TrueNAS deploy image with Wild Dragon branding, plus a single-file Wild Dragon WebRTC admin page for one-click webrtc.enabled toggling.
  • Browser-side smoke player at whep-player.html — zero-dependency WHEP subscriber, ICE/codec/bitrate stats, JWT field, shareable ?url=&token= URLs.
  • Prometheus observability — eleven dragonfork_webrtc_* metrics (RED-method counters/histograms + state gauges). Grafana health dashboard with 5 rows and 4 pre-loaded alert rules.
  • Multi-viewer correctness: per-stream peer cap, ICE-failure auto-cleanup, process-stop broadcast tear-down.
  • Error matrix per the design spec: 406 on codec mismatch, 504 on ICE timeout, 503 on cap, 204 on idempotent DELETE, CORS preflights on every WHEP route.

The existing upstream Datarhei feature set is intact — see "From upstream Datarhei" below.

Quick start

Docker (TrueNAS / any host with Docker + LAN-reachable IP)

git clone https://forge.wilddragon.net/zgaetano/datarhei-dragonfork-core.git
cd datarhei-dragonfork-core/deploy/truenas/core

cat > .env <<EOF
PUBLIC_IP=10.0.0.25
CORE_HTTP_PORT=8080
API_AUTH_USERNAME=admin
API_AUTH_PASSWORD=$(openssl rand -base64 24)
API_AUTH_JWT_SECRET=$(openssl rand -base64 48)
GRAFANA_ADMIN_PASSWORD=$(openssl rand -base64 24)
GRAFANA_PORT=3000
PROM_PORT=9090
EOF

docker compose up -d --build

Then open in a browser (replace <host> with your PUBLIC_IP):

URL What it does
http://<host>:8080/ Restreamer UI — manage processes, ingests, outputs
http://<host>:8080/wilddragon-webrtc.html Wild Dragon WebRTC admin — toggle webrtc.enabled per process, copy WHEP URL
http://<host>:8080/whep-player.html WHEP smoke player — verify the WebRTC stream renders
http://<host>:3000/ Grafana — WebRTC Health dashboard (login with GRAFANA_ADMIN_PASSWORD)
http://<host>:9090/ Prometheus — raw metrics, alert rules
http://<host>:8080/api/swagger/index.html Swagger — full API docs

The Restreamer UI doesn't yet have a WebRTC checkbox in its process editor — use /wilddragon-webrtc.html for that. Tracked in issue #15.

Pulling a pre-built image (after first tag is published)

# Update .env, then:
docker compose pull   # pulls pre-built multi-arch image
docker compose up -d  # no --build needed

Sample process JSON

{
  "id": "live",
  "input": [
    { "address": "{rtmp,name=live.stream}", "options": [] }
  ],
  "output": [],
  "webrtc": { "enabled": true }
}

That's it. No webrtc:// URL scheme to learn — the toggle on config.webrtc.enabled is the entire surface. The resolver allocates ports, injects -f rtp udp://… legs into the FFmpeg command, and the WHEP endpoint at /api/v3/whep/live becomes live the moment the process starts.

For multi-input pipelines (lavfi test sources, multi-camera switches, SDI + file audio), use the video_map and audio_map fields:

"webrtc": {
  "enabled": true,
  "video_map": "0:v:0",
  "audio_map": "1:a:0",
  "force_transcode": true
}

Documentation

Topic Where
Design spec docs/design/2026-04-16-datarhei-dragon-fork-webrtc-design.md
M1 (PoC) plan docs/design/2026-04-16-datarhei-dragon-fork-m1-webrtc-poc.md
M2 (Core integration) spec docs/design/2026-04-17-datarhei-dragon-fork-m2-webrtc-core-integration.md
Prometheus metrics design docs/design/2026-05-03-datarhei-dragon-fork-webrtc-prometheus-metrics-design.md
Upstream rebase policy docs/REBASE.md
TrueNAS deploy guide deploy/truenas/core/README.md
Testing test/TESTING.md
Changelog (Dragon Fork) CHANGELOG.md
Upstream Datarhei docs docs.datarhei.com/core

Building from source

Go 1.24 required (vendored).

make release   # cross-compiles linux/amd64 to ./core/core
make test      # full suite, race detector
go test -tags latency -timeout 90s -count=1 \
  -run TestLatencyServerHop ./app/webrtc/...   # latency p95 gate

Load testing

go run ./test/load/sustained.go \
  -url http://<host>:8080 \
  -stream <processID> \
  -peers 5 \
  -duration 10m \
  -auth "Bearer <TOKEN>" \
  -out test/load/results/

Reports are written to test/load/results/. Observe the Grafana WebRTC Health dashboard during the run.

From upstream Datarhei

This fork preserves everything upstream Datarhei Core does — Dragon Fork is purely additive. If a feature isn't WebRTC-related, the behaviour is unchanged from upstream and the upstream documentation applies as-is.

Subsystem Upstream feature set
Process management API-driven FFmpeg, error detection / recovery, log history, resource limits, statistics, FFprobe input verification, process metadata
Media delivery HTTP/S, RTMP/S, SRT services with Let's Encrypt, configurable file systems (in-memory / disk / S3), HLS/DASH session limits, viewer session API
Misc HTTP REST + GraphQL, Swagger, Prometheus metrics, multi-arch Docker images

Attribution

Dragon Fork is built on:

  • datarhei Core — Apache 2.0, © datarhei. The base repository this fork tracks. See NOTICE for the required attribution.
  • datarhei Restreamer UI — Apache 2.0, © datarhei. The React frontend bundled into the TrueNAS deploy image with Wild Dragon overlays.
  • Pion WebRTC — MIT. The Go WebRTC stack the egress path is built on.
  • FFmpeg — LGPL / GPL (build-flag dependent). Used as a subprocess for transcoding and RTP packetisation; Dragon Fork doesn't link against it.

Full third-party credits in CREDITS.

License

Apache License 2.0 — same as upstream. See LICENSE.