-
Notifications
You must be signed in to change notification settings - Fork 0
Developer Player Look
otakase gives the mpv it starts its own controls (MpvSkin). This page is how
that works; what users see is on Configuration.
-
otakase_skin.lua (
internal/mpvskin/assets/scripts) is the whole on-screen controller, drawn with ASS into oneosd-overlay: the top bar (back button, title, tracker/source chips), the seek bar with openings and endings marked, the control row (previous, play, next, time, volume, episodes, audio, subtitles, quality, fullscreen) and its menus, the Skip Opening/Ending button, the Skipped Opening · Undo notice and the Up next card. mpv's own OSC is turned off with--osc=no. -
MaterialIconsRound.otf (
assets/fonts, Apache-2.0, licence inassets/LICENSE.MaterialIcons) draws the icons by ligature name (play_arrow,skip_next,subtitles, …). It is loaded with--osd-fonts-dir, so nothing is installed and Windows works the same. Keep only fonts in that folder: libass tries to open every file in it.
mpvskin.Install writes the embedded files to
<StoragePath>/mpv-skin/<content hash>/ once per build (written to a
temporary folder and renamed, so two otakase processes never race), and
removes copies from older builds.
mpvSkinArgs (internal/mpv_skin.go) decides per launch, and adds nothing
when:
-
MpvSkin=false, or the player is notmpv/mpv.exe(IINA, mpv-android, others); -
MpvArgsalready decide the controls (--osc,--script=,--no-config); -
MpvSkin=autoand the user's mpv config has a skin script (uosc,modernx,modernz,osc*, … inscripts/) orosc=noinmpv.conf(mpvskin.ConfigDirslists where mpv looks,$MPV_HOMEandportable_configincluded); -
mpv --versionis older than 0.37 or unreadable:--osd-fonts-diris 0.37+, and mpv refuses to start on a flag it does not know.
The flags go first on the command line, so the user's MpvArgs after them
still win: --osc=no, --script=, --osd-fonts-dir, --osd-font (the
monospace font from theme.MonospaceFont, unless mpv.conf or MpvArgs
set one), and one --script-opts-append=otakase_skin-<key>=<value> per
option. Command-line script options beat the user's own
script-opts/otakase_skin.conf, for this process only.
mpvSkinColors maps the active palette: background (bar fades, cards),
surface (menus, chips, hovered buttons), foreground, bright (title,
current time), dim (MetaText), accent (play button, seek fill),
accent_text (readable on the accent) and highlight (ResumeText, the
opening/ending marks). They are passed as rrggbb; ASS wants bbggrr,
which the script converts.
- Text is measured by libass itself: a hidden overlay with
compute_boundsreturns the box a string was drawn in (cached per string and size). - ASS has no gradients; the bar fades are bands 3 px tall that meet exactly. Overlapping bands double their alpha into visible stripes.
- Sizes scale with the window height (
h / 720, clamped). - While the controls are up,
sub-posis raised so subtitles sit above them, and put back when they hide.sub-margin-ywould not move them while paused.
The skin reads openings and endings from the chapter list otakase already
writes (SendSkipTimesToMPV: chapters titled Opening and Ending).
otakase skips by seeking from the first two seconds of a span to its end
(SkipSeekTarget, polled once a second). The script, told by
otakase_skin-skip_op/-skip_ed that otakase skips these:
- hides the Skip button for the first 2.5 s of the span, so it does not flash before the automatic skip;
- treats a seek from there to the span's end as that skip and shows Undo, which seeks back to 2.5 s into the span, past the window otakase skips from, so it is not skipped again.
SendMPVSkinState sends script-message-to otakase_skin otakase-state {"chips":[{"icon":"sync","text":"AniList"},...],"episode_title":"..."} when
an episode starts and when the playlist moves on (the source can change after
a fallback). episode_title is the episode's name from Jikan (English, else
romaji), shown after the title in the top bar; it is sent only once Jikan has
been asked for that episode (finalizePlaylistEpisodeChange), left out
otherwise so a stale one never shows, and the script clears it whenever the
playlist position changes. It retries for a few seconds, because right after launch the script may not
have registered yet. Only sockets started with the skin are sent to.
The script binds MBTN_LEFT and the wheel only while the pointer is over
one of its buttons or bars, so every other click still reaches the user's
input.conf. ENTER is bound only while the corner offers something
(skip, undo, play next), ESC only while a menu is open.
Under X11 (or Xvfb with --vo=x11), start mpv with the output of
mpvskin.Args and two local files, then set chapters and chips over IPC:
{"command":["set_property","chapter-list",[{"title":"Opening","time":90},{"title":"Main","time":180},{"title":"Ending","time":1330},{"title":"Post-Credits","time":1420}]]}
{"command":["script-message-to","otakase_skin","otakase-state","{\"chips\":[{\"icon\":\"sync\",\"text\":\"AniList\"}]}"]}IPC mouse x y moves the pointer and mouse x y 0 single clicks.