Overview
PlayerScreen manages live HLS stream playback using Roku’s built-in Video node. It layers an info banner, a channel number badge, and ad renderers on top of the video, and handles errors, reconnection, and network loss gracefully.
Video node
Roku’s native
Video SceneGraph node plays HLS streams with streamFormat = "hls" and live = trueChannel banner
Info banner shows channel name, number, logo, and live status — auto-hides after 3 s
Number overlay
Digit-key input accumulates a channel number and tunes to it on commit
Watchdog timer
Freeze detection fires every 10 s; restarts the stream if position has not advanced
Starting playback
Playback is initiated byPlayChannel(idx), called either from onChannelIndexChanged() (when MainScene sets m.top.channelIndex) or from user navigation keys inside the player.
URL normalization
GTV_NormalizePlayerUrl rewrites non-standard URL schemes:
Channel index persistence
Every time a channel is tuned, its index is written to the Registry:MainScene reads this value to resume the last channel.
Buffer and startup
During the buffering state, the spinner overlay is shown and the banner displays
"Reconectando la transmisión".
Overlay system
Channel banner
ThechannelBanner node (m.banner) displays channel metadata and a live/status label. Timing constants:
The banner updates
statusText reactively based on player state:
Number overlay
The number overlay (m.numberOverlay) accumulates digit key presses. When the user stops pressing digits, numberCommitted fires and OnNumberCommitted() looks up the channel by number and calls PlayChannel:
Error handling and reconnection
Automatic retry
WhenOnVideoError() fires and the error is not an auth/inactive signal, PlayerScreen retries up to RETRY_MAX = 3 times with a 2-second delay between attempts:
RETRY_MAX failures, an error dialog is shown with Retry and Back options.
Stream restart
RestartStream() clears the Video node’s content, reassigns it, and calls play again — it does not change the channel.
Auto-recoverable errors
GTV_IsAutoRecoverableStreamError classifies timeout, network, and HTTP response errors as auto-recoverable. When network connectivity is restored (via ConnectivityTask), any open error dialog of this type is automatically dismissed and the stream restarts.
Auth/inactive errors from stream
GTV_IsInactiveStreamError inspects the error code and message for inactive-account signals (HTTP 401/403 with inactivo, inactive, subscriberDisabledReason, etc.). If detected:
- Playback is stopped.
m.global.authReasonCodeis set toAUTH_REASON_INACTIVEorAUTH_REASON_PASSWORD_CHANGED.m.top.userInactive = trueis set —MainScenehandles the re-login flow.
Freeze detection
The watchdog timer fires everyFREEZE_CHECK_MS = 10000 ms while the video state is "playing". It compares the current playback position against the last recorded position. If they are equal (and the position is valid), the stream is considered frozen and RestartStream() is called:
Network handling
AnetCheckTimer fires periodically during playback. It reads both GTV_IsOnline() (network interface up) and m.global.hasInternet (real internet reachability). Either failure puts the player into the offline state:
- Video is stopped.
- An offline dialog is shown with a Retry button.
ConnectivityTaskis triggered for an immediate reachability probe.
TryRecoverDialogsAfterNetworkRestore() hides the offline dialog and restarts the stream.
Interaction with ads (viewport reduction)
WhenAdManager activates a Format C ad, it emits videoHeightReduction and videoOffsetY fields. PlayerScreen observes these and adjusts the Video node’s geometry accordingly:
SyncAdViewport() pushes the updated viewport rect back to AdManager so ad renderers can reposition themselves relative to the live video area.
If all ads are hidden (allAdsHidden event from AdManager), the video is restored to its base dimensions.
OPTIONS key handling
Theoptions key is explicitly not intercepted — it returns false to let the Roku OS handle it. This is a certification requirement: