Skip to content

feat(playback): enable instant external text subtitle switching - #532

Closed
RXWatcher wants to merge 7 commits into
Silo-Server:mainfrom
RXWatcher:feature/instant-external-srt-switching
Closed

feat(playback): enable instant external text subtitle switching#532
RXWatcher wants to merge 7 commits into
Silo-Server:mainfrom
RXWatcher:feature/instant-external-srt-switching

Conversation

@RXWatcher

@RXWatcher RXWatcher commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Problem

Part of the coordinated instant external subtitle switching work with silo-android.

Switching between external SRT subtitles currently requires a playback replan and visible rebuffer even though text subtitles can be mounted by the client immediately.

Approach

  • Add the negotiated external_text_sidecar_set_v1 playback feature and additive V3 sidecar contract.
  • Advertise only readable, non-empty external SRT/VTT tracks when both client feature locations opt in.
  • Serve authenticated raw SRT/VTT bytes through the existing session-owned subtitle route.
  • Preserve sidecars across start, replan, persisted attempts, and idempotent replay.
  • Keep unnegotiated clients and existing selected-artifact behavior unchanged.

Companion Android PR: Silo-Server/silo-android#159

Testing

Passing:

  • go test -count=1 ./internal/api/handlers — PASS
  • go test ./internal/playback -run 'Test(ServerFeaturesV3ReturnsCompleteIndependentSlices|SubtitleDecisionV3SidecarsRoundTrip|ProtocolV3GoldenWireFixtures)$' — PASS
  • make verify-local-paths — PASS
  • cd web && pnpm run format:check — PASS
  • git diff --check — PASS

Known baseline limitations, reproduced independently of this diff:

  • make test-go reaches the repository-wide suite but four macOS NVENC fake-probe timing tests fail identically on an untouched upstream/main snapshot.
  • make lint reports the existing repository lint backlog (308 findings, including stale paths from another checkout).
  • make test-web fails current Node localStorage-dependent tests; this PR changes no web code.

AI Disclosure

  • Tool(s): OpenAI Codex, Gradle, Go tooling, GitHub CLI
  • Model(s): GPT-5
  • Involvement: design, implementation, tests, verification, and PR preparation
  • Adversarial review: independent read-only review found no Critical or Important server issues; Android burn-in route risk was identified, fixed, and re-reviewed cleanly

Checklist

  • I ran an adversarial AI review of the diff and summarized findings above.
  • I ran the repo verify commands: relevant Go tests and local-path verification pass; repository-wide lint/test exceptions are documented above and reproduce outside this diff.

Summary by CodeRabbit

  • New Features

    • Added negotiated external SRT and WebVTT subtitle support in Playback V3.
    • Compatible playback clients can switch between external text tracks without restarting playback or replanning.
    • External subtitle files are served in their native format with appropriate content types.
    • Subtitle sidecars persist consistently across playback starts, replans, and replay requests.
  • Bug Fixes

    • Invalid, empty, missing, or unsupported subtitle files are safely excluded without affecting primary playback.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 68653c35-cb94-4998-9da2-47cbc0cfe30b

📥 Commits

Reviewing files that changed from the base of the PR and between 88d6ac2 and 508bd34.

📒 Files selected for processing (5)
  • docs/superpowers/specs/2026-08-02-instant-external-srt-switching-design.md
  • internal/api/handlers/playback_v3.go
  • internal/api/handlers/stream.go
  • internal/playback/protocol_v3_test.go
  • web/src/lib/overlays/schema.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • internal/playback/protocol_v3_test.go
  • internal/api/handlers/playback_v3.go
  • docs/superpowers/specs/2026-08-02-instant-external-srt-switching-design.md
  • internal/api/handlers/stream.go

📝 Walkthrough

Walkthrough

Adds negotiated external SRT/WebVTT subtitle sidecars to Playback V3. The change adds a protocol field and feature flag, validates and persists sidecars during start and replan, serves raw subtitle files, and adds tests and design documentation.

Changes

External subtitle sidecar feature

Layer / File(s) Summary
Protocol contract and feature flag
internal/playback/protocol_v3.go, internal/playback/protocol_v3_test.go
Adds the sidecar feature flag, SubtitleSidecarV3, optional Sidecars, feature advertisement, and JSON round-trip coverage.
Playback sidecar construction and persistence
internal/api/handlers/playback_v3.go, internal/api/handlers/playback_v3_sidecars_test.go, internal/api/handlers/playback_v3_test.go
Negotiates features in both request locations, validates readable non-empty SRT/WebVTT files, attaches sidecars during start and replan, and verifies stable metadata across repeated requests.
Raw external subtitle serving
internal/api/handlers/stream.go, internal/api/handlers/stream_test.go
Serves external SRT and VTT files without conversion and returns format-specific content types. Tests verify raw response bodies.
Design and implementation documentation
docs/superpowers/specs/..., docs/superpowers/plans/...
Documents the protocol, validation, serving, playback integration, fallback behavior, compatibility, tests, and verification steps.
Overlay schema formatting
web/src/lib/overlays/schema.ts
Reformats PASSTHROUGH_IDS without changing its values or type.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant PlaybackHandlerV3
  participant SubtitleStorage
  participant StreamHandler

  Client->>PlaybackHandlerV3: Start or replan with feature flags
  PlaybackHandlerV3->>SubtitleStorage: Load external SRT/VTT file
  SubtitleStorage-->>PlaybackHandlerV3: Subtitle content or error
  PlaybackHandlerV3-->>Client: Playback plan with sidecars
  Client->>StreamHandler: Request subtitle by sidecar URL
  StreamHandler->>SubtitleStorage: Load raw subtitle file
  SubtitleStorage-->>StreamHandler: Raw subtitle content
  StreamHandler-->>Client: Subtitle content with MIME type
Loading

Possibly related PRs

Suggested labels: v1

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: enabling instant switching for external text subtitles during playback.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the v1 Silo v1 scope - auto-adds to the Silo v1 project label Aug 2, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/superpowers/plans/2026-08-02-instant-external-srt-switching-server.md`:
- Around line 29-32: Update the V3 sidecar contract and its round-trip test to
explicitly use and assert the JSON keys track_id, index, url, mime_type, format,
and timing_origin_seconds for SubtitleSidecarV3, matching the existing
snake_case conventions in protocol_v3.go. Ensure SubtitleDecisionV3 serializes
sidecars with these exact field names so the Android decoder receives the
metadata.
- Around line 195-205: Update attachExternalTextSidecarsV3 to derive each
external track’s index from the canonical merged subtitle inventory used by
buildSubtitleURLs, preserving that index through filtering instead of using the
local file.ExternalSubtitles position. Use the canonical index for TrackIDV3 and
the subtitle URL, sort sidecars by it, reject duplicate indexes before
serialization, and add coverage for an external track whose merged index is
nonzero.

In `@docs/superpowers/specs/2026-08-02-instant-external-srt-switching-design.md`:
- Around line 91-94: Update the V3-to-session adapter specification to
explicitly state that a singular artifact takes precedence over any sidecar with
the same combined index, regardless of merge order. Add an Android test covering
this collision and asserting that the artifact is retained while the duplicate
sidecar is discarded.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c86e4a51-880a-4af7-8b03-631cb2dc39e3

📥 Commits

Reviewing files that changed from the base of the PR and between 97669d5 and 88d6ac2.

📒 Files selected for processing (9)
  • docs/superpowers/plans/2026-08-02-instant-external-srt-switching-server.md
  • docs/superpowers/specs/2026-08-02-instant-external-srt-switching-design.md
  • internal/api/handlers/playback_v3.go
  • internal/api/handlers/playback_v3_sidecars_test.go
  • internal/api/handlers/playback_v3_test.go
  • internal/api/handlers/stream.go
  • internal/api/handlers/stream_test.go
  • internal/playback/protocol_v3.go
  • internal/playback/protocol_v3_test.go

Comment thread docs/superpowers/specs/2026-08-02-instant-external-srt-switching-design.md Outdated
@Quick104

Copy link
Copy Markdown
Contributor

Closing this implementation rather than rejecting the product goal. The draft parallel sidecar shape was superseded by the platform-neutral protocol-v3 inventory in #567, and this branch now conflicts with the current playback implementation. A defect-first review also found synchronous full-file reads of every eligible SRT/VTT during start and replan, which could block playback or consume unbounded memory on large, numerous, or slow files. The current-contract follow-up, including bounded loading and behavioral acceptance criteria, is tracked in #689. The web app did not negotiate this feature and is not materially affected. Thanks for exploring the original direction.

@Quick104 Quick104 closed this Aug 20, 2026
@github-project-automation github-project-automation Bot moved this to Done in Silo v1 Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v1 Silo v1 scope - auto-adds to the Silo v1 project

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants