Conversation
… override Two related video-playback fixes: - lease.proxy is set to the media service's own public hostname when an off-host EUD/ATAK-plugin is publishing directly to it - correct for the EUD, but when this same media service pulls that source to relay it, resolving its own public hostname back to itself is a hairpin-NAT path many networks/NAT setups can't route, and the pull just hangs (no error, surfaces client-side as an HLS manifest load timeout). Adds an ingestSource() helper that rewrites the RTSP proxy source to an internal alias when its hostname matches media::url's own hostname - but only when an operator opts in via the new media::ingest_internal_host setting, since which alias (if any) is valid is deployment-specific. Unset (the default), this is a complete no-op. - Some networks block the media server's dedicated port (9997) outright. Adds an optional media::playback_url setting so the browser-facing HLS URL can be served through a standard-port reverse proxy instead, without touching RTSP/RTMP/SRT/WebRTC URLs or changing behavior for deployments that don't set it. Both settings default to empty/unset and are strictly additive - byte- identical behavior for every deployment that doesn't configure them. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Member
|
Thanks for the PR, One catch to a further review/merge, The Env vars don't appear to actually work as intended from my initial test as |
…internal_host CLOUDTAK_Config_* env vars translate to Setting keys by replacing every underscore with `::` (api/common/config.ts), so CLOUDTAK_Config_media_playback_url resolved to media::playback::url, never matching the media::playback_url key - the setting silently never applied. Same bug for ingest_internal_host. Renamed both keys to use `::` per word, matching the translation rule and the existing login::background::color-style convention elsewhere in FullConfig. No env var or docker-compose.yml changes needed - only the internal key spelling had to match what the translation already produces. Flagged by @ingalls in review. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Author
|
Fixed the config key names — media::playback::url and media::ingest::internal::host — to match the existing ::-per-word convention in the codebase. The underscores in the original names were getting converted to :: by the config translation, splitting them into extra namespace levels the settings never actually applied to. No env var or docker-compose changes needed. Verified with full build/typecheck/test pass. |
dfndr13
pushed a commit
to dfndr13/CloudTAK
that referenced
this pull request
Aug 17, 2026
api/common/config.ts's CLOUDTAK_Config_* env var translation replaces every underscore with ::, so CLOUDTAK_Config_media_internal_url resolved to media::internal::url while the setting was actually keyed media::internal_url (and same for media_public_url) - the env vars could never reach their setting, silently falling back to the legacy media::url default. Renamed both keys to media::internal::url and media::public::url to match the translation rule, same fix already applied to media::playback_url in PR dfpc-coe#1645.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two related bugs prevent EUD/ATAK-plugin video from playing in some deployments:
1. Hairpin-NAT on the RTSP proxy source. When an off-host EUD or ATAK plugin publishes video,
lease.proxyis set to the media service's own public hostname (media::url) — correct, since the EUD needs to reach it publicly. But when the media service itself pulls that same URL as a relay source (sourcein the MediaMTX path config), it's asking to reach its own public hostname from inside its own network. On networks/NAT setups that don't support hairpinning, that pull just hangs — no error at the MediaMTX layer, no timeout — and surfaces client-side as an HLSmanifestLoadTimeOut.2. No way to route HLS playback through a standard port. The media service's dedicated port (9997) is blocked outright on some networks (guest wifi, restrictive agency networks), with no way to work around it short of changing the media service's own listen port.
Fix
ingestSource()helper rewrites an RTSP/RTSPS proxy source to an internal alias when its hostname matchesmedia::url's own hostname — but only when an operator has opted in via a newmedia::ingest_internal_hostsetting. Left unset (the default), this is a complete no-op.media::playback_urlsetting lets operators serve the browser-facing HLS URL through a different host/port (e.g. a standard-port reverse proxy) without touching RTSP/RTMP/SRT/WebRTC URLs or affecting deployments that don't set it.Both settings default to empty and are strictly additive — behavior for any deployment that doesn't configure them is unchanged.
On the
ingestSource()designThe obvious version of this fix is to hardcode the internal alias to rewrite to. We deliberately didn't do that: which internal hostname (if any) is reachable is entirely deployment-specific — it depends on how an operator's media/ingest containers are networked relative to each other, which varies a lot between a plain single-container
media-infradeployment, ECS, and setups with a separate ingest tier in front of it. A hardcoded value would be meaningless (or actively wrong) for anyone whose topology differs from ours, so we made it an opt-in setting that's a no-op by default instead. Open to other approaches if maintainers see a better way to express "this deployment needs a hairpin workaround" — this is the smallest one we found that can't silently misbehave for anyone who doesn't ask for it.Validation
Both issues (the hairpin hang and the port-9997 block) were reproduced and confirmed fixed in an independent deployment running current
media-inframain, separately from the environment these patches were originally written against.Testing
tsc --noEmitcleaningestSource()(opt-in rewrite, no-op default, non-matching hosts, non-RTSP sources, malformed URLs)