From 4b9d965facb86b6da0c8f6ba0f2f79a5bad8562d Mon Sep 17 00:00:00 2001 From: "every.channel" Date: Tue, 24 Feb 2026 23:06:30 -0800 Subject: [PATCH 01/10] wt-publish: force explicit AAC-LC stereo mapping --- crates/ec-node/src/main.rs | 8 +++++- ...ECP-0077-explicit-aac-transcode-profile.md | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 evolution/proposals/ECP-0077-explicit-aac-transcode-profile.md diff --git a/crates/ec-node/src/main.rs b/crates/ec-node/src/main.rs index b4b68b3..3b1be70 100644 --- a/crates/ec-node/src/main.rs +++ b/crates/ec-node/src/main.rs @@ -6312,6 +6312,10 @@ async fn wt_publish(args: WtPublishArgs) -> Result<()> { if args.transcode { cmd.args([ + "-map", + "0:v:0", + "-map", + "0:a:0?", "-c:v", "libx264", "-preset", @@ -6332,8 +6336,10 @@ async fn wt_publish(args: WtPublishArgs) -> Result<()> { "1", "-c:a", "aac", + "-profile:a", + "aac_low", "-b:a", - "128k", + "160k", "-ac", "2", "-ar", diff --git a/evolution/proposals/ECP-0077-explicit-aac-transcode-profile.md b/evolution/proposals/ECP-0077-explicit-aac-transcode-profile.md new file mode 100644 index 0000000..fd22aaf --- /dev/null +++ b/evolution/proposals/ECP-0077-explicit-aac-transcode-profile.md @@ -0,0 +1,27 @@ +# ECP-0077: Explicit AAC-LC Live Audio Profile In `wt-publish` + +## Context + +Live OTA inputs expose multiple AC-3 audio tracks (5.1 + stereo language variants). Browser watcher behavior is more stable when the published relay stream has a single explicit AAC-LC stereo track shape. + +## Decision + +In `ec-node wt-publish` transcode mode, force explicit stream mapping and AAC profile: + +- `-map 0:v:0` +- `-map 0:a:0?` +- `-c:a aac` +- `-profile:a aac_low` +- `-b:a 160k` +- `-ac 2` +- `-ar 48000` + +## Rationale + +- Removes ambiguity from ffmpeg auto stream selection when multiple audio tracks exist. +- Keeps audio encoding browser-friendly and deterministic. +- Preserves optional audio behavior (`0:a:0?`) for edge cases where input temporarily lacks audio. + +## Reversibility + +- Revert to ffmpeg auto mapping/profile by removing explicit `-map` and `-profile:a` flags. From c545b2381dca4960aa46c882e0ddc6e252a5e765 Mon Sep 17 00:00:00 2001 From: "every.channel" Date: Tue, 24 Feb 2026 23:13:02 -0800 Subject: [PATCH 02/10] web: keep canvas renderer while forcing audio signals --- apps/web/app.js | 11 +++-------- .../ECP-0076-webtransport-only-web-watcher.md | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/apps/web/app.js b/apps/web/app.js index 7c5dab5..43086c8 100644 --- a/apps/web/app.js +++ b/apps/web/app.js @@ -169,14 +169,9 @@ function mountPlayer(relayUrl, name) { watch.connection.websocket = { enabled: false }; } - // Use a media element for live playback so browser audio controls/policies apply naturally. - const video = document.createElement("video"); - video.className = "archiveVideo"; - video.controls = true; - video.autoplay = true; - video.muted = false; - video.playsInline = true; - watch.appendChild(video); + const canvas = document.createElement("canvas"); + canvas.className = "canvas"; + watch.appendChild(canvas); mount.appendChild(watch); const forceAudioOn = () => { diff --git a/evolution/proposals/ECP-0076-webtransport-only-web-watcher.md b/evolution/proposals/ECP-0076-webtransport-only-web-watcher.md index 31e78bc..8046cd8 100644 --- a/evolution/proposals/ECP-0076-webtransport-only-web-watcher.md +++ b/evolution/proposals/ECP-0076-webtransport-only-web-watcher.md @@ -10,7 +10,7 @@ In `apps/web/app.js`, configure each `` instance to disable WebSocket - `watch.connection.websocket = { enabled: false }` -Also set default watcher volume to full (`volume="1"`) and mount live playback on a `