fix(player): stack bilingual subtitle cues so they don't overlap - #59
fix(player): stack bilingual subtitle cues so they don't overlap#59ModerRAS wants to merge 2 commits into
Conversation
Bilingual (CN+JP) ASS subtitles rendered as overlapping layers because every dialogue cue shared the bottom-centre position and media3's SubtitleView drew them on top of each other. With many simultaneous lines the stack also overflowed the screen and clipped every line to half-height. Intercept onCues from the ExoPlayer, restack simultaneous cues into explicit vertical line positions counting up from the bottom, clear embedded horizontal position/size so nothing drifts off-screen, and cap the stack so it never overflows the top. Render on a controlled SubtitleView overlay (the PlayerView's built-in SubtitleView is hidden) so the restacked layout actually takes effect. - Add restackSubtitleCues() pure function (ui-tv) with unit tests - Wire Player.Listener.onCues in PlayerScreen to collect current cues - Hide PlayerView.subtitleView; render a restacked SubtitleView overlay - Preserve ASS embedded styling (colours/typeface); only positioning is normalised - Apply the existing transparent-background preference to the overlay
|
Warning Review limit reached
Next review available in: 8 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
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. Comment |
Set sub-ass-override=force on the embedded mpv backend so bilingual (CN+JP) ASS dialogue lines stack vertically instead of overlapping at the same \pos, mirroring the ExoPlayer cue-restack fix. libass then renders plain, wrapped, bottom-stacked subtitles via its default collision avoidance. - Add mpvSubtitleLayoutNormalisationOptions declarative config + unit test - Apply the options in MiruMpvSurfaceView.initOptions() Note: this discards ASS styling (colours/fonts) on the mpv backend, trading fidelity for readability — consistent with normalising layout on ExoPlayer.
Problem
Bilingual (CN+JP) ASS subtitles rendered as two overlapping layers because every dialogue cue shared the bottom-centre position and the renderers drew them on top of each other. With many simultaneous lines the stack also overflowed the screen and clipped every line to half-height.
Fix — both backends
ExoPlayer / media3 (default backend)
Subtitles were rendered by the
PlayerView's built-inSubtitleViewwith no cue processing, so cues kept their ASS positions and collided.Player.Listener.onCues(CueGroup)inPlayerScreento collect current cues.restackSubtitleCues(cues)(pure fn): assign explicit line numbers counting up from the bottom (-1,-2, … withLINE_TYPE_NUMBER+ANCHOR_TYPE_END) so cues stack without overlapping; clear embedded horizontalposition/size(DIMEN_UNSET) so nothing drifts off-screen → fixes overflow; cap the stack at 4 (keeping most recent) so it never overflows the top → fixes clipping; preserves ASS embedded styling (colours/typeface) viabuildUpon().PlayerView.subtitleView; render a controlledSubtitleViewoverlay with the restacked cues, applying the existing transparent-background preference.mpv / libass (experimental embedded backend)
sub-ass-override=forceinMiruMpvSurfaceView.initOptions()so libass ignores embedded ASS\pos/styles and renders plain, wrapped, bottom-stacked subtitles via its default collision avoidance → bilingual lines stack instead of overlapping.mpvSubtitleLayoutNormalisationOptionsconfig (applied ininitOptions).Tests
SubtitleCueLayoutTest(6 tests, ExoPlayer restack logic) — all passing.MpvSubtitleLayoutTest(2 tests, mpv normalisation option) — all passing.:ui-tv:testDebugUnitTestand:player-mpv-android:testDebugUnitTestboth BUILD SUCCESSFUL (no regressions).Notes
force).