Skip to content

feat: multi-track subtitle selection - #948

Merged
diegotori merged 7 commits into
fluttercommunity:masterfrom
Fullphysio:feat/subtitle-tracks-upstream
Sep 16, 2026
Merged

diegotori merged 7 commits into
fluttercommunity:masterfrom
Fullphysio:feat/subtitle-tracks-upstream

Conversation

@Ortes

@Ortes Ortes commented May 31, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Streaming sources (notably HLS) expose multiple subtitle renditions in their manifest, but Chewie currently has no UI to let the user pick one. This adds a source-agnostic subtitle-track picker to the Material controls.

What this adds

  • A track picker in the options menu (plus an Off entry) that appears only when subtitleTracks is non-empty.
  • Support for streaming cues that arrive over time (via setLiveSubtitle), alongside the existing static subtitle cue list.

The widget is source-agnostic: the host populates the track list and reacts to selection; Chewie never assumes HLS or any particular backend.

API (all opt-in — defaults preserve current behavior)

ChewieController:

  • List<SubtitleTrack> subtitleTracks — selectable tracks (default empty).
  • Object? activeSubtitleTrackId — currently selected id (null = Off).
  • void Function(SubtitleTrack?)? onSubtitleTrackChanged — selection callback.
  • setSubtitleTracks() / selectSubtitleTrack() — for tracks known only after load.
  • setLiveSubtitle(String?) + ValueNotifier<String?> liveSubtitle — push current cue text for streaming sources.
  • bool get hasSubtitleTracks — gates the menu entry.

New: SubtitleTrack model and SubtitleTrackDialog bottom sheet.

Backwards compatibility

Fully backwards compatible — every field is optional and defaults to the current behavior. No menu entry appears unless the host provides tracks.

Testing

  • dart analyze — no issues.
  • In production use in an HLS web player (subtitle tracks parsed from the manifest, cues pushed via setLiveSubtitle).

Independent of the audio-track PR (#949) — single commit, based on master.

@codecov

codecov Bot commented May 31, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.28571% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.60%. Comparing base (a0ddf90) to head (d568acf).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
lib/src/material/material_controls.dart 98.38% 1 Missing ⚠️
lib/src/material/material_desktop_controls.dart 98.38% 1 Missing ⚠️
lib/src/models/subtitle_track.dart 90.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #948      +/-   ##
==========================================
+ Coverage   78.18%   82.60%   +4.42%     
==========================================
  Files          45       48       +3     
  Lines        2760     2967     +207     
==========================================
+ Hits         2158     2451     +293     
+ Misses        602      516      -86     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Ortes
Ortes marked this pull request as ready for review May 31, 2026 20:49
@diegotori

Copy link
Copy Markdown
Collaborator

@Ortes please resolve the conflicts currently present in this PR. Thanks.

@Ortes
Ortes force-pushed the feat/subtitle-tracks-upstream branch from 2ad5fc7 to 5781617 Compare August 12, 2026 06:41
Ortes added a commit to Fullphysio/chewie that referenced this pull request Aug 12, 2026
Ortes added a commit to Fullphysio/chewie that referenced this pull request Aug 15, 2026
@Ortes
Ortes force-pushed the feat/subtitle-tracks-upstream branch from 06cfaf8 to b927929 Compare August 15, 2026 11:13
@diegotori

Copy link
Copy Markdown
Collaborator

@Ortes please resolve conflicts. Thanks.

Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 1, 2026
@Ortes
Ortes force-pushed the feat/subtitle-tracks-upstream branch 2 times, most recently from ca59ac7 to 17a9fe6 Compare September 1, 2026 12:16
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 1, 2026
@Ortes
Ortes force-pushed the feat/subtitle-tracks-upstream branch from 17a9fe6 to 20143d9 Compare September 1, 2026 19:57
Ortes added a commit to Fullphysio/chewie that referenced this pull request Sep 9, 2026
@Ortes
Ortes force-pushed the feat/subtitle-tracks-upstream branch 2 times, most recently from ae14bc3 to dc4ab7d Compare September 14, 2026 21:21
@Ortes
Ortes force-pushed the feat/subtitle-tracks-upstream branch 2 times, most recently from f3d9209 to 2b10925 Compare September 16, 2026 21:39

@diegotori diegotori left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM.

@diegotori

Copy link
Copy Markdown
Collaborator

@Ortes if you fix the conflicts on this one, then I'll be able to release a new build today. Thanks.

Generalise subtitle support beyond a single on/off cue list: the controller
now holds a source-agnostic list of selectable SubtitleTracks, an active id
and an onSubtitleTrackChanged callback, plus a liveSubtitle ValueNotifier for
streaming sources (e.g. HLS) that emit cue text over time.

- ChewieController: subtitleTracks / activeSubtitleTrackId /
  onSubtitleTrackChanged / liveSubtitle, setSubtitleTracks, selectSubtitleTrack,
  setLiveSubtitle; copyWith + dispose wired.
- Material + Material desktop controls: a Subtitles entry in the options menu
  opening a track picker, live-cue rendering reusing subtitleBuilder, and a
  track-aware toggle.
- SubtitleTrackDialog widget + SubtitleTrack model.
Adds unit and widget tests for the new subtitle-track API:
- SubtitleTrack model (equality, hashCode, toString)
- SubtitleTrackDialog (rendering, selection, custom off label, dismissal)
- ChewieController track methods (setSubtitleTracks, selectSubtitleTrack,
  setLiveSubtitle, copyWith, dispose, hasSubtitleTracks)
- Material and desktop controls: toggle-driven selection, options-menu
  track picker, live-cue and static-cue rendering, custom subtitleBuilder

Brings patch coverage to ~99%.
The Material controls passed the optionsTranslation subtitle label into the
SubtitleTrackDialog's "off" entry, but the desktop controls always showed the
hardcoded "Off". Mirror the Material behavior so both variants honor
optionsTranslation.subtitlesButtonText.
The Flutter 3.47 upgrade enabled prefer_initializing_formals. Keeps the
fields private, matching _PlaybackSpeedDialog in cupertino_controls.dart;
callers still pass tracks:/selectedId:.
selectSubtitleTrack and setSubtitleTracks notify ChewieController, but the
Material and desktop controls only listened to the video controller, so
_subtitleOn never moved when the host drove selection from code instead of a
UI tap. Since _buildSubtitleLayer bails out on !_subtitleOn, a programmatic
selection rendered no cues at all until the user tapped the toggle — the
common path for HLS, where tracks are discovered from the manifest.

Listen to ChewieController in both controls and mirror activeSubtitleTrackId
into _subtitleOn. Guarded on hasSubtitleTracks so the legacy single-subtitle
toggle keeps its current behaviour, and on an actual value change so the
other notifyListeners callers don't trigger spurious rebuilds.
@Ortes
Ortes force-pushed the feat/subtitle-tracks-upstream branch from 2b10925 to d568acf Compare September 16, 2026 21:47
@diegotori
diegotori merged commit 3fb93a3 into fluttercommunity:master Sep 16, 2026
5 checks passed
diegotori added a commit that referenced this pull request Sep 16, 2026
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.

2 participants