@mentra/miniapp 0.3.0-dev.0
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/README.md +259 -0
- package/dist/background/index.d.ts +59 -0
- package/dist/background/index.d.ts.map +1 -0
- package/dist/background/index.js +25 -0
- package/dist/background/index.js.map +1 -0
- package/dist/background/register.d.ts +38 -0
- package/dist/background/register.d.ts.map +1 -0
- package/dist/background/register.js +75 -0
- package/dist/background/register.js.map +1 -0
- package/dist/dev-reload.d.ts +21 -0
- package/dist/dev-reload.d.ts.map +1 -0
- package/dist/dev-reload.js +62 -0
- package/dist/dev-reload.js.map +1 -0
- package/dist/envelope.d.ts +23 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +47 -0
- package/dist/envelope.js.map +1 -0
- package/dist/globals.d.ts +54 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +12 -0
- package/dist/globals.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/actions.d.ts +54 -0
- package/dist/modules/actions.d.ts.map +1 -0
- package/dist/modules/actions.js +122 -0
- package/dist/modules/actions.js.map +1 -0
- package/dist/modules/auth.d.ts +25 -0
- package/dist/modules/auth.d.ts.map +1 -0
- package/dist/modules/auth.js +52 -0
- package/dist/modules/auth.js.map +1 -0
- package/dist/modules/base64.d.ts +16 -0
- package/dist/modules/base64.d.ts.map +1 -0
- package/dist/modules/base64.js +92 -0
- package/dist/modules/base64.js.map +1 -0
- package/dist/modules/blob.d.ts +161 -0
- package/dist/modules/blob.d.ts.map +1 -0
- package/dist/modules/blob.js +277 -0
- package/dist/modules/blob.js.map +1 -0
- package/dist/modules/camera.d.ts +137 -0
- package/dist/modules/camera.d.ts.map +1 -0
- package/dist/modules/camera.js +104 -0
- package/dist/modules/camera.js.map +1 -0
- package/dist/modules/cloud.d.ts +34 -0
- package/dist/modules/cloud.d.ts.map +1 -0
- package/dist/modules/cloud.js +70 -0
- package/dist/modules/cloud.js.map +1 -0
- package/dist/modules/dashboard.d.ts +16 -0
- package/dist/modules/dashboard.d.ts.map +1 -0
- package/dist/modules/dashboard.js +27 -0
- package/dist/modules/dashboard.js.map +1 -0
- package/dist/modules/display.d.ts +106 -0
- package/dist/modules/display.d.ts.map +1 -0
- package/dist/modules/display.js +57 -0
- package/dist/modules/display.js.map +1 -0
- package/dist/modules/events.d.ts +167 -0
- package/dist/modules/events.d.ts.map +1 -0
- package/dist/modules/events.js +123 -0
- package/dist/modules/events.js.map +1 -0
- package/dist/modules/glasses.d.ts +28 -0
- package/dist/modules/glasses.d.ts.map +1 -0
- package/dist/modules/glasses.js +39 -0
- package/dist/modules/glasses.js.map +1 -0
- package/dist/modules/heading.d.ts +16 -0
- package/dist/modules/heading.d.ts.map +1 -0
- package/dist/modules/heading.js +20 -0
- package/dist/modules/heading.js.map +1 -0
- package/dist/modules/imu.d.ts +31 -0
- package/dist/modules/imu.d.ts.map +1 -0
- package/dist/modules/imu.js +40 -0
- package/dist/modules/imu.js.map +1 -0
- package/dist/modules/input.d.ts +34 -0
- package/dist/modules/input.d.ts.map +1 -0
- package/dist/modules/input.js +50 -0
- package/dist/modules/input.js.map +1 -0
- package/dist/modules/led.d.ts +35 -0
- package/dist/modules/led.d.ts.map +1 -0
- package/dist/modules/led.js +39 -0
- package/dist/modules/led.js.map +1 -0
- package/dist/modules/location.d.ts +27 -0
- package/dist/modules/location.d.ts.map +1 -0
- package/dist/modules/location.js +35 -0
- package/dist/modules/location.js.map +1 -0
- package/dist/modules/mic.d.ts +44 -0
- package/dist/modules/mic.d.ts.map +1 -0
- package/dist/modules/mic.js +67 -0
- package/dist/modules/mic.js.map +1 -0
- package/dist/modules/miniapps.d.ts +72 -0
- package/dist/modules/miniapps.d.ts.map +1 -0
- package/dist/modules/miniapps.js +48 -0
- package/dist/modules/miniapps.js.map +1 -0
- package/dist/modules/navigation.d.ts +326 -0
- package/dist/modules/navigation.d.ts.map +1 -0
- package/dist/modules/navigation.js +386 -0
- package/dist/modules/navigation.js.map +1 -0
- package/dist/modules/permissions.d.ts +58 -0
- package/dist/modules/permissions.d.ts.map +1 -0
- package/dist/modules/permissions.js +66 -0
- package/dist/modules/permissions.js.map +1 -0
- package/dist/modules/phone.d.ts +61 -0
- package/dist/modules/phone.d.ts.map +1 -0
- package/dist/modules/phone.js +94 -0
- package/dist/modules/phone.js.map +1 -0
- package/dist/modules/pivots/engine.d.ts +169 -0
- package/dist/modules/pivots/engine.d.ts.map +1 -0
- package/dist/modules/pivots/engine.js +779 -0
- package/dist/modules/pivots/engine.js.map +1 -0
- package/dist/modules/pivots/geometry.d.ts +84 -0
- package/dist/modules/pivots/geometry.d.ts.map +1 -0
- package/dist/modules/pivots/geometry.js +371 -0
- package/dist/modules/pivots/geometry.js.map +1 -0
- package/dist/modules/pivots/instructions.d.ts +139 -0
- package/dist/modules/pivots/instructions.d.ts.map +1 -0
- package/dist/modules/pivots/instructions.js +280 -0
- package/dist/modules/pivots/instructions.js.map +1 -0
- package/dist/modules/speaker.d.ts +163 -0
- package/dist/modules/speaker.d.ts.map +1 -0
- package/dist/modules/speaker.js +250 -0
- package/dist/modules/speaker.js.map +1 -0
- package/dist/modules/storage.d.ts +50 -0
- package/dist/modules/storage.d.ts.map +1 -0
- package/dist/modules/storage.js +99 -0
- package/dist/modules/storage.js.map +1 -0
- package/dist/modules/stream.d.ts +129 -0
- package/dist/modules/stream.d.ts.map +1 -0
- package/dist/modules/stream.js +52 -0
- package/dist/modules/stream.js.map +1 -0
- package/dist/modules/system.d.ts +45 -0
- package/dist/modules/system.d.ts.map +1 -0
- package/dist/modules/system.js +42 -0
- package/dist/modules/system.js.map +1 -0
- package/dist/modules/transcription.d.ts +67 -0
- package/dist/modules/transcription.d.ts.map +1 -0
- package/dist/modules/transcription.js +106 -0
- package/dist/modules/transcription.js.map +1 -0
- package/dist/modules/translation.d.ts +59 -0
- package/dist/modules/translation.d.ts.map +1 -0
- package/dist/modules/translation.js +119 -0
- package/dist/modules/translation.js.map +1 -0
- package/dist/modules/ui.d.ts +186 -0
- package/dist/modules/ui.d.ts.map +1 -0
- package/dist/modules/ui.js +293 -0
- package/dist/modules/ui.js.map +1 -0
- package/dist/protocol.d.ts +294 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +320 -0
- package/dist/protocol.js.map +1 -0
- package/dist/react/MentraProvider.d.ts +33 -0
- package/dist/react/MentraProvider.d.ts.map +1 -0
- package/dist/react/MentraProvider.js +15 -0
- package/dist/react/MentraProvider.js.map +1 -0
- package/dist/react/MiniappHeader.d.ts +44 -0
- package/dist/react/MiniappHeader.d.ts.map +1 -0
- package/dist/react/MiniappHeader.js +32 -0
- package/dist/react/MiniappHeader.js.map +1 -0
- package/dist/react/index.d.ts +13 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +9 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/useCapabilities.d.ts +26 -0
- package/dist/react/useCapabilities.d.ts.map +1 -0
- package/dist/react/useCapabilities.js +27 -0
- package/dist/react/useCapabilities.js.map +1 -0
- package/dist/react/useCapsuleHeaderStyle.d.ts +27 -0
- package/dist/react/useCapsuleHeaderStyle.d.ts.map +1 -0
- package/dist/react/useCapsuleHeaderStyle.js +36 -0
- package/dist/react/useCapsuleHeaderStyle.js.map +1 -0
- package/dist/react/useColorScheme.d.ts +18 -0
- package/dist/react/useColorScheme.d.ts.map +1 -0
- package/dist/react/useColorScheme.js +24 -0
- package/dist/react/useColorScheme.js.map +1 -0
- package/dist/react/useConnected.d.ts +17 -0
- package/dist/react/useConnected.d.ts.map +1 -0
- package/dist/react/useConnected.js +39 -0
- package/dist/react/useConnected.js.map +1 -0
- package/dist/react/useRpc.d.ts +29 -0
- package/dist/react/useRpc.d.ts.map +1 -0
- package/dist/react/useRpc.js +82 -0
- package/dist/react/useRpc.js.map +1 -0
- package/dist/react/useSafeArea.d.ts +21 -0
- package/dist/react/useSafeArea.d.ts.map +1 -0
- package/dist/react/useSafeArea.js +22 -0
- package/dist/react/useSafeArea.js.map +1 -0
- package/dist/session.d.ts +310 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +653 -0
- package/dist/session.js.map +1 -0
- package/dist/sub-path-types.test-d.d.ts +28 -0
- package/dist/sub-path-types.test-d.d.ts.map +1 -0
- package/dist/sub-path-types.test-d.js +37 -0
- package/dist/sub-path-types.test-d.js.map +1 -0
- package/dist/transport/auto.d.ts +35 -0
- package/dist/transport/auto.d.ts.map +1 -0
- package/dist/transport/auto.js +125 -0
- package/dist/transport/auto.js.map +1 -0
- package/dist/transport/dispatch.d.ts +43 -0
- package/dist/transport/dispatch.d.ts.map +1 -0
- package/dist/transport/dispatch.js +91 -0
- package/dist/transport/dispatch.js.map +1 -0
- package/dist/transport/local-socket.d.ts +28 -0
- package/dist/transport/local-socket.d.ts.map +1 -0
- package/dist/transport/local-socket.js +80 -0
- package/dist/transport/local-socket.js.map +1 -0
- package/dist/transport/mock.d.ts +54 -0
- package/dist/transport/mock.d.ts.map +1 -0
- package/dist/transport/mock.js +205 -0
- package/dist/transport/mock.js.map +1 -0
- package/dist/transport/postmessage.d.ts +36 -0
- package/dist/transport/postmessage.d.ts.map +1 -0
- package/dist/transport/postmessage.js +78 -0
- package/dist/transport/postmessage.js.map +1 -0
- package/dist/transport/types.d.ts +25 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +11 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/ui/index.d.ts +98 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +32 -0
- package/dist/ui/index.js.map +1 -0
- package/package.json +75 -0
- package/src/background/index.ts +152 -0
- package/src/background/register.ts +85 -0
- package/src/dev-reload.ts +60 -0
- package/src/envelope.ts +54 -0
- package/src/globals.ts +62 -0
- package/src/index.ts +171 -0
- package/src/modules/actions.ts +156 -0
- package/src/modules/auth.ts +68 -0
- package/src/modules/base64.ts +87 -0
- package/src/modules/blob.ts +341 -0
- package/src/modules/camera.ts +196 -0
- package/src/modules/cloud.ts +94 -0
- package/src/modules/dashboard.ts +31 -0
- package/src/modules/display.ts +122 -0
- package/src/modules/events.ts +264 -0
- package/src/modules/glasses.ts +44 -0
- package/src/modules/heading.ts +23 -0
- package/src/modules/imu.ts +44 -0
- package/src/modules/input.ts +71 -0
- package/src/modules/led.ts +61 -0
- package/src/modules/location.ts +39 -0
- package/src/modules/mic.ts +74 -0
- package/src/modules/miniapps.ts +90 -0
- package/src/modules/navigation.ts +670 -0
- package/src/modules/permissions.ts +84 -0
- package/src/modules/phone.ts +120 -0
- package/src/modules/pivots/engine.ts +863 -0
- package/src/modules/pivots/geometry.ts +409 -0
- package/src/modules/pivots/instructions.ts +343 -0
- package/src/modules/speaker.ts +328 -0
- package/src/modules/storage.ts +109 -0
- package/src/modules/stream.ts +163 -0
- package/src/modules/system.ts +76 -0
- package/src/modules/transcription.ts +128 -0
- package/src/modules/translation.ts +149 -0
- package/src/modules/ui.ts +498 -0
- package/src/protocol.ts +371 -0
- package/src/react/MentraProvider.tsx +50 -0
- package/src/react/MiniappHeader.tsx +122 -0
- package/src/react/index.ts +12 -0
- package/src/react/useCapabilities.ts +29 -0
- package/src/react/useCapsuleHeaderStyle.ts +54 -0
- package/src/react/useColorScheme.ts +26 -0
- package/src/react/useConnected.ts +47 -0
- package/src/react/useRpc.ts +106 -0
- package/src/react/useSafeArea.ts +40 -0
- package/src/session.ts +878 -0
- package/src/sub-path-types.test-d.ts +49 -0
- package/src/transport/auto.ts +143 -0
- package/src/transport/dispatch.ts +106 -0
- package/src/transport/local-socket.ts +93 -0
- package/src/transport/mock.ts +248 -0
- package/src/transport/postmessage.ts +95 -0
- package/src/transport/types.ts +26 -0
- package/src/ui/index.ts +122 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SpeakerModule — phone-side audio output.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors cloud SDK v3's SpeakerManager naming. Audio *input* (transcription,
|
|
5
|
+
* audio chunks, VAD) lives on session.mic — the split is by I/O direction.
|
|
6
|
+
*
|
|
7
|
+
* Imperative surface:
|
|
8
|
+
* speaker.play({audioUrl}) — play an arbitrary URL via the phone's
|
|
9
|
+
* AudioPlaybackService.
|
|
10
|
+
* speaker.speak(text) — send a SPEAK request. Phone streams cloud
|
|
11
|
+
* TTS when connected and falls back to local
|
|
12
|
+
* offline TTS when cloud is unavailable.
|
|
13
|
+
* Resolves when playback completes; rejects
|
|
14
|
+
* with a TTS_* error code on cloud failure.
|
|
15
|
+
* speaker.createStream(opts) — open a live PCM output stream (16-bit LE).
|
|
16
|
+
* Returns a SpeakerStreamWriter: write() PCM
|
|
17
|
+
* chunks as they arrive (e.g. from a WebSocket
|
|
18
|
+
* in the background), close() to drain, abort()
|
|
19
|
+
* to drop. write() resolves with {bufferedMs}
|
|
20
|
+
* so producers can throttle.
|
|
21
|
+
* speaker.stop() — stop any audio this miniapp is playing.
|
|
22
|
+
*
|
|
23
|
+
* State observability:
|
|
24
|
+
* speaker.state — current SpeakerState (sync getter).
|
|
25
|
+
* speaker.isPlaying — true iff state === "playing".
|
|
26
|
+
* speaker.onStateChange(h) — fires on every state transition.
|
|
27
|
+
*
|
|
28
|
+
* State machine (per miniapp):
|
|
29
|
+
* idle ─── speak()/play() ──► loading ──► playing ──► stopped
|
|
30
|
+
* │ │ │
|
|
31
|
+
* └── error ───┴── stop ───┘
|
|
32
|
+
*
|
|
33
|
+
* `error` is transient — fires once with errorCode set, then settles to
|
|
34
|
+
* `stopped` so isPlaying reads false correctly.
|
|
35
|
+
*/
|
|
36
|
+
import { MiniappErrorCode, MiniappRequestType } from "../protocol";
|
|
37
|
+
import { bytesToBase64, toUint8Array } from "./base64";
|
|
38
|
+
/** Raw bytes per bridge write. PCM chunks are small; keep messages snappy. */
|
|
39
|
+
export const SPEAKER_WRITE_CHUNK_BYTES = 256 * 1024;
|
|
40
|
+
// Every non-final base64 slice must decode to complete 16-bit samples. Six
|
|
41
|
+
// raw bytes map to eight base64 chars, preserving both base64 and PCM framing.
|
|
42
|
+
const SPEAKER_WRITE_CHUNK_B64 = Math.floor(SPEAKER_WRITE_CHUNK_BYTES / 6) * 8;
|
|
43
|
+
/**
|
|
44
|
+
* Soft backpressure ceiling. When the host reports more than this buffered,
|
|
45
|
+
* it holds the WRITE reply until the buffer drains below it, so a producer
|
|
46
|
+
* that awaits each write self-throttles to realtime.
|
|
47
|
+
*/
|
|
48
|
+
export const SPEAKER_STREAM_MAX_BUFFERED_MS = 2000;
|
|
49
|
+
/**
|
|
50
|
+
* Live PCM writer returned by `speaker.createStream()`. 16-bit little-endian
|
|
51
|
+
* PCM only — decode compressed formats (MP3/Opus) server-side before sending.
|
|
52
|
+
*
|
|
53
|
+
* Call `write()` as chunks arrive (each is auto-split into bridge-safe
|
|
54
|
+
* messages), then `close()` to drain and finish, or `abort()` to drop
|
|
55
|
+
* immediately. Shaped like BlobWriter so the two stream APIs feel the same.
|
|
56
|
+
*/
|
|
57
|
+
export class SpeakerStreamWriter {
|
|
58
|
+
constructor(session, streamId) {
|
|
59
|
+
this.session = session;
|
|
60
|
+
this.streamId = streamId;
|
|
61
|
+
this.settled = false;
|
|
62
|
+
this.writeChain = Promise.resolve();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Append raw PCM bytes (16-bit LE). Auto-chunked. Resolves with the host's
|
|
66
|
+
* buffered-ms after the last chunk. The host holds the reply while its
|
|
67
|
+
* buffer is above the backpressure ceiling, so a producer that awaits each
|
|
68
|
+
* write self-throttles to realtime.
|
|
69
|
+
*/
|
|
70
|
+
async write(chunk) {
|
|
71
|
+
this.assertOpen();
|
|
72
|
+
const bytes = toUint8Array(chunk);
|
|
73
|
+
if (bytes.byteLength === 0)
|
|
74
|
+
throw new Error("PCM chunk cannot be empty");
|
|
75
|
+
if (bytes.byteLength % 2 !== 0)
|
|
76
|
+
throw new Error("PCM chunk must contain complete 16-bit samples");
|
|
77
|
+
return this.enqueueWrite(async () => {
|
|
78
|
+
let last = { bufferedMs: 0 };
|
|
79
|
+
for (let off = 0; off < bytes.length; off += SPEAKER_WRITE_CHUNK_BYTES) {
|
|
80
|
+
last = await this.send(bytesToBase64(bytes.subarray(off, off + SPEAKER_WRITE_CHUNK_BYTES)));
|
|
81
|
+
}
|
|
82
|
+
return last;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/** Append already-base64-encoded PCM bytes (e.g. relayed straight off a WS frame). */
|
|
86
|
+
async writeBase64(b64) {
|
|
87
|
+
this.assertOpen();
|
|
88
|
+
if (b64.length === 0 || b64.length % 4 !== 0)
|
|
89
|
+
throw new Error("PCM base64 must be non-empty and padded");
|
|
90
|
+
const padding = b64.endsWith("==") ? 2 : b64.endsWith("=") ? 1 : 0;
|
|
91
|
+
const decodedBytes = (b64.length / 4) * 3 - padding;
|
|
92
|
+
if (decodedBytes % 2 !== 0)
|
|
93
|
+
throw new Error("PCM base64 must contain complete 16-bit samples");
|
|
94
|
+
return this.enqueueWrite(async () => {
|
|
95
|
+
let last = { bufferedMs: 0 };
|
|
96
|
+
// Slice on 4-char boundaries so each chunk is whole base64 groups.
|
|
97
|
+
for (let off = 0; off < b64.length; off += SPEAKER_WRITE_CHUNK_B64) {
|
|
98
|
+
last = await this.send(b64.slice(off, off + SPEAKER_WRITE_CHUNK_B64));
|
|
99
|
+
}
|
|
100
|
+
return last;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/** Drain the remaining buffer and finish. Resolves when playback has ended. */
|
|
104
|
+
async close() {
|
|
105
|
+
this.assertOpen();
|
|
106
|
+
this.settled = true;
|
|
107
|
+
await this.writeChain;
|
|
108
|
+
// Draining takes as long as the buffered audio — opt out of the default
|
|
109
|
+
// request timeout like play()/speak() do.
|
|
110
|
+
const res = await this.session.sendRequest({ type: MiniappRequestType.SPEAKER_STREAM_CLOSE, streamId: this.streamId }, { timeoutMs: 0 });
|
|
111
|
+
return res ?? {};
|
|
112
|
+
}
|
|
113
|
+
/** Stop immediately and drop any buffered audio. Idempotent. */
|
|
114
|
+
async abort() {
|
|
115
|
+
if (this.settled)
|
|
116
|
+
return;
|
|
117
|
+
this.settled = true;
|
|
118
|
+
await this.session.sendRequest({
|
|
119
|
+
type: MiniappRequestType.SPEAKER_STREAM_ABORT,
|
|
120
|
+
streamId: this.streamId,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
assertOpen() {
|
|
124
|
+
if (this.settled)
|
|
125
|
+
throw new Error("SpeakerStreamWriter is already closed/aborted");
|
|
126
|
+
}
|
|
127
|
+
async send(base64) {
|
|
128
|
+
const res = await this.session.sendRequest({
|
|
129
|
+
type: MiniappRequestType.SPEAKER_STREAM_WRITE,
|
|
130
|
+
streamId: this.streamId,
|
|
131
|
+
base64,
|
|
132
|
+
});
|
|
133
|
+
return res ?? { bufferedMs: 0 };
|
|
134
|
+
}
|
|
135
|
+
/** Preserve PCM ordering even when a producer issues overlapping writes. */
|
|
136
|
+
enqueueWrite(operation) {
|
|
137
|
+
const result = this.writeChain.then(operation);
|
|
138
|
+
this.writeChain = result.then(() => undefined, () => undefined);
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export class SpeakerModule {
|
|
143
|
+
constructor(session) {
|
|
144
|
+
this.session = session;
|
|
145
|
+
this._state = "idle";
|
|
146
|
+
this._lastEvent = { state: "idle" };
|
|
147
|
+
}
|
|
148
|
+
/** Current speaker playback state. */
|
|
149
|
+
get state() {
|
|
150
|
+
return this._state;
|
|
151
|
+
}
|
|
152
|
+
/** True iff state === "playing". */
|
|
153
|
+
get isPlaying() {
|
|
154
|
+
return this._state === "playing";
|
|
155
|
+
}
|
|
156
|
+
/** Play a URL. Resolves when playback completes on the phone. */
|
|
157
|
+
async play(options) {
|
|
158
|
+
// Playback length is unbounded (a clip can run for minutes), and the host
|
|
159
|
+
// only sends its REQUEST_RESULT when playback finishes or is interrupted, so
|
|
160
|
+
// opt out of the default request timeout — otherwise a long clip would reject
|
|
161
|
+
// with ACTION_TIMEOUT mid-playback. A `stop()` or disconnect still settles it.
|
|
162
|
+
await this.session.sendRequest({
|
|
163
|
+
type: MiniappRequestType.PLAY_AUDIO,
|
|
164
|
+
audioUrl: options.audioUrl,
|
|
165
|
+
volume: options.volume,
|
|
166
|
+
stopOtherAudio: options.stopOtherAudio ?? false,
|
|
167
|
+
}, { timeoutMs: 0 });
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Speak text through the phone. The host streams cloud TTS when connected,
|
|
171
|
+
* then falls back to local offline TTS.
|
|
172
|
+
*
|
|
173
|
+
* Rejects with a MiniappRequestError containing a `code` field on cloud-side
|
|
174
|
+
* TTS failures: `TTS_TEXT_TOO_LONG`, `TTS_INVALID_VOICE`, `TTS_UPSTREAM_ERROR`.
|
|
175
|
+
*/
|
|
176
|
+
async speak(text, options = {}) {
|
|
177
|
+
try {
|
|
178
|
+
// Like play(): resolves only when TTS playback completes, so opt out of the
|
|
179
|
+
// default request timeout (long text can outlast it). Settled by the host
|
|
180
|
+
// result, a stop(), or disconnect.
|
|
181
|
+
const result = await this.session.sendRequest({
|
|
182
|
+
type: MiniappRequestType.SPEAK,
|
|
183
|
+
text,
|
|
184
|
+
voice_id: options.voice_id,
|
|
185
|
+
voice_settings: options.voice_settings,
|
|
186
|
+
volume: options.volume,
|
|
187
|
+
stopOtherAudio: options.stopOtherAudio ?? false,
|
|
188
|
+
}, { timeoutMs: 0 });
|
|
189
|
+
return result ?? { completed: true };
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
// Normalize so callers can `catch (e) { if (e.code === "TTS_TEXT_TOO_LONG") ...`
|
|
193
|
+
if (err && typeof err === "object" && "code" in err) {
|
|
194
|
+
throw err;
|
|
195
|
+
}
|
|
196
|
+
throw { code: MiniappErrorCode.INTERNAL, message: String(err) };
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Open a live PCM output stream (16-bit LE) to the phone's audio playback
|
|
201
|
+
* service. Use from the background to play audio that arrives in chunks
|
|
202
|
+
* (e.g. live meeting audio over a WebSocket) with low latency — unlike
|
|
203
|
+
* `play()`, nothing has to be a file or URL first.
|
|
204
|
+
*
|
|
205
|
+
* One stream per miniapp: opening a second closes the first. Rejects with
|
|
206
|
+
* `NOT_IMPLEMENTED` on hosts that predate streaming. Miniapps that depend on
|
|
207
|
+
* this API must declare `minHostVersion: "2.13.0"` or newer.
|
|
208
|
+
*/
|
|
209
|
+
async createStream(options = {}) {
|
|
210
|
+
if (options.volume !== undefined &&
|
|
211
|
+
(!Number.isFinite(options.volume) || options.volume < 0 || options.volume > 1)) {
|
|
212
|
+
throw new RangeError("speaker stream volume must be between 0 and 1");
|
|
213
|
+
}
|
|
214
|
+
const res = await this.session.sendRequest({
|
|
215
|
+
type: MiniappRequestType.SPEAKER_STREAM_OPEN,
|
|
216
|
+
sampleRate: options.sampleRate ?? 16000,
|
|
217
|
+
channels: options.channels ?? 1,
|
|
218
|
+
volume: options.volume,
|
|
219
|
+
stopOtherAudio: options.stopOtherAudio ?? true,
|
|
220
|
+
});
|
|
221
|
+
return new SpeakerStreamWriter(this.session, res.streamId);
|
|
222
|
+
}
|
|
223
|
+
/** Stop any audio this miniapp is currently playing. */
|
|
224
|
+
stop() {
|
|
225
|
+
this.session.sendOneShot({ type: MiniappRequestType.STOP_AUDIO });
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Subscribe to speaker state transitions. Fires for every change. Does NOT
|
|
229
|
+
* fire immediately with the current value — call `state` separately if you
|
|
230
|
+
* want the seed.
|
|
231
|
+
*/
|
|
232
|
+
onStateChange(handler) {
|
|
233
|
+
return this.session.on("speakerState", handler);
|
|
234
|
+
}
|
|
235
|
+
/** @internal — applied by MiniappSession on inbound SPEAKER_STATE envelope. */
|
|
236
|
+
_applyState(event) {
|
|
237
|
+
// Idempotent: skip if state didn't change. Error events are transient
|
|
238
|
+
// and are not deduped against the prior state — they're informational
|
|
239
|
+
// and the phone immediately follows up with `stopped`.
|
|
240
|
+
if (event.state === this._state && event.state !== "error")
|
|
241
|
+
return;
|
|
242
|
+
this._state = event.state;
|
|
243
|
+
this._lastEvent = event;
|
|
244
|
+
}
|
|
245
|
+
/** @internal — for tests. */
|
|
246
|
+
_getLastEvent() {
|
|
247
|
+
return { ...this._lastEvent };
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=speaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speaker.js","sourceRoot":"","sources":["../../src/modules/speaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SimpleStorage — phone-local key-value store scoped to
|
|
3
|
+
* (userId, packageName). Mirrors cloud SDK v3's StorageManager surface.
|
|
4
|
+
*
|
|
5
|
+
* All operations round-trip to LocalMiniappRuntime, which reads/writes
|
|
6
|
+
* the phone's storage with a namespaced key format:
|
|
7
|
+
* mentraos_localstorage_{userId}_{packageName}_{key}
|
|
8
|
+
*
|
|
9
|
+
* Values are plain strings. Callers serialize structured data with
|
|
10
|
+
* JSON.stringify themselves (matching cloud's SimpleStorage shape).
|
|
11
|
+
*/
|
|
12
|
+
import { MiniappSession } from "../session";
|
|
13
|
+
export declare class SimpleStorage {
|
|
14
|
+
private readonly session;
|
|
15
|
+
constructor(session: MiniappSession);
|
|
16
|
+
/** Get a value by key. Resolves to null when the key is unset. */
|
|
17
|
+
get(key: string): Promise<string | null>;
|
|
18
|
+
/** Set a single key/value pair. Overwrites silently. */
|
|
19
|
+
set(key: string, value: string): Promise<void>;
|
|
20
|
+
/** Delete one key. No-op if the key is unset. */
|
|
21
|
+
delete(key: string): Promise<void>;
|
|
22
|
+
/** List every key in this miniapp's namespace. */
|
|
23
|
+
keys(): Promise<string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated Renamed to `keys()` for cloud SDK parity. This alias will be
|
|
26
|
+
* removed in a future release.
|
|
27
|
+
*/
|
|
28
|
+
list(): Promise<string[]>;
|
|
29
|
+
/** Drop every key in this miniapp's namespace. */
|
|
30
|
+
clear(): Promise<void>;
|
|
31
|
+
/** True iff `key` is set in this miniapp's namespace. */
|
|
32
|
+
has(key: string): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Read every key/value pair in this miniapp's namespace. Useful for
|
|
35
|
+
* hydrating state on bootstrap. Bounded by the underlying namespace
|
|
36
|
+
* size — keep total stored payload small (typical < 1 MB) to avoid
|
|
37
|
+
* stalling the JSContext when this resolves.
|
|
38
|
+
*/
|
|
39
|
+
getAll(): Promise<Record<string, string>>;
|
|
40
|
+
/** Write many key/value pairs in one round-trip. */
|
|
41
|
+
setMultiple(values: Record<string, string>): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Force any pending in-flight writes to disk. No-op today because the
|
|
44
|
+
* host writes through immediately, but reserved so a future debounced
|
|
45
|
+
* backend can honor "flush before I quit" calls without breaking the
|
|
46
|
+
* API.
|
|
47
|
+
*/
|
|
48
|
+
flush(): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/modules/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAA;AAEzC,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAEpD,kEAAkE;IAC5D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQ9C,wDAAwD;IAClD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpD,iDAAiD;IAC3C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxC,kDAAkD;IAC5C,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAO/B;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAI/B,kDAAkD;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,yDAAyD;IACnD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQxC;;;;;OAKG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAO/C,oDAAoD;IAC9C,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhE;;;;;OAKG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SimpleStorage — phone-local key-value store scoped to
|
|
3
|
+
* (userId, packageName). Mirrors cloud SDK v3's StorageManager surface.
|
|
4
|
+
*
|
|
5
|
+
* All operations round-trip to LocalMiniappRuntime, which reads/writes
|
|
6
|
+
* the phone's storage with a namespaced key format:
|
|
7
|
+
* mentraos_localstorage_{userId}_{packageName}_{key}
|
|
8
|
+
*
|
|
9
|
+
* Values are plain strings. Callers serialize structured data with
|
|
10
|
+
* JSON.stringify themselves (matching cloud's SimpleStorage shape).
|
|
11
|
+
*/
|
|
12
|
+
import { MiniappRequestType } from "../protocol";
|
|
13
|
+
export class SimpleStorage {
|
|
14
|
+
constructor(session) {
|
|
15
|
+
this.session = session;
|
|
16
|
+
}
|
|
17
|
+
/** Get a value by key. Resolves to null when the key is unset. */
|
|
18
|
+
async get(key) {
|
|
19
|
+
const result = await this.session.sendRequest({
|
|
20
|
+
type: MiniappRequestType.STORAGE_GET,
|
|
21
|
+
key,
|
|
22
|
+
});
|
|
23
|
+
return result?.value ?? null;
|
|
24
|
+
}
|
|
25
|
+
/** Set a single key/value pair. Overwrites silently. */
|
|
26
|
+
async set(key, value) {
|
|
27
|
+
await this.session.sendRequest({
|
|
28
|
+
type: MiniappRequestType.STORAGE_SET,
|
|
29
|
+
key,
|
|
30
|
+
value,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** Delete one key. No-op if the key is unset. */
|
|
34
|
+
async delete(key) {
|
|
35
|
+
await this.session.sendRequest({
|
|
36
|
+
type: MiniappRequestType.STORAGE_DELETE,
|
|
37
|
+
key,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** List every key in this miniapp's namespace. */
|
|
41
|
+
async keys() {
|
|
42
|
+
const result = await this.session.sendRequest({
|
|
43
|
+
type: MiniappRequestType.STORAGE_LIST,
|
|
44
|
+
});
|
|
45
|
+
return result?.keys ?? [];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @deprecated Renamed to `keys()` for cloud SDK parity. This alias will be
|
|
49
|
+
* removed in a future release.
|
|
50
|
+
*/
|
|
51
|
+
async list() {
|
|
52
|
+
return this.keys();
|
|
53
|
+
}
|
|
54
|
+
/** Drop every key in this miniapp's namespace. */
|
|
55
|
+
async clear() {
|
|
56
|
+
await this.session.sendRequest({
|
|
57
|
+
type: MiniappRequestType.STORAGE_CLEAR,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/** True iff `key` is set in this miniapp's namespace. */
|
|
61
|
+
async has(key) {
|
|
62
|
+
const result = await this.session.sendRequest({
|
|
63
|
+
type: MiniappRequestType.STORAGE_HAS,
|
|
64
|
+
key,
|
|
65
|
+
});
|
|
66
|
+
return !!result?.has;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Read every key/value pair in this miniapp's namespace. Useful for
|
|
70
|
+
* hydrating state on bootstrap. Bounded by the underlying namespace
|
|
71
|
+
* size — keep total stored payload small (typical < 1 MB) to avoid
|
|
72
|
+
* stalling the JSContext when this resolves.
|
|
73
|
+
*/
|
|
74
|
+
async getAll() {
|
|
75
|
+
const result = await this.session.sendRequest({
|
|
76
|
+
type: MiniappRequestType.STORAGE_GET_ALL,
|
|
77
|
+
});
|
|
78
|
+
return result?.values ?? {};
|
|
79
|
+
}
|
|
80
|
+
/** Write many key/value pairs in one round-trip. */
|
|
81
|
+
async setMultiple(values) {
|
|
82
|
+
await this.session.sendRequest({
|
|
83
|
+
type: MiniappRequestType.STORAGE_SET_MULTIPLE,
|
|
84
|
+
values,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Force any pending in-flight writes to disk. No-op today because the
|
|
89
|
+
* host writes through immediately, but reserved so a future debounced
|
|
90
|
+
* backend can honor "flush before I quit" calls without breaking the
|
|
91
|
+
* API.
|
|
92
|
+
*/
|
|
93
|
+
async flush() {
|
|
94
|
+
await this.session.sendRequest({
|
|
95
|
+
type: MiniappRequestType.STORAGE_FLUSH,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/modules/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAC,kBAAkB,EAAC,MAAM,aAAa,CAAA;AAG9C,MAAM,OAAO,aAAa;IACxB,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAExD,kEAAkE;IAClE,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAyB;YACpE,IAAI,EAAE,kBAAkB,CAAC,WAAW;YACpC,GAAG;SACJ,CAAC,CAAA;QACF,OAAO,MAAM,EAAE,KAAK,IAAI,IAAI,CAAA;IAC9B,CAAC;IAED,wDAAwD;IACxD,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAa;QAClC,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAO;YACnC,IAAI,EAAE,kBAAkB,CAAC,WAAW;YACpC,GAAG;YACH,KAAK;SACN,CAAC,CAAA;IACJ,CAAC;IAED,iDAAiD;IACjD,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAO;YACnC,IAAI,EAAE,kBAAkB,CAAC,cAAc;YACvC,GAAG;SACJ,CAAC,CAAA;IACJ,CAAC;IAED,kDAAkD;IAClD,KAAK,CAAC,IAAI;QACR,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAmB;YAC9D,IAAI,EAAE,kBAAkB,CAAC,YAAY;SACtC,CAAC,CAAA;QACF,OAAO,MAAM,EAAE,IAAI,IAAI,EAAE,CAAA;IAC3B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;IACpB,CAAC;IAED,kDAAkD;IAClD,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAO;YACnC,IAAI,EAAE,kBAAkB,CAAC,aAAa;SACvC,CAAC,CAAA;IACJ,CAAC;IAED,yDAAyD;IACzD,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAiB;YAC5D,IAAI,EAAE,kBAAkB,CAAC,WAAW;YACpC,GAAG;SACJ,CAAC,CAAA;QACF,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,CAAA;IACtB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM;QACV,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAmC;YAC9E,IAAI,EAAE,kBAAkB,CAAC,eAAe;SACzC,CAAC,CAAA;QACF,OAAO,MAAM,EAAE,MAAM,IAAI,EAAE,CAAA;IAC7B,CAAC;IAED,oDAAoD;IACpD,KAAK,CAAC,WAAW,CAAC,MAA8B;QAC9C,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAO;YACnC,IAAI,EAAE,kBAAkB,CAAC,oBAAoB;YAC7C,MAAM;SACP,CAAC,CAAA;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAO;YACnC,IAAI,EAAE,kBAAkB,CAAC,aAAa;SACvC,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview StreamModule -- video streaming from glasses.
|
|
3
|
+
*
|
|
4
|
+
* Wires to cloud streaming extensions via the __phone__ subscriber path.
|
|
5
|
+
*
|
|
6
|
+
* One entry point: `startStream`. By default it provisions a Mentra-hosted
|
|
7
|
+
* stream and returns playback URLs (managed). Pass `direct` to publish straight
|
|
8
|
+
* to your own ingest URL with no relay.
|
|
9
|
+
*/
|
|
10
|
+
import { MiniappSession } from "../session";
|
|
11
|
+
export interface StreamVideoConfig {
|
|
12
|
+
width?: number;
|
|
13
|
+
height?: number;
|
|
14
|
+
bitrate?: number;
|
|
15
|
+
fps?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface StreamAudioConfig {
|
|
18
|
+
bitrate?: number;
|
|
19
|
+
sampleRate?: number;
|
|
20
|
+
echoCancellation?: boolean;
|
|
21
|
+
noiseSuppression?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface StreamResolvedConfig {
|
|
24
|
+
transport?: "rtmp" | "srt" | "whip";
|
|
25
|
+
video?: {
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
captureWidth?: number;
|
|
29
|
+
captureHeight?: number;
|
|
30
|
+
bitrate: number;
|
|
31
|
+
fps: number;
|
|
32
|
+
};
|
|
33
|
+
audio?: {
|
|
34
|
+
bitrate?: number;
|
|
35
|
+
sampleRate?: number;
|
|
36
|
+
echoCancellation?: boolean;
|
|
37
|
+
noiseSuppression?: boolean;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Restream destination. The full stream key is part of the URL (e.g.
|
|
42
|
+
* `rtmp://yt.com/live/STREAM-KEY`). `name` is a human label that surfaces
|
|
43
|
+
* in dashboards but doesn't affect routing.
|
|
44
|
+
*/
|
|
45
|
+
export interface RestreamDestination {
|
|
46
|
+
url: string;
|
|
47
|
+
name?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface StartStreamOptions {
|
|
50
|
+
/**
|
|
51
|
+
* Publish straight to your own ingest URL (rtmp/rtmps/srt/whip). The glasses
|
|
52
|
+
* connect to it directly with no Mentra relay, so no playback URLs come back.
|
|
53
|
+
* Omit this to use the managed relay (the default, best for most apps).
|
|
54
|
+
*/
|
|
55
|
+
direct?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Restream destinations the managed relay fans out to (YouTube, Twitch, …).
|
|
58
|
+
* Bare URL strings or `{url, name?}` objects; mix freely. Managed streams
|
|
59
|
+
* only — ignored when `direct` is set.
|
|
60
|
+
*/
|
|
61
|
+
destinations?: Array<string | RestreamDestination>;
|
|
62
|
+
video?: StreamVideoConfig;
|
|
63
|
+
audio?: StreamAudioConfig;
|
|
64
|
+
/** Play glasses-side stream start/stop sounds. Defaults to true. */
|
|
65
|
+
sound?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Managed ingest protocol, a latency/durability trade. Ignored when `direct`
|
|
68
|
+
* is set.
|
|
69
|
+
* - "srt" (default): ~10-20s latency via LL-HLS, shareable HLS/DASH URLs,
|
|
70
|
+
* and automatic recording.
|
|
71
|
+
* - "whip": sub-second WebRTC playback (use `webrtcUrl`/WHEP), but no
|
|
72
|
+
* HLS/DASH and no recording.
|
|
73
|
+
*/
|
|
74
|
+
ingest?: "srt" | "whip";
|
|
75
|
+
}
|
|
76
|
+
export interface StreamResult {
|
|
77
|
+
streamId: string;
|
|
78
|
+
status: string;
|
|
79
|
+
resolvedConfig?: StreamResolvedConfig;
|
|
80
|
+
/** Managed streams only: the live-input UID for building hosted-player URLs. */
|
|
81
|
+
liveInputId?: string;
|
|
82
|
+
/** Managed streams only: which playback this stream serves. In "webrtc" mode
|
|
83
|
+
* `hlsUrl` never serves content. */
|
|
84
|
+
mode?: "hls" | "webrtc";
|
|
85
|
+
/** Managed streams only: HLS playback URL. */
|
|
86
|
+
hlsUrl?: string;
|
|
87
|
+
/** Managed streams only: DASH playback URL. */
|
|
88
|
+
dashUrl?: string;
|
|
89
|
+
/** Managed streams only: WHEP playback URL (present in "webrtc" mode). */
|
|
90
|
+
webrtcUrl?: string;
|
|
91
|
+
}
|
|
92
|
+
/** Live encoder telemetry, when the glasses emit it (no firmware does yet). */
|
|
93
|
+
export interface StreamLiveStats {
|
|
94
|
+
/** Current encoded video bitrate in bits per second. */
|
|
95
|
+
bitrate?: number;
|
|
96
|
+
/** Current encode frame rate. */
|
|
97
|
+
fps?: number;
|
|
98
|
+
droppedFrames?: number;
|
|
99
|
+
/** Seconds since the stream started. */
|
|
100
|
+
duration?: number;
|
|
101
|
+
/** Device temperature in °C, if the hardware reports it. */
|
|
102
|
+
temperatureC?: number;
|
|
103
|
+
}
|
|
104
|
+
export interface StreamStatus {
|
|
105
|
+
streamId: string;
|
|
106
|
+
status: string;
|
|
107
|
+
errorDetails?: string;
|
|
108
|
+
/** Negotiated encode config — forwarded once, on the first status ack. */
|
|
109
|
+
resolvedConfig?: StreamResolvedConfig;
|
|
110
|
+
stats?: StreamLiveStats;
|
|
111
|
+
}
|
|
112
|
+
export declare class StreamModule {
|
|
113
|
+
private readonly session;
|
|
114
|
+
constructor(session: MiniappSession);
|
|
115
|
+
/**
|
|
116
|
+
* Start a live video stream from the glasses camera.
|
|
117
|
+
*
|
|
118
|
+
* Managed (default) -- Mentra hosts the stream and the result carries
|
|
119
|
+
* `hlsUrl`/`dashUrl`/`webrtcUrl` for playback. Optionally fan out to your own
|
|
120
|
+
* `destinations`.
|
|
121
|
+
*
|
|
122
|
+
* Direct -- pass `direct` with your own ingest URL; the glasses publish to it
|
|
123
|
+
* and no playback URLs are returned.
|
|
124
|
+
*/
|
|
125
|
+
startStream(options?: StartStreamOptions): Promise<StreamResult>;
|
|
126
|
+
/** Stop the active stream, or a specific one by `streamId`. */
|
|
127
|
+
stop(streamId?: string): Promise<void>;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/modules/stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview StreamModule -- video streaming from glasses.
|
|
3
|
+
*
|
|
4
|
+
* Wires to cloud streaming extensions via the __phone__ subscriber path.
|
|
5
|
+
*
|
|
6
|
+
* One entry point: `startStream`. By default it provisions a Mentra-hosted
|
|
7
|
+
* stream and returns playback URLs (managed). Pass `direct` to publish straight
|
|
8
|
+
* to your own ingest URL with no relay.
|
|
9
|
+
*/
|
|
10
|
+
import { MiniappRequestType } from "../protocol";
|
|
11
|
+
export class StreamModule {
|
|
12
|
+
constructor(session) {
|
|
13
|
+
this.session = session;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Start a live video stream from the glasses camera.
|
|
17
|
+
*
|
|
18
|
+
* Managed (default) -- Mentra hosts the stream and the result carries
|
|
19
|
+
* `hlsUrl`/`dashUrl`/`webrtcUrl` for playback. Optionally fan out to your own
|
|
20
|
+
* `destinations`.
|
|
21
|
+
*
|
|
22
|
+
* Direct -- pass `direct` with your own ingest URL; the glasses publish to it
|
|
23
|
+
* and no playback URLs are returned.
|
|
24
|
+
*/
|
|
25
|
+
async startStream(options = {}) {
|
|
26
|
+
if (options.direct !== undefined) {
|
|
27
|
+
return this.session.sendRequest({
|
|
28
|
+
type: MiniappRequestType.STREAM_START,
|
|
29
|
+
streamUrl: options.direct,
|
|
30
|
+
video: options.video,
|
|
31
|
+
audio: options.audio,
|
|
32
|
+
sound: options.sound ?? true,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return this.session.sendRequest({
|
|
36
|
+
type: MiniappRequestType.MANAGED_STREAM_START,
|
|
37
|
+
restreamDestinations: options.destinations,
|
|
38
|
+
video: options.video,
|
|
39
|
+
audio: options.audio,
|
|
40
|
+
sound: options.sound ?? true,
|
|
41
|
+
ingest: options.ingest,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** Stop the active stream, or a specific one by `streamId`. */
|
|
45
|
+
async stop(streamId) {
|
|
46
|
+
await this.session.sendRequest({
|
|
47
|
+
type: MiniappRequestType.STREAM_STOP,
|
|
48
|
+
streamId,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/modules/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,kBAAkB,EAAC,MAAM,aAAa,CAAA;AAgH9C,MAAM,OAAO,YAAY;IACvB,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAExD;;;;;;;;;OASG;IACH,KAAK,CAAC,WAAW,CAAC,UAA8B,EAAE;QAChD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAe;gBAC5C,IAAI,EAAE,kBAAkB,CAAC,YAAY;gBACrC,SAAS,EAAE,OAAO,CAAC,MAAM;gBACzB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;aAC7B,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAe;YAC5C,IAAI,EAAE,kBAAkB,CAAC,oBAAoB;YAC7C,oBAAoB,EAAE,OAAO,CAAC,YAAY;YAC1C,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;YAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAA;IACJ,CAAC;IAED,+DAA+D;IAC/D,KAAK,CAAC,IAAI,CAAC,QAAiB;QAC1B,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAO;YACnC,IAAI,EAAE,kBAAkB,CAAC,WAAW;YACpC,QAAQ;SACT,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SystemModule — OS-level utilities (share, open URL, clipboard, download).
|
|
3
|
+
*
|
|
4
|
+
* These bridge to native phone capabilities via LocalMiniappRuntime.
|
|
5
|
+
*/
|
|
6
|
+
import { MiniappSession } from "../session";
|
|
7
|
+
export interface ShareOptions {
|
|
8
|
+
text?: string;
|
|
9
|
+
url?: string;
|
|
10
|
+
title?: string;
|
|
11
|
+
/** Base64-encoded file data for file sharing. */
|
|
12
|
+
base64?: string;
|
|
13
|
+
/** MIME type when sharing base64 data. */
|
|
14
|
+
mimeType?: string;
|
|
15
|
+
/** Filename when sharing base64 data. */
|
|
16
|
+
filename?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ShareResult {
|
|
19
|
+
success: boolean;
|
|
20
|
+
cancelled?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface DownloadOptions {
|
|
23
|
+
/** URL to download from, OR base64 data. */
|
|
24
|
+
url?: string;
|
|
25
|
+
base64?: string;
|
|
26
|
+
filename?: string;
|
|
27
|
+
mimeType?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface DownloadResult {
|
|
30
|
+
success: boolean;
|
|
31
|
+
cancelled?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare class SystemModule {
|
|
34
|
+
private readonly session;
|
|
35
|
+
constructor(session: MiniappSession);
|
|
36
|
+
/** Open the OS share sheet with the given content. */
|
|
37
|
+
share(options: ShareOptions): Promise<ShareResult>;
|
|
38
|
+
/** Open a URL in the system browser. Blocks dangerous schemes (javascript:, file:). */
|
|
39
|
+
openUrl(url: string): void;
|
|
40
|
+
/** Copy text to the system clipboard. */
|
|
41
|
+
copyToClipboard(text: string): Promise<void>;
|
|
42
|
+
/** Download a file. Opens the OS share sheet so user can choose save location. */
|
|
43
|
+
download(options: DownloadOptions): Promise<DownloadResult>;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=system.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../src/modules/system.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAEpD,sDAAsD;IAChD,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAQxD,uFAAuF;IACvF,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAO1B,yCAAyC;IACnC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlD,kFAAkF;IAC5E,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAOlE"}
|