@vestra-player/sdk 1.5.33 → 1.5.35
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 +38 -18
- package/dist/api-requests.js +3 -0
- package/dist/capabilities.d.ts +2 -2
- package/dist/capabilities.js +2 -2
- package/dist/host-capabilities.js +12 -0
- package/dist/player-runtime.d.ts +1 -0
- package/dist/player-runtime.js +1 -0
- package/dist/plugin/scope.d.ts +1 -0
- package/dist/plugin/scope.js +2 -1
- package/dist/plugin/services.d.ts +2 -1
- package/dist/plugin/services.js +22 -2
- package/dist/plugin/subtitles.d.ts +59 -0
- package/dist/plugin/subtitles.js +70 -4
- package/dist/plugin/testing.d.ts +93 -6
- package/dist/plugin/testing.js +210 -10
- package/dist/plugin/types.d.ts +408 -6
- package/dist/wire.d.ts +32 -1
- package/dist/wire.js +11 -0
- package/llms-full.txt +642 -19
- package/llms.txt +22 -21
- package/package.json +1 -1
package/dist/plugin/types.d.ts
CHANGED
|
@@ -293,6 +293,8 @@ export interface Scope extends Disposable {
|
|
|
293
293
|
readonly window: MainWindow;
|
|
294
294
|
/** The player's version and components, and the system it runs on. */
|
|
295
295
|
readonly app: App;
|
|
296
|
+
/** GPU or software rendering: read the choice, change it (`rendering.manage`). */
|
|
297
|
+
readonly rendering: Rendering;
|
|
296
298
|
/** Every command's bindings and the user's overrides (`bindings.manage`). */
|
|
297
299
|
readonly bindings: Bindings;
|
|
298
300
|
/** Runtime images for Slint `image` properties. */
|
|
@@ -3991,8 +3993,9 @@ export interface AppInfo {
|
|
|
3991
3993
|
*/
|
|
3992
3994
|
export interface App extends AppInfo {
|
|
3993
3995
|
/**
|
|
3994
|
-
* The operating system and the
|
|
3995
|
-
* and go
|
|
3996
|
+
* The operating system, the displays and the renderer, read when called
|
|
3997
|
+
* (displays come and go; the renderer can fall back from GPU to software
|
|
3998
|
+
* once). No capability. CPU and memory: Node's `os` module.
|
|
3996
3999
|
*
|
|
3997
4000
|
* @capability None.
|
|
3998
4001
|
* @throws `busy` (rejects) The player could not start the request (no
|
|
@@ -4034,6 +4037,71 @@ export interface SystemInfo {
|
|
|
4034
4037
|
readonly arch: string;
|
|
4035
4038
|
/** Primary display first; empty without a user interface. */
|
|
4036
4039
|
readonly displays: readonly DisplayInfo[];
|
|
4040
|
+
/**
|
|
4041
|
+
* Which renderer draws the video now: `"gpu"` (the GPU renderer, so
|
|
4042
|
+
* {@link RenderOptions | render options} apply) or `"software"` (they
|
|
4043
|
+
* fail with `unsupported`). Read at each call. It changes at most once
|
|
4044
|
+
* while the player runs, from `"gpu"` to `"software"` when a window
|
|
4045
|
+
* cannot show GPU frames; the owner of the render options hears that
|
|
4046
|
+
* switch through {@link RenderOptions.onStatus}.
|
|
4047
|
+
*
|
|
4048
|
+
* Absent (`undefined`) on players before 0.5.12, which do not report it:
|
|
4049
|
+
* the renderer is then unknown, not software.
|
|
4050
|
+
*
|
|
4051
|
+
* Today the player renders on the GPU on macOS and in software on
|
|
4052
|
+
* Windows, Linux and without a user interface (see
|
|
4053
|
+
* [Platforms](../../docs/reference/platforms.md)); test this field
|
|
4054
|
+
* rather than {@link SystemInfo.os}.
|
|
4055
|
+
*
|
|
4056
|
+
* @example Offer the HDR menu only where render options work
|
|
4057
|
+
* The plugin adds its HDR command only when the player renders on the
|
|
4058
|
+
* GPU, instead of creating the render options just to find out from a
|
|
4059
|
+
* failed status. `system()` asks the player, which reports the renderer
|
|
4060
|
+
* drawing at that moment; no capability is needed to ask. A player before
|
|
4061
|
+
* 0.5.12 leaves the field out, so the test is for `"gpu"` exactly (an
|
|
4062
|
+
* older player gets no HDR command).
|
|
4063
|
+
* ```ts
|
|
4064
|
+
* const { rendering } = await plugin.app.system();
|
|
4065
|
+
* if (rendering === "gpu") {
|
|
4066
|
+
* const render = plugin.video.render(); // one handle, kept
|
|
4067
|
+
* plugin.commands.add({
|
|
4068
|
+
* id: "hdr",
|
|
4069
|
+
* path: ["@video", "HDR Tone Mapping"],
|
|
4070
|
+
* run: () => render.set({ toneMapping: "bt.2390", targetPeak: 250 }),
|
|
4071
|
+
* });
|
|
4072
|
+
* }
|
|
4073
|
+
* ```
|
|
4074
|
+
*
|
|
4075
|
+
* @player 0.5.12; older players leave it out (declare
|
|
4076
|
+
* `"minPlayerVersion": "0.5.12"` when the plugin relies on it).
|
|
4077
|
+
* @since 1.5.34
|
|
4078
|
+
*/
|
|
4079
|
+
readonly rendering?: "gpu" | "software";
|
|
4080
|
+
/**
|
|
4081
|
+
* Why {@link SystemInfo.rendering} is what it is now: the same reason as
|
|
4082
|
+
* {@link RenderingState.reason} (`default`, `no-gpu-backend`,
|
|
4083
|
+
* `preference`, `denylist`, `window-fallback`…, see
|
|
4084
|
+
* {@link RenderingReasonCode}). Read at each call, like `rendering`.
|
|
4085
|
+
*
|
|
4086
|
+
* Absent (`undefined`) on players before 0.5.13.
|
|
4087
|
+
*
|
|
4088
|
+
* @example Say why the video is drawn in software
|
|
4089
|
+
* An About page explains a software renderer with the player's own words,
|
|
4090
|
+
* for example that the graphics driver is on the player's denylist.
|
|
4091
|
+
* `system()` reports the renderer and its reason together, with no
|
|
4092
|
+
* capability; the message is English text that may name the adapter and
|
|
4093
|
+
* the driver version.
|
|
4094
|
+
* ```ts
|
|
4095
|
+
* const { rendering, renderingReason } = await plugin.app.system();
|
|
4096
|
+
* if (rendering === "software" && renderingReason)
|
|
4097
|
+
* console.log(`Rendering: software (${renderingReason.message})`);
|
|
4098
|
+
* ```
|
|
4099
|
+
*
|
|
4100
|
+
* @player 0.5.13; older players leave it out (declare
|
|
4101
|
+
* `"minPlayerVersion": "0.5.13"` when the plugin relies on it).
|
|
4102
|
+
* @since 1.5.35
|
|
4103
|
+
*/
|
|
4104
|
+
readonly renderingReason?: RenderingReason;
|
|
4037
4105
|
}
|
|
4038
4106
|
/**
|
|
4039
4107
|
* One display in {@link SystemInfo.displays}.
|
|
@@ -6294,8 +6362,10 @@ export interface RenderSettings {
|
|
|
6294
6362
|
*
|
|
6295
6363
|
* Platforms: only macOS renders on the GPU. Under software rendering
|
|
6296
6364
|
* (Windows, Linux, headless, fallback) every `set` fails with
|
|
6297
|
-
* `unsupported
|
|
6298
|
-
*
|
|
6365
|
+
* `unsupported`; {@link SystemInfo.rendering} tells which renderer draws
|
|
6366
|
+
* without creating the handle. macOS OpenGL 4.1 has no
|
|
6367
|
+
* compute shaders, so `peakDetect` is accepted but has no effect; output
|
|
6368
|
+
* is always SDR.
|
|
6299
6369
|
*
|
|
6300
6370
|
* @example Tone-map HDR video and hide the menu where it cannot work
|
|
6301
6371
|
* On a GPU-rendering player HDR video is tone-mapped with BT.2390 for a
|
|
@@ -6591,7 +6661,10 @@ export interface Subtitles {
|
|
|
6591
6661
|
*
|
|
6592
6662
|
* Limits: SRT ≤ 2 MiB and ≤ 10,000 cues; ASS ≤ 2 MiB with `[Script Info]`
|
|
6593
6663
|
* and `[Events]` and 1–20,000 `Dialogue:` lines. Convert other formats
|
|
6594
|
-
* (VTT, SAMI) to SRT first.
|
|
6664
|
+
* (VTT, SAMI) to SRT first. Per source, a plugin has at most 4 loaded
|
|
6665
|
+
* tracks at once and loads at most 16 files (removed ones count), and
|
|
6666
|
+
* every plugin together at most 16 tracks; see `SUBTITLE_LIMITS` in
|
|
6667
|
+
* `@vestra-player/sdk/testing`.
|
|
6595
6668
|
*
|
|
6596
6669
|
* @capability subtitles.control and subtitles.read
|
|
6597
6670
|
* @throws `invalid` (rejects) A bad `format` or `title`, or a file over the
|
|
@@ -6602,7 +6675,10 @@ export interface Subtitles {
|
|
|
6602
6675
|
* loading.
|
|
6603
6676
|
* @throws `aborted` (rejects) `signal` aborted before the commit (an
|
|
6604
6677
|
* `AbortError`); the upload is discarded.
|
|
6605
|
-
* @throws `busy` (rejects) Too many subtitle operations at once
|
|
6678
|
+
* @throws `busy` (rejects) Too many subtitle operations at once, or a
|
|
6679
|
+
* limit of `SUBTITLE_LIMITS` is reached (4 tracks of this plugin, 16
|
|
6680
|
+
* loads of this plugin or 16 tracks in the source, or another of its
|
|
6681
|
+
* limits); nothing is loaded.
|
|
6606
6682
|
* @throws `capability` (rejects) The manifest does not declare
|
|
6607
6683
|
* `subtitles.control` and `subtitles.read`.
|
|
6608
6684
|
*
|
|
@@ -8885,3 +8961,329 @@ export interface Secrets {
|
|
|
8885
8961
|
*/
|
|
8886
8962
|
delete(name: string): Promise<void>;
|
|
8887
8963
|
}
|
|
8964
|
+
/**
|
|
8965
|
+
* Which renderer draws the video: `"gpu"` (the GPU renderer, where
|
|
8966
|
+
* {@link RenderOptions | render options} apply) or `"software"` (they fail
|
|
8967
|
+
* with `unsupported`). The same values as {@link SystemInfo.rendering}.
|
|
8968
|
+
*
|
|
8969
|
+
* @example Tell the user which renderer draws the video
|
|
8970
|
+
* The plugin shows "Rendering: GPU" or "Rendering: software" on the
|
|
8971
|
+
* video. `state()` asks the player; `mode` is the renderer drawing now,
|
|
8972
|
+
* which can differ from the saved choice until the next start.
|
|
8973
|
+
* ```ts
|
|
8974
|
+
* const { mode } = await plugin.rendering.state();
|
|
8975
|
+
* const label: Record<RenderingMode, string> = { gpu: "GPU", software: "software" };
|
|
8976
|
+
* await plugin.osd.show("Rendering: {}", [label[mode]]);
|
|
8977
|
+
* ```
|
|
8978
|
+
*
|
|
8979
|
+
* @player 0.5.13
|
|
8980
|
+
* @since 1.5.35
|
|
8981
|
+
* @category Services
|
|
8982
|
+
*/
|
|
8983
|
+
export type RenderingMode = "gpu" | "software";
|
|
8984
|
+
/**
|
|
8985
|
+
* The user's saved rendering choice: `"auto"` (the player decides: the GPU
|
|
8986
|
+
* where this system has a GPU renderer that is not ruled out, software
|
|
8987
|
+
* elsewhere), `"gpu"` or `"software"`. It applies from the next start.
|
|
8988
|
+
*
|
|
8989
|
+
* @example Describe the saved choice on a settings page
|
|
8990
|
+
* The plugin turns the saved choice into the words its settings page
|
|
8991
|
+
* shows. `preference` is what the user chose, not what draws now:
|
|
8992
|
+
* {@link RenderingState.nextMode} says what the next start will use.
|
|
8993
|
+
* ```ts
|
|
8994
|
+
* const { preference } = await plugin.rendering.state();
|
|
8995
|
+
* // One word per choice; the Record type makes sure none is missing.
|
|
8996
|
+
* const words: Record<RenderingPreference, string> = {
|
|
8997
|
+
* auto: "Automatic",
|
|
8998
|
+
* gpu: "GPU",
|
|
8999
|
+
* software: "Software",
|
|
9000
|
+
* };
|
|
9001
|
+
* console.log(words[preference]);
|
|
9002
|
+
* ```
|
|
9003
|
+
*
|
|
9004
|
+
* @player 0.5.13
|
|
9005
|
+
* @since 1.5.35
|
|
9006
|
+
* @category Services
|
|
9007
|
+
*/
|
|
9008
|
+
export type RenderingPreference = "auto" | "gpu" | "software";
|
|
9009
|
+
/**
|
|
9010
|
+
* Why the player renders the way it does, as a stable kebab-case code. A
|
|
9011
|
+
* newer player may add codes: compare with the ones you handle and show
|
|
9012
|
+
* {@link RenderingReason.message} for the rest. The codes of player 0.5.13:
|
|
9013
|
+
*
|
|
9014
|
+
* | Code | Meaning |
|
|
9015
|
+
* | --- | --- |
|
|
9016
|
+
* | `default` | Nothing ruled the GPU out; the platform's default. |
|
|
9017
|
+
* | `pending` | GPU rendering is starting. |
|
|
9018
|
+
* | `headless` | The player runs without a user interface. |
|
|
9019
|
+
* | `no-gpu-backend` | This player has no GPU renderer on this system (Windows today). |
|
|
9020
|
+
* | `env` | The environment chose it (`VESTRA_RENDER`, `VESTRA_SOFTWARE_RENDER`). |
|
|
9021
|
+
* | `preference` | The user chose software rendering ({@link Rendering.setPreference}); GPU chosen and available reports `default`. |
|
|
9022
|
+
* | `denylist` | The graphics driver is on the player's denylist. |
|
|
9023
|
+
* | `previous-crash` | GPU rendering crashed at an earlier start; it is tried again after a driver or player update, or after 7 days. |
|
|
9024
|
+
* | `init-failed` | GPU rendering could not start. |
|
|
9025
|
+
* | `window-fallback` | A window could not show GPU frames; the player switched to software during the run. |
|
|
9026
|
+
*
|
|
9027
|
+
* @example Explain a driver problem differently from a user choice
|
|
9028
|
+
* The plugin adds advice only when the graphics driver is the cause.
|
|
9029
|
+
* `reason.code` is looked up among the codes the plugin knows; an unknown
|
|
9030
|
+
* code from a newer player falls through to the player's own message.
|
|
9031
|
+
* ```ts
|
|
9032
|
+
* const { reason } = await plugin.rendering.state();
|
|
9033
|
+
* // Advice for the codes this plugin knows; any other code shows the message.
|
|
9034
|
+
* const advice: Partial<Record<RenderingReasonCode, string>> = {
|
|
9035
|
+
* denylist: "Update the graphics driver to use the GPU.",
|
|
9036
|
+
* "previous-crash": "The GPU renderer crashed earlier; it is retried after an update.",
|
|
9037
|
+
* };
|
|
9038
|
+
* console.log(advice[reason.code] ?? reason.message);
|
|
9039
|
+
* ```
|
|
9040
|
+
*
|
|
9041
|
+
* @player 0.5.13
|
|
9042
|
+
* @since 1.5.35
|
|
9043
|
+
* @category Services
|
|
9044
|
+
*/
|
|
9045
|
+
export type RenderingReasonCode = "default" | "pending" | "headless" | "no-gpu-backend" | "env" | "preference" | "denylist" | "previous-crash" | "init-failed" | "window-fallback" | (string & {});
|
|
9046
|
+
/**
|
|
9047
|
+
* Why the player renders, or will render, the way it does: a stable
|
|
9048
|
+
* {@link RenderingReasonCode} to branch on and a sentence to show.
|
|
9049
|
+
*
|
|
9050
|
+
* @example Show why GPU rendering is off
|
|
9051
|
+
* The plugin logs the player's explanation when the video is drawn in
|
|
9052
|
+
* software. `message` is the player's English text and may name the
|
|
9053
|
+
* graphics adapter and driver version; `code` is for decisions.
|
|
9054
|
+
* ```ts
|
|
9055
|
+
* const { mode, reason } = await plugin.rendering.state();
|
|
9056
|
+
* if (mode === "software") console.log(`${reason.code}: ${reason.message}`);
|
|
9057
|
+
* ```
|
|
9058
|
+
*
|
|
9059
|
+
* @player 0.5.13
|
|
9060
|
+
* @since 1.5.35
|
|
9061
|
+
* @category Services
|
|
9062
|
+
*/
|
|
9063
|
+
export interface RenderingReason {
|
|
9064
|
+
/** The reason as a stable kebab-case code; branch on this. */
|
|
9065
|
+
readonly code: RenderingReasonCode;
|
|
9066
|
+
/**
|
|
9067
|
+
* The reason as English text for people, for example with the graphics
|
|
9068
|
+
* adapter's name and driver version; never branch on it.
|
|
9069
|
+
*/
|
|
9070
|
+
readonly message: string;
|
|
9071
|
+
}
|
|
9072
|
+
/**
|
|
9073
|
+
* What {@link Rendering.state} and {@link Rendering.setPreference} report:
|
|
9074
|
+
* the renderer drawing now and why, the saved choice, what the next start
|
|
9075
|
+
* will use, and whether `"gpu"` can be chosen.
|
|
9076
|
+
*
|
|
9077
|
+
* @example Label a menu item while a change waits for a restart
|
|
9078
|
+
* The plugin adds "(Restart to Apply)" to its GPU item after the user
|
|
9079
|
+
* changed the choice. `restartPending` compares the mode the next start
|
|
9080
|
+
* will use with the mode this run started with, so it turns false again
|
|
9081
|
+
* when the user changes the choice back.
|
|
9082
|
+
* ```ts
|
|
9083
|
+
* const state = await plugin.rendering.state();
|
|
9084
|
+
* const title = state.restartPending
|
|
9085
|
+
* ? "GPU Rendering (Experimental) (Restart to Apply)"
|
|
9086
|
+
* : "GPU Rendering (Experimental)";
|
|
9087
|
+
* console.log(title, state.nextMode, state.nextReason.message);
|
|
9088
|
+
* ```
|
|
9089
|
+
*
|
|
9090
|
+
* @player 0.5.13
|
|
9091
|
+
* @since 1.5.35
|
|
9092
|
+
* @category Services
|
|
9093
|
+
*/
|
|
9094
|
+
export interface RenderingState {
|
|
9095
|
+
/** The renderer drawing the video now; the same as {@link SystemInfo.rendering}. */
|
|
9096
|
+
readonly mode: RenderingMode;
|
|
9097
|
+
/** Why {@link RenderingState.mode} is what it is now. */
|
|
9098
|
+
readonly reason: RenderingReason;
|
|
9099
|
+
/** The saved choice; it applies from the next start. */
|
|
9100
|
+
readonly preference: RenderingPreference;
|
|
9101
|
+
/**
|
|
9102
|
+
* The renderer the next start will use, as far as the player knows now:
|
|
9103
|
+
* from the saved choice, the environment, the driver denylist and an
|
|
9104
|
+
* earlier GPU crash.
|
|
9105
|
+
*/
|
|
9106
|
+
readonly nextMode: RenderingMode;
|
|
9107
|
+
/** Why the next start will use {@link RenderingState.nextMode}. */
|
|
9108
|
+
readonly nextReason: RenderingReason;
|
|
9109
|
+
/**
|
|
9110
|
+
* `true` while {@link RenderingState.nextMode} differs from the mode this
|
|
9111
|
+
* run started with, so a restart would change the renderer; `false` again
|
|
9112
|
+
* when the user changes the choice back.
|
|
9113
|
+
*/
|
|
9114
|
+
readonly restartPending: boolean;
|
|
9115
|
+
/** Whether the user can choose `"gpu"` now. */
|
|
9116
|
+
readonly gpu: {
|
|
9117
|
+
/** `true` when `setPreference("gpu")` would be accepted. */
|
|
9118
|
+
readonly available: boolean;
|
|
9119
|
+
/**
|
|
9120
|
+
* Why `"gpu"` cannot be chosen (`no-gpu-backend`, `headless`,
|
|
9121
|
+
* `denylist`, `previous-crash`…); `null` while it is available.
|
|
9122
|
+
*/
|
|
9123
|
+
readonly reason: RenderingReason | null;
|
|
9124
|
+
};
|
|
9125
|
+
}
|
|
9126
|
+
/**
|
|
9127
|
+
* `plugin.rendering`: the player's rendering choice, GPU or software.
|
|
9128
|
+
* Reading it needs no capability; changing the saved choice and restarting
|
|
9129
|
+
* the player need `rendering.manage`.
|
|
9130
|
+
*
|
|
9131
|
+
* @remarks
|
|
9132
|
+
* The choice works like a browser's hardware acceleration switch: the
|
|
9133
|
+
* player saves it in its own settings at once, and the running player
|
|
9134
|
+
* keeps its renderer. The next start uses it, whether the user restarts
|
|
9135
|
+
* now through {@link Rendering.restartPlayer} or quits and starts the
|
|
9136
|
+
* player later. The player can still rule the GPU out at a start (an
|
|
9137
|
+
* environment variable, a graphics driver on its denylist, a GPU crash at
|
|
9138
|
+
* an earlier start); {@link RenderingState.nextMode} and
|
|
9139
|
+
* {@link RenderingState.nextReason} say what the next start will do.
|
|
9140
|
+
*
|
|
9141
|
+
* The renderer is a choice for the whole player and a restart stops every
|
|
9142
|
+
* plugin, so change it only when the user asks. A plugin that only needs
|
|
9143
|
+
* to know whether render options work reads {@link SystemInfo.rendering}.
|
|
9144
|
+
*
|
|
9145
|
+
* Players before 0.5.13 do not know these requests: `state()` rejects with
|
|
9146
|
+
* `unsupported`, and they do not load a plugin that declares
|
|
9147
|
+
* `rendering.manage` (an unknown capability). Declare
|
|
9148
|
+
* `"minPlayerVersion": "0.5.13"` when the plugin needs this.
|
|
9149
|
+
*
|
|
9150
|
+
* @example Offer GPU rendering as a menu item
|
|
9151
|
+
* Settings ▸ GPU Rendering (Experimental) carries a check mark while the
|
|
9152
|
+
* next start will draw on the GPU, is greyed out with the player's reason
|
|
9153
|
+
* where the GPU cannot be chosen, and saves the other choice when picked.
|
|
9154
|
+
* `state()` reads the player's view once; `setPreference` saves the choice
|
|
9155
|
+
* and resolves with the new state, which the item's bound values read
|
|
9156
|
+
* again after the handler. The how-to guide adds the restart.
|
|
9157
|
+
* ```ts
|
|
9158
|
+
* let state = await plugin.rendering.state();
|
|
9159
|
+
* plugin.commands.add({
|
|
9160
|
+
* id: "gpu-rendering",
|
|
9161
|
+
* path: ["@settings", "GPU Rendering (Experimental)"],
|
|
9162
|
+
* checked: () => state.nextMode === "gpu", // also for "auto" on a GPU system
|
|
9163
|
+
* enabled: () => state.gpu.available,
|
|
9164
|
+
* reason: () => state.gpu.reason?.message ?? null, // shown while disabled
|
|
9165
|
+
* run: async () => {
|
|
9166
|
+
* const choice = state.nextMode === "gpu" ? "software" : "gpu";
|
|
9167
|
+
* state = await plugin.rendering.setPreference(choice);
|
|
9168
|
+
* },
|
|
9169
|
+
* });
|
|
9170
|
+
* ```
|
|
9171
|
+
*
|
|
9172
|
+
* @capability None to read the state; `rendering.manage` to change the
|
|
9173
|
+
* choice or restart the player.
|
|
9174
|
+
* @see [Offer a GPU rendering switch](../../docs/how-to/gpu-rendering.md)
|
|
9175
|
+
* @player 0.5.13; older players reject the requests as unknown
|
|
9176
|
+
* (`unsupported`).
|
|
9177
|
+
* @since 1.5.35
|
|
9178
|
+
* @category Services
|
|
9179
|
+
*/
|
|
9180
|
+
export interface Rendering {
|
|
9181
|
+
/**
|
|
9182
|
+
* Read the renderer drawing now, the saved choice, what the next start
|
|
9183
|
+
* will use and whether `"gpu"` can be chosen. No capability.
|
|
9184
|
+
*
|
|
9185
|
+
* @capability None.
|
|
9186
|
+
* @throws `unsupported` (rejects) A player before 0.5.13, which does not
|
|
9187
|
+
* know the request.
|
|
9188
|
+
*
|
|
9189
|
+
* @example Find out whether the GPU can be chosen
|
|
9190
|
+
* The plugin reads the state once while it starts and keeps it for its
|
|
9191
|
+
* menu. Each call asks the player; `gpu.available` is false, with a
|
|
9192
|
+
* reason, where this player has no GPU renderer, without a user
|
|
9193
|
+
* interface, or when the driver is ruled out. An older player rejects
|
|
9194
|
+
* with `unsupported`, and the plugin then offers nothing.
|
|
9195
|
+
* ```ts
|
|
9196
|
+
* const state = await plugin.rendering.state().catch((error: PluginError) => {
|
|
9197
|
+
* if (error.code === "unsupported") return null; // a player before 0.5.13
|
|
9198
|
+
* throw error;
|
|
9199
|
+
* });
|
|
9200
|
+
* if (state && !state.gpu.available) console.log(state.gpu.reason?.message);
|
|
9201
|
+
* ```
|
|
9202
|
+
*
|
|
9203
|
+
* @since 1.5.35
|
|
9204
|
+
*/
|
|
9205
|
+
state(): Promise<RenderingState>;
|
|
9206
|
+
/**
|
|
9207
|
+
* Save the user's rendering choice. The player writes it to its settings
|
|
9208
|
+
* at once; the running player keeps its renderer, and the next start
|
|
9209
|
+
* uses the choice whether or not the user restarts now. `"auto"` and
|
|
9210
|
+
* `"software"` are always accepted.
|
|
9211
|
+
*
|
|
9212
|
+
* @param preference - `"auto"`, `"gpu"` or `"software"`.
|
|
9213
|
+
* @returns The new state; {@link RenderingState.restartPending} tells
|
|
9214
|
+
* whether a restart would change the renderer.
|
|
9215
|
+
*
|
|
9216
|
+
* @capability rendering.manage
|
|
9217
|
+
* @throws `invalid` (rejects) `preference` is not `"auto"`, `"gpu"` or
|
|
9218
|
+
* `"software"`.
|
|
9219
|
+
* @throws `unsupported` (rejects) `"gpu"` where this player has no GPU
|
|
9220
|
+
* renderer on this system, or runs without a user interface; also any
|
|
9221
|
+
* value on a player before 0.5.13.
|
|
9222
|
+
* @throws `unavailable` (rejects) `"gpu"` while it is ruled out: the
|
|
9223
|
+
* graphics driver is on the player's denylist, or GPU rendering crashed
|
|
9224
|
+
* at an earlier start. The message says which, with the adapter's name
|
|
9225
|
+
* and the driver version.
|
|
9226
|
+
* @throws `failed` (rejects) The player could not write its settings file.
|
|
9227
|
+
* @throws `capability` (rejects) The manifest does not declare
|
|
9228
|
+
* `rendering.manage`.
|
|
9229
|
+
*
|
|
9230
|
+
* @example Switch back to the automatic choice
|
|
9231
|
+
* A Reset item returns the renderer to the player's own choice and tells
|
|
9232
|
+
* the user when it takes effect. `setPreference` saves the choice and
|
|
9233
|
+
* resolves with the new state; `restartPending` is true when the next
|
|
9234
|
+
* start will draw differently from this run. A refused save leaves the
|
|
9235
|
+
* old choice in place.
|
|
9236
|
+
* ```ts
|
|
9237
|
+
* try {
|
|
9238
|
+
* const state = await plugin.rendering.setPreference("auto");
|
|
9239
|
+
* if (state.restartPending) await plugin.osd.show("Applies after a restart");
|
|
9240
|
+
* } catch (error) {
|
|
9241
|
+
* // `failed`: the player's settings file could not be written.
|
|
9242
|
+
* await plugin.osd.show("Not saved ({})", [(error as PluginError).code]);
|
|
9243
|
+
* }
|
|
9244
|
+
* ```
|
|
9245
|
+
*
|
|
9246
|
+
* @since 1.5.35
|
|
9247
|
+
*/
|
|
9248
|
+
setPreference(preference: RenderingPreference): Promise<RenderingState>;
|
|
9249
|
+
/**
|
|
9250
|
+
* Restart the player so that a changed choice applies now. Resolves once
|
|
9251
|
+
* the player has accepted; the player then quits normally, which stops
|
|
9252
|
+
* every plugin (this one included), and starts again with the same
|
|
9253
|
+
* plugins. A local file that was open continues at its position, paused
|
|
9254
|
+
* or playing as it was; a stream or another source that is not a file is
|
|
9255
|
+
* not reopened.
|
|
9256
|
+
*
|
|
9257
|
+
* @capability rendering.manage
|
|
9258
|
+
* @throws `unsupported` (rejects) The player runs without a user
|
|
9259
|
+
* interface; also a player before 0.5.13.
|
|
9260
|
+
* @throws `busy` (rejects) A restart is already under way, or this player
|
|
9261
|
+
* was itself started by a restart less than 30 seconds ago (so a plugin
|
|
9262
|
+
* that restarts on activation cannot make a loop).
|
|
9263
|
+
* @throws `failed` (rejects) The new player process could not be started;
|
|
9264
|
+
* the player keeps running.
|
|
9265
|
+
* @throws `capability` (rejects) The manifest does not declare
|
|
9266
|
+
* `rendering.manage`.
|
|
9267
|
+
*
|
|
9268
|
+
* @example Restart after asking the user
|
|
9269
|
+
* After the user changed the renderer, the plugin offers to restart now.
|
|
9270
|
+
* `confirm` asks first, because a restart closes every window (it needs
|
|
9271
|
+
* `ui.dialog`); once `restartPlayer` resolves, the player is quitting and
|
|
9272
|
+
* will stop this plugin, so nothing else is started after it.
|
|
9273
|
+
* ```ts
|
|
9274
|
+
* const { confirmed } = await plugin.dialogs.confirm({
|
|
9275
|
+
* message: "Restart the player now?",
|
|
9276
|
+
* detail: "The new renderer is used from the restart on. The video continues where it is.",
|
|
9277
|
+
* confirm: "Restart",
|
|
9278
|
+
* });
|
|
9279
|
+
* if (confirmed)
|
|
9280
|
+
* await plugin.rendering.restartPlayer().catch((error: PluginError) => {
|
|
9281
|
+
* // `failed`: the new player could not start; this one keeps running.
|
|
9282
|
+
* void plugin.osd.show("Could not restart ({})", [error.code]);
|
|
9283
|
+
* });
|
|
9284
|
+
* ```
|
|
9285
|
+
*
|
|
9286
|
+
* @since 1.5.35
|
|
9287
|
+
*/
|
|
9288
|
+
restartPlayer(): Promise<void>;
|
|
9289
|
+
}
|
package/dist/wire.d.ts
CHANGED
|
@@ -297,7 +297,7 @@ export interface LocalServices {
|
|
|
297
297
|
signal: AbortSignal;
|
|
298
298
|
}): Promise<Uint8Array>;
|
|
299
299
|
}
|
|
300
|
-
/** `app.system`: the operating system and the
|
|
300
|
+
/** `app.system`: the operating system, the displays and the renderer. */
|
|
301
301
|
export interface WireSystemInfo {
|
|
302
302
|
os: "macos" | "windows" | "linux" | "other";
|
|
303
303
|
name: string;
|
|
@@ -313,6 +313,28 @@ export interface WireSystemInfo {
|
|
|
313
313
|
refreshRate: number | null;
|
|
314
314
|
primary: boolean;
|
|
315
315
|
}[];
|
|
316
|
+
/** Player 0.5.12; older players leave it out. */
|
|
317
|
+
rendering?: "gpu" | "software";
|
|
318
|
+
/** Why `rendering` is what it is (player 0.5.13; older players leave it out). */
|
|
319
|
+
renderingReason?: WireRenderingReason;
|
|
320
|
+
}
|
|
321
|
+
/** A rendering reason: a stable kebab-case `code` and English text. */
|
|
322
|
+
export interface WireRenderingReason {
|
|
323
|
+
code: string;
|
|
324
|
+
message: string;
|
|
325
|
+
}
|
|
326
|
+
/** `rendering.state` and `rendering.setPreference` (player 0.5.13). */
|
|
327
|
+
export interface WireRenderingState {
|
|
328
|
+
mode: "gpu" | "software";
|
|
329
|
+
reason: WireRenderingReason;
|
|
330
|
+
preference: "auto" | "gpu" | "software";
|
|
331
|
+
nextMode: "gpu" | "software";
|
|
332
|
+
nextReason: WireRenderingReason;
|
|
333
|
+
restartPending: boolean;
|
|
334
|
+
gpu: {
|
|
335
|
+
available: boolean;
|
|
336
|
+
reason: WireRenderingReason | null;
|
|
337
|
+
};
|
|
316
338
|
}
|
|
317
339
|
/**
|
|
318
340
|
* Template arguments on the wire (`osd.show`, `osd.panel`, `dialogs.confirm`,
|
|
@@ -525,6 +547,15 @@ export declare function createWire(transport: Transport): {
|
|
|
525
547
|
app: {
|
|
526
548
|
system: () => Promise<WireSystemInfo>;
|
|
527
549
|
};
|
|
550
|
+
/**
|
|
551
|
+
* The rendering choice (player 0.5.13): `state` needs no capability,
|
|
552
|
+
* `setPreference` and `restart` need `rendering.manage`.
|
|
553
|
+
*/
|
|
554
|
+
rendering: {
|
|
555
|
+
state: () => Promise<WireRenderingState>;
|
|
556
|
+
setPreference: (preference: string) => Promise<WireRenderingState>;
|
|
557
|
+
restart: () => Promise<null>;
|
|
558
|
+
};
|
|
528
559
|
power: {
|
|
529
560
|
preventSleep: (mode: "off" | "playing") => Promise<void>;
|
|
530
561
|
};
|
package/dist/wire.js
CHANGED
|
@@ -214,6 +214,17 @@ export function createWire(transport) {
|
|
|
214
214
|
app: {
|
|
215
215
|
system: () => transport.request("app.system"),
|
|
216
216
|
},
|
|
217
|
+
/**
|
|
218
|
+
* The rendering choice (player 0.5.13): `state` needs no capability,
|
|
219
|
+
* `setPreference` and `restart` need `rendering.manage`.
|
|
220
|
+
*/
|
|
221
|
+
rendering: {
|
|
222
|
+
state: () => transport.request("rendering.state"),
|
|
223
|
+
setPreference: (preference) => transport.request("rendering.setPreference", {
|
|
224
|
+
preference,
|
|
225
|
+
}),
|
|
226
|
+
restart: () => transport.request("rendering.restart"),
|
|
227
|
+
},
|
|
217
228
|
power: {
|
|
218
229
|
preventSleep: (mode) => transport.request("power.preventSleep", { mode }),
|
|
219
230
|
},
|