@solidrt/flux-types 0.0.59 → 0.0.60
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/gui/audio.d.ts +4 -3
- package/gui/video.d.ts +128 -23
- package/package.json +1 -1
package/gui/audio.d.ts
CHANGED
|
@@ -144,9 +144,10 @@ declare module "flux:audio" {
|
|
|
144
144
|
/**
|
|
145
145
|
* Open a clip for streaming: it is decoded on demand instead of loaded fully
|
|
146
146
|
* into memory, so a large track needs little RAM. Takes a `file()` from
|
|
147
|
-
* `flux:fs` (not a path),
|
|
148
|
-
*
|
|
149
|
-
* playback; do not overlap a stream with itself. Call
|
|
147
|
+
* `flux:fs` (not a path), read from local storage like any `file()` (the
|
|
148
|
+
* app's assets in a packed app); there is no network streaming. Play the
|
|
149
|
+
* result as a single playback; do not overlap a stream with itself. Call
|
|
150
|
+
* `unload()` when done.
|
|
150
151
|
*/
|
|
151
152
|
export function stream(source: ReturnType<typeof import("flux:fs").file>): Clip
|
|
152
153
|
/**
|
package/gui/video.d.ts
CHANGED
|
@@ -1,49 +1,154 @@
|
|
|
1
1
|
// Video playback (gui-enabled runtime only). The imperative primitive;
|
|
2
2
|
// @solidrt/core wraps it with SolidJS reactivity. There is no video element:
|
|
3
|
-
//
|
|
4
|
-
// richer Video component composes in a higher layer.
|
|
3
|
+
// a texture player's `texture` id is displayed with <texture>/<d-texture>,
|
|
4
|
+
// and a richer Video component composes in a higher layer. A plane player
|
|
5
|
+
// (Android) has no texture at all: the platform composites the decoded
|
|
6
|
+
// picture fullscreen beneath the UI, off the frame loop entirely, and it
|
|
7
|
+
// streams: its source may be a URL, read as it plays.
|
|
5
8
|
|
|
6
9
|
declare module "flux:video" {
|
|
10
|
+
import type { FluxFile } from "flux:fs"
|
|
7
11
|
import type { TextureId } from "flux:gpu"
|
|
8
12
|
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
/**
|
|
14
|
+
* What went wrong with a stream, for the app to key on:
|
|
15
|
+
* - "network": the source could not be opened or stopped delivering (an
|
|
16
|
+
* unreachable or failing server, an unreadable file, a truncated body);
|
|
17
|
+
* - "decode": the bytes are not a stream the decoders can follow;
|
|
18
|
+
* - "unsupported": a stream, codec or feature this player does not play;
|
|
19
|
+
* - "no-plane": no video plane (not on this platform, or one is open).
|
|
20
|
+
* An app falling back from a plane to a texture keys on "no-plane" only:
|
|
21
|
+
* a network error would fail the texture the same way.
|
|
22
|
+
*/
|
|
23
|
+
export type VideoErrorKind = "network" | "decode" | "unsupported" | "no-plane"
|
|
24
|
+
|
|
25
|
+
/** The Error `open` rejects with and `error()` returns. */
|
|
26
|
+
export interface VideoError extends Error {
|
|
27
|
+
kind: VideoErrorKind
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Controls and facts shared by both kinds of player. */
|
|
31
|
+
export type VideoTransport = {
|
|
32
|
+
/** Frame width in pixels, at open. */
|
|
17
33
|
width: number
|
|
18
|
-
/** Frame height in pixels. */
|
|
34
|
+
/** Frame height in pixels, at open. */
|
|
19
35
|
height: number
|
|
20
|
-
/**
|
|
21
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Duration in seconds; undefined when the source has no known end (a
|
|
38
|
+
* live stream, a container written to a pipe).
|
|
39
|
+
*/
|
|
40
|
+
duration: number | undefined
|
|
22
41
|
/** Whether the file has a playable audio track. */
|
|
23
42
|
hasAudio: boolean
|
|
43
|
+
/**
|
|
44
|
+
* Whether `seek` does anything. False for a texture player, and for a
|
|
45
|
+
* source that cannot be read at an offset (an HTTP response without
|
|
46
|
+
* Range support); `seek` is then a no-op.
|
|
47
|
+
*/
|
|
48
|
+
seekable: boolean
|
|
24
49
|
/** Start or resume playback. */
|
|
25
50
|
play(): void
|
|
26
51
|
/** Pause playback (the current frame stays displayed). */
|
|
27
52
|
pause(): void
|
|
53
|
+
/**
|
|
54
|
+
* Seek to a time in seconds. Lands on the frame at that time (decoding
|
|
55
|
+
* from the preceding keyframe); while paused the target frame is shown.
|
|
56
|
+
* A no-op when `seekable` is false.
|
|
57
|
+
*/
|
|
58
|
+
seek(seconds: number): void
|
|
28
59
|
/** Whether playback is running. */
|
|
29
60
|
playing(): boolean
|
|
30
61
|
/** Presentation time of the displayed frame, in seconds. */
|
|
31
62
|
currentTime(): number
|
|
32
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* Whether the last frame has been displayed. A failure does not set
|
|
65
|
+
* it: see `error`.
|
|
66
|
+
*/
|
|
33
67
|
finished(): boolean
|
|
34
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Whether playback is held for the source to catch up: playing, with
|
|
70
|
+
* the picture and the sound paused until enough is read ahead. Never
|
|
71
|
+
* true for a texture player.
|
|
72
|
+
*/
|
|
73
|
+
buffering(): boolean
|
|
74
|
+
/**
|
|
75
|
+
* The failure that stopped playback, if one did: the reader could not
|
|
76
|
+
* read on, or the decoder gave up. Playback stops where it was
|
|
77
|
+
* (`playing()` goes false, the last frame stays up); a `seek` retries
|
|
78
|
+
* the source. The same object `failed` resolves with.
|
|
79
|
+
*/
|
|
80
|
+
error(): VideoError | undefined
|
|
81
|
+
/**
|
|
82
|
+
* Resolves with the failure that stops playback, once, or with
|
|
83
|
+
* undefined when the player closes without one. What a reactive layer
|
|
84
|
+
* watches instead of polling `error()`.
|
|
85
|
+
*/
|
|
86
|
+
failed: Promise<VideoError | undefined>
|
|
87
|
+
/** Stop playback and release everything the player holds. */
|
|
35
88
|
close(): void
|
|
36
89
|
}
|
|
37
90
|
|
|
91
|
+
/** A texture player: frames land in a GPU texture on the UI's clock. */
|
|
92
|
+
export type VideoPlayer = VideoTransport & {
|
|
93
|
+
/**
|
|
94
|
+
* GPU texture id decoded frames are uploaded into (use as a texture
|
|
95
|
+
* source). Holds the current frame; black until playback starts.
|
|
96
|
+
*/
|
|
97
|
+
texture: TextureId
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* A plane player: the decoder renders into the platform's own video
|
|
102
|
+
* surface, fullscreen beneath the UI, on the video's clock. Exists from
|
|
103
|
+
* open until close; one at a time. The UI draws over it wherever it
|
|
104
|
+
* paints, and the window's uncovered pixels show the video. Its audio
|
|
105
|
+
* track plays on the default output, in sync with the picture.
|
|
106
|
+
*/
|
|
107
|
+
export type VideoPlane = VideoTransport
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* A video source: a path resolved like file() paths (through the app's
|
|
111
|
+
* assets in a packed app), an http: or https: URL, or a file() from
|
|
112
|
+
* flux:fs (a packed asset is read out of the exe). Any other scheme
|
|
113
|
+
* throws. A URL plays on a plane only, and is read by the runtime
|
|
114
|
+
* directly: no disk cache, no dev-server proxying, so the device must
|
|
115
|
+
* reach the host itself.
|
|
116
|
+
*/
|
|
117
|
+
export type VideoSource = string | FluxFile
|
|
118
|
+
|
|
119
|
+
export type VideoOpenOptions = {
|
|
120
|
+
/** Where the picture goes: a texture (default) or the platform's video plane. */
|
|
121
|
+
present?: "texture"
|
|
122
|
+
/**
|
|
123
|
+
* Aborting it abandons the open: the promise rejects with the signal's
|
|
124
|
+
* reason and the source is closed. (A texture player opens at once;
|
|
125
|
+
* the signal matters for a plane's streamed open.)
|
|
126
|
+
*/
|
|
127
|
+
signal?: AbortSignal
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type VideoPlaneOptions = {
|
|
131
|
+
present: "plane"
|
|
132
|
+
/** How the picture fits the window: letterboxed (default) or cropped to fill. */
|
|
133
|
+
fit?: "contain" | "cover"
|
|
134
|
+
/** Aborting it abandons the open (see VideoOpenOptions). */
|
|
135
|
+
signal?: AbortSignal
|
|
136
|
+
}
|
|
137
|
+
|
|
38
138
|
/**
|
|
39
|
-
* Open a video
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* its codec
|
|
139
|
+
* Open a video (WebM with 8-bit 4:2:0 VP9 video, i.e. profile 0; Opus
|
|
140
|
+
* audio plays, other audio tracks are ignored). Playback starts paused;
|
|
141
|
+
* call `play()`. Rejects with a VideoError: "network" when the source
|
|
142
|
+
* cannot be opened (or does not answer within the open timeout),
|
|
143
|
+
* "unsupported" when its codec is not played or a URL is given to a
|
|
144
|
+
* texture player, "no-plane" for `present: "plane"` on a platform without
|
|
145
|
+
* a video plane (Android only) or while another plane is open or opening.
|
|
146
|
+
* A plane open reads the header off the JS thread and resolves once the
|
|
147
|
+
* plane exists; a texture player opens at once.
|
|
44
148
|
*
|
|
45
|
-
* Encode with `ffmpeg -c:v libvpx-vp9 -c:a
|
|
46
|
-
* royalty-free, so
|
|
149
|
+
* Encode with `ffmpeg -c:v libvpx-vp9 -c:a libopus out.webm`; VP9 and
|
|
150
|
+
* Opus are royalty-free, so both decoders ship on every platform.
|
|
47
151
|
*/
|
|
48
|
-
export function open(
|
|
152
|
+
export function open(source: VideoSource, options?: VideoOpenOptions): Promise<VideoPlayer>
|
|
153
|
+
export function open(source: VideoSource, options: VideoPlaneOptions): Promise<VideoPlane>
|
|
49
154
|
}
|