Skip to content

Fix HDHomeRun preview: GET fallback when HEAD not supported by device#112

Merged
cbulock merged 4 commits intomainfrom
fix/hdhomerun-probe-get-fallback
Apr 5, 2026
Merged

Fix HDHomeRun preview: GET fallback when HEAD not supported by device#112
cbulock merged 4 commits intomainfrom
fix/hdhomerun-probe-get-fallback

Conversation

@cbulock
Copy link
Copy Markdown
Owner

@cbulock cbulock commented Apr 5, 2026

Summary

  • HDHomeRun devices do not implement HEAD on their stream endpoints
  • The server's HEAD handler calls axios.head() to the upstream; on failure it returns 502, causing probeResponse.ok to be false and the .catch() to fire silently — so HLS.js still runs, downloads ~1MB of MPEG-TS, and mpegts.js fails silently on MPEG-2 video (no error event emitted)
  • Fix: when HEAD fails, issue a GET probe and cancel the body immediately after reading the Content-Type header; if MPEG-TS is confirmed, tear down any active players and show the unsupported-codec error overlay

How it works

The existing parallel probe structure is preserved — HEAD fires alongside HLS.js with no added latency. If HEAD succeeds (device supports it), it works as before. If HEAD fails, the .catch() now issues a GET probe, reads just the headers, cancels the body, and interrupts HLS.js/mpegts.js if the content type confirms MPEG-TS. A staleness guard prevents the callback firing on stale results after the user has closed or switched the player.

Test plan

  • Open an HDHomeRun OTA channel — error overlay should appear with the MPEG-2/AC-3 message instead of a black screen after 1MB of data
  • Open a non-HDHomeRun HLS channel — should play normally (probe is skipped for non-hdhomerun channels)
  • All 289 existing tests pass

🤖 Generated with Claude Code

HDHomeRun devices do not implement HEAD on their stream endpoints.
The server's HEAD handler issues axios.head() to the upstream and
returns 502 on failure, causing probeResponse.ok to be false and
the .catch() to fire — silently doing nothing, so HLS.js runs,
downloads ~1MB of MPEG-TS, and mpegts.js fails silently on MPEG-2.

When HEAD fails, now issue a GET probe and cancel the body immediately
after reading the Content-Type header. If the content type confirms
MPEG-TS, the active players are torn down and the unsupported-codec
error overlay is shown. The staleness guard prevents the callback
from firing on a stale result after the user has switched channels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 5, 2026 20:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Admin “Preview” video player logic to better detect HDHomeRun stream endpoints that don’t support HEAD, so the UI can reliably show the unsupported-codec overlay instead of leaving the user with a black screen.

Changes:

  • Adds a GET-based probe fallback when the existing HEAD probe fails for HDHomeRun preview streams.
  • Cancels the GET response body after reading headers and, if MPEG-TS is detected, tears down active players and shows the unsupported-codec error (with a staleness guard).

Comment on lines +1722 to +1733
if (hlsInstance) {
hlsInstance.destroy();
hlsInstance = null;
}
if (mpegtsInstance) {
mpegtsInstance.destroy();
mpegtsInstance = null;
}

video.removeAttribute('src');
video.load();
showPlayerError(ERR_UNSUPPORTED_CODEC);
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The destroy/reset/error sequence is duplicated in both the successful HEAD probe path and the GET fallback path. Consider extracting a small helper (e.g., “tearDownPlayersAndShowUnsupportedCodec(video)”) to keep these paths in sync and reduce future maintenance risk.

Copilot uses AI. Check for mistakes.
cbulock and others added 3 commits April 5, 2026 16:23
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…down

The destroy/reset/showPlayerError sequence was identical in both the
HEAD probe path and the GET fallback path. Extract it into a shared
helper so the two paths stay in sync and the staleness guard is only
written once.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 5, 2026

@cbulock Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: fc4a55a1-3ee0-4946-9018-c6541d36ecbe

Sorry for the inconvenience!

2 similar comments
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 5, 2026

@cbulock Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: fc4a55a1-3ee0-4946-9018-c6541d36ecbe

Sorry for the inconvenience!

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 5, 2026

@cbulock Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: fc4a55a1-3ee0-4946-9018-c6541d36ecbe

Sorry for the inconvenience!

@cbulock cbulock merged commit 543a567 into main Apr 5, 2026
7 of 9 checks passed
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.

3 participants