Player: sharp video and subtitles at screen size; dev tools: danmaku preview, subtitle lift with a stand-in chat line

- "Sharp video and subtitles" (Settings → Player and the player settings
  card, on by default): the video output renders at the view's physical
  size (debounced, GPU rendering only), so libass, mpv's scaler and the
  shaders work at screen resolution; re-sent after media_kit's own reset
  on new video params, redrawn while paused.
- Dev builds only (Settings → About → Developer): a danmaku preview
  (DanmakuLayer: free lanes in an upper band, density cap with a queue,
  equal crossing time, outlined text, avatars, own-line frame) over the
  real player or a stand-in picture, with samples, a random stream, live
  toasts, every knob and mock subtitles; and "Lift subtitles above the
  chat line and controls": Enter opens a stand-in chat line, bottom
  subtitles move up via mpv sub-pos while it or the control bar is up.
- tool/make_sub_test.sh: a test video with a top \an8 sign, bottom
  dialogue and an SRT track.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
foxyzandClaude Opus 5.5 committed 2026-10-18 02:19:40 +03:00
1 parent 638a30e16c
commit 5bc252bf02
18 files changed
+2253 -16

No files matched your search

+24
View File
@@ -46,6 +46,8 @@ const _keyNotifyPeople = 'notifyPeople';
const _keyShareDiagnostics = 'shareDiagnostics';
const _keyWhatsNewSeen = 'whatsNewSeen';
const _keyWhatsNewNotes = 'whatsNewNotes';
const _keyScreenResVideo = 'screenResVideo';
const _keyLiftSubtitles = 'liftSubtitles';
enum HwdecMode { auto, off, custom }
@@ -89,6 +91,14 @@ class AppSettings {
/// Send this app's log lines to the server's session log while in a
/// session (never chat). Off: nothing is sent but a note that it is off.
final shareDiagnostics = signal(true);
/// The video output renders at the player's size on screen, so mpv
/// scales the picture (and runs shaders) and draws subtitles at screen
/// resolution; off: at the video's own size, scaled by Flutter. Applies
/// live (GPU rendering only).
final screenResVideo = signal(true);
/// Dev builds only, an experiment: bottom subtitles move up while the
/// controls are up (mpv `sub-pos`). Applies live.
final liftSubtitles = signal(false);
/// Chat message toasts (default: all). Applies live.
final chatPopups = signal(ChatPopups.all);
/// Joins and leaves also notify while sitting out or with the window in
@@ -175,6 +185,10 @@ class AppSettings {
if (hideRe is bool) hideReReleases.value = hideRe;
final line = box.get(_keyProgressLine);
if (line is bool) progressLine.value = line;
final screenRes = box.get(_keyScreenResVideo);
if (screenRes is bool) screenResVideo.value = screenRes;
final lift = box.get(_keyLiftSubtitles);
if (lift is bool) liftSubtitles.value = lift;
final share = box.get(_keyShareDiagnostics);
if (share is bool) shareDiagnostics.value = share;
final popups = box.get(_keyChatPopups);
@@ -279,6 +293,16 @@ class AppSettings {
_put(_keyProgressLine, on);
}
void setScreenResVideo(bool on) {
screenResVideo.value = on;
_put(_keyScreenResVideo, on);
}
void setLiftSubtitles(bool on) {
liftSubtitles.value = on;
_put(_keyLiftSubtitles, on);
}
void setShareDiagnostics(bool on) {
shareDiagnostics.value = on;
_put(_keyShareDiagnostics, on);