every.channel: sanitized baseline

This commit is contained in:
every.channel 2026-02-15 16:17:27 -05:00
commit 897e556bea
No known key found for this signature in database
258 changed files with 74298 additions and 0 deletions

279
docs/USAGE.md Normal file
View file

@ -0,0 +1,279 @@
# Usage
## Tauri viewer (local)
If `trunk` or `cargo-tauri` is missing, enter the nix shell (or install the tools manually).
`direnv allow` also sets `EVERY_CHANNEL_ROOT` so Tauri can find the UI folder.
```sh
direnv allow
cd apps/tauri
cargo tauri dev
```
If you want deterministic transcoding instead of stream copy:
```sh
EVERY_CHANNEL_TRANSCODE=1 cargo tauri dev
```
For node ingest/MoQ publish, you can force deterministic transcode with:
```sh
EVERY_CHANNEL_DETERMINISTIC=1 cargo run -p ec-node -- ingest hdhr --channel 8.1
```
iroh discovery is opt-in (DNS discovery is off by default). Enable DHT and/or mDNS like this:
```sh
EVERY_CHANNEL_IROH_DISCOVERY=dht,mdns cargo tauri dev
```
In the Tauri app, use **Add stream** to add an HDHomeRun host, a direct HLS URL, or a yt-dlp supported URL (e.g. YouTube Live). The flow rejects non-live sources.
Linux DVB sources can be added with a URL like:
```
linux-dvb://localhost?adapter=0&dvr=0&tune=dvbv5-zap&tune=-r&tune=Channel%20Name
```
On Linux, if `/dev/dvb` exists and a `channels.conf` is found, Linux DVB channels are auto-listed in the Channels panel.
You can override the `channels.conf` path with `EVERY_CHANNEL_DVB_CHANNELS_CONF=/path/to/channels.conf`.
In the UI, you can still type `linux-dvb` in the Add stream field to open the Linux DVB picker (adapter, channels.conf, channel).
Select a channel and click **Share** to start a MoQ publisher. The share bundle (endpoint addr, broadcast, track) appears under the viewer panel and can be pasted into **Manual MoQ connect** on another node.
For gossip announcements, you can provide peers in the UI or set `EVERY_CHANNEL_GOSSIP_PEERS` (comma-separated). mDNS peer discovery is used on LANs to supplement the peer list when available.
## Coverage
See `docs/COVERAGE.md`.
## HDHomeRun E2E Test (Local Network)
This runs two local `ec-node` processes (publish then subscribe) against a real HDHomeRun source and validates that:
chunks are encrypted, manifests are required, and the subscriber produces a playable HLS output directory.
Requires Nix (so `ac-ffmpeg` finds FFmpeg headers):
```sh
./scripts/e2e-hdhr.sh --host <HDHR_HOST> --channel <CHANNEL>
```
## Mesh E2E Test (Split Sources)
This runs two publishers over the same broadcast:
- peer A publishes **manifests only** (`--publish-chunks=false`)
- peer B publishes **objects only**
The subscriber fetches objects from peer B and manifests from peer A using `--remote-manifests`.
```sh
./scripts/e2e-mesh-split.sh --host <HDHR_HOST> --channel <CHANNEL>
```
### yt-dlp bundling (YouTube Live URLs)
To enable the “Add stream (yt-dlp)” UI flow, bundle the Python runtime + yt-dlp into the app resources:
```sh
scripts/vendor-yt-dlp.sh
```
The app will use the bundled runtime under `apps/tauri/resources/yt-dlp/<platform>/venv`. You can override with `EVERY_CHANNEL_YTDLP_PYTHON`.
## Node ingest (MoQ file relay)
### HDHomeRun
```sh
cargo run -p ec-node -- ingest hdhr --channel 8.1
```
Enable deterministic transcode:
```sh
cargo run -p ec-node -- ingest hdhr --channel 8.1 --deterministic
```
Use a specific device:
```sh
cargo run -p ec-node -- ingest hdhr --device-id <DEVICE_ID> --channel 8.1
```
### Linux DVB
```sh
cargo run -p ec-node -- ingest linux-dvb --adapter 0 --dvr 0 --tune-cmd dvbv5-zap --tune-cmd -r --tune-cmd "Channel Name"
```
### HLS playlist
```sh
cargo run -p ec-node -- ingest hls --url https://example.com/live.m3u8
```
Use deterministic transcode if needed:
```sh
cargo run -p ec-node -- ingest hls --url https://example.com/live.m3u8 --mode transcode
```
### Raw TS file or URL
```sh
cargo run -p ec-node -- ingest ts --input /path/to/stream.ts
```
## Time sync inspection
```sh
cargo run -p ec-cli -- ts-sync /path/to/stream.ts --chunk-ms 2000 --max-events 50
```
## MoQ publish over iroh
```sh
cargo run -p ec-node -- moq-publish hdhr --channel 8.1
```
Publish with deterministic transcode:
```sh
cargo run -p ec-node -- moq-publish hdhr --channel 8.1 --deterministic
```
Use a specific device:
```sh
cargo run -p ec-node -- moq-publish hdhr --device-id <DEVICE_ID> --channel 8.1
```
Publish an HLS source:
```sh
cargo run -p ec-node -- moq-publish hls --url https://example.com/live.m3u8
```
Set a stable identity:
```sh
IROH_SECRET=<hex> cargo run -p ec-node -- moq-publish ts --input /path/to/stream.ts
```
Enable discovery (DHT + mDNS):
```sh
cargo run -p ec-node -- moq-publish hdhr --channel 8.1 \\
--discovery dht,mdns
```
Announce to catalog gossip:
```sh
cargo run -p ec-node -- moq-publish hdhr --channel 8.1 \\
--announce --gossip-peer <ENDPOINT_ADDR>
```
Publish per-chunk manifests alongside chunks:
```sh
EVERY_CHANNEL_MANIFEST_SIGNING_KEY=<hex> cargo run -p ec-node -- moq-publish hdhr --channel 8.1 \\
--publish-manifests --announce --gossip-peer <ENDPOINT_ADDR>
```
Batch multiple chunks per manifest (epoch):
```sh
cargo run -p ec-node -- moq-publish hdhr --channel 8.1 \\
--publish-manifests --epoch-chunks 8
```
## MoQ subscribe (HLS output)
```sh
cargo run -p ec-node -- moq-subscribe \\
--remote <ENDPOINT_ADDR> \\
--broadcast-name <STREAM_ID>
```
Enable discovery (DHT + mDNS):
```sh
cargo run -p ec-node -- moq-subscribe \\
--remote <ENDPOINT_ADDR> \\
--broadcast-name <STREAM_ID> \\
--discovery dht,mdns
```
Segments and `index.m3u8` will be written to `./tmp/moq-hls` by default.
Subscribe to manifests and require them for validation:
```sh
cargo run -p ec-node -- moq-subscribe \\
--remote <ENDPOINT_ADDR> \\
--broadcast-name <STREAM_ID> \\
--subscribe-manifests --require-manifest
```
Restrict to a manifest signer:
```sh
cargo run -p ec-node -- moq-subscribe \\
--remote <ENDPOINT_ADDR> \\
--broadcast-name <STREAM_ID> \\
--subscribe-manifests --require-manifest \\
--manifest-signers ed25519:<hex>
```
Throttle incoming data:
```sh
cargo run -p ec-node -- moq-subscribe \\
--remote <ENDPOINT_ADDR> \\
--broadcast-name <STREAM_ID> \\
--max-bytes-per-sec 5000000 --max-bytes-burst 10000000
```
If the stream is encrypted, pass the same network secret used by the publisher:
```sh
EVERY_CHANNEL_NETWORK_SECRET=<hex> cargo run -p ec-node -- moq-subscribe \\
--remote <ENDPOINT_ADDR> \\
--broadcast-name <STREAM_ID>
```
## MoQ self-test (local round trip)
```sh
cargo run -p ec-node -- moq-selftest /path/to/stream.ts
```
Pass a URL (for HDHomeRun):
```sh
cargo run -p ec-node -- moq-selftest http://<hdhr>/auto/v8.1 --max-chunks 8
```
## Determinism test (libx264 single-thread)
```sh
cargo run -p ec-cli -- determinism-test /path/to/stream.ts ./tmp/determinism --runs 3
```
## Tests and coverage
Run the core unit tests:
```sh
just test-core
```
Generate a coverage report (requires `nix develop` so ffmpeg headers are visible to `ac-ffmpeg`):
```sh
just cov-core-html
```