@vestra-player/sdk 1.6.15 → 1.6.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.6.17
4
+
5
+ **Who must change: nobody.** Tables follow the slim context menu (B5): a data refresh of `BUILTIN_COMMANDS`, `BUILTIN_SUBMENUS` and the test host's core commands for the player's right-click menu (player 0.7.6); no API change, `apiVersion` stays `vestra/1`. A plugin whose tests compare a path or a key against the tables sees the player's current ones.
6
+
7
+ - **`BUILTIN_COMMANDS`**: the top level is now Open File…, Open ▸, Close — **Play/Pause** (`host/play-pause`, from Playback ▸), Audio Track ▸, Subtitle Track ▸, **Snapshot ▸** (`vestra.capture`, from Video ▸) — Picture…, Audio…, Subtitles…, Playback…, Playlist, **Chapter and Bookmark List…** (`vestra.marks`, from Playback ▸ Chapters and Bookmarks ▸) — Toggle Fullscreen — Vestra Player AI…, Plugin Store… — **Command Palette…** (`host/palette`, in the menu now, with an ellipsis; `Ctrl+Shift+P` unchanged), **Options…** (`vestra.preferences`, from Settings ▸), About Vestra Player… — Quit. Open ▸ gains **Search and Download Subtitles…** (`vestra.subtitle-online`, from Subtitles ▸ Online Subtitles ▸). Everything else left the menu for the command palette, with ids, keys and categories unchanged: the player's Previous and Next (PageUp, PageDown, the side mouse buttons), Volume +, Volume − and Mute (the Audio panel has their controls); the playback plugin's Reopen, Copy to Clipboard ▸, Disable Screen Saver and the seek-bar hover items; the window plugin's Hide Pointer and the whole Screen ▸ menu; Playback ▸ Playlist ▸; Resume Playback ▸; the marks plugin's bookmark, chapter and A-B Loop items; Online Subtitle Settings…; the visualizer's Show Album Cover, Show Logo When Idle, Choose Logo Image… and Reset ▸ Idle Logo; Keyboard Shortcuts…, Mouse… and Ignore Default Shortcuts; Appearance ▸ and Language ▸; Playback Info, Playback Properties… and Check for Updates…. The table in [Reference: commands](docs/reference/commands.md) follows, with the new top level, its groups and orders (Toggle Fullscreen 810, Command Palette… 829).
8
+ - **`BUILTIN_SUBMENUS`**: Open ▸ Recently Played, Audio Track, Subtitle Track and Snapshot (a top-level submenu now) remain; the Playback, Subtitles, Screen and Settings submenus and Copy to Clipboard are gone. The built-in menus (`@playback`, `@subtitles`, `@video`, `@audio`, `@screen`, `@settings`, `@reset`) stay valid for plugins at their fixed orders and are shown only while a command is in them.
9
+ - **`TestHost`**: the core commands carry the player's menu places: Play/Pause at the top level (`["Play/Pause"]`, order 201), Previous, Next, the volume steps and Mute outside the menu, and the seek, frame and speed actions outside the menu as the player has had them since 1.6.15 (the test host kept their Playback ▸ Seek and Speed paths until now). A plugin item at `["Playback", "Seek", …]`, `["@playback", "Speed"]` or `["Audio", …]` is therefore accepted, as the player accepts it (1.5.48 listed `Playback ▸ Speed` as an item and `Audio ▸ Mute ▸ …` as conflicts: they were, while the player's items were there); `["Play/Pause"]`, `["Close"]` and an item below either are conflicts.
10
+
11
+ ## 1.6.16
12
+
13
+ **Who must change: nobody.** A data refresh for the player's four built-in panels (player 0.7.6) and one additive read; no API is removed, `apiVersion` stays `vestra/1`.
14
+
15
+ - **`BUILTIN_COMMANDS`**: the Picture, Audio, Subtitles and Playback panels open from four top-level items, **Picture…** (`vestra.video`, `video.picture`, Alt+1), **Audio…** (`audio.workbench`, Alt+2), **Subtitles…** (`tune`, Alt+3) and **Playback…** (`vestra.playback`, `panel`, Alt+4), next to Playlist. The commands their panels hold left the menus for the command palette, with their keys and categories: Video's Pixel Shaders, Deinterlace, Aspect, Crop/Stretch, Framing, Image Processing and Rotation, the picture steps and GPU Rendering; Audio's track, channel, equalizer, preset, sync and processing items; Subtitles' show, style, secondary subtitle, sync and reload items; the playback plugin's seek steps, keyframes, Jump to Time… and speeds; the Reset items of the video, audio and subtitles plugins (the visualizer's Reset ▸ Idle Logo stays). **Subtitle Track ▸ Off** and **Audio Track ▸ No Audio Tracks** are now top-level submenus. New palette commands: Remove External Subtitle (`vestra.subtitles`, `remove`) and Picture Panel (`video.resetPanel`, a reset of the panel's values). Audio ▸ Output Device ▸ No Output Devices (`audio.device.none`) is gone.
16
+ - **`BUILTIN_SUBMENUS`**: the Video, Audio and Subtitles submenus of these plugins are gone; **Subtitle Track** (`vestra.subtitles`) and **Audio Track** (`vestra.audio`) are new, at the top level. Online Subtitles and Snapshot stay.
17
+ - **`plugin.commands.keys("host/<id>")`** reads the keys of the player's own commands (`host/volume-up`, `host/mute`, the ids of the `host` rows of `BUILTIN_COMMANDS`), read-only and current like a plugin's own, so a panel can show the player's key caps beside its controls; `onKeysChange` fires for their changes too. The `commands.keys` answer and event carry them as `host/<id>` entries (a local id has no `/`); player 0.7.6, like `keys` itself. A side effect: rebinding one of the player's own commands now sends `commands.keys` to every plugin listening for it, and a listener in standby is started for it (as for a change to its own keys); `onKeysChange` still fires only when a label the plugin can read changed.
18
+ - **`TestHost`**: `commands.keys` answers the core commands as `host/<id>` too, and `rebind` takes a core command's `host/<id>`.
19
+
3
20
  ## 1.6.15
4
21
 
5
22
  **Who must change: nobody.** A plugin may now mount one panel per slot (player 0.7.6) instead of one panel in all; plugins with one panel work as before, and `apiVersion` stays `vestra/1`.
@@ -208,10 +208,10 @@ export interface BuiltinSubmenu {
208
208
  * built-in plugins declare.
209
209
  *
210
210
  * @example Add an item to the built-in Snapshot submenu
211
- * "Copy Snapshot" appears in Video ▸ Snapshot next to the built-in capture
211
+ * "Copy Snapshot" appears in Snapshot ▸ next to the built-in capture
212
212
  * plugin's items. Paths merge by their English keys, so a command whose
213
- * path continues with the submenu's keys (`["Video", "Snapshot"]`, the menu
214
- * written as `@video`) lands in the same submenu whatever the interface
213
+ * path starts with the submenu's keys (`["Snapshot"]`, a top-level submenu
214
+ * since player 0.7.6) lands in the same submenu whatever the interface
215
215
  * language.
216
216
  * ```ts
217
217
  * import type { Plugin } from "@vestra-player/sdk";
@@ -223,8 +223,8 @@ export interface BuiltinSubmenu {
223
223
  * const snapshot = BUILTIN_SUBMENUS.find((menu) => menu.path.at(-1) === "Snapshot")!;
224
224
  * plugin.commands.add({
225
225
  * id: "snapshot-to-clipboard",
226
- * // ["@video", "Snapshot", "Copy Snapshot"]; @video stands for "Video".
227
- * path: ["@video", ...snapshot.path.slice(1), "Copy Snapshot"],
226
+ * // ["Snapshot", "Copy Snapshot"]
227
+ * path: [...snapshot.path, "Copy Snapshot"],
228
228
  * run: copySnapshot,
229
229
  * });
230
230
  * ```
@@ -348,8 +348,9 @@ export type CommandDeclaration = {
348
348
  };
349
349
  /**
350
350
  * `commands.keys` (player 0.7.6): each of the plugin's own commands, by
351
- * local id, with the labels of its current keys; the answer to the request
352
- * and the data of the event of that name.
351
+ * local id, and (SDK 1.6.16) each of the player's own as `host/<id>`, with
352
+ * the labels of its current keys; the answer to the request and the data of
353
+ * the event of that name.
353
354
  */
354
355
  export type CommandKeys = {
355
356
  keys: Record<string, string[]>;
package/dist/commands.js CHANGED
@@ -234,10 +234,10 @@ export const BAR_BUTTON_LIMITS = {
234
234
  * built-in plugins declare.
235
235
  *
236
236
  * @example Add an item to the built-in Snapshot submenu
237
- * "Copy Snapshot" appears in Video ▸ Snapshot next to the built-in capture
237
+ * "Copy Snapshot" appears in Snapshot ▸ next to the built-in capture
238
238
  * plugin's items. Paths merge by their English keys, so a command whose
239
- * path continues with the submenu's keys (`["Video", "Snapshot"]`, the menu
240
- * written as `@video`) lands in the same submenu whatever the interface
239
+ * path starts with the submenu's keys (`["Snapshot"]`, a top-level submenu
240
+ * since player 0.7.6) lands in the same submenu whatever the interface
241
241
  * language.
242
242
  * ```ts
243
243
  * import type { Plugin } from "@vestra-player/sdk";
@@ -249,8 +249,8 @@ export const BAR_BUTTON_LIMITS = {
249
249
  * const snapshot = BUILTIN_SUBMENUS.find((menu) => menu.path.at(-1) === "Snapshot")!;
250
250
  * plugin.commands.add({
251
251
  * id: "snapshot-to-clipboard",
252
- * // ["@video", "Snapshot", "Copy Snapshot"]; @video stands for "Video".
253
- * path: ["@video", ...snapshot.path.slice(1), "Copy Snapshot"],
252
+ * // ["Snapshot", "Copy Snapshot"]
253
+ * path: [...snapshot.path, "Copy Snapshot"],
254
254
  * run: copySnapshot,
255
255
  * });
256
256
  * ```
@@ -261,54 +261,9 @@ export const BAR_BUTTON_LIMITS = {
261
261
  */
262
262
  export const BUILTIN_SUBMENUS = Object.freeze([
263
263
  { path: ["Open", "Recently Played"], plugins: ["vestra.history"] },
264
- { path: ["Playback", "A-B Loop"], plugins: ["vestra.marks"] },
265
- { path: ["Playback", "A-B Loop", "Loop Count"], plugins: ["vestra.marks"] },
266
- { path: ["Playback", "Chapters and Bookmarks"], plugins: ["vestra.marks"] },
267
- { path: ["Playback", "Playlist"], plugins: ["vestra.playlist"] },
268
- { path: ["Playback", "Playlist", "Repeat"], plugins: ["vestra.playlist"] },
269
- {
270
- path: ["Playback", "Playlist", "When Opening a File"],
271
- plugins: ["vestra.playlist"],
272
- },
273
- { path: ["Playback", "Resume Playback"], plugins: ["vestra.history"] },
274
- {
275
- path: ["Subtitles", "Online Subtitles"],
276
- plugins: ["vestra.subtitle-online"],
277
- },
278
- { path: ["Subtitles", "Secondary Subtitle"], plugins: ["vestra.subtitles"] },
279
- {
280
- path: ["Subtitles", "Secondary Subtitle", "Position"],
281
- plugins: ["vestra.subtitles"],
282
- },
283
- { path: ["Subtitles", "Subtitle Style"], plugins: ["vestra.subtitles"] },
284
- { path: ["Subtitles", "Subtitle Track"], plugins: ["vestra.subtitles"] },
285
- { path: ["Subtitles", "Sync"], plugins: ["vestra.subtitles"] },
286
- { path: ["Video", "Aspect"], plugins: ["vestra.video"] },
287
- { path: ["Video", "Crop/Stretch"], plugins: ["vestra.video"] },
288
- { path: ["Video", "Deinterlace"], plugins: ["vestra.video"] },
289
- { path: ["Video", "Deinterlace", "Output"], plugins: ["vestra.video"] },
290
- { path: ["Video", "Framing"], plugins: ["vestra.video"] },
291
- { path: ["Video", "Image Processing"], plugins: ["vestra.video"] },
292
- { path: ["Video", "Pixel Shaders"], plugins: ["vestra.video"] },
293
- {
294
- path: ["Video", "Pixel Shaders", "HDR Tone Mapping"],
295
- plugins: ["vestra.video"],
296
- },
297
- { path: ["Video", "Rotation"], plugins: ["vestra.video"] },
298
- { path: ["Video", "Snapshot"], plugins: ["vestra.capture"] },
299
- { path: ["Audio", "Audio Sync"], plugins: ["vestra.audio"] },
300
- { path: ["Audio", "Audio Track"], plugins: ["vestra.audio"] },
301
- { path: ["Audio", "Output Device"], plugins: ["vestra.audio"] },
302
- { path: ["Audio", "Preset"], plugins: ["vestra.audio"] },
303
- { path: ["Audio", "Processing"], plugins: ["vestra.audio"] },
304
- { path: ["Screen", "Always on Top"], plugins: ["vestra.window"] },
305
- { path: ["Screen", "When Playback Starts"], plugins: ["vestra.window"] },
306
- {
307
- path: ["Settings", "Appearance"],
308
- plugins: ["vestra.preferences", "vestra.visualizer"],
309
- },
310
- { path: ["Settings", "Language"], plugins: ["vestra.preferences"] },
311
- { path: ["Copy to Clipboard"], plugins: ["vestra.playback"] },
264
+ { path: ["Audio Track"], plugins: ["vestra.audio"] },
265
+ { path: ["Subtitle Track"], plugins: ["vestra.subtitles"] },
266
+ { path: ["Snapshot"], plugins: ["vestra.capture"] },
312
267
  ]);
313
268
  /** owner | id | key path, or (title) outside the menu | bindings | panel */
314
269
  const BUILTIN_COMMAND_TABLE = `
@@ -316,277 +271,44 @@ vestra.playback | open | Open File… | Ctrl+O, F3
316
271
  vestra.playback | open-url | Open ▸ Open URL… | Ctrl+U
317
272
  vestra.playlist | playlist.open-folder | Open ▸ Open Folder… | F2
318
273
  vestra.subtitles | load | Open ▸ Open Subtitle… | Alt+O
274
+ vestra.subtitles | load-secondary | Open ▸ Add Secondary Subtitle…
319
275
  vestra.audio | audio.load | Open ▸ Load External Audio…
276
+ vestra.subtitle-online | search | Open ▸ Search and Download Subtitles…
320
277
  vestra.history | recent.empty | Open ▸ Recently Played ▸ (No Entries)
321
278
  vestra.history | recent.prune | Open ▸ Recently Played ▸ Remove Invalid Entries
322
279
  vestra.history | recent.clear | Open ▸ Recently Played ▸ Clear Entries
323
280
  vestra.history | recent.enabled | Open ▸ Recently Played ▸ Record Playback History
324
- vestra.subtitles | load-secondary | Open ▸ Add Secondary Subtitle…
325
281
  host | stop | Close | F4
326
- vestra.playback | reopen | Reopen Current/Last File | Ctrl+Y
327
- vestra.playback | copy-name | Copy to Clipboard ▸ File Name
328
- vestra.playback | copy-folder | Copy to Clipboard ▸ Folder Path
329
- vestra.playback | copy-path | Copy to Clipboard ▸ Full Path
330
- host | play-pause | Playback ▸ Play/Pause | Space, Mouse:LeftClick
331
- host | previous | Playback ▸ Previous | PageUp, Mouse:X2
332
- host | next | Playback ▸ Next | PageDown, Mouse:X1
333
- vestra.playback | keyframe-back | Playback ▸ Seek ▸ Previous Keyframe | Ctrl+Shift+ArrowLeft
334
- vestra.playback | keyframe-forward | Playback ▸ Seek ▸ Next Keyframe | Ctrl+Shift+ArrowRight
335
- vestra.playback | backward-2 | Playback ▸ Seek ▸ Back 30 s | Ctrl+ArrowLeft
336
- vestra.playback | forward-2 | Playback ▸ Seek ▸ Forward 30 s | Ctrl+ArrowRight
337
- vestra.playback | backward-3 | Playback ▸ Seek ▸ Back 60 s | Shift+ArrowLeft
338
- vestra.playback | forward-3 | Playback ▸ Seek ▸ Forward 60 s | Shift+ArrowRight
339
- vestra.playback | backward-4 | Playback ▸ Seek ▸ Back 300 s | Ctrl+Alt+ArrowLeft
340
- vestra.playback | forward-4 | Playback ▸ Seek ▸ Forward 300 s | Ctrl+Alt+ArrowRight
341
- vestra.subtitles | dialogue-previous | Playback ▸ Seek ▸ Previous Dialogue | Home
342
- vestra.subtitles | dialogue-next | Playback ▸ Seek ▸ Next Dialogue | End
343
- vestra.subtitles | dialogue-current | Playback ▸ Seek ▸ Current Subtitle Start | Ctrl+Home
344
- vestra.playback | jump-start | Playback ▸ Seek ▸ Jump to Start | Backspace
345
- vestra.playback | time-jump | Playback ▸ Seek ▸ Seek Steps…
346
- vestra.playback | jump | Playback ▸ Jump to Time… | G
347
- vestra.playback | rate-05 | Playback ▸ Speed ▸ 0.5×
348
- vestra.playback | rate-15 | Playback ▸ Speed ▸ 1.5×
349
- vestra.playback | rate-20 | Playback ▸ Speed ▸ 2×
350
- vestra.playback | rate-custom | Playback ▸ Speed ▸ Custom…
351
- vestra.playlist | playlist.add | Playback ▸ Playlist ▸ Add Files…
352
- vestra.playlist | playlist.link | Playback ▸ Playlist ▸ Add Link…
353
- vestra.playlist | playlist.add-folder | Playback ▸ Playlist ▸ Add Folder…
354
- vestra.playlist | playlist.repeat-none | Playback ▸ Playlist ▸ Repeat ▸ Off
355
- vestra.playlist | playlist.repeat-all | Playback ▸ Playlist ▸ Repeat ▸ All
356
- vestra.playlist | playlist.repeat-one | Playback ▸ Playlist ▸ Repeat ▸ One
357
- vestra.playlist | playlist.shuffle | Playback ▸ Playlist ▸ Shuffle
358
- vestra.playlist | playlist.open-list | Playback ▸ Playlist ▸ Open List File…
359
- vestra.playlist | playlist.save-list | Playback ▸ Playlist ▸ Save List…
360
- vestra.playlist | playlist.open-mode-only | Playback ▸ Playlist ▸ When Opening a File ▸ Open Only That File
361
- vestra.playlist | playlist.open-mode-similar | Playback ▸ Playlist ▸ When Opening a File ▸ Add Similar Files
362
- vestra.playlist | playlist.open-mode-folder | Playback ▸ Playlist ▸ When Opening a File ▸ Add All Files in the Folder
363
- vestra.playlist | playlist.fast-advance | Playback ▸ Playlist ▸ Fast Advance to Next
364
- vestra.playlist | playlist.remember | Playback ▸ Playlist ▸ Remember List
365
- vestra.playlist | playlist.confirm-clear | Playback ▸ Playlist ▸ Confirm Before Removing All
366
- vestra.playback | prevent-sleep | Playback ▸ Disable Screen Saver While Playing
367
- vestra.window | hide-cursor | Playback ▸ Hide Pointer While Playing
368
- vestra.playback | hover-time | Playback ▸ Show Time on Seek Bar Hover
369
- vestra.playback | hover-thumbnail | Playback ▸ Show Thumbnail on Seek Bar Hover
370
- vestra.history | resume.off | Playback ▸ Resume Playback ▸ Don't Resume
371
- vestra.history | resume.auto | Playback ▸ Resume Playback ▸ Resume Automatically
372
- vestra.history | resume.ask | Playback ▸ Resume Playback ▸ Ask Every Time
373
- vestra.history | resume.audio | Playback ▸ Resume Playback ▸ Also Remember Audio Files
374
- vestra.history | resume.clear | Playback ▸ Resume Playback ▸ Clear All Saved Positions
375
- vestra.marks | marks.list | Playback ▸ Chapters and Bookmarks ▸ Chapter and Bookmark List… | H
376
- vestra.marks | marks.add | Playback ▸ Chapters and Bookmarks ▸ Add Bookmark | P
377
- vestra.marks | marks.previous | Playback ▸ Chapters and Bookmarks ▸ Previous Bookmark or Chapter | Shift+PageUp
378
- vestra.marks | marks.next | Playback ▸ Chapters and Bookmarks ▸ Next Bookmark or Chapter | Shift+PageDown
379
- vestra.marks | marks.previous-chapter | Playback ▸ Chapters and Bookmarks ▸ Previous Chapter | Ctrl+PageUp
380
- vestra.marks | marks.next-chapter | Playback ▸ Chapters and Bookmarks ▸ Next Chapter | Ctrl+PageDown
381
- vestra.marks | marks.seekbar | Playback ▸ Chapters and Bookmarks ▸ Show Marks on Seek Bar
382
- vestra.marks | ab.set-a | Playback ▸ A-B Loop ▸ Set Start Point | [
383
- vestra.marks | ab.clear-a | Playback ▸ A-B Loop ▸ Clear Start Point | {
384
- vestra.marks | ab.a-back | Playback ▸ A-B Loop ▸ Start Point Back 0.1 s | Ctrl+[
385
- vestra.marks | ab.a-forward | Playback ▸ A-B Loop ▸ Start Point Forward 0.1 s | Alt+[
386
- vestra.marks | ab.set-b | Playback ▸ A-B Loop ▸ Set End Point | ]
387
- vestra.marks | ab.clear-b | Playback ▸ A-B Loop ▸ Clear End Point | }
388
- vestra.marks | ab.b-back | Playback ▸ A-B Loop ▸ End Point Back 0.1 s | Ctrl+]
389
- vestra.marks | ab.b-forward | Playback ▸ A-B Loop ▸ End Point Forward 0.1 s | Alt+]
390
- vestra.marks | ab.back | Playback ▸ A-B Loop ▸ Move Range Back 0.1 s | Ctrl+Alt+[
391
- vestra.marks | ab.forward | Playback ▸ A-B Loop ▸ Move Range Forward 0.1 s | Ctrl+Alt+]
392
- vestra.marks | ab.segment | Playback ▸ A-B Loop ▸ Loop Current Chapter or Bookmark Range | Alt+\\
393
- vestra.marks | ab.toggle | Playback ▸ A-B Loop ▸ A-B Loop On/Off | \\
394
- vestra.marks | ab.count.endless | Playback ▸ A-B Loop ▸ Loop Count ▸ Endless
395
- vestra.marks | ab.count.1 | Playback ▸ A-B Loop ▸ Loop Count ▸ Once
396
- vestra.marks | ab.count.2 | Playback ▸ A-B Loop ▸ Loop Count ▸ 2 Times
397
- vestra.marks | ab.count.3 | Playback ▸ A-B Loop ▸ Loop Count ▸ 3 Times
398
- vestra.marks | ab.count.5 | Playback ▸ A-B Loop ▸ Loop Count ▸ 5 Times
399
- vestra.marks | ab.count.10 | Playback ▸ A-B Loop ▸ Loop Count ▸ 10 Times
400
- vestra.subtitles | show | Subtitles ▸ Show Subtitles | Alt+H
401
- vestra.subtitles | track-off | Subtitles ▸ Subtitle Track ▸ Off
402
- vestra.subtitles | track-cycle | Subtitles ▸ Subtitle Track ▸ Cycle | Alt+L
403
- vestra.subtitles | second-off | Subtitles ▸ Secondary Subtitle ▸ Off
404
- vestra.subtitles | second-position-top | Subtitles ▸ Secondary Subtitle ▸ Position ▸ Top
405
- vestra.subtitles | second-position-aboveMain | Subtitles ▸ Secondary Subtitle ▸ Position ▸ Above Main Subtitle
406
- vestra.subtitles | bold | Subtitles ▸ Subtitle Style ▸ Bold | Alt+B
407
- vestra.subtitles | size-up | Subtitles ▸ Subtitle Style ▸ Size + | Alt+PageUp
408
- vestra.subtitles | size-down | Subtitles ▸ Subtitle Style ▸ Size − | Alt+PageDown
409
- vestra.subtitles | move-up | Subtitles ▸ Subtitle Style ▸ Move Up
410
- vestra.subtitles | move-down | Subtitles ▸ Subtitle Style ▸ Move Down
411
- vestra.subtitles | shadow | Subtitles ▸ Subtitle Style ▸ Shadow
412
- vestra.subtitles | box | Subtitles ▸ Subtitle Style ▸ Opaque Box
413
- vestra.subtitles | ass-original | Subtitles ▸ Original ASS/SSA Styles
414
- vestra.subtitles | sync-earlier | Subtitles ▸ Sync ▸ Earlier 0.5 s | .
415
- vestra.subtitles | sync-later | Subtitles ▸ Sync ▸ Later 0.5 s | ,
416
- vestra.subtitles | sync-input | Subtitles ▸ Sync ▸ Adjust Sync…
417
- vestra.subtitle-online | search | Subtitles ▸ Online Subtitles ▸ Search and Download Subtitles…
418
- vestra.subtitle-online | settings | Subtitles ▸ Online Subtitles ▸ Online Subtitle Settings…
419
- vestra.subtitles | reload | Subtitles ▸ Reload Subtitles | Ctrl+Alt+Y
420
- vestra.subtitles | refresh | Subtitles ▸ Refresh Subtitle Tracks
421
- vestra.subtitles | tune | Subtitles ▸ Subtitle Tuning…
422
- vestra.subtitles | settings | Subtitles ▸ Subtitle Settings…
423
- vestra.video | video.shader.use | Video ▸ Pixel Shaders ▸ Use Shaders | Shift+P
424
- vestra.video | video.shader.list | Video ▸ Pixel Shaders ▸ Shader List…
425
- vestra.video | video.shader.folder | Video ▸ Pixel Shaders ▸ Open Shader Folder
426
- vestra.video | video.shader.reload | Video ▸ Pixel Shaders ▸ Reload Shaders
427
- vestra.video | video.hdr.auto | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Auto
428
- vestra.video | video.hdr.off | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Off
429
- vestra.video | video.hdr.bt.2390 | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ BT.2390
430
- vestra.video | video.hdr.hable | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Hable
431
- vestra.video | video.hdr.mobius | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Mobius
432
- vestra.video | video.hdr.reinhard | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Reinhard
433
- vestra.video | video.hdr.clip | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Clip
434
- vestra.video | video.hdr.peak | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Dynamic Peak Detection
435
- vestra.video | video.hdr.settings | Video ▸ Pixel Shaders ▸ HDR Settings…
436
- vestra.video | video.deinterlace.cycle | Video ▸ Deinterlace ▸ Cycle | Ctrl+I
437
- vestra.video | video.deinterlace.auto | Video ▸ Deinterlace ▸ Auto
438
- vestra.video | video.deinterlace.on | Video ▸ Deinterlace ▸ Always
439
- vestra.video | video.deinterlace.off | Video ▸ Deinterlace ▸ Never
440
- vestra.video | video.deinterlace.output.frame | Video ▸ Deinterlace ▸ Output ▸ By Frame
441
- vestra.video | video.deinterlace.output.field | Video ▸ Deinterlace ▸ Output ▸ By Field (Double Rate)
442
- vestra.video | video.fit.keep | Video ▸ Aspect ▸ Keep Aspect Ratio
443
- vestra.video | video.fit.stretch | Video ▸ Aspect ▸ Ignore Aspect Ratio
444
- vestra.video | video.fit.fill | Video ▸ Aspect ▸ Fill Window (Crop Excess)
445
- vestra.video | video.aspect.cycle | Video ▸ Aspect ▸ Cycle Aspect Ratio | Shift+F6
446
- vestra.video | video.aspect.default | Video ▸ Aspect ▸ Default (Source)
447
- vestra.video | video.aspect.0 | Video ▸ Aspect ▸ 4:3
448
- vestra.video | video.aspect.1 | Video ▸ Aspect ▸ 16:9
449
- vestra.video | video.aspect.2 | Video ▸ Aspect ▸ 16:10
450
- vestra.video | video.aspect.3 | Video ▸ Aspect ▸ 1.85:1
451
- vestra.video | video.aspect.4 | Video ▸ Aspect ▸ 2.35:1
452
- vestra.video | video.aspect.custom | Video ▸ Aspect ▸ Custom (x:y)
453
- vestra.video | video.aspect.edit | Video ▸ Aspect ▸ Custom Aspect Ratio…
454
- vestra.video | video.reframe.none | Video ▸ Crop/Stretch ▸ None
455
- vestra.video | video.reframe.pad.0 | Video ▸ Crop/Stretch ▸ Stretch to 4:3
456
- vestra.video | video.reframe.pad.1 | Video ▸ Crop/Stretch ▸ Stretch to 16:9
457
- vestra.video | video.reframe.pad.2 | Video ▸ Crop/Stretch ▸ Stretch to 16:10
458
- vestra.video | video.reframe.pad.3 | Video ▸ Crop/Stretch ▸ Stretch to 1.85:1
459
- vestra.video | video.reframe.pad.4 | Video ▸ Crop/Stretch ▸ Stretch to 2.35:1
460
- vestra.video | video.reframe.crop.0 | Video ▸ Crop/Stretch ▸ Crop to 4:3
461
- vestra.video | video.reframe.crop.1 | Video ▸ Crop/Stretch ▸ Crop to 16:9
462
- vestra.video | video.reframe.crop.2 | Video ▸ Crop/Stretch ▸ Crop to 16:10
463
- vestra.video | video.reframe.crop.3 | Video ▸ Crop/Stretch ▸ Crop to 1.85:1
464
- vestra.video | video.reframe.crop.4 | Video ▸ Crop/Stretch ▸ Crop to 2.35:1
465
- vestra.video | video.reframe.left | Video ▸ Crop/Stretch ▸ Move Left
466
- vestra.video | video.reframe.right | Video ▸ Crop/Stretch ▸ Move Right
467
- vestra.video | video.reframe.up | Video ▸ Crop/Stretch ▸ Move Up
468
- vestra.video | video.reframe.down | Video ▸ Crop/Stretch ▸ Move Down
469
- vestra.video | video.frame.zoom-in | Video ▸ Framing ▸ Zoom In | Numpad9, Alt+Plus
470
- vestra.video | video.frame.zoom-out | Video ▸ Framing ▸ Zoom Out | Numpad1, Alt+-
471
- vestra.video | video.frame.right | Video ▸ Framing ▸ Pan → | Ctrl+Numpad6, Alt+ArrowRight
472
- vestra.video | video.frame.left | Video ▸ Framing ▸ Pan ← | Ctrl+Numpad4, Alt+ArrowLeft
473
- vestra.video | video.frame.up | Video ▸ Framing ▸ Pan ↑ | Ctrl+Numpad8, Alt+ArrowUp
474
- vestra.video | video.frame.down | Video ▸ Framing ▸ Pan ↓ | Ctrl+Numpad2, Alt+ArrowDown
475
- vestra.video | video.frame.centre | Video ▸ Framing ▸ Center Frame | Ctrl+Numpad5
476
- vestra.video | video.flip.vertical | Video ▸ Image Processing ▸ Flip Vertically | Ctrl+P
477
- vestra.video | video.flip.horizontal | Video ▸ Image Processing ▸ Flip Horizontally | Ctrl+Z
478
- vestra.video | video.gaussian | Video ▸ Image Processing ▸ Gaussian Blur | Ctrl+B
479
- vestra.video | video.sharpen | Video ▸ Image Processing ▸ Sharpen | Ctrl+R
480
- vestra.video | video.edge | Video ▸ Image Processing ▸ Edge Sharpen
481
- vestra.video | video.deblock | Video ▸ Image Processing ▸ Deblock | Ctrl+H
482
- vestra.video | video.deband | Video ▸ Image Processing ▸ Deband
483
- vestra.video | video.denoise.d3 | Video ▸ Image Processing ▸ 3D Denoise | Ctrl+N
484
- vestra.video | video.denoise.gradual | Video ▸ Image Processing ▸ Gradual Denoise
485
- vestra.video | video.denoise.temporal | Video ▸ Image Processing ▸ Temporal Denoise | Ctrl+M
486
- vestra.video | video.frame-blend | Video ▸ Image Processing ▸ Frame Doubling
487
- vestra.video | video.interpolation | Video ▸ Image Processing ▸ Motion Interpolation
488
- vestra.video | video.rotate.cycle | Video ▸ Rotation ▸ Cycle | Alt+K
489
- vestra.video | video.rotate.0 | Video ▸ Rotation ▸ No Rotation
490
- vestra.video | video.rotate.90 | Video ▸ Rotation ▸ 90°
491
- vestra.video | video.rotate.180 | Video ▸ Rotation ▸ 180°
492
- vestra.video | video.rotate.270 | Video ▸ Rotation ▸ 270°
493
- vestra.capture | capture.save | Video ▸ Snapshot ▸ Save Current Frame | Ctrl+E
494
- vestra.capture | capture.panel | Video ▸ Snapshot ▸ Capture… | Alt+S
495
- vestra.capture | capture.copy | Video ▸ Snapshot ▸ Copy Current Frame | Ctrl+C
496
- vestra.capture | capture.burst | Video ▸ Snapshot ▸ Burst… | Ctrl+G
497
- vestra.capture | capture.clip | Video ▸ Snapshot ▸ Export Clip…
498
- vestra.video | video.picture | Video ▸ Picture Adjustments…
499
- vestra.video | video.brightness.down | Video ▸ Brightness -1% | W
500
- vestra.video | video.brightness.up | Video ▸ Brightness +1% | E
501
- vestra.video | video.contrast.down | Video ▸ Contrast -1% | R
502
- vestra.video | video.contrast.up | Video ▸ Contrast +1% | T
503
- vestra.video | video.saturation.down | Video ▸ Saturation -1% | Y
504
- vestra.video | video.saturation.up | Video ▸ Saturation +1% | U
505
- vestra.video | video.hue.down | Video ▸ Hue -1% | I
506
- vestra.video | video.hue.up | Video ▸ Hue +1% | O
507
- vestra.video | video.gpu-rendering | Video ▸ GPU Rendering (Experimental)
508
- host | volume-up | Audio ▸ Volume + | ArrowUp, Mouse:WheelUp
509
- host | volume-down | Audio ▸ Volume − | ArrowDown, Mouse:WheelDown
510
- host | mute | Audio ▸ Mute | M
511
- vestra.audio | audio.workbench | Audio ▸ Audio Workbench…
512
- vestra.audio | audio.track.none | Audio ▸ Audio Track ▸ No Audio Tracks
513
- vestra.audio | audio.track.cycle | Audio ▸ Audio Track ▸ Cycle Tracks | Alt+A
514
- vestra.audio | audio.channels.stereo | Audio ▸ Audio Track ▸ Stereo
515
- vestra.audio | audio.channels.left | Audio ▸ Audio Track ▸ Left Channel
516
- vestra.audio | audio.channels.right | Audio ▸ Audio Track ▸ Right Channel
517
- vestra.audio | audio.channels.mono | Audio ▸ Audio Track ▸ Mono Mix
518
- vestra.audio | audio.channels.swap | Audio ▸ Audio Track ▸ Swap Left and Right
519
- vestra.audio | audio.device.none | Audio ▸ Output Device ▸ No Output Devices
520
- vestra.audio | audio.equalizer | Audio ▸ Equalizer | Shift+E
521
- vestra.audio | audio.preset.0 | Audio ▸ Preset ▸ Flat
522
- vestra.audio | audio.preset.1 | Audio ▸ Preset ▸ Voice
523
- vestra.audio | audio.preset.2 | Audio ▸ Preset ▸ Music
524
- vestra.audio | audio.preset.3 | Audio ▸ Preset ▸ Cinema
525
- vestra.audio | audio.sync.earlier | Audio ▸ Audio Sync ▸ 50 ms Earlier | >
526
- vestra.audio | audio.sync.later | Audio ▸ Audio Sync ▸ 50 ms Later | <
527
- vestra.audio | audio.sync.keep.none | Audio ▸ Audio Sync ▸ Don't Keep
528
- vestra.audio | audio.sync.keep.session | Audio ▸ Audio Sync ▸ Keep for This Run
529
- vestra.audio | audio.sync.keep.always | Audio ▸ Audio Sync ▸ Always Keep
530
- vestra.audio | audio.normalize | Audio ▸ Processing ▸ Normalize | Shift+N
531
- vestra.audio | audio.clarity | Audio ▸ Processing ▸ Crystalizer | Shift+C
532
- vestra.visualizer | audio-cover | Audio ▸ Show Album Cover for Audio Only
533
- host | fullscreen | Toggle Fullscreen | Escape
534
- vestra.window | pip | Screen ▸ Picture-in-Picture
535
- vestra.window | mini | Screen ▸ Mini Size | \`
536
- vestra.window | size.0.5 | Screen ▸ 0.5× | 1
537
- vestra.window | size.1 | Screen ▸ 1× | 2
538
- vestra.window | size.1.5 | Screen ▸ 1.5× | 3
539
- vestra.window | size.2 | Screen ▸ 2× | 4
540
- vestra.window | fit | Screen ▸ Fit to Video Aspect Ratio | 8
541
- vestra.window | auto.off | Screen ▸ When Playback Starts ▸ Don't Resize
542
- vestra.window | auto.0.5 | Screen ▸ When Playback Starts ▸ 0.5×
543
- vestra.window | auto.1 | Screen ▸ When Playback Starts ▸ 1×
544
- vestra.window | auto.1.5 | Screen ▸ When Playback Starts ▸ 1.5×
545
- vestra.window | auto.2 | Screen ▸ When Playback Starts ▸ 2×
546
- vestra.window | auto.fit | Screen ▸ When Playback Starts ▸ Fit to Video Aspect Ratio
547
- vestra.window | auto.once | Screen ▸ When Playback Starts ▸ Only Once
548
- vestra.window | top.cycle | Screen ▸ Always on Top ▸ Cycle Mode | Ctrl+T
549
- vestra.window | top.never | Screen ▸ Always on Top ▸ Never
550
- vestra.window | top.always | Screen ▸ Always on Top ▸ Always
551
- vestra.window | top.playing | Screen ▸ Always on Top ▸ While Playing
552
- vestra.window | top.fullscreen | Screen ▸ Always on Top ▸ While Playing in Fullscreen
282
+ host | play-pause | Play/Pause | Space, Mouse:LeftClick
283
+ vestra.audio | audio.track.none | Audio Track ▸ No Audio Tracks
284
+ vestra.subtitles | track-off | Subtitle Track ▸ Off
285
+ vestra.capture | capture.save | Snapshot ▸ Save Current Frame | Ctrl+E
286
+ vestra.capture | capture.copy | Snapshot ▸ Copy Current Frame | Ctrl+C
287
+ vestra.capture | capture.burst | Snapshot ▸ Burst… | Ctrl+G
288
+ vestra.capture | capture.clip | Snapshot ▸ Export Clip…
289
+ vestra.capture | capture.panel | Snapshot ▸ Capture… | Alt+S
290
+ vestra.video | video.picture | Picture… | Alt+1
291
+ vestra.audio | audio.workbench | Audio… | Alt+2
292
+ vestra.subtitles | tune | Subtitles… | Alt+3
293
+ vestra.playback | panel | Playback… | Alt+4
553
294
  vestra.playlist | playlist.visibility | Playlist | F6
554
- vestra.info | info.toggle | Playback Info | Tab
555
- vestra.info | info.properties | Playback Properties… | Ctrl+F1
295
+ vestra.marks | marks.list | Chapter and Bookmark List… | H
296
+ host | fullscreen | Toggle Fullscreen | Escape
556
297
  vestra.workshop | workshop.open | Vestra Player AI…
557
298
  vestra.store | open | Plugin Store…
558
- vestra.preferences | options | Settings ▸ Options… | F5
559
- vestra.hotkeys | keys | Settings ▸ Keyboard Shortcuts…
560
- vestra.hotkeys | mouse | Settings ▸ Mouse…
561
- vestra.hotkeys | ignore-defaults | Settings ▸ Ignore Default Shortcuts
562
- vestra.preferences | theme.vestra | Settings ▸ Appearance ▸ Vestra Dark
563
- vestra.preferences | theme.vestra-light | Settings ▸ Appearance ▸ Vestra Light
564
- vestra.visualizer | idle-logo | Settings ▸ Appearance ▸ Show Logo When Idle
565
- vestra.visualizer | choose-logo | Settings ▸ Appearance ▸ Choose Logo Image…
566
- vestra.preferences | language.system | Settings ▸ Language ▸ Follow System
567
- vestra.preferences | language.en | Settings ▸ Language ▸ English
568
- vestra.preferences | language.zh-Hans | Settings ▸ Language ▸ 简体中文
569
- vestra.preferences | language.ja | Settings ▸ Language ▸ 日本語
570
- vestra.preferences | language.ko | Settings ▸ Language ▸ 한국어
571
- vestra.preferences | language.de | Settings ▸ Language ▸ Deutsch
572
- vestra.preferences | language.fr | Settings ▸ Language ▸ Français
573
- vestra.preferences | language.es | Settings ▸ Language ▸ Español
574
- vestra.subtitles | move-reset | Reset ▸ Subtitle Position | Alt+Home
575
- vestra.subtitles | sync-reset | Reset ▸ Subtitle Sync | /
576
- vestra.video | video.reset | Reset ▸ Picture | Q
577
- vestra.video | video.frame.reset | Reset ▸ Framing | Numpad5, Alt+Backspace
578
- vestra.video | video.reframe.reset | Reset ▸ Crop Position
579
- vestra.audio | audio.sync.reset | Reset ▸ Audio Sync | ?
580
- vestra.audio | audio.reset | Reset ▸ Audio Processing
581
- vestra.visualizer | reset-logo | Reset ▸ Idle Logo
299
+ host | palette | Command Palette… | Ctrl+Shift+P
300
+ vestra.preferences | options | Options… | F5
582
301
  vestra.info | info.about | About Vestra Player… | F1
583
- vestra.info | info.update | Check for Updates…
584
302
  host | quit | Quit | Cmd+Q
303
+ host | previous | (Previous) | PageUp, Mouse:X2
304
+ host | next | (Next) | PageDown, Mouse:X1
585
305
  host | enter-fullscreen | (Enter Fullscreen)
586
306
  host | exit-fullscreen | (Leave Fullscreen)
587
307
  host | sidebar | (Toggle Sidebar)
588
- host | palette | (Command Palette) | Ctrl+Shift+P
589
308
  host | adjust | (Adjust)
309
+ host | volume-up | (Volume +) | ArrowUp, Mouse:WheelUp
310
+ host | volume-down | (Volume −) | ArrowDown, Mouse:WheelDown
311
+ host | mute | (Mute) | M
590
312
  host | frame-back | (Previous Frame) | D
591
313
  host | frame-forward | (Next Frame) | F
592
314
  host | seek-backward | (Back 5 s) | ArrowLeft
@@ -594,6 +316,118 @@ host | seek-forward | (Forward 5 s) | ArrowRight
594
316
  host | rate-normal | (Normal) | Z
595
317
  host | rate-down | (Slower 0.1) | X
596
318
  host | rate-up | (Faster 0.1) | C
319
+ vestra.playback | reopen | (Reopen Current/Last File) | Ctrl+Y
320
+ vestra.playback | copy-name | (File Name)
321
+ vestra.playback | copy-folder | (Folder Path)
322
+ vestra.playback | copy-path | (Full Path)
323
+ vestra.playback | prevent-sleep | (Disable Screen Saver While Playing)
324
+ vestra.playback | hover-time | (Show Time on Seek Bar Hover)
325
+ vestra.playback | hover-thumbnail | (Show Thumbnail on Seek Bar Hover)
326
+ vestra.window | hide-cursor | (Hide Pointer While Playing)
327
+ vestra.window | pip | (Picture-in-Picture)
328
+ vestra.window | mini | (Mini Size) | \`
329
+ vestra.window | size.0.5 | (0.5×) | 1
330
+ vestra.window | size.1 | (1×) | 2
331
+ vestra.window | size.1.5 | (1.5×) | 3
332
+ vestra.window | size.2 | (2×) | 4
333
+ vestra.window | fit | (Fit to Video Aspect Ratio) | 8
334
+ vestra.window | auto.off | (Don't Resize)
335
+ vestra.window | auto.0.5 | (0.5×)
336
+ vestra.window | auto.1 | (1×)
337
+ vestra.window | auto.1.5 | (1.5×)
338
+ vestra.window | auto.2 | (2×)
339
+ vestra.window | auto.fit | (Fit to Video Aspect Ratio)
340
+ vestra.window | auto.once | (Only Once)
341
+ vestra.window | top.cycle | (Cycle Mode) | Ctrl+T
342
+ vestra.window | top.never | (Never)
343
+ vestra.window | top.always | (Always)
344
+ vestra.window | top.playing | (While Playing)
345
+ vestra.window | top.fullscreen | (While Playing in Fullscreen)
346
+ vestra.playlist | playlist.add | (Add Files…)
347
+ vestra.playlist | playlist.link | (Add Link…)
348
+ vestra.playlist | playlist.add-folder | (Add Folder…)
349
+ vestra.playlist | playlist.repeat-none | (Off)
350
+ vestra.playlist | playlist.repeat-all | (All)
351
+ vestra.playlist | playlist.repeat-one | (One)
352
+ vestra.playlist | playlist.shuffle | (Shuffle)
353
+ vestra.playlist | playlist.open-list | (Open List File…)
354
+ vestra.playlist | playlist.save-list | (Save List…)
355
+ vestra.playlist | playlist.open-mode-only | (Open Only That File)
356
+ vestra.playlist | playlist.open-mode-similar | (Add Similar Files)
357
+ vestra.playlist | playlist.open-mode-folder | (Add All Files in the Folder)
358
+ vestra.playlist | playlist.fast-advance | (Fast Advance to Next)
359
+ vestra.playlist | playlist.remember | (Remember List)
360
+ vestra.playlist | playlist.confirm-clear | (Confirm Before Removing All)
361
+ vestra.history | resume.off | (Don't Resume)
362
+ vestra.history | resume.auto | (Resume Automatically)
363
+ vestra.history | resume.ask | (Ask Every Time)
364
+ vestra.history | resume.audio | (Also Remember Audio Files)
365
+ vestra.history | resume.clear | (Clear All Saved Positions)
366
+ vestra.marks | marks.add | (Add Bookmark) | P
367
+ vestra.marks | marks.previous | (Previous Bookmark or Chapter) | Shift+PageUp
368
+ vestra.marks | marks.next | (Next Bookmark or Chapter) | Shift+PageDown
369
+ vestra.marks | marks.previous-chapter | (Previous Chapter) | Ctrl+PageUp
370
+ vestra.marks | marks.next-chapter | (Next Chapter) | Ctrl+PageDown
371
+ vestra.marks | marks.seekbar | (Show Marks on Seek Bar)
372
+ vestra.marks | ab.set-a | (Set Start Point) | [
373
+ vestra.marks | ab.clear-a | (Clear Start Point) | {
374
+ vestra.marks | ab.a-back | (Start Point Back 0.1 s) | Ctrl+[
375
+ vestra.marks | ab.a-forward | (Start Point Forward 0.1 s) | Alt+[
376
+ vestra.marks | ab.set-b | (Set End Point) | ]
377
+ vestra.marks | ab.clear-b | (Clear End Point) | }
378
+ vestra.marks | ab.b-back | (End Point Back 0.1 s) | Ctrl+]
379
+ vestra.marks | ab.b-forward | (End Point Forward 0.1 s) | Alt+]
380
+ vestra.marks | ab.back | (Move Range Back 0.1 s) | Ctrl+Alt+[
381
+ vestra.marks | ab.forward | (Move Range Forward 0.1 s) | Ctrl+Alt+]
382
+ vestra.marks | ab.segment | (Loop Current Chapter or Bookmark Range) | Alt+\\
383
+ vestra.marks | ab.toggle | (A-B Loop On/Off) | \\
384
+ vestra.marks | ab.count.endless | (Endless)
385
+ vestra.marks | ab.count.1 | (Once)
386
+ vestra.marks | ab.count.2 | (2 Times)
387
+ vestra.marks | ab.count.3 | (3 Times)
388
+ vestra.marks | ab.count.5 | (5 Times)
389
+ vestra.marks | ab.count.10 | (10 Times)
390
+ vestra.subtitle-online | settings | (Online Subtitle Settings…)
391
+ vestra.visualizer | audio-cover | (Show Album Cover for Audio Only)
392
+ vestra.visualizer | idle-logo | (Show Logo When Idle)
393
+ vestra.visualizer | choose-logo | (Choose Logo Image…)
394
+ vestra.visualizer | reset-logo | (Idle Logo)
395
+ vestra.hotkeys | keys | (Keyboard Shortcuts…)
396
+ vestra.hotkeys | mouse | (Mouse…)
397
+ vestra.hotkeys | ignore-defaults | (Ignore Default Shortcuts)
398
+ vestra.preferences | theme.vestra | (Vestra Dark)
399
+ vestra.preferences | theme.vestra-light | (Vestra Light)
400
+ vestra.preferences | language.system | (Follow System)
401
+ vestra.preferences | language.en | (English)
402
+ vestra.preferences | language.zh-Hans | (简体中文)
403
+ vestra.preferences | language.ja | (日本語)
404
+ vestra.preferences | language.ko | (한국어)
405
+ vestra.preferences | language.de | (Deutsch)
406
+ vestra.preferences | language.fr | (Français)
407
+ vestra.preferences | language.es | (Español)
408
+ vestra.info | info.toggle | (Playback Info) | Tab
409
+ vestra.info | info.properties | (Playback Properties…) | Ctrl+F1
410
+ vestra.info | info.update | (Check for Updates…)
411
+ vestra.audio | audio.track.cycle | (Cycle Tracks) | Alt+A
412
+ vestra.audio | audio.channels.stereo | (Stereo)
413
+ vestra.audio | audio.channels.left | (Left Channel)
414
+ vestra.audio | audio.channels.right | (Right Channel)
415
+ vestra.audio | audio.channels.mono | (Mono Mix)
416
+ vestra.audio | audio.channels.swap | (Swap Left and Right)
417
+ vestra.audio | audio.equalizer | (Equalizer) | Shift+E
418
+ vestra.audio | audio.preset.0 | (Flat)
419
+ vestra.audio | audio.preset.1 | (Voice)
420
+ vestra.audio | audio.preset.2 | (Music)
421
+ vestra.audio | audio.preset.3 | (Cinema)
422
+ vestra.audio | audio.sync.earlier | (50 ms Earlier) | >
423
+ vestra.audio | audio.sync.later | (50 ms Later) | <
424
+ vestra.audio | audio.sync.reset | (Reset) | ?
425
+ vestra.audio | audio.sync.keep.none | (Don't Keep)
426
+ vestra.audio | audio.sync.keep.session | (Keep for This Run)
427
+ vestra.audio | audio.sync.keep.always | (Always Keep)
428
+ vestra.audio | audio.normalize | (Normalize) | Shift+N
429
+ vestra.audio | audio.clarity | (Crystalizer) | Shift+C
430
+ vestra.audio | audio.reset | (Reset)
597
431
  vestra.capture | capture.clipExport | (Export Clip Range) | Ctrl+Shift+E
598
432
  vestra.capture | capture.saveAs | (Save Current Frame As…)
599
433
  vestra.capture | capture.saveScreen | (Save Rendered Frame) | Ctrl+Alt+E
@@ -615,6 +449,21 @@ vestra.capture | capture.clipStart | (Set Clip Start)
615
449
  vestra.capture | capture.clipEnd | (Set Clip End)
616
450
  vestra.capture | capture.last30 | (Export Last 30 Seconds) | Ctrl+Shift+R
617
451
  vestra.info | info.brief | (Brief Info) | Shift+Tab
452
+ vestra.playback | keyframe-back | (Previous Keyframe) | Ctrl+Shift+ArrowLeft
453
+ vestra.playback | keyframe-forward | (Next Keyframe) | Ctrl+Shift+ArrowRight
454
+ vestra.playback | jump | (Jump to Time…) | G
455
+ vestra.playback | jump-start | (Jump to Start) | Backspace
456
+ vestra.playback | time-jump | (Seek Steps…)
457
+ vestra.playback | rate-05 | (0.5×)
458
+ vestra.playback | rate-15 | (1.5×)
459
+ vestra.playback | rate-20 | (2×)
460
+ vestra.playback | rate-custom | (Custom…)
461
+ vestra.playback | backward-2 | (Back 30 s) | Ctrl+ArrowLeft
462
+ vestra.playback | forward-2 | (Forward 30 s) | Ctrl+ArrowRight
463
+ vestra.playback | backward-3 | (Back 60 s) | Shift+ArrowLeft
464
+ vestra.playback | forward-3 | (Forward 60 s) | Shift+ArrowRight
465
+ vestra.playback | backward-4 | (Back 300 s) | Ctrl+Alt+ArrowLeft
466
+ vestra.playback | forward-4 | (Forward 300 s) | Ctrl+Alt+ArrowRight
618
467
  vestra.playlist | playlist.play | (Play) | Enter, P | panel
619
468
  vestra.playlist | playlist.list-add | (Add Files…) | Ctrl+I | panel
620
469
  vestra.playlist | playlist.list-add-folder | (Add Folder…) | Ctrl+O | panel
@@ -646,6 +495,114 @@ vestra.playlist | playlist.list-open-list | (Open List File…) | F3 | panel
646
495
  vestra.playlist | playlist.list-save-list | (Save List…) | F2 | panel
647
496
  vestra.playlist | playlist.close | (Close List) | F6 | panel
648
497
  vestra.playlist | playlist.settings | (Playlist Settings…) | F5 | panel
498
+ vestra.subtitles | show | (Show Subtitles) | Alt+H
499
+ vestra.subtitles | second-off | (Off)
500
+ vestra.subtitles | second-position-top | (Top)
501
+ vestra.subtitles | second-position-aboveMain | (Above Main Subtitle)
502
+ vestra.subtitles | track-cycle | (Cycle) | Alt+L
503
+ vestra.subtitles | size-up | (Size +) | Alt+PageUp
504
+ vestra.subtitles | size-down | (Size −) | Alt+PageDown
505
+ vestra.subtitles | move-up | (Move Up)
506
+ vestra.subtitles | move-down | (Move Down)
507
+ vestra.subtitles | move-reset | (Subtitle Position) | Alt+Home
508
+ vestra.subtitles | bold | (Bold) | Alt+B
509
+ vestra.subtitles | shadow | (Shadow)
510
+ vestra.subtitles | box | (Opaque Box)
511
+ vestra.subtitles | ass-original | (Original ASS/SSA Styles)
512
+ vestra.subtitles | dialogue-previous | (Previous Dialogue) | Home
513
+ vestra.subtitles | dialogue-next | (Next Dialogue) | End
514
+ vestra.subtitles | dialogue-current | (Current Subtitle Start) | Ctrl+Home
515
+ vestra.subtitles | sync-reset | (Subtitle Sync) | /
516
+ vestra.subtitles | sync-input | (Adjust Sync…)
517
+ vestra.subtitles | reload | (Reload Subtitles) | Ctrl+Alt+Y
518
+ vestra.subtitles | refresh | (Refresh Subtitle Tracks)
519
+ vestra.subtitles | remove | (Remove External Subtitle)
520
+ vestra.subtitles | settings | (Subtitle Settings…)
521
+ vestra.subtitles | sync-earlier | (Earlier 0.5 s) | .
522
+ vestra.subtitles | sync-later | (Later 0.5 s) | ,
523
+ vestra.video | video.shader.use | (Use Shaders) | Shift+P
524
+ vestra.video | video.shader.list | (Shader List…)
525
+ vestra.video | video.shader.folder | (Open Shader Folder)
526
+ vestra.video | video.shader.reload | (Reload Shaders)
527
+ vestra.video | video.hdr.auto | (Auto)
528
+ vestra.video | video.hdr.off | (Off)
529
+ vestra.video | video.hdr.bt.2390 | (BT.2390)
530
+ vestra.video | video.hdr.hable | (Hable)
531
+ vestra.video | video.hdr.mobius | (Mobius)
532
+ vestra.video | video.hdr.reinhard | (Reinhard)
533
+ vestra.video | video.hdr.clip | (Clip)
534
+ vestra.video | video.hdr.peak | (Dynamic Peak Detection)
535
+ vestra.video | video.hdr.settings | (HDR Settings…)
536
+ vestra.video | video.deinterlace.cycle | (Cycle) | Ctrl+I
537
+ vestra.video | video.deinterlace.auto | (Auto)
538
+ vestra.video | video.deinterlace.on | (Always)
539
+ vestra.video | video.deinterlace.off | (Never)
540
+ vestra.video | video.deinterlace.output.frame | (By Frame)
541
+ vestra.video | video.deinterlace.output.field | (By Field (Double Rate))
542
+ vestra.video | video.fit.keep | (Keep Aspect Ratio)
543
+ vestra.video | video.fit.stretch | (Ignore Aspect Ratio)
544
+ vestra.video | video.fit.fill | (Fill Window (Crop Excess))
545
+ vestra.video | video.aspect.cycle | (Cycle Aspect Ratio) | Shift+F6
546
+ vestra.video | video.aspect.default | (Default (Source))
547
+ vestra.video | video.aspect.0 | (4:3)
548
+ vestra.video | video.aspect.1 | (16:9)
549
+ vestra.video | video.aspect.2 | (16:10)
550
+ vestra.video | video.aspect.3 | (1.85:1)
551
+ vestra.video | video.aspect.4 | (2.35:1)
552
+ vestra.video | video.aspect.custom | (Custom (x:y))
553
+ vestra.video | video.aspect.edit | (Custom Aspect Ratio…)
554
+ vestra.video | video.reframe.none | (None)
555
+ vestra.video | video.reframe.pad.0 | (Stretch to 4:3)
556
+ vestra.video | video.reframe.pad.1 | (Stretch to 16:9)
557
+ vestra.video | video.reframe.pad.2 | (Stretch to 16:10)
558
+ vestra.video | video.reframe.pad.3 | (Stretch to 1.85:1)
559
+ vestra.video | video.reframe.pad.4 | (Stretch to 2.35:1)
560
+ vestra.video | video.reframe.crop.0 | (Crop to 4:3)
561
+ vestra.video | video.reframe.crop.1 | (Crop to 16:9)
562
+ vestra.video | video.reframe.crop.2 | (Crop to 16:10)
563
+ vestra.video | video.reframe.crop.3 | (Crop to 1.85:1)
564
+ vestra.video | video.reframe.crop.4 | (Crop to 2.35:1)
565
+ vestra.video | video.reframe.left | (Move Left)
566
+ vestra.video | video.reframe.right | (Move Right)
567
+ vestra.video | video.reframe.up | (Move Up)
568
+ vestra.video | video.reframe.down | (Move Down)
569
+ vestra.video | video.reframe.reset | (Crop Position)
570
+ vestra.video | video.frame.zoom-in | (Zoom In) | Alt+Plus, Numpad9
571
+ vestra.video | video.frame.zoom-out | (Zoom Out) | Alt+-, Numpad1
572
+ vestra.video | video.frame.right | (Pan →) | Alt+ArrowRight, Ctrl+Numpad6
573
+ vestra.video | video.frame.left | (Pan ←) | Alt+ArrowLeft, Ctrl+Numpad4
574
+ vestra.video | video.frame.up | (Pan ↑) | Alt+ArrowUp, Ctrl+Numpad8
575
+ vestra.video | video.frame.down | (Pan ↓) | Alt+ArrowDown, Ctrl+Numpad2
576
+ vestra.video | video.frame.centre | (Center Frame) | Ctrl+Numpad5
577
+ vestra.video | video.frame.reset | (Framing) | Alt+Backspace, Numpad5
578
+ vestra.video | video.flip.vertical | (Flip Vertically) | Ctrl+P
579
+ vestra.video | video.flip.horizontal | (Flip Horizontally) | Ctrl+Z
580
+ vestra.video | video.gaussian | (Gaussian Blur) | Ctrl+B
581
+ vestra.video | video.sharpen | (Sharpen) | Ctrl+R
582
+ vestra.video | video.edge | (Edge Sharpen)
583
+ vestra.video | video.deblock | (Deblock) | Ctrl+H
584
+ vestra.video | video.deband | (Deband)
585
+ vestra.video | video.denoise.d3 | (3D Denoise) | Ctrl+N
586
+ vestra.video | video.denoise.gradual | (Gradual Denoise)
587
+ vestra.video | video.denoise.temporal | (Temporal Denoise) | Ctrl+M
588
+ vestra.video | video.frame-blend | (Frame Doubling)
589
+ vestra.video | video.interpolation | (Motion Interpolation)
590
+ vestra.video | video.rotate.cycle | (Cycle) | Alt+K
591
+ vestra.video | video.rotate.0 | (No Rotation)
592
+ vestra.video | video.rotate.90 | (90°)
593
+ vestra.video | video.rotate.180 | (180°)
594
+ vestra.video | video.rotate.270 | (270°)
595
+ vestra.video | video.reset | (Picture) | Q
596
+ vestra.video | video.resetPanel | (Picture Panel)
597
+ vestra.video | video.brightness.down | (Brightness -1%) | W
598
+ vestra.video | video.brightness.up | (Brightness +1%) | E
599
+ vestra.video | video.contrast.down | (Contrast -1%) | R
600
+ vestra.video | video.contrast.up | (Contrast +1%) | T
601
+ vestra.video | video.saturation.down | (Saturation -1%) | Y
602
+ vestra.video | video.saturation.up | (Saturation +1%) | U
603
+ vestra.video | video.hue.down | (Hue -1%) | I
604
+ vestra.video | video.hue.up | (Hue +1%) | O
605
+ vestra.video | video.gpu-rendering | (GPU Rendering (Experimental))
649
606
  `;
650
607
  /**
651
608
  * The commands the player and its built-in plugins register when the
Binary file
@@ -13,7 +13,9 @@ const SDK_DIRECTORY = fileURLToPath(new URL("..", import.meta.url));
13
13
  export const WAKE_EVENTS = [
14
14
  "packages.changed",
15
15
  "bindings.changed",
16
- // Player 0.7.6: sent only to the plugin whose own keys changed.
16
+ // Player 0.7.6: sent to a plugin whose own keys changed and, from SDK
17
+ // 1.6.16, to every listener when a player command (`host/<id>`) is
18
+ // rebound, which wakes each parked listener.
17
19
  "commands.keys",
18
20
  "appearance.changed",
19
21
  "resolvers.fileTypes",
@@ -2557,8 +2557,9 @@ export declare class TestHost implements Transport {
2557
2557
  */
2558
2558
  get conflicts(): string[][];
2559
2559
  /**
2560
- * Change the keys of one of the plugin's commands as the user does in
2561
- * Keyboard Shortcuts (SDK 1.6.6): `inputs` replaces its keys (`[]`
2560
+ * Change the keys of one of the plugin's commands, or of one of the
2561
+ * player's core commands by its `host/<id>` (SDK 1.6.16), as the user
2562
+ * does in Keyboard Shortcuts (SDK 1.6.6): `inputs` replaces its keys (`[]`
2562
2563
  * clears them, as Ignore Default Shortcuts does for every default),
2563
2564
  * `null` gives it its own defaults back. It writes
2564
2565
  * {@link TestHost.bindings | bindings.overlay}, and the plugin hears it
@@ -2580,7 +2581,8 @@ export declare class TestHost implements Transport {
2580
2581
  * ```
2581
2582
  *
2582
2583
  * @capability None.
2583
- * @throws `Error` `command` is not a command of the plugin.
2584
+ * @throws `Error` `command` is neither a command of the plugin nor a
2585
+ * core command.
2584
2586
  * @since 1.6.6
2585
2587
  */
2586
2588
  rebind(command: string, inputs: readonly string[] | null): void;
@@ -2524,109 +2524,54 @@ export class TestHost {
2524
2524
  return { enabled, checked, busy: false, reason: enabled ? null : reason };
2525
2525
  }
2526
2526
  #registerCoreActions() {
2527
+ // As the player declares them (host/src/core_actions.rs `declarations`,
2528
+ // player 0.7.6): title, menu path (empty: the command palette only), order,
2529
+ // group, default bindings, repeat, radio. Close and Play/Pause are in the
2530
+ // menu; the rest left it for the panels and the command palette (seek,
2531
+ // frame and speed with the playback plugin's panel, volume and mute with
2532
+ // the audio plugin's, Previous and Next with the slim menu).
2527
2533
  const table = [
2528
- ["stop", ["Close"], 120, "open", ["F4"], false],
2534
+ ["stop", "Close", ["Close"], 120, "open", ["F4"], false],
2529
2535
  [
2530
2536
  "play-pause",
2531
- ["Playback", "Play/Pause"],
2537
+ "Play/Pause",
2538
+ ["Play/Pause"],
2532
2539
  201,
2533
2540
  "domain",
2534
2541
  ["Space", "Mouse:LeftClick"],
2535
2542
  false,
2536
2543
  ],
2537
- [
2538
- "previous",
2539
- ["Playback", "Previous"],
2540
- 202,
2541
- "domain",
2542
- ["PageUp", "Mouse:X2"],
2543
- false,
2544
- ],
2545
- [
2546
- "next",
2547
- ["Playback", "Next"],
2548
- 203,
2549
- "domain",
2550
- ["PageDown", "Mouse:X1"],
2551
- false,
2552
- ],
2553
- [
2554
- "frame-back",
2555
- ["Playback", "Seek", "Previous Frame"],
2556
- 204,
2557
- "frame",
2558
- ["D"],
2559
- true,
2560
- ],
2561
- [
2562
- "frame-forward",
2563
- ["Playback", "Seek", "Next Frame"],
2564
- 205,
2565
- "frame",
2566
- ["F"],
2567
- true,
2568
- ],
2569
- [
2570
- "seek-backward",
2571
- ["Playback", "Seek", "Back 5 s"],
2572
- 210,
2573
- "step",
2574
- ["ArrowLeft"],
2575
- true,
2576
- ],
2577
- [
2578
- "seek-forward",
2579
- ["Playback", "Seek", "Forward 5 s"],
2580
- 211,
2581
- "step",
2582
- ["ArrowRight"],
2583
- true,
2584
- ],
2585
- [
2586
- "rate-normal",
2587
- ["Playback", "Speed", "Normal"],
2588
- 220,
2589
- "domain",
2590
- ["Z"],
2591
- false,
2592
- true,
2593
- ],
2594
- [
2595
- "rate-down",
2596
- ["Playback", "Speed", "Slower 0.1"],
2597
- 221,
2598
- "domain",
2599
- ["X"],
2600
- false,
2601
- ],
2602
- [
2603
- "rate-up",
2604
- ["Playback", "Speed", "Faster 0.1"],
2605
- 222,
2606
- "domain",
2607
- ["C"],
2608
- false,
2609
- ],
2544
+ ["previous", "Previous", [], 0, "domain", ["PageUp", "Mouse:X2"], false],
2545
+ ["next", "Next", [], 0, "domain", ["PageDown", "Mouse:X1"], false],
2546
+ ["frame-back", "Previous Frame", [], 0, "domain", ["D"], true],
2547
+ ["frame-forward", "Next Frame", [], 0, "domain", ["F"], true],
2548
+ ["seek-backward", "Back 5 s", [], 0, "domain", ["ArrowLeft"], true],
2549
+ ["seek-forward", "Forward 5 s", [], 0, "domain", ["ArrowRight"], true],
2550
+ ["rate-normal", "Normal", [], 0, "domain", ["Z"], false, true],
2551
+ ["rate-down", "Slower 0.1", [], 0, "domain", ["X"], false],
2552
+ ["rate-up", "Faster 0.1", [], 0, "domain", ["C"], false],
2610
2553
  [
2611
2554
  "volume-up",
2612
- ["Audio", "Volume +"],
2613
- 501,
2555
+ "Volume +",
2556
+ [],
2557
+ 0,
2614
2558
  "domain",
2615
2559
  ["ArrowUp", "Mouse:WheelUp"],
2616
2560
  true,
2617
2561
  ],
2618
2562
  [
2619
2563
  "volume-down",
2620
- ["Audio", "Volume −"],
2621
- 502,
2564
+ "Volume −",
2565
+ [],
2566
+ 0,
2622
2567
  "domain",
2623
2568
  ["ArrowDown", "Mouse:WheelDown"],
2624
2569
  true,
2625
2570
  ],
2626
- ["mute", ["Audio", "Mute"], 503, "domain", ["M"], false],
2571
+ ["mute", "Mute", [], 0, "domain", ["M"], false],
2627
2572
  ];
2628
2573
  const host = this;
2629
- for (const [id, fixed, order, group, bindings, repeat, radio] of table) {
2574
+ for (const [id, fixed, path, order, group, bindings, repeat, radio,] of table) {
2630
2575
  // The seek items carry the step (`setStepSeek`): the player
2631
2576
  // registers them again when it changes (core_actions.rs `seek_title`).
2632
2577
  const seek = id === "seek-forward"
@@ -2634,13 +2579,11 @@ export class TestHost {
2634
2579
  : id === "seek-backward"
2635
2580
  ? "Back"
2636
2581
  : null;
2637
- const pathOf = () => seek === null
2582
+ const titleOf = () => seek === null
2638
2583
  ? fixed
2639
- : [
2640
- ...fixed.slice(0, -1),
2641
- `${seek} ${String(Math.round(host.stepSeek * 1000) / 1000)} s`,
2642
- ];
2584
+ : `${seek} ${String(Math.round(host.stepSeek * 1000) / 1000)} s`;
2643
2585
  const declaration = {
2586
+ path,
2644
2587
  order,
2645
2588
  group,
2646
2589
  radio: radio ?? false,
@@ -2648,22 +2591,22 @@ export class TestHost {
2648
2591
  repeat,
2649
2592
  };
2650
2593
  Object.defineProperties(declaration, {
2651
- title: { get: () => pathOf().at(-1), enumerable: true },
2652
- path: { get: pathOf, enumerable: true },
2594
+ title: { get: titleOf, enumerable: true },
2653
2595
  });
2654
2596
  const command = {
2655
2597
  declaration,
2656
2598
  // The player's own words in the player's language.
2657
2599
  get display() {
2658
- const path = pathOf();
2659
- const leaf = path.at(-1);
2600
+ const leaf = titleOf();
2660
2601
  const step = /^(Back|Forward) (\S+) s$/.exec(leaf);
2661
2602
  const title = step
2662
2603
  ? host.#hostText(`${step[1]} {} s`, [step[2]])
2663
2604
  : host.#hostText(leaf);
2664
2605
  return {
2665
2606
  title,
2666
- path: [...path.slice(0, -1).map((s) => host.#hostText(s)), title],
2607
+ path: path.length
2608
+ ? [...path.slice(0, -1).map((s) => host.#hostText(s)), title]
2609
+ : [],
2667
2610
  };
2668
2611
  },
2669
2612
  get state() {
@@ -3244,8 +3187,9 @@ export class TestHost {
3244
3187
  return this.coreCommands.has(id) ? id : `${this.manifestId}/${id}`;
3245
3188
  }
3246
3189
  /**
3247
- * Change the keys of one of the plugin's commands as the user does in
3248
- * Keyboard Shortcuts (SDK 1.6.6): `inputs` replaces its keys (`[]`
3190
+ * Change the keys of one of the plugin's commands, or of one of the
3191
+ * player's core commands by its `host/<id>` (SDK 1.6.16), as the user
3192
+ * does in Keyboard Shortcuts (SDK 1.6.6): `inputs` replaces its keys (`[]`
3249
3193
  * clears them, as Ignore Default Shortcuts does for every default),
3250
3194
  * `null` gives it its own defaults back. It writes
3251
3195
  * {@link TestHost.bindings | bindings.overlay}, and the plugin hears it
@@ -3267,11 +3211,12 @@ export class TestHost {
3267
3211
  * ```
3268
3212
  *
3269
3213
  * @capability None.
3270
- * @throws `Error` `command` is not a command of the plugin.
3214
+ * @throws `Error` `command` is neither a command of the plugin nor a
3215
+ * core command.
3271
3216
  * @since 1.6.6
3272
3217
  */
3273
3218
  rebind(command, inputs) {
3274
- if (!this.commands.has(command))
3219
+ if (!this.commands.has(command) && !this.coreCommands.has(command))
3275
3220
  throw new Error(`test host: no command ${command}`);
3276
3221
  const key = this.#bindingKey(command);
3277
3222
  if (inputs === null)
@@ -3287,15 +3232,19 @@ export class TestHost {
3287
3232
  #keysRevision = 0;
3288
3233
  /**
3289
3234
  * `commands.keys` as the player answers it: each of the plugin's own
3290
- * commands with the labels of the keys it holds now (the overlay, else
3291
- * its defaults; not a key an earlier command holds), as menus write
3292
- * them on `systemInfo.os`.
3235
+ * commands, and the player's core commands as `host/<id>` (SDK 1.6.16),
3236
+ * with the labels of the keys it holds now (the overlay, else its
3237
+ * defaults; not a key an earlier command holds), as menus write them on
3238
+ * `systemInfo.os`.
3293
3239
  */
3294
3240
  #keys() {
3295
3241
  const claims = this.#claims();
3296
3242
  const mac = this.systemInfo.os === "macos";
3297
3243
  const keys = {};
3298
- for (const [id, { declaration }] of this.commands) {
3244
+ for (const [id, { declaration }] of [
3245
+ ...this.commands,
3246
+ ...this.coreCommands,
3247
+ ]) {
3299
3248
  const scope = declaration.focus ? "panel" : "global";
3300
3249
  const current = this.bindings.overlay.get(this.#bindingKey(id)) ??
3301
3250
  declaration.bindings ??
@@ -4397,8 +4346,9 @@ export class TestHost {
4397
4346
  if (this.commands.has(id))
4398
4347
  throw commandConflict("owner/localId already registered");
4399
4348
  // The player's own commands beside the core actions (host/actions.rs
4400
- // `host_declarations`: Toggle Fullscreen, Quit and three outside the
4401
- // menu), which take part in conflicts and the total like any other.
4349
+ // `host_declarations`: Toggle Fullscreen, Command Palette…, Quit and
4350
+ // four outside the menu), which take part in conflicts and the total
4351
+ // like any other.
4402
4352
  const hostOnly = BUILTIN_COMMANDS.filter((row) => row.owner === "host" && !this.coreCommands.has(`host/${row.id}`));
4403
4353
  // A path may not repeat another command's (the player's own
4404
4354
  // included) nor be a submenu of one, or one of its submenus.
@@ -1470,8 +1470,11 @@ export interface Commands {
1470
1470
  * player, and until its answer arrives (a few milliseconds) every
1471
1471
  * command reads `[]`; a binding that read it runs again then.
1472
1472
  *
1473
- * Only the plugin's own commands: an id the plugin has not added (or
1474
- * another plugin's) reads `[]`. Needs nothing beyond `commands`, not
1473
+ * The plugin's own commands, and the player's own as `host/<id>` (SDK
1474
+ * 1.6.16; `host/volume-up`, `host/mute`: the ids of
1475
+ * {@link "@vestra-player/sdk/testing"!BUILTIN_COMMANDS | BUILTIN_COMMANDS} rows owned by `host`), for a panel that
1476
+ * shows the player's keys beside its own controls; an id the plugin has
1477
+ * not added (or another plugin's) reads `[]`. Needs nothing beyond `commands`, not
1475
1478
  * `bindings.manage` (the whole binding table, every plugin's, is
1476
1479
  * {@link Bindings.list}). Without the `commands` capability every
1477
1480
  * command reads `[]`. Players before 0.7.6 have no `keys` (the player
package/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # Vestra Player SDK
2
2
 
3
- > @vestra-player/sdk 1.6.15: write plugins for Vestra Player in TypeScript (plugin API `vestra/1`). A plugin is a folder with `manifest.json` and an entry module whose default export `activate(plugin)` the player calls. The documentation is a tree of short pages read by path, like `go doc`: the same pages and API as https://vestrasys.github.io/vestra-player-sdk/.
3
+ > @vestra-player/sdk 1.6.17: write plugins for Vestra Player in TypeScript (plugin API `vestra/1`). A plugin is a folder with `manifest.json` and an entry module whose default export `activate(plugin)` the player calls. The documentation is a tree of short pages read by path, like `go doc`: the same pages and API as https://vestrasys.github.io/vestra-player-sdk/.
4
4
 
5
5
  ## Read the documentation
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vestra-player/sdk",
3
- "version": "1.6.15",
3
+ "version": "1.6.17",
4
4
  "description": "Plugin API types, test host and plugin CLI for Vestra Player (apiVersion vestra/1)",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {