@vestra-player/sdk 1.5.9 → 1.5.11
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 +26 -0
- package/dist/commands.d.ts +7 -4
- package/dist/i18n-tools.js +59 -3
- package/dist/i18n.d.ts +92 -0
- package/dist/i18n.js +299 -0
- package/dist/player-runtime.d.ts +2 -1
- package/dist/player-runtime.js +2 -1
- package/dist/plugin/bindings.js +1 -0
- package/dist/plugin/commands.js +24 -4
- package/dist/plugin/index.js +9 -1
- package/dist/plugin/language.d.ts +6 -2
- package/dist/plugin/language.js +74 -0
- package/dist/plugin/osd.d.ts +10 -2
- package/dist/plugin/osd.js +35 -16
- package/dist/plugin/subtitles.js +9 -1
- package/dist/plugin/testing.d.ts +54 -5
- package/dist/plugin/testing.js +199 -49
- package/dist/plugin/timeline.js +3 -1
- package/dist/plugin/types.d.ts +338 -43
- package/dist/plugin/ui.js +26 -10
- package/dist/plugin/values.d.ts +55 -0
- package/dist/plugin/values.js +117 -0
- package/dist/source-resolvers.d.ts +0 -1
- package/dist/source-resolvers.js +9 -1
- package/dist/subtitles.d.ts +3 -1
- package/dist/wire.d.ts +17 -9
- package/dist/wire.js +2 -1
- package/llms-full.txt +295 -47
- package/llms.txt +41 -41
- package/package.json +1 -1
package/llms-full.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @vestra-player/sdk 1.5.
|
|
1
|
+
# @vestra-player/sdk 1.5.11: full reference
|
|
2
2
|
|
|
3
3
|
> Everything needed to write a Vestra Player plugin (plugin API `vestra/1`): the guides, every public declaration of `@vestra-player/sdk` and `@vestra-player/sdk/testing` with its documentation, and the complete source of the example plugins. Generated from the SDK's sources by scripts/llms.mjs; the short index is llms.txt.
|
|
4
4
|
|
|
@@ -998,11 +998,11 @@ change).
|
|
|
998
998
|
| `timeout` | A time limit ran out (`openStream` start-up, `tools.run`, `system.*` after 10 s). |
|
|
999
999
|
| `stream`, `device` | `openStream`: the producer failed / the audio device is not ready. |
|
|
1000
1000
|
| `backend-uncertain` | The player's backend blocked a filter stage; call `retry()`. |
|
|
1001
|
-
| `limit` | A player-wide limit was reached (for example the number of commands). |
|
|
1001
|
+
| `limit` | A player-wide limit was reached (for example the number of commands), a property value is over the limits of PropValue, or a request is longer than the player's 1 MiB message. |
|
|
1002
1002
|
| `reserved` | Packages.validate, PackageCandidate.install: the id is `vestra` or starts with `vestra.` (any case), which only the player's built-in plugins use (player 0.4.1). |
|
|
1003
1003
|
| `versionMismatch` | The package needs a newer player (`minPlayerVersion`) or another `apiVersion`. |
|
|
1004
1004
|
| `ui-prepare` | The player could not prepare a mounted panel or a settings page (its Slint file does not compile, a bound property is not declared, or another plugin's panel holds the slot); `message` has the diagnostics. |
|
|
1005
|
-
| `ui` | The player could not apply a property to a tool window or a settings page, or could not build the Options window (a property the Slint file does not declare, a value of the wrong type); `message` has Slint's reason. |
|
|
1005
|
+
| `ui` | The player could not apply a property to a tool window or a settings page, or could not build the Options window (a property the Slint file does not declare, a value of the wrong type); `message` has Slint's reason. Also reported to Scope.onError without a request: a callback whose arguments the player could not convert, a property it could not show again when it rebuilt a view (an image file removed since). |
|
|
1006
1006
|
| `host` | Any other failure inside the player; `message` is the player's reason. |
|
|
1007
1007
|
| `disabled` | The plugin is being stopped; pending requests fail with it. |
|
|
1008
1008
|
| `unknown`, `rejected`, `expired` | After a transport problem the SDK could not confirm the outcome (does not happen in normal operation). |
|
|
@@ -1201,8 +1201,8 @@ interface CommandState {
|
|
|
1201
1201
|
checked: boolean | null;
|
|
1202
1202
|
/** Shown as busy; like `enabled: false`, the player does not call `run`. Default false. */
|
|
1203
1203
|
busy: boolean;
|
|
1204
|
-
/** Shown when the command is disabled or busy. */
|
|
1205
|
-
reason:
|
|
1204
|
+
/** Shown when the command is disabled or busy: English source text the player translates, or a Text (SDK 1.5.11). */
|
|
1205
|
+
reason: TextValue | null;
|
|
1206
1206
|
}
|
|
1207
1207
|
```
|
|
1208
1208
|
|
|
@@ -1279,10 +1279,15 @@ interface CommandOptions {
|
|
|
1279
1279
|
* titled their menus in Chinese (视频…): there `["Video", "Blur"]` is a
|
|
1280
1280
|
* menu of its own, so plugins for those players write `@video`; player
|
|
1281
1281
|
* 0.4.3 still accepts the old Chinese titles of its own menus.
|
|
1282
|
+
*
|
|
1283
|
+
* A segment that mixes words with data (a track number, a count) is a
|
|
1284
|
+
* Text (SDK 1.5.11, player 0.4.3): `plugin.i18n.text("Track {}
|
|
1285
|
+
* ({})", [n, codec])`. The menu shows it translated and filled in; it
|
|
1286
|
+
* merges by its English rendering ("Track 2 (opus)").
|
|
1282
1287
|
*/
|
|
1283
|
-
path?: string[];
|
|
1284
|
-
/** Menu label (English source text, shown translated); defaults to the last path segment. */
|
|
1285
|
-
title?: string;
|
|
1288
|
+
path?: (string | Text)[];
|
|
1289
|
+
/** Menu label (English source text, shown translated, or a Text); defaults to the last path segment. */
|
|
1290
|
+
title?: string | Text;
|
|
1286
1291
|
/**
|
|
1287
1292
|
* Sibling order in the menu, ascending (integer, default 0). A submenu sits where its first command sits, except a built-in menu, which keeps its fixed place. Directly inside a built-in menu, 0 (the default) sorts last. Equal orders: plugin id, then declaration order. Range ±1,000,000. See CommandOptions for the menu order rules.
|
|
1288
1293
|
*/
|
|
@@ -1324,8 +1329,8 @@ interface CommandOptions {
|
|
|
1324
1329
|
checked?: Bindable<boolean | null>;
|
|
1325
1330
|
/** Busy state (default false); the player does not call `run` while busy. */
|
|
1326
1331
|
busy?: Bindable<boolean>;
|
|
1327
|
-
/** Why the command is disabled or busy (shown to the user). */
|
|
1328
|
-
reason?: Bindable<
|
|
1332
|
+
/** Why the command is disabled or busy (shown to the user): English source text, or a Text for one with data in it (SDK 1.5.11). */
|
|
1333
|
+
reason?: Bindable<TextValue | null>;
|
|
1329
1334
|
/**
|
|
1330
1335
|
* Run the command (menu item, binding, panel menu or `host.command(id).run()` in tests). It may return a promise; errors and rejections go to Scope.onError, and bound values are re-evaluated when it returns and when its promise settles.
|
|
1331
1336
|
*/
|
|
@@ -1432,7 +1437,7 @@ JSON whose values may also be Markdown documents, at any depth: the part
|
|
|
1432
1437
|
of PropValue that nests.
|
|
1433
1438
|
|
|
1434
1439
|
```ts
|
|
1435
|
-
type PropData = null | boolean | number | string | MarkdownRef | PropData[] | {
|
|
1440
|
+
type PropData = null | boolean | number | string | MarkdownRef | Text | TextList | PropData[] | {
|
|
1436
1441
|
[key: string]: PropData;
|
|
1437
1442
|
};
|
|
1438
1443
|
```
|
|
@@ -1948,12 +1953,82 @@ type LanguagePreference = "system" | Locale;
|
|
|
1948
1953
|
### TemplateArgs
|
|
1949
1954
|
|
|
1950
1955
|
Arguments of a template sentence (Osd.show,
|
|
1951
|
-
OsdPanel.set, ConfirmOptions.args): an
|
|
1952
|
-
`{0}`, `{1}` placeholders, or an object for `{name}`
|
|
1953
|
-
16
|
|
1956
|
+
OsdPanel.set, ConfirmOptions.args, I18n.text): an
|
|
1957
|
+
array for `{}` and `{0}`, `{1}` placeholders, or an object for `{name}`
|
|
1958
|
+
placeholders. At most 16. Strings and finite numbers are data, shown as
|
|
1959
|
+
they are (whole numbers without a fraction); a Text or
|
|
1960
|
+
TextList argument (SDK 1.5.11, player 0.4.3) is translated too,
|
|
1961
|
+
so a sentence can be built from translated parts.
|
|
1954
1962
|
|
|
1955
1963
|
```ts
|
|
1956
|
-
type TemplateArgs = readonly
|
|
1964
|
+
type TemplateArgs = readonly TextArg[] | Readonly<Record<string, TextArg>>;
|
|
1965
|
+
```
|
|
1966
|
+
|
|
1967
|
+
### Text
|
|
1968
|
+
|
|
1969
|
+
A text the player translates with the plugin's catalog and fills in:
|
|
1970
|
+
English source text with its arguments. Made by I18n.text; plain
|
|
1971
|
+
data, not a translation (the plugin never sees the translated string).
|
|
1972
|
+
|
|
1973
|
+
```ts
|
|
1974
|
+
interface Text {
|
|
1975
|
+
/** The English source text: a template with `{}`, `{0}` or `{name}`. */
|
|
1976
|
+
readonly $vestraText: string;
|
|
1977
|
+
/** Values for its placeholders. */
|
|
1978
|
+
readonly args?: TemplateArgs;
|
|
1979
|
+
}
|
|
1980
|
+
```
|
|
1981
|
+
|
|
1982
|
+
### TextList
|
|
1983
|
+
|
|
1984
|
+
Values joined the way the interface language joins them ("a, b" in
|
|
1985
|
+
English, "a、b" in Chinese). Made by I18n.list; accepted where a
|
|
1986
|
+
Text is.
|
|
1987
|
+
|
|
1988
|
+
```ts
|
|
1989
|
+
interface TextList {
|
|
1990
|
+
/** The items: data, or texts the player translates. */
|
|
1991
|
+
readonly $vestraList: readonly TextArg[];
|
|
1992
|
+
/** How they are joined; `"list"` by default. */
|
|
1993
|
+
readonly style?: ListStyle;
|
|
1994
|
+
}
|
|
1995
|
+
```
|
|
1996
|
+
|
|
1997
|
+
### ListStyle
|
|
1998
|
+
|
|
1999
|
+
How a TextList is joined, per interface language:
|
|
2000
|
+
|
|
2001
|
+
| style | English | 简体中文 | 日本語 |
|
|
2002
|
+
| --- | --- | --- | --- |
|
|
2003
|
+
| `list` (enumeration) | `, ` | `、` | `、` |
|
|
2004
|
+
| `clauses` (parts of one sentence) | `, ` | `,` | `、` |
|
|
2005
|
+
| `semicolons` | `; ` | `;` | `;` |
|
|
2006
|
+
| `sentences` (no final full stop) | `. ` | `。` | `。` |
|
|
2007
|
+
| `lines` | line break | line break | line break |
|
|
2008
|
+
|
|
2009
|
+
Korean, German and Spanish join as English; French puts a narrow space
|
|
2010
|
+
before `;`.
|
|
2011
|
+
|
|
2012
|
+
```ts
|
|
2013
|
+
type ListStyle = "list" | "clauses" | "semicolons" | "sentences" | "lines";
|
|
2014
|
+
```
|
|
2015
|
+
|
|
2016
|
+
### TextArg
|
|
2017
|
+
|
|
2018
|
+
An argument of a template: data (a string or a finite number, shown as it
|
|
2019
|
+
is) or a Text or TextList (translated).
|
|
2020
|
+
|
|
2021
|
+
```ts
|
|
2022
|
+
type TextArg = string | number | Text | TextList;
|
|
2023
|
+
```
|
|
2024
|
+
|
|
2025
|
+
### TextValue
|
|
2026
|
+
|
|
2027
|
+
A text the player shows: English source text (translated as a whole), a
|
|
2028
|
+
Text or a TextList.
|
|
2029
|
+
|
|
2030
|
+
```ts
|
|
2031
|
+
type TextValue = string | Text | TextList;
|
|
1957
2032
|
```
|
|
1958
2033
|
|
|
1959
2034
|
### I18n
|
|
@@ -1968,6 +2043,68 @@ interface I18n {
|
|
|
1968
2043
|
* The interface language of this run, chosen at start-up from the saved Appearance.language or the system's languages; English when neither names a Locale. Players before 0.4.3 report `"en"`.
|
|
1969
2044
|
*/
|
|
1970
2045
|
readonly locale: Locale;
|
|
2046
|
+
/**
|
|
2047
|
+
* A text that mixes words with data, for the player to translate: the
|
|
2048
|
+
* English source text (a template) and its arguments. It returns a plain
|
|
2049
|
+
* Text value, not a translation; pass it where the player shows
|
|
2050
|
+
* text (see Text) and the player shows it translated with this
|
|
2051
|
+
* plugin's catalog. `vestra-plugin i18n extract` collects `source` from
|
|
2052
|
+
* every call, so write it as a literal (or a conditional of literals, or
|
|
2053
|
+
* an `as const` table entry).
|
|
2054
|
+
*
|
|
2055
|
+
* Arguments are data unless they are texts themselves, so a sentence can
|
|
2056
|
+
* be built from translated parts without composing it in TypeScript.
|
|
2057
|
+
* `text` does not use `this`: `const { text, list } = plugin.i18n` works.
|
|
2058
|
+
* @param source - English source text; `{}`, `{0}` or `{name}` for the arguments, `{{` and `}}` for braces.
|
|
2059
|
+
* @param args - Values for its placeholders.
|
|
2060
|
+
* @throws invalid A malformed or over-limit value (`TEXT_LIMITS`).
|
|
2061
|
+
* @capability None.
|
|
2062
|
+
*/
|
|
2063
|
+
text(source: string, args?: TemplateArgs): Text;
|
|
2064
|
+
/**
|
|
2065
|
+
* Items joined the way the interface language joins them (see ListStyle): `list(["a.glsl", "b.glsl"])` shows "a.glsl, b.glsl" in English and "a.glsl、b.glsl" in Chinese. Items are data, or texts the player translates. Accepted where a Text is.
|
|
2066
|
+
* @param items - At most 256.
|
|
2067
|
+
* @param style - `"list"` by default.
|
|
2068
|
+
* @throws invalid A malformed or over-limit value.
|
|
2069
|
+
* @capability None.
|
|
2070
|
+
*/
|
|
2071
|
+
list(items: readonly TextArg[], style?: ListStyle): TextList;
|
|
2072
|
+
/**
|
|
2073
|
+
* An `Error` whose words the player shows translated: throw it where the player shows a plugin's failure to the user, such as from a file or web resolver's `resolve` (FileResolverOptions, WebResolverOptions) (also when a stream fails while it starts). The player shows `text` translated with this plugin's catalog (as `player.state.error` and the failure message); `message` is the English rendering, for logs and older players. Elsewhere it is an ordinary `Error`.
|
|
2074
|
+
* @param source - English source text, as I18n.text's.
|
|
2075
|
+
* @param args - Values for its placeholders.
|
|
2076
|
+
* @throws invalid A malformed or over-limit value.
|
|
2077
|
+
* @capability None.
|
|
2078
|
+
*/
|
|
2079
|
+
error(source: string, args?: TemplateArgs): TextError;
|
|
2080
|
+
/**
|
|
2081
|
+
* The string a text shows in this run's language, for text that leaves
|
|
2082
|
+
* the player: what the plugin copies to the clipboard or writes to a file
|
|
2083
|
+
* ("Copy info", "Save as…"). Translated with this plugin's catalog (a
|
|
2084
|
+
* string as a whole, a Text or TextList with its
|
|
2085
|
+
* arguments), the way the player would show it.
|
|
2086
|
+
*
|
|
2087
|
+
* Only for text leaving the player. Never use it for the interface (a
|
|
2088
|
+
* window, the menu, the OSD, a dialog): pass the value itself there, so
|
|
2089
|
+
* the player translates it and `vestra-plugin i18n check` can see the
|
|
2090
|
+
* sentence is whole.
|
|
2091
|
+
* @param value - Source text, or a text value.
|
|
2092
|
+
* @returns The translated string.
|
|
2093
|
+
* @throws invalid A malformed value.
|
|
2094
|
+
* @capability None.
|
|
2095
|
+
*/
|
|
2096
|
+
resolve(value: TextValue): string;
|
|
2097
|
+
}
|
|
2098
|
+
```
|
|
2099
|
+
|
|
2100
|
+
### TextError
|
|
2101
|
+
|
|
2102
|
+
An `Error` the player shows translated (I18n.error).
|
|
2103
|
+
|
|
2104
|
+
```ts
|
|
2105
|
+
interface TextError extends Error {
|
|
2106
|
+
/** What the player shows. */
|
|
2107
|
+
readonly text: Text;
|
|
1971
2108
|
}
|
|
1972
2109
|
```
|
|
1973
2110
|
|
|
@@ -2135,12 +2272,12 @@ This plugin's own marks; disposing it removes them.
|
|
|
2135
2272
|
```ts
|
|
2136
2273
|
interface TimelineLayer extends Disposable {
|
|
2137
2274
|
/**
|
|
2138
|
-
* Replace the layer (last write wins; `[]` clears it). At most 1000 marks, titles ≤ 100 characters, times within the media. Failures go to `onError`; with `ifCurrent`, a write for another source is dropped silently.
|
|
2275
|
+
* Replace the layer (last write wins; `[]` clears it). At most 1000 marks, titles ≤ 100 characters, times within the media. Failures go to `onError`; with `ifCurrent`, a write for another source is dropped silently. A title is data (a chapter's or bookmark's own name), or a Text the player translates (`text("Chapter {}", [n])`, SDK 1.5.11); other plugins read the shown string.
|
|
2139
2276
|
*/
|
|
2140
2277
|
set(marks: {
|
|
2141
2278
|
time: number;
|
|
2142
2279
|
kind: MarkKind;
|
|
2143
|
-
title?: string;
|
|
2280
|
+
title?: string | Text;
|
|
2144
2281
|
}[], options?: {
|
|
2145
2282
|
ifCurrent?: PlayerState;
|
|
2146
2283
|
}): void;
|
|
@@ -2335,19 +2472,19 @@ Chinese character is one character).
|
|
|
2335
2472
|
```ts
|
|
2336
2473
|
interface ConfirmOptions {
|
|
2337
2474
|
/** The question, shown in bold; 1–200 characters. */
|
|
2338
|
-
message:
|
|
2475
|
+
message: TextValue;
|
|
2339
2476
|
/** More text under the message; at most 2000 characters. */
|
|
2340
|
-
detail?:
|
|
2477
|
+
detail?: TextValue;
|
|
2341
2478
|
/** The confirm button's text (the default button: Enter picks it); 1–40 characters. */
|
|
2342
|
-
confirm:
|
|
2479
|
+
confirm: TextValue;
|
|
2343
2480
|
/** The cancel button's text (Escape picks it); 1–40 characters. */
|
|
2344
|
-
cancel?:
|
|
2481
|
+
cancel?: TextValue;
|
|
2345
2482
|
/** Mark the confirm button as destructive: red text on macOS, a warning icon on Windows. */
|
|
2346
2483
|
destructive?: boolean;
|
|
2347
2484
|
/** A checkbox under the text, such as "Don't ask again"; 1–40 characters. */
|
|
2348
|
-
checkbox?:
|
|
2485
|
+
checkbox?: TextValue;
|
|
2349
2486
|
/**
|
|
2350
|
-
* Values for the placeholders of `message` and `detail` (player 0.4.3). Every text of the dialog is English source text that the player shows translated from the plugin's catalog; `message` and `detail` are templates like Osd.show's. The length limits apply to the shown text.
|
|
2487
|
+
* Values for the placeholders of `message` and `detail` (player 0.4.3). Any of the texts may instead be a Text (SDK 1.5.11), which carries its own arguments; `args` only fills the string ones. Every text of the dialog is English source text that the player shows translated from the plugin's catalog; `message` and `detail` are templates like Osd.show's. The length limits apply to the shown text.
|
|
2351
2488
|
*/
|
|
2352
2489
|
args?: TemplateArgs;
|
|
2353
2490
|
}
|
|
@@ -2390,8 +2527,8 @@ interface Dialogs {
|
|
|
2390
2527
|
* @throws capability (rejects) The manifest does not declare `ui.dialog`.
|
|
2391
2528
|
*/
|
|
2392
2529
|
openFile(options?: {
|
|
2393
|
-
/** The dialog's title, at most 256 bytes. */
|
|
2394
|
-
title?:
|
|
2530
|
+
/** The dialog's title (English source text or a Text), at most 256 bytes. */
|
|
2531
|
+
title?: TextValue;
|
|
2395
2532
|
}): Promise<string | null>;
|
|
2396
2533
|
/**
|
|
2397
2534
|
* Ask the user for one or more files to open.
|
|
@@ -2404,8 +2541,8 @@ interface Dialogs {
|
|
|
2404
2541
|
* @throws capability (rejects) The manifest does not declare `ui.dialog`.
|
|
2405
2542
|
*/
|
|
2406
2543
|
openFiles(options?: {
|
|
2407
|
-
/** The dialog's title, at most 256 bytes. */
|
|
2408
|
-
title?:
|
|
2544
|
+
/** The dialog's title (English source text or a Text), at most 256 bytes. */
|
|
2545
|
+
title?: TextValue;
|
|
2409
2546
|
}): Promise<string[]>;
|
|
2410
2547
|
/**
|
|
2411
2548
|
* Ask the user for a folder.
|
|
@@ -2418,8 +2555,8 @@ interface Dialogs {
|
|
|
2418
2555
|
* @throws capability (rejects) The manifest does not declare `ui.dialog`.
|
|
2419
2556
|
*/
|
|
2420
2557
|
openDirectory(options?: {
|
|
2421
|
-
/** The dialog's title, at most 256 bytes. */
|
|
2422
|
-
title?:
|
|
2558
|
+
/** The dialog's title (English source text or a Text), at most 256 bytes. */
|
|
2559
|
+
title?: TextValue;
|
|
2423
2560
|
}): Promise<string | null>;
|
|
2424
2561
|
/**
|
|
2425
2562
|
* Ask the user where to save a file.
|
|
@@ -2432,10 +2569,12 @@ interface Dialogs {
|
|
|
2432
2569
|
* @throws capability (rejects) The manifest does not declare `ui.dialog`.
|
|
2433
2570
|
*/
|
|
2434
2571
|
saveFile(options?: {
|
|
2435
|
-
/** The dialog's title, at most 256 bytes. */
|
|
2436
|
-
title?:
|
|
2437
|
-
/**
|
|
2438
|
-
|
|
2572
|
+
/** The dialog's title (English source text or a Text), at most 256 bytes. */
|
|
2573
|
+
title?: TextValue;
|
|
2574
|
+
/**
|
|
2575
|
+
* The proposed file name: a plain name, at most 256 bytes. A string is data (not translated); a Text (SDK 1.5.11) is shown translated, `text("Playlist.m3u8")` (a `/` or `\\` in a translation becomes `-`).
|
|
2576
|
+
*/
|
|
2577
|
+
fileName?: TextValue;
|
|
2439
2578
|
}): Promise<string | null>;
|
|
2440
2579
|
}
|
|
2441
2580
|
```
|
|
@@ -2973,9 +3112,23 @@ interface OsdPanel extends Disposable {
|
|
|
2973
3112
|
* Show the block with this text, change it, or hide it.
|
|
2974
3113
|
* @capability ui.osd
|
|
2975
3114
|
* @param text - The text, with `\n` between lines: at most 32 lines and 4096 bytes once translated and formatted. `null` hides the block. A template, like Osd.show's.
|
|
2976
|
-
* @param args - Values for its placeholders (player 0.4.3).
|
|
3115
|
+
* @param args - Values for its placeholders (player 0.4.3); `null` or omitted for none.
|
|
3116
|
+
* @param options - `maxColumns`: cut long lines (SDK 1.5.11).
|
|
3117
|
+
*/
|
|
3118
|
+
set(text: TextValue | null, args?: TemplateArgs | null, options?: OsdPanelOptions): void;
|
|
3119
|
+
}
|
|
3120
|
+
```
|
|
3121
|
+
|
|
3122
|
+
### OsdPanelOptions
|
|
3123
|
+
|
|
3124
|
+
Options of OsdPanel.set.
|
|
3125
|
+
|
|
3126
|
+
```ts
|
|
3127
|
+
interface OsdPanelOptions {
|
|
3128
|
+
/**
|
|
3129
|
+
* Cut every line longer than this many columns, after translation and formatting, ending it with `…`: a wide character (Chinese, Japanese, Korean, full-width forms) is two columns, a combining mark none, any other one. An integer from 8 to 1000 (player 0.4.3; older players show whole lines). Measure the video area to choose it.
|
|
2977
3130
|
*/
|
|
2978
|
-
|
|
3131
|
+
maxColumns?: number;
|
|
2979
3132
|
}
|
|
2980
3133
|
```
|
|
2981
3134
|
|
|
@@ -2998,7 +3151,7 @@ interface Osd {
|
|
|
2998
3151
|
* @throws unavailable (rejects) The player runs without a user interface.
|
|
2999
3152
|
* @throws capability (rejects) The manifest does not declare `ui.osd`.
|
|
3000
3153
|
*/
|
|
3001
|
-
show(text:
|
|
3154
|
+
show(text: TextValue, args?: TemplateArgs): Promise<void>;
|
|
3002
3155
|
/**
|
|
3003
3156
|
* Create this plugin's information block.
|
|
3004
3157
|
* @capability ui.osd
|
|
@@ -3268,7 +3421,9 @@ interface Subtitles {
|
|
|
3268
3421
|
/**
|
|
3269
3422
|
* Upload a subtitle file's bytes (UTF-8 SRT, or ASS/SSA with
|
|
3270
3423
|
* `format: "ass"`) for the current source; select it unless
|
|
3271
|
-
* `select: "none"`. `title` (1–200 characters) names the track
|
|
3424
|
+
* `select: "none"`. `title` (1–200 characters) names the track: data, or
|
|
3425
|
+
* a Text the player translates (`text("{} · {}", [text("Simplified
|
|
3426
|
+
* Chinese"), file])`, SDK 1.5.11). Aborting
|
|
3272
3427
|
* `signal` before the commit discards the upload (rejects with AbortError);
|
|
3273
3428
|
* once the commit was sent it completes.
|
|
3274
3429
|
*
|
|
@@ -3278,7 +3433,7 @@ interface Subtitles {
|
|
|
3278
3433
|
*/
|
|
3279
3434
|
load(bytes: Uint8Array, options?: SubtitleConditional & {
|
|
3280
3435
|
format?: "srt" | "ass";
|
|
3281
|
-
title?: string;
|
|
3436
|
+
title?: string | Text;
|
|
3282
3437
|
select?: "primary" | "secondary" | "none";
|
|
3283
3438
|
signal?: AbortSignal;
|
|
3284
3439
|
}): Promise<SubtitleTrack>;
|
|
@@ -3810,8 +3965,12 @@ One command's bindings, from Bindings.list.
|
|
|
3810
3965
|
interface BindingInfo extends BindingRef {
|
|
3811
3966
|
/** Menu title. */
|
|
3812
3967
|
title: string;
|
|
3813
|
-
/** Menu path; `null` for a command outside the menu. */
|
|
3968
|
+
/** Menu path as shown; `null` for a command outside the menu. */
|
|
3814
3969
|
path: string[] | null;
|
|
3970
|
+
/**
|
|
3971
|
+
* The menu path's keys: the English text menus merge by, the same in every interface language (`["Playback", "Seek", "Back 5 s"]`; a built-in menu by its key, `"Video"`, also when declared as `@video`). `null` for a command outside the menu, and from players before 0.4.3. Find a command by where it is in the menu with this, not with `path`. Always set by `list()`; optional so that test fakes written for older SDKs still type-check.
|
|
3972
|
+
*/
|
|
3973
|
+
key?: string[] | null;
|
|
3815
3974
|
/** Global, or only while the plugin's panel has focus. */
|
|
3816
3975
|
scope: "global" | "panel";
|
|
3817
3976
|
/** The command's own bindings. */
|
|
@@ -4287,8 +4446,9 @@ and its semantics are simplified:
|
|
|
4287
4446
|
value ranges (an out-of-range `filter.set` ends in `failed` with
|
|
4288
4447
|
`invalid`), an empty chain removes the plugin's chain, a chain on a
|
|
4289
4448
|
generated stream fails `unsupported` (the player's own conformance
|
|
4290
|
-
cases check all three), and the command limits (COMMAND_LIMITS)
|
|
4291
|
-
|
|
4449
|
+
cases check all three), and the command limits (COMMAND_LIMITS),
|
|
4450
|
+
property value limits (UI_VALUE_LIMITS) and menu ids
|
|
4451
|
+
(MENU_IDS) are enforced.
|
|
4292
4452
|
|
|
4293
4453
|
Typical workflow: start the plugin with startPlugin (it reads the
|
|
4294
4454
|
plugin's `manifest.json`), drive it the way the user or another plugin
|
|
@@ -4329,6 +4489,21 @@ interface FakeWindow {
|
|
|
4329
4489
|
}
|
|
4330
4490
|
```
|
|
4331
4491
|
|
|
4492
|
+
### FileDialogText
|
|
4493
|
+
|
|
4494
|
+
A file dialog as the player shows it (TestHost.fileDialogs).
|
|
4495
|
+
|
|
4496
|
+
```ts
|
|
4497
|
+
interface FileDialogText {
|
|
4498
|
+
/** Which dialog. */
|
|
4499
|
+
kind: "openFile" | "openFiles" | "openDirectory" | "saveFile";
|
|
4500
|
+
/** Its title as shown, if the plugin gave one. */
|
|
4501
|
+
title?: string;
|
|
4502
|
+
/** The proposed file name as shown, if the plugin gave one. */
|
|
4503
|
+
fileName?: string;
|
|
4504
|
+
}
|
|
4505
|
+
```
|
|
4506
|
+
|
|
4332
4507
|
### FakeCommand
|
|
4333
4508
|
|
|
4334
4509
|
A command the plugin registered with `plugin.commands.add`, as the test
|
|
@@ -4347,6 +4522,10 @@ interface FakeCommand {
|
|
|
4347
4522
|
title: string;
|
|
4348
4523
|
/** Each segment of the path as shown; empty without a path. */
|
|
4349
4524
|
path: string[];
|
|
4525
|
+
/**
|
|
4526
|
+
* The disabled or busy reason as shown, `null` without one (a plugin command's; not enumerable, so comparing `display` with `{ title, path }` still works).
|
|
4527
|
+
*/
|
|
4528
|
+
reason?: string | null;
|
|
4350
4529
|
};
|
|
4351
4530
|
/** The command state the player last received (after the update pass). */
|
|
4352
4531
|
state: {
|
|
@@ -4356,8 +4535,8 @@ interface FakeCommand {
|
|
|
4356
4535
|
checked: boolean | null;
|
|
4357
4536
|
/** `true` while the plugin reports the command as busy. */
|
|
4358
4537
|
busy: boolean;
|
|
4359
|
-
/** The reason
|
|
4360
|
-
reason:
|
|
4538
|
+
/** The reason the plugin sent (source text or a text value; see `display.reason`). */
|
|
4539
|
+
reason: TextValue | null;
|
|
4361
4540
|
};
|
|
4362
4541
|
/** The state revision the player holds; increases with every state update the SDK sends. */
|
|
4363
4542
|
revision: number;
|
|
@@ -4518,7 +4697,7 @@ class TestHost implements Transport {
|
|
|
4518
4697
|
* @param args - Values for its placeholders.
|
|
4519
4698
|
* @returns The shown text.
|
|
4520
4699
|
*/
|
|
4521
|
-
translate(text:
|
|
4700
|
+
translate(text: TextValue, args?: TemplateArgs): string;
|
|
4522
4701
|
/** The saved interface language (`plugin.appearance.language`), changed by `appearance.setLanguage` or TestHost.setLanguage. */
|
|
4523
4702
|
language: LanguagePreference;
|
|
4524
4703
|
/**
|
|
@@ -4541,6 +4720,10 @@ class TestHost implements Transport {
|
|
|
4541
4720
|
/** The checkbox, if any. */
|
|
4542
4721
|
checkbox?: string;
|
|
4543
4722
|
}[];
|
|
4723
|
+
/**
|
|
4724
|
+
* Every file dialog (`openFile`, `openFiles`, `openDirectory`, `saveFile`) as the player shows it: the title translated, a text file name translated, newest last. The options the plugin sent are in `host.sent("dialogs.open")`.
|
|
4725
|
+
*/
|
|
4726
|
+
readonly fileDialogs: FileDialogText[];
|
|
4544
4727
|
/** The sequence provider's flags, `null` without a provider. */
|
|
4545
4728
|
sequence: {
|
|
4546
4729
|
/** The provider's `canNext`, as last evaluated. */
|
|
@@ -5257,6 +5440,70 @@ they agree).
|
|
|
5257
5440
|
const LOCALES: readonly ["en", "zh-Hans", "ja", "ko", "de", "fr", "es"];
|
|
5258
5441
|
```
|
|
5259
5442
|
|
|
5443
|
+
### LIST_SEPARATORS
|
|
5444
|
+
|
|
5445
|
+
The separator of each list style per interface language, as the player's
|
|
5446
|
+
table (`i18n::text::SEPARATORS`; its tests check that they agree).
|
|
5447
|
+
|
|
5448
|
+
```ts
|
|
5449
|
+
const LIST_SEPARATORS: Readonly<Record<Locale, Readonly<Record<ListStyle, string>>>>;
|
|
5450
|
+
```
|
|
5451
|
+
|
|
5452
|
+
### TEXT_LIMITS
|
|
5453
|
+
|
|
5454
|
+
The player's limits on one text value (a
|
|
5455
|
+
Text or
|
|
5456
|
+
TextList with everything nested in it), as the player's
|
|
5457
|
+
`i18n::text` (its tests check that they agree).
|
|
5458
|
+
|
|
5459
|
+
```ts
|
|
5460
|
+
const TEXT_LIMITS: {
|
|
5461
|
+
/** Nesting depth of texts and lists; the value itself is depth 0 (8). */
|
|
5462
|
+
readonly depth: 8;
|
|
5463
|
+
/** Texts, lists and arguments in all, the value itself included (1024). */
|
|
5464
|
+
readonly nodes: 1024;
|
|
5465
|
+
/** Arguments of one text (16). */
|
|
5466
|
+
readonly args: 16;
|
|
5467
|
+
/** Items of one list (256). */
|
|
5468
|
+
readonly items: 256;
|
|
5469
|
+
/** UTF-8 bytes of a source text or a string argument (4096). */
|
|
5470
|
+
readonly stringBytes: 4096;
|
|
5471
|
+
};
|
|
5472
|
+
```
|
|
5473
|
+
|
|
5474
|
+
### UI_VALUE_LIMITS
|
|
5475
|
+
|
|
5476
|
+
The player's limits on one property value (a `PropValue` as written
|
|
5477
|
+
by `View.set` or `View.bind`, or an initial property of a
|
|
5478
|
+
window, panel or settings page). The player's tests check that these
|
|
5479
|
+
agree with the player; TestHost enforces them the same way.
|
|
5480
|
+
|
|
5481
|
+
A value over a limit is refused whole with code `limit` (the property
|
|
5482
|
+
keeps what it showed) and reported to `Scope.onError`: a write by
|
|
5483
|
+
`View.set` or `View.bind` as described there. As an initial property it
|
|
5484
|
+
makes `Window.show` reject; a panel or settings page opens without it and
|
|
5485
|
+
the failure goes to the plugin's `onError`.
|
|
5486
|
+
|
|
5487
|
+
They bound the work one write costs the player's interface thread; they
|
|
5488
|
+
are not meant as list sizes to aim for. A list that can grow without
|
|
5489
|
+
bound (a playlist, a history) should send the rows near the view and say
|
|
5490
|
+
how many there are, not the whole list.
|
|
5491
|
+
|
|
5492
|
+
```ts
|
|
5493
|
+
const UI_VALUE_LIMITS: {
|
|
5494
|
+
/** Nesting depth; the value itself is depth 0 (8). */
|
|
5495
|
+
readonly depth: 8;
|
|
5496
|
+
/** Values in all, counting every array, object, string, number, boolean and null, the value itself included; a Markdown document is one (16384). */
|
|
5497
|
+
readonly values: 16384;
|
|
5498
|
+
/** Rows of one array (4096). */
|
|
5499
|
+
readonly arrayRows: 4096;
|
|
5500
|
+
/** UTF-8 bytes of one string or object field name (64 KiB). */
|
|
5501
|
+
readonly stringBytes: number;
|
|
5502
|
+
/** UTF-8 bytes of all strings and field names together, the text of the value's Markdown documents included (1 MiB). */
|
|
5503
|
+
readonly textBytes: number;
|
|
5504
|
+
};
|
|
5505
|
+
```
|
|
5506
|
+
|
|
5260
5507
|
### HostError
|
|
5261
5508
|
|
|
5262
5509
|
A definite refusal from the player (or the plugin runner), with a stable
|
|
@@ -5653,9 +5900,10 @@ interface WireSystemInfo {
|
|
|
5653
5900
|
|
|
5654
5901
|
```ts
|
|
5655
5902
|
type CommandDeclaration = {
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
path
|
|
5903
|
+
/** Source text, or a text value (player 0.4.3). */
|
|
5904
|
+
title: string | TextJson;
|
|
5905
|
+
/** Complete primary menu path INCLUDING its leaf; empty = not in the main menu. Segments may be text values (player 0.4.3). */
|
|
5906
|
+
path: (string | TextJson)[];
|
|
5659
5907
|
/** Sibling order, ascending; a submenu takes its first command's order (a built-in menu keeps a fixed one). */
|
|
5660
5908
|
order: number;
|
|
5661
5909
|
/** Separator label: adjacent siblings of different groups get a line. */
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vestra Player SDK
|
|
2
2
|
|
|
3
|
-
> @vestra-player/sdk 1.5.
|
|
3
|
+
> @vestra-player/sdk 1.5.11: 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; it runs in its own Node.js process. llms-full.txt, next to this file, has every declaration, the guides and the examples; L<n> below are its line numbers.
|
|
4
4
|
|
|
5
5
|
**How plugins run**
|
|
6
6
|
|
|
@@ -137,7 +137,7 @@ test("shows the position", async () => {
|
|
|
137
137
|
- `failed`: The operation ran and failed
|
|
138
138
|
- `aborted`: An `AbortSignal` fired
|
|
139
139
|
- `timeout`: A time limit ran out
|
|
140
|
-
- `limit`: A player-wide limit was reached
|
|
140
|
+
- `limit`: A player-wide limit was reached, a property value is over the limits of PropValue, or a request is longer than the player's 1 MiB message
|
|
141
141
|
- `reserved`: Packages.validate, PackageCandidate.install: the id is `vestra` or starts with `vestra.`, which only the player's built-in plugins use
|
|
142
142
|
- `versionMismatch`: The package needs a newer player or another `apiVersion`
|
|
143
143
|
- `ui-prepare`: The player could not prepare a mounted panel or a settings page
|
|
@@ -152,56 +152,56 @@ test("shows the position", async () => {
|
|
|
152
152
|
- [Concept: Windows, panels, settings pages, dialogs and the OSD](https://vestrasys.github.io/vestra-player-sdk/documents/Windows__panels__settings_pages__dialogs_and_the_OSD.html): L281–626
|
|
153
153
|
- [How-to: Keep a slider responsive while dragging](https://vestrasys.github.io/vestra-player-sdk/documents/Keep_a_slider_responsive_while_dragging.html): L627–801
|
|
154
154
|
- [How-to: Remember a window's state between runs](https://vestrasys.github.io/vestra-player-sdk/documents/Remember_a_window_s_state_between_runs.html): L802–931
|
|
155
|
-
- [API: @vestra-player/sdk](https://vestrasys.github.io/vestra-player-sdk/modules/_vestra-player_sdk.html): L932–
|
|
156
|
-
- [API: @vestra-player/sdk/testing](https://vestrasys.github.io/vestra-player-sdk/modules/_vestra-player_sdk_testing.html) (TestHost, startPlugin):
|
|
155
|
+
- [API: @vestra-player/sdk](https://vestrasys.github.io/vestra-player-sdk/modules/_vestra-player_sdk.html): L932–4427
|
|
156
|
+
- [API: @vestra-player/sdk/testing](https://vestrasys.github.io/vestra-player-sdk/modules/_vestra-player_sdk_testing.html) (TestHost, startPlugin): L4428–5537
|
|
157
157
|
|
|
158
158
|
## API
|
|
159
159
|
|
|
160
160
|
Where each module of `plugin` is declared:
|
|
161
161
|
|
|
162
162
|
- Plugin L1153, Scope L1022, PluginError L974, Disposable L947
|
|
163
|
-
- plugin.commands: Commands
|
|
164
|
-
- plugin.windows: Windows
|
|
165
|
-
- plugin.panels: Panels
|
|
166
|
-
- plugin.dialogs: Dialogs
|
|
167
|
-
- plugin.player: Player
|
|
168
|
-
- plugin.video: VideoFilter
|
|
169
|
-
- plugin.audio: AudioFilter
|
|
170
|
-
- plugin.subtitles: Subtitles
|
|
171
|
-
- plugin.media: MediaCapture
|
|
172
|
-
- plugin.resolvers: Resolvers
|
|
173
|
-
- plugin.packages: Packages
|
|
174
|
-
- plugin.osd: Osd
|
|
175
|
-
- plugin.host: Host
|
|
176
|
-
- plugin.clipboard: Clipboard
|
|
177
|
-
- plugin.power: Power
|
|
178
|
-
- plugin.tools: Tools
|
|
179
|
-
- plugin.storage: Storage
|
|
180
|
-
- plugin.system: System
|
|
181
|
-
- plugin.secrets: Secrets
|
|
182
|
-
- plugin.window: MainWindow
|
|
183
|
-
- plugin.app: App
|
|
184
|
-
- plugin.bindings: Bindings
|
|
185
|
-
- plugin.ui: Ui
|
|
186
|
-
- plugin.timeline: Timeline
|
|
187
|
-
- plugin.drops: Drops
|
|
188
|
-
- plugin.appearance: Appearance
|
|
189
|
-
- plugin.i18n: I18n
|
|
190
|
-
- plugin.settings: Settings
|
|
163
|
+
- plugin.commands: Commands L1361
|
|
164
|
+
- plugin.windows: Windows L1566
|
|
165
|
+
- plugin.panels: Panels L2207
|
|
166
|
+
- plugin.dialogs: Dialogs L2493
|
|
167
|
+
- plugin.player: Player L2934
|
|
168
|
+
- plugin.video: VideoFilter L3199, VideoView L3262, RenderOptions L3304
|
|
169
|
+
- plugin.audio: AudioFilter L3223
|
|
170
|
+
- plugin.subtitles: Subtitles L3402
|
|
171
|
+
- plugin.media: MediaCapture L3562
|
|
172
|
+
- plugin.resolvers: Resolvers L3667
|
|
173
|
+
- plugin.packages: Packages L3907
|
|
174
|
+
- plugin.osd: Osd L3135
|
|
175
|
+
- plugin.host: Host L3083
|
|
176
|
+
- plugin.clipboard: Clipboard L4024
|
|
177
|
+
- plugin.power: Power L4044
|
|
178
|
+
- plugin.tools: Tools L4077
|
|
179
|
+
- plugin.storage: Storage L4120
|
|
180
|
+
- plugin.system: System L4143
|
|
181
|
+
- plugin.secrets: Secrets L4161
|
|
182
|
+
- plugin.window: MainWindow L2330
|
|
183
|
+
- plugin.app: App L2411
|
|
184
|
+
- plugin.bindings: Bindings L3994
|
|
185
|
+
- plugin.ui: Ui L1453
|
|
186
|
+
- plugin.timeline: Timeline L2287
|
|
187
|
+
- plugin.drops: Drops L1863
|
|
188
|
+
- plugin.appearance: Appearance L1892
|
|
189
|
+
- plugin.i18n: I18n L2034
|
|
190
|
+
- plugin.settings: Settings L2140
|
|
191
191
|
|
|
192
192
|
## Examples
|
|
193
193
|
|
|
194
194
|
Complete plugins with tests, in [examples/](https://github.com/vestrasys/vestra-player-sdk/tree/main/examples) and in llms-full.txt:
|
|
195
195
|
|
|
196
|
-
- hello: The README Quick start: one menu command and an on-screen message.
|
|
197
|
-
- blur: A tool window with one slider that blurs the playing video.
|
|
198
|
-
- signal-generator: Generates its own video and audio: colour bars and a 1 kHz tone.
|
|
199
|
-
- bookmark: A tool window bound to the playback state: remember the position and jump back to it.
|
|
200
|
-
- panel-menu: A sidebar panel with its own right-click menu.
|
|
201
|
-
- menus: Radio menu items, separator groups and a menu item whose title changes.
|
|
202
|
-
- theme-widgets: A tool window drawn with the player's theme and widgets.
|
|
203
|
-
- markdown: A window that shows a Markdown document.
|
|
204
|
-
- i18n: A plugin in the player's language: English source text, a Chinese translation.
|
|
196
|
+
- hello: The README Quick start: one menu command and an on-screen message. L5954–6043
|
|
197
|
+
- blur: A tool window with one slider that blurs the playing video. L6044–6305
|
|
198
|
+
- signal-generator: Generates its own video and audio: colour bars and a 1 kHz tone. L6306–6638
|
|
199
|
+
- bookmark: A tool window bound to the playback state: remember the position and jump back to it. L6639–6823
|
|
200
|
+
- panel-menu: A sidebar panel with its own right-click menu. L6824–7029
|
|
201
|
+
- menus: Radio menu items, separator groups and a menu item whose title changes. L7030–7189
|
|
202
|
+
- theme-widgets: A tool window drawn with the player's theme and widgets. L7190–7353
|
|
203
|
+
- markdown: A window that shows a Markdown document. L7354–7547
|
|
204
|
+
- i18n: A plugin in the player's language: English source text, a Chinese translation. L7548–7715
|
|
205
205
|
|
|
206
206
|
## Optional
|
|
207
207
|
|