Files
Classroom_Desktop/lib/classroom_vlc.py
ekklesiaandClaude Opus 5 13aac85b87 docs: record Parent Call, the DVD migration and what is left to test
Three things in this window that a container cannot answer, and they are
now the top of the next-steps list: a real key pressed into Parent Call,
a television switched on after the computer, and a disc that plays.

Also brings the comments in the shared libraries up to date. The only
mention of sway left in the tree is the upgrade step that removes the
sway-era login shell from a room being upgraded.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-10 13:09:42 -05:00

129 lines
5.0 KiB
Python

"""How the classroom launches VLC.
VLC is the DVD backend because its dvdnav module is what decodes disc
menus. Everything a user can see or press, though, belongs to the
classroom: the visible controls are classroom-dvd-session's overlay, and
VLC's own interface and keyboard are shut down here.
"""
import secrets
PLAYER = "vlc"
# Every hotkey VLC 3.0.23 defines, read out of `vlc -H --advanced` on
# Debian Trixie. All of them are unset before anything is bound, so a
# volunteer cannot land on crop, aspect ratio, subtitle tracks, audio
# tracks, deinterlacing or the volume by pressing a key at random.
#
# A future VLC that adds a hotkey would leave it bound. Regenerate with:
# vlc -H --advanced | grep -oP '^\s+--key-\K[a-z0-9-]+'
ALL_HOTKEYS = (
"aspect-ratio", "audio-track", "audiodelay-down", "audiodelay-up",
"audiodevice-cycle", "chapter-next", "chapter-prev", "clear-playlist",
"crop", "crop-bottom", "crop-left", "crop-right", "crop-top",
"decr-scalefactor", "deinterlace", "deinterlace-mode", "disc-menu",
"faster", "frame-next", "incr-scalefactor", "intf-boss",
"intf-popup-menu", "intf-show", "jump-extrashort", "jump-long",
"jump-medium", "jump-short", "leave-fullscreen", "length", "loop",
"nav-activate", "nav-down", "nav-left", "nav-right", "nav-up", "next",
"pause", "play", "play-bookmark1", "play-bookmark10", "play-bookmark2",
"play-bookmark3", "play-bookmark4", "play-bookmark5", "play-bookmark6",
"play-bookmark7", "play-bookmark8", "play-bookmark9", "play-pause",
"position", "prev", "program-sid-next", "program-sid-prev", "quit",
"random", "rate-faster-fine", "rate-normal", "rate-slower-fine",
"record", "set-bookmark1", "set-bookmark10", "set-bookmark2",
"set-bookmark3", "set-bookmark4", "set-bookmark5", "set-bookmark6",
"set-bookmark7", "set-bookmark8", "set-bookmark9", "slower",
"snapshot", "stop", "subdelay-down", "subdelay-up", "subpos-down",
"subpos-up", "subsync-apply", "subsync-markaudio", "subsync-marksub",
"subsync-reset", "subtitle-revtrack", "subtitle-text-scale-down",
"subtitle-text-scale-normal", "subtitle-text-scale-up",
"subtitle-toggle", "subtitle-track", "title-next", "title-prev",
"toggle-autoscale", "toggle-fullscreen", "uncrop-bottom",
"uncrop-left", "uncrop-right", "uncrop-top", "unzoom",
"viewpoint-fov-in", "viewpoint-fov-out", "viewpoint-roll-anticlock",
"viewpoint-roll-clock", "vol-down", "vol-mute", "vol-up", "wallpaper",
"zoom", "zoom-double", "zoom-half", "zoom-original", "zoom-quarter",
)
# The only keys a classroom DVD responds to.
#
# Esc quits rather than leaving fullscreen: DVD mode is the whole screen,
# so there is nothing to leave, and leaving it used to strand people on a
# black VLC window with no way out. Volume is deliberately absent — the
# television owns volume.
CLASSROOM_HOTKEYS = {
"play-pause": "Space",
"quit": "Esc",
# Disc menu navigation. Without these a menu can only be clicked.
"nav-up": "Up",
"nav-down": "Down",
"nav-left": "Left",
"nav-right": "Right",
"nav-activate": "Enter",
}
# VLC dressed down to a playback surface. Verified against 3.0.23.
PRESENTATION = (
# DVD mode is the whole display, and the compositor fullscreens the
# window the
# moment it maps so no wallpaper is ever visible around it.
"--fullscreen",
# No menu bar, no panels, dark rather than light grey.
"--qt-minimal-view",
"--qt-dark-palette",
# No orange cone or album-art panel behind the video.
"--no-qt-bgcone",
# VLC's own fullscreen controller is replaced by the classroom bar.
"--no-qt-fs-controller",
# Nothing that behaves like a desktop application.
"--no-qt-system-tray",
"--no-qt-name-in-title",
"--no-qt-video-autoresize",
"--qt-notification=0",
# Never offer to resume, never keep a list of the discs played here.
"--qt-continue=0",
"--no-qt-recentplay",
# No first-run privacy dialog, no title banner over the video.
"--no-qt-privacy-ask",
"--no-video-title-show",
)
def control_password():
"""A fresh password for this session's control interface."""
return secrets.token_urlsafe(24)
def player_command(device, port, password):
"""The full VLC command line for a DVD session.
The HTTP control interface is how the classroom's own control bar
reaches VLC. It triggers hotkey *actions* by name, which keeps
working after every key has been unbound, and it listens on the
loopback address behind a password generated for this session only.
"""
command = [PLAYER, *PRESENTATION]
for hotkey in ALL_HOTKEYS:
command.append(f"--key-{hotkey}=")
for hotkey, binding in CLASSROOM_HOTKEYS.items():
command.append(f"--key-{hotkey}={binding}")
command += [
"--extraintf",
"http",
"--http-host",
"127.0.0.1",
"--http-port",
str(port),
"--http-password",
password,
]
# dvd:// selects dvdnav, which is what provides the disc menus.
command.append(f"dvd://{device}")
return command