Skip to content

fix(signage): stop playback leaks, restarts and stalls - #527

Merged
MrYuion merged 2 commits into
developfrom
fix/signage-player-playback
Oct 2, 2026
Merged

MrYuion merged 2 commits into
developfrom
fix/signage-player-playback

Conversation

@MrYuion

@MrYuion MrYuion commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

Over days of looping, the media player leaked blob URLs, restarted items, cut items short and could hold the screen:

  • No ngOnDestroy, so up to 5 blob URLs leaked per takeover or template change.
  • Any playlist change restarted the current item after a blank gap.
  • A fatal error from a preloaded plugin cut the active image short.
  • Retries counted as plays in the metrics.
  • iframe.src comparisons failed after URL normalisation, so preloaded webpages loaded twice.
  • A lone play-through plugin played once, then stopped.
  • A single-pass takeover with one webpage or plugin never ended.

Changes

  • URL cleanup: ngOnDestroy revokes item URLs, and URLs that resolve late are revoked.
  • Playlist changes: the current item keeps its URL and output when it is still in the new list.
  • Plugin errors: handled only for the active plugin on its own output.
  • Metrics: emitted on a real advance only. Debug "previous" and playlist-panel picks no longer count.
  • URL storage: item URLs are stored as normalised strings.
  • plugin-embed: a new finished output, emitted for every finished message. The player replays a lone play-through plugin on each one. Other users of the component don't bind it.
  • Held lone items: a held webpage or plugin reports one pass, so a single-pass takeover can end.
  • Other: mutedInput changes are applied, webpage iframes get sandbox="allow-scripts allow-same-origin allow-forms", hot validity checks use isMediaValid, and dead members are removed.

Testing

  • Unit tests for each fix. Each fails without its fix, including a test through the real plugin-embed.
  • nx test signage (432), nx test components and nx build signage pass.
  • Local PlaceOS stack: all checks pass. These covered no restart on playlist edits, one preload request, no second plugin play, a preloaded plugin's fatal error, lone plugin replay over 12 rounds, single-pass with a lone webpage or plugin, a timed takeover holding until its end, blob URL count across takeovers, the sandbox, and mute.

Notes

  • Chrome warns that allow-scripts + allow-same-origin can escape the sandbox. That is expected for this setting; cross-origin pages stay blocked.

Independent of the other signage PRs from this review. Based on develop.


Changes made by Claude Opus 5.5 (1M context) in Claude Code, running in T3 Code.

🤖 Generated with Claude Code

- Revoke item blob URLs on destroy and URLs that resolve late.
- Keep the current item playing when the playlist changes around it.
- A fatal error from a preloaded plugin no longer cuts the active item.
- Count playlist metrics only on a real advance, not on retries.
- Store item URLs as normalised strings, so a preloaded webpage is not
  loaded again on reveal.
- Replay a lone play-through plugin after every finished message. The
  plugin embed now emits finished for each message.
- A held lone webpage or plugin reports one pass, so a single-pass
  takeover can end.
- Apply muted changes, sandbox webpage iframes, skip formatting in hot
  validity checks, and remove dead members.
@vercel

vercel Bot commented Oct 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
frontend-templates Ignored Ignored Oct 2, 2026 3:14am UTC

@greptile-apps

greptile-apps Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium risk] Fixes media playback timing and plugin lifecycle handling.

The PR appears safe to merge; both earlier findings are addressed, and no new actionable issue was found.

What we checked:

  • Old media source returns late: No. Each request has a token, and the player releases a result when that token is no longer current.
  • Failed preload reused later: No. The player clears the failed output, skips another preload, and clears that skip when it starts a fresh display attempt.

Summary

The signage player keeps playback steady through playlist edits and handles plugin finishes, media URLs, and playback counts more consistently. It also limits webpage frames, applies mute to both video outputs, and updates the playback controls and media-validity checks.

  • Unchanged items keep playing when a playlist changes.
  • Plugin preloads and repeated finishes no longer control the wrong playback step.
  • URL cleanup and playback counts follow real playback activity.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Playlist changes] --> B{Item unchanged?}
  B -- Yes --> C[Keep its URL and output]
  B -- No --> D[Cancel its URL request]
  D --> E[Start a fresh request]
  F[Old request returns] --> G{Token still current?}
  G -- No --> H[Release result]
  G -- Yes --> I[Save URL]
Loading

Reviews (2) · Last reviewed commit: "fix(signage): reload failed preloads and..."

Comment thread apps/signage/src/app/media-player.component.ts Outdated
Comment thread apps/signage/src/app/media-player.component.ts
- A fatal error from a preloaded plugin clears its output and marks it,
  so it is not preloaded again and loads afresh on its turn.
- URL requests carry a per-item token. Results from a superseded or
  cancelled request are revoked instead of saved, and playlist edits
  cancel requests for removed or changed items.
@vercel

vercel Bot commented Oct 2, 2026

Copy link
Copy Markdown

Deployment failed for project frontend-templates with the following error:

Resource is limited - try again in 24 hours (more than 100, code: "api-deployments-free-per-day").

Learn More: https://vercel.com/placeos?upgradeToPro=build-rate-limit

@MrYuion
MrYuion merged commit 528a846 into develop Oct 2, 2026
4 of 5 checks passed
@MrYuion
MrYuion deleted the fix/signage-player-playback branch October 2, 2026 04:05
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