Skip to content

feat: optional remote source (MP4, HLS, DASH) - #7

Merged
pzanella merged 1 commit into
mainfrom
feat/remote-source
Oct 8, 2026
Merged

pzanella merged 1 commit into
mainfrom
feat/remote-source

Conversation

@pzanella

@pzanella pzanella commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Adds an optional --source URL flag: stream an existing MP4, HLS, or DASH stream (on demand or live) over MoQ, instead of a file in assets/. Without the flag nothing changes.

./stream.sh --source 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8'          # live.hang
./stream.sh bbb --source 'https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd'
./stream.sh trailer --source 'https://media.w3.org/2010/05/sintel/trailer.mp4' --abr-ladder

How it works:

  • Before the relay starts, lib/probe-source.mjs reads the URL with ffprobe. If it can't (404, timeout, not a stream, no audio or video), the run stops with the reason.
  • From an HLS/DASH ladder, it picks the highest-resolution variant and its own audio. ffmpeg downloads only that variant. --abr-ladder makes the usual 5 renditions from it.
  • H.264/AAC is copied as-is; anything else (HEVC, AC-3, ...) is re-encoded to H.264/AAC.
  • A remote source plays once. A live stream runs until Ctrl+C; a VOD ends the run (Source ended.). ffmpeg 5.1 can't seek HLS back to its start, so looping isn't reliable.
  • <name> only names the broadcast (default live).

Checks:

  • Only http(s) URLs, and no backslashes (zsh adds them when pasting, which breaks signed CDN URLs with a 403).
  • ffmpeg may only use network protocols (http,https,tcp,tls,crypto), so a playlist can't make it read a local file. -rw_timeout ends the run instead of hanging.
  • Not available with --ssai-mode (SSAI cuts the content at fixed offsets).

Works with --abr-ladder, --csai-mode, --sgai-mode, --auth, and --dashboard.

Tested locally against MP4 over HTTP, HLS (VOD and live, multi-variant), DASH (VOD and live), an HEVC/AC-3 source (re-encoded), and the local-file pipelines (base, ABR, CSAI, SSAI) for regressions.

Also:

  • New CI job smoke-test-podman-source: a two-variant HLS ladder and a DASH manifest served from the runner, plus an unreachable URL.
  • README: new "Stream from a URL" section, flags table, troubleshooting (including authentication is disabled when the player sends a ?jwt= to a public relay).

Add --source URL to stream.sh: publish an MP4 file, an HLS playlist, or a
DASH manifest (on demand or live) over MoQ instead of assets/<name>.mp4.
<name> then only names the broadcast (default: live).

Before the relay starts, lib/probe-source.mjs reads the URL with ffprobe and
stops the run with the reason if it can't. From an HLS/DASH ladder it picks
the highest-resolution variant and its audio, so ffmpeg downloads only that
one. H.264/AAC is copied, anything else is re-encoded to H.264/AAC.

Only http(s) URLs are accepted (and none with backslashes, which zsh adds
when pasting), and ffmpeg may only use network protocols, so a playlist
can't make it read a local file. A remote source plays once: ffmpeg can't
seek HLS back to its start.

Works with --abr-ladder, --csai-mode, --sgai-mode, --auth, and --dashboard;
not with --ssai-mode. Without the flag the pipeline is unchanged. Adds the
smoke-test-podman-source CI job and documents the feature in the README.
@pzanella
pzanella merged commit 5167887 into main Oct 8, 2026
11 checks passed
pzanella added a commit that referenced this pull request Oct 27, 2026
Add --source URL to stream.sh: publish an MP4 file, an HLS playlist, or a
DASH manifest (on demand or live) over MoQ instead of assets/<name>.mp4.
<name> then only names the broadcast (default: live).

Before the relay starts, lib/probe-source.mjs reads the URL with ffprobe and
stops the run with the reason if it can't. From an HLS/DASH ladder it picks
the highest-resolution variant and its audio, so ffmpeg downloads only that
one. H.264/AAC is copied, anything else is re-encoded to H.264/AAC.

Only http(s) URLs are accepted (and none with backslashes, which zsh adds
when pasting), and ffmpeg may only use network protocols, so a playlist
can't make it read a local file. A remote source plays once: ffmpeg can't
seek HLS back to its start.

Works with --abr-ladder, --csai-mode, --sgai-mode, --auth, and --dashboard;
not with --ssai-mode. Without the flag the pipeline is unchanged. Adds the
smoke-test-podman-source CI job and documents the feature in the README.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant