@mentra/sdk 2.1.2 → 2.1.4
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/dist/app/session/events.d.ts +3 -2
- package/dist/app/session/events.d.ts.map +1 -1
- package/dist/app/session/events.js +3 -0
- package/dist/app/session/index.d.ts +8 -1
- package/dist/app/session/index.d.ts.map +1 -1
- package/dist/app/session/index.js +9 -0
- package/dist/app/session/layouts.d.ts +71 -14
- package/dist/app/session/layouts.d.ts.map +1 -1
- package/dist/app/session/layouts.js +114 -31
- package/dist/app/session/modules/audio.d.ts +2 -2
- package/dist/app/session/modules/audio.d.ts.map +1 -1
- package/dist/app/session/modules/audio.js +21 -17
- package/dist/app/session/modules/camera-managed-extension.d.ts +3 -1
- package/dist/app/session/modules/camera-managed-extension.d.ts.map +1 -1
- package/dist/app/session/modules/camera-managed-extension.js +26 -18
- package/dist/app/session/modules/camera.d.ts +4 -4
- package/dist/app/session/modules/camera.d.ts.map +1 -1
- package/dist/app/session/modules/camera.js +28 -22
- package/dist/app/session/modules/location.d.ts +3 -3
- package/dist/app/session/modules/location.d.ts.map +1 -1
- package/dist/app/session/modules/location.js +8 -5
- package/dist/examples/managed-rtmp-streaming-example.js +3 -0
- package/dist/examples/managed-rtmp-streaming-with-restream-example.d.ts +11 -0
- package/dist/examples/managed-rtmp-streaming-with-restream-example.d.ts.map +1 -0
- package/dist/examples/managed-rtmp-streaming-with-restream-example.js +124 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/types/enums.d.ts +3 -1
- package/dist/types/enums.d.ts.map +1 -1
- package/dist/types/enums.js +2 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/layouts.d.ts +16 -1
- package/dist/types/layouts.d.ts.map +1 -1
- package/dist/types/message-types.d.ts +2 -2
- package/dist/types/message-types.d.ts.map +1 -1
- package/dist/types/message-types.js +3 -3
- package/dist/types/messages/app-to-cloud.d.ts +11 -0
- package/dist/types/messages/app-to-cloud.d.ts.map +1 -1
- package/dist/types/messages/cloud-to-app.d.ts +19 -0
- package/dist/types/messages/cloud-to-app.d.ts.map +1 -1
- package/dist/types/messages/glasses-to-cloud.d.ts +8 -4
- package/dist/types/messages/glasses-to-cloud.d.ts.map +1 -1
- package/dist/types/messages/glasses-to-cloud.js +3 -3
- package/dist/types/models.d.ts +1 -0
- package/dist/types/models.d.ts.map +1 -1
- package/dist/types/models.js +1 -0
- package/dist/types/streams.d.ts +1 -1
- package/dist/types/streams.d.ts.map +1 -1
- package/dist/types/streams.js +2 -2
- package/dist/types/user-session.d.ts +8 -8
- package/dist/types/user-session.d.ts.map +1 -1
- package/dist/utils/animation-utils.d.ts +206 -0
- package/dist/utils/animation-utils.d.ts.map +1 -0
- package/dist/utils/animation-utils.js +340 -0
- package/dist/utils/bitmap-utils.d.ts +149 -0
- package/dist/utils/bitmap-utils.d.ts.map +1 -0
- package/dist/utils/bitmap-utils.js +465 -0
- package/package.json +2 -1
@@ -4,7 +4,7 @@
|
|
4
4
|
* Extends the camera module with managed streaming capabilities.
|
5
5
|
* Apps can request managed streams and receive HLS/DASH URLs without managing RTMP endpoints.
|
6
6
|
*/
|
7
|
-
import { ManagedStreamStatus } from '../../../types';
|
7
|
+
import { ManagedStreamStatus, RestreamDestination } from '../../../types';
|
8
8
|
import { VideoConfig, AudioConfig, StreamConfig } from '../../../types/rtmp-stream';
|
9
9
|
import { Logger } from 'pino';
|
10
10
|
/**
|
@@ -21,6 +21,8 @@ export interface ManagedStreamOptions {
|
|
21
21
|
audio?: AudioConfig;
|
22
22
|
/** Optional stream configuration settings */
|
23
23
|
stream?: StreamConfig;
|
24
|
+
/** Optional RTMP destinations to re-stream to (YouTube, Twitch, etc) */
|
25
|
+
restreamDestinations?: RestreamDestination[];
|
24
26
|
}
|
25
27
|
/**
|
26
28
|
* Result returned when starting a managed stream
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"camera-managed-extension.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/camera-managed-extension.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGL,mBAAmB,
|
1
|
+
{"version":3,"file":"camera-managed-extension.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/camera-managed-extension.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGL,mBAAmB,EAKnB,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,wEAAwE;IACxE,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,IAAI,CAAyB;IACrC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAC,CAAM;IAGtB,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,sBAAsB,CAAC,CAAS;IACxC,OAAO,CAAC,wBAAwB,CAAC,CAAsB;IACvD,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAGlD,OAAO,CAAC,2BAA2B,CAAC,CAGlC;gBAGA,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,EAC5B,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,GAAG;IASf;;;;;;;;;;;;;;;;;;OAkBG;IACG,kBAAkB,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAyC1F;;;;;;;OAOG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBxC;;;;OAIG;IACH,qBAAqB,IAAI,OAAO;IAIhC;;;;OAIG;IACH,oBAAoB,IAAI,mBAAmB,GAAG,SAAS;IAIvD;;;;OAIG;IACH,sBAAsB,IAAI,mBAAmB,GAAG,SAAS;IAIzD;;;;;;;;;;;;;;;;;;OAkBG;IACH,qBAAqB,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,GAAG,MAAM,IAAI;IAYjF;;;OAGG;IACH,yBAAyB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAwD5D;;OAEG;IACH,OAAO,IAAI,IAAI;CAahB"}
|
@@ -78,7 +78,8 @@ class CameraManagedExtension {
|
|
78
78
|
enableWebRTC: options.enableWebRTC,
|
79
79
|
video: options.video,
|
80
80
|
audio: options.audio,
|
81
|
-
stream: options.stream
|
81
|
+
stream: options.stream,
|
82
|
+
restreamDestinations: options.restreamDestinations
|
82
83
|
};
|
83
84
|
// Send the request
|
84
85
|
this.send(request);
|
@@ -115,12 +116,8 @@ class CameraManagedExtension {
|
|
115
116
|
packageName: this.packageName
|
116
117
|
};
|
117
118
|
this.send(request);
|
118
|
-
//
|
119
|
-
|
120
|
-
this.currentManagedStreamId = undefined;
|
121
|
-
this.currentManagedStreamUrls = undefined;
|
122
|
-
this.managedStreamStatus = undefined;
|
123
|
-
this.pendingManagedStreamRequest = undefined;
|
119
|
+
// Don't clean up state immediately - wait for the 'stopped' status from cloud
|
120
|
+
// This ensures we can retry stop if needed and maintains accurate state
|
124
121
|
}
|
125
122
|
/**
|
126
123
|
* 📊 Check if currently managed streaming
|
@@ -184,19 +181,30 @@ class CameraManagedExtension {
|
|
184
181
|
streamId: status.streamId
|
185
182
|
}, '📹 Received managed stream status');
|
186
183
|
this.managedStreamStatus = status;
|
184
|
+
// Handle initializing status - stream is starting
|
185
|
+
if (status.status === 'initializing' && status.streamId) {
|
186
|
+
this.isManagedStreaming = true;
|
187
|
+
this.currentManagedStreamId = status.streamId;
|
188
|
+
}
|
187
189
|
// Handle initial stream ready status
|
188
|
-
if (status.status === 'active'
|
189
|
-
|
190
|
-
|
191
|
-
dashUrl: status.dashUrl,
|
192
|
-
webrtcUrl: status.webrtcUrl,
|
193
|
-
streamId: status.streamId || ''
|
194
|
-
};
|
190
|
+
if (status.status === 'active') {
|
191
|
+
// Always update state when stream is active
|
192
|
+
this.isManagedStreaming = true;
|
195
193
|
this.currentManagedStreamId = status.streamId;
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
194
|
+
if (status.hlsUrl && status.dashUrl) {
|
195
|
+
const result = {
|
196
|
+
hlsUrl: status.hlsUrl,
|
197
|
+
dashUrl: status.dashUrl,
|
198
|
+
webrtcUrl: status.webrtcUrl,
|
199
|
+
streamId: status.streamId || ''
|
200
|
+
};
|
201
|
+
this.currentManagedStreamUrls = result;
|
202
|
+
// Resolve pending promise if exists
|
203
|
+
if (this.pendingManagedStreamRequest) {
|
204
|
+
this.pendingManagedStreamRequest.resolve(result);
|
205
|
+
this.pendingManagedStreamRequest = undefined;
|
206
|
+
}
|
207
|
+
}
|
200
208
|
}
|
201
209
|
// Handle error status
|
202
210
|
if ((status.status === 'error' || status.status === 'stopped') && this.pendingManagedStreamRequest) {
|
@@ -4,10 +4,10 @@
|
|
4
4
|
* Unified camera functionality for App Sessions.
|
5
5
|
* Handles both photo requests and RTMP streaming from connected glasses.
|
6
6
|
*/
|
7
|
-
import { PhotoData, RtmpStreamStatus, ManagedStreamStatus } from
|
8
|
-
import { VideoConfig, AudioConfig, StreamConfig, StreamStatusHandler } from
|
9
|
-
import { Logger } from
|
10
|
-
import { ManagedStreamOptions, ManagedStreamResult } from
|
7
|
+
import { PhotoData, RtmpStreamStatus, ManagedStreamStatus } from "../../../types";
|
8
|
+
import { VideoConfig, AudioConfig, StreamConfig, StreamStatusHandler } from "../../../types/rtmp-stream";
|
9
|
+
import { Logger } from "pino";
|
10
|
+
import { ManagedStreamOptions, ManagedStreamResult } from "./camera-managed-extension";
|
11
11
|
/**
|
12
12
|
* Options for photo requests
|
13
13
|
*/
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/camera.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAEL,SAAS,EAIT,gBAAgB,EAEhB,mBAAmB,EAEpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,
|
1
|
+
{"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/camera.ts"],"names":[],"mappings":"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"}
|
@@ -90,7 +90,7 @@ class CameraModule {
|
|
90
90
|
sessionId: this.sessionId,
|
91
91
|
requestId,
|
92
92
|
timestamp: new Date(),
|
93
|
-
saveToGallery: options?.saveToGallery || false
|
93
|
+
saveToGallery: options?.saveToGallery || false,
|
94
94
|
};
|
95
95
|
// Send request to cloud
|
96
96
|
this.send(message);
|
@@ -101,7 +101,9 @@ class CameraModule {
|
|
101
101
|
// Use session's resource tracker for automatic cleanup
|
102
102
|
this.session.resources.setTimeout(() => {
|
103
103
|
if (this.pendingPhotoRequests.has(requestId)) {
|
104
|
-
this.pendingPhotoRequests
|
104
|
+
this.pendingPhotoRequests
|
105
|
+
.get(requestId)
|
106
|
+
.reject("Photo request timed out");
|
105
107
|
this.pendingPhotoRequests.delete(requestId);
|
106
108
|
this.logger.warn({ requestId }, `📸 Photo request timed out`);
|
107
109
|
}
|
@@ -111,7 +113,9 @@ class CameraModule {
|
|
111
113
|
// Fallback to regular setTimeout if session not available
|
112
114
|
setTimeout(() => {
|
113
115
|
if (this.pendingPhotoRequests.has(requestId)) {
|
114
|
-
this.pendingPhotoRequests
|
116
|
+
this.pendingPhotoRequests
|
117
|
+
.get(requestId)
|
118
|
+
.reject("Photo request timed out");
|
115
119
|
this.pendingPhotoRequests.delete(requestId);
|
116
120
|
this.logger.warn({ requestId }, `📸 Photo request timed out`);
|
117
121
|
}
|
@@ -120,7 +124,7 @@ class CameraModule {
|
|
120
124
|
}
|
121
125
|
catch (error) {
|
122
126
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
123
|
-
reject(
|
127
|
+
reject(`Failed to request photo: ${errorMessage}`);
|
124
128
|
}
|
125
129
|
});
|
126
130
|
}
|
@@ -181,7 +185,7 @@ class CameraModule {
|
|
181
185
|
cancelPhotoRequest(requestId) {
|
182
186
|
const pendingRequest = this.pendingPhotoRequests.get(requestId);
|
183
187
|
if (pendingRequest) {
|
184
|
-
pendingRequest.reject(
|
188
|
+
pendingRequest.reject("Photo request cancelled");
|
185
189
|
this.pendingPhotoRequests.delete(requestId);
|
186
190
|
this.logger.info({ requestId }, `📸 Photo request cancelled`);
|
187
191
|
return true;
|
@@ -196,7 +200,7 @@ class CameraModule {
|
|
196
200
|
cancelAllPhotoRequests() {
|
197
201
|
const count = this.pendingPhotoRequests.size;
|
198
202
|
for (const [requestId, { reject }] of this.pendingPhotoRequests) {
|
199
|
-
reject(
|
203
|
+
reject("Photo request cancelled - session cleanup");
|
200
204
|
this.logger.info({ requestId }, `📸 Photo request cancelled during cleanup`);
|
201
205
|
}
|
202
206
|
this.pendingPhotoRequests.clear();
|
@@ -223,14 +227,14 @@ class CameraModule {
|
|
223
227
|
async startStream(options) {
|
224
228
|
this.logger.info({ rtmpUrl: options.rtmpUrl }, `📹 RTMP stream request starting`);
|
225
229
|
if (!options.rtmpUrl) {
|
226
|
-
throw new Error(
|
230
|
+
throw new Error("rtmpUrl is required");
|
227
231
|
}
|
228
232
|
if (this.isStreaming) {
|
229
233
|
this.logger.error({
|
230
234
|
currentStreamUrl: this.currentStreamUrl,
|
231
|
-
requestedUrl: options.rtmpUrl
|
235
|
+
requestedUrl: options.rtmpUrl,
|
232
236
|
}, `📹 Already streaming error`);
|
233
|
-
throw new Error(
|
237
|
+
throw new Error("Already streaming. Stop the current stream before starting a new one.");
|
234
238
|
}
|
235
239
|
// Create stream request message
|
236
240
|
const message = {
|
@@ -241,7 +245,7 @@ class CameraModule {
|
|
241
245
|
video: options.video,
|
242
246
|
audio: options.audio,
|
243
247
|
stream: options.stream,
|
244
|
-
timestamp: new Date()
|
248
|
+
timestamp: new Date(),
|
245
249
|
};
|
246
250
|
// Save stream URL for reference
|
247
251
|
this.currentStreamUrl = options.rtmpUrl;
|
@@ -255,7 +259,7 @@ class CameraModule {
|
|
255
259
|
catch (error) {
|
256
260
|
this.logger.error({ error, rtmpUrl: options.rtmpUrl }, `📹 Failed to send RTMP stream request`);
|
257
261
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
258
|
-
return Promise.reject(
|
262
|
+
return Promise.reject(`Failed to request RTMP stream: ${errorMessage}`);
|
259
263
|
}
|
260
264
|
}
|
261
265
|
/**
|
@@ -271,7 +275,7 @@ class CameraModule {
|
|
271
275
|
async stopStream() {
|
272
276
|
this.logger.info({
|
273
277
|
isCurrentlyStreaming: this.isStreaming,
|
274
|
-
currentStreamUrl: this.currentStreamUrl
|
278
|
+
currentStreamUrl: this.currentStreamUrl,
|
275
279
|
}, `📹 RTMP stream stop request`);
|
276
280
|
if (!this.isStreaming) {
|
277
281
|
this.logger.info(`📹 Not streaming - no-op`);
|
@@ -284,7 +288,7 @@ class CameraModule {
|
|
284
288
|
packageName: this.packageName,
|
285
289
|
sessionId: this.sessionId,
|
286
290
|
streamId: this.currentStreamState?.streamId, // Include streamId if available
|
287
|
-
timestamp: new Date()
|
291
|
+
timestamp: new Date(),
|
288
292
|
};
|
289
293
|
// Send the request
|
290
294
|
try {
|
@@ -293,7 +297,7 @@ class CameraModule {
|
|
293
297
|
}
|
294
298
|
catch (error) {
|
295
299
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
296
|
-
return Promise.reject(
|
300
|
+
return Promise.reject(`Failed to stop RTMP stream: ${errorMessage}`);
|
297
301
|
}
|
298
302
|
}
|
299
303
|
/**
|
@@ -329,7 +333,7 @@ class CameraModule {
|
|
329
333
|
this.session.subscribe(streams_1.StreamType.RTMP_STREAM_STATUS);
|
330
334
|
}
|
331
335
|
else {
|
332
|
-
this.logger.error(
|
336
|
+
this.logger.error("Cannot subscribe to status updates: session reference not available");
|
333
337
|
}
|
334
338
|
}
|
335
339
|
/**
|
@@ -360,7 +364,7 @@ class CameraModule {
|
|
360
364
|
*/
|
361
365
|
onStreamStatus(handler) {
|
362
366
|
if (!this.session) {
|
363
|
-
this.logger.error(
|
367
|
+
this.logger.error("Cannot listen for status updates: session reference not available");
|
364
368
|
return () => { };
|
365
369
|
}
|
366
370
|
this.subscribeToStreamStatusUpdates();
|
@@ -376,7 +380,7 @@ class CameraModule {
|
|
376
380
|
this.logger.debug({
|
377
381
|
messageType: message?.type,
|
378
382
|
messageStatus: message?.status,
|
379
|
-
currentIsStreaming: this.isStreaming
|
383
|
+
currentIsStreaming: this.isStreaming,
|
380
384
|
}, `📹 Stream state update`);
|
381
385
|
// Verify this is a valid stream response
|
382
386
|
if (!(0, types_1.isRtmpStreamStatus)(message)) {
|
@@ -391,19 +395,21 @@ class CameraModule {
|
|
391
395
|
errorDetails: message.errorDetails,
|
392
396
|
appId: message.appId,
|
393
397
|
stats: message.stats,
|
394
|
-
timestamp: message.timestamp || new Date()
|
398
|
+
timestamp: message.timestamp || new Date(),
|
395
399
|
};
|
396
400
|
this.logger.info({
|
397
401
|
streamId: status.streamId,
|
398
402
|
oldStatus: this.currentStreamState?.status,
|
399
403
|
newStatus: status.status,
|
400
|
-
wasStreaming: this.isStreaming
|
404
|
+
wasStreaming: this.isStreaming,
|
401
405
|
}, `📹 Stream status processed`);
|
402
406
|
// Update local state based on status
|
403
|
-
if (status.status ===
|
407
|
+
if (status.status === "stopped" ||
|
408
|
+
status.status === "error" ||
|
409
|
+
status.status === "timeout") {
|
404
410
|
this.logger.info({
|
405
411
|
status: status.status,
|
406
|
-
wasStreaming: this.isStreaming
|
412
|
+
wasStreaming: this.isStreaming,
|
407
413
|
}, `📹 Stream stopped - updating local state`);
|
408
414
|
this.isStreaming = false;
|
409
415
|
this.currentStreamUrl = undefined;
|
@@ -500,7 +506,7 @@ class CameraModule {
|
|
500
506
|
// Stop streaming if active
|
501
507
|
if (this.isStreaming) {
|
502
508
|
this.stopStream().catch((error) => {
|
503
|
-
this.logger.error({ error },
|
509
|
+
this.logger.error({ error }, "Error stopping stream during cleanup");
|
504
510
|
});
|
505
511
|
}
|
506
512
|
// Clean up managed extension
|
@@ -1,12 +1,12 @@
|
|
1
|
-
import { AppSession } from
|
2
|
-
import { LocationUpdate } from
|
1
|
+
import { AppSession } from "..";
|
2
|
+
import { LocationUpdate } from "../../../types";
|
3
3
|
export declare class LocationManager {
|
4
4
|
private session;
|
5
5
|
private send;
|
6
6
|
private lastLocationCleanupHandler;
|
7
7
|
constructor(session: AppSession, send: (message: any) => void);
|
8
8
|
subscribeToStream(options: {
|
9
|
-
accuracy:
|
9
|
+
accuracy: "standard" | "high" | "realtime" | "tenMeters" | "hundredMeters" | "kilometer" | "threeKilometers" | "reduced";
|
10
10
|
}, handler: (data: LocationUpdate) => void): () => void;
|
11
11
|
unsubscribeFromStream(): void;
|
12
12
|
getLatestLocation(options: {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"location.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/location.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,
|
1
|
+
{"version":3,"file":"location.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/location.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAGL,cAAc,EAEf,MAAM,gBAAgB,CAAC;AAExB,qBAAa,eAAe;IAIxB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,IAAI;IAJd,OAAO,CAAC,0BAA0B,CAAwB;gBAGhD,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI;IAI/B,iBAAiB,CACtB,OAAO,EAAE;QACP,QAAQ,EACJ,UAAU,GACV,MAAM,GACN,UAAU,GACV,WAAW,GACX,eAAe,GACf,WAAW,GACX,iBAAiB,GACjB,SAAS,CAAC;KACf,EACD,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,GACtC,MAAM,IAAI;IAWN,qBAAqB,IAAI,IAAI;IAUvB,iBAAiB,CAAC,OAAO,EAAE;QACtC,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,cAAc,CAAC;CA+B5B"}
|
@@ -10,7 +10,10 @@ class LocationManager {
|
|
10
10
|
}
|
11
11
|
// subscribes to the continuous location stream with a specified accuracy tier
|
12
12
|
subscribeToStream(options, handler) {
|
13
|
-
const subscription = {
|
13
|
+
const subscription = {
|
14
|
+
stream: "location_stream",
|
15
|
+
rate: options.accuracy,
|
16
|
+
};
|
14
17
|
this.session.subscribe(subscription);
|
15
18
|
this.lastLocationCleanupHandler = this.session.events.onLocation(handler);
|
16
19
|
return this.lastLocationCleanupHandler;
|
@@ -22,7 +25,7 @@ class LocationManager {
|
|
22
25
|
this.lastLocationCleanupHandler = () => { };
|
23
26
|
}
|
24
27
|
else {
|
25
|
-
this.session.unsubscribe(
|
28
|
+
this.session.unsubscribe("location_stream");
|
26
29
|
}
|
27
30
|
}
|
28
31
|
// performs a one-time, intelligent poll for a location fix
|
@@ -30,7 +33,7 @@ class LocationManager {
|
|
30
33
|
return new Promise((resolve, reject) => {
|
31
34
|
const requestId = `poll_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
32
35
|
// listens for a location update with a matching correlationId
|
33
|
-
const unsubscribe = this.session.events.on(
|
36
|
+
const unsubscribe = this.session.events.on("location_update", (data) => {
|
34
37
|
if (data.correlationId === requestId) {
|
35
38
|
unsubscribe(); // clean up the listener
|
36
39
|
resolve(data);
|
@@ -42,12 +45,12 @@ class LocationManager {
|
|
42
45
|
correlationId: requestId,
|
43
46
|
packageName: this.session.getPackageName(),
|
44
47
|
sessionId: this.session.getSessionId(),
|
45
|
-
accuracy: options.accuracy
|
48
|
+
accuracy: options.accuracy,
|
46
49
|
});
|
47
50
|
// sets a timeout to prevent the promise from hanging indefinitely
|
48
51
|
setTimeout(() => {
|
49
52
|
unsubscribe();
|
50
|
-
reject(
|
53
|
+
reject("Location poll request timed out");
|
51
54
|
}, 15000); // 15 second timeout
|
52
55
|
});
|
53
56
|
}
|
@@ -11,6 +11,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
* - Social media streaming (X, YouTube Live, TikTok Live)
|
12
12
|
* - Quick demos and prototypes
|
13
13
|
* - Production apps without existing streaming infrastructure
|
14
|
+
*
|
15
|
+
* NEW: You can now add re-streaming to multiple platforms! See
|
16
|
+
* managed-rtmp-streaming-with-restream-example.ts for details.
|
14
17
|
*/
|
15
18
|
const __1 = require("../");
|
16
19
|
// Initialize App session
|
@@ -0,0 +1,11 @@
|
|
1
|
+
/**
|
2
|
+
* Example: Managed RTMP Streaming with Re-streaming to Multiple Platforms
|
3
|
+
*
|
4
|
+
* This example demonstrates how to use the managed streaming feature with
|
5
|
+
* automatic re-streaming to platforms like YouTube, Twitch, and Facebook.
|
6
|
+
*
|
7
|
+
* The cloud handles all RTMP endpoints and automatically forwards your stream
|
8
|
+
* to the specified destinations.
|
9
|
+
*/
|
10
|
+
export {};
|
11
|
+
//# sourceMappingURL=managed-rtmp-streaming-with-restream-example.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"managed-rtmp-streaming-with-restream-example.d.ts","sourceRoot":"","sources":["../../src/examples/managed-rtmp-streaming-with-restream-example.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
@@ -0,0 +1,124 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* Example: Managed RTMP Streaming with Re-streaming to Multiple Platforms
|
4
|
+
*
|
5
|
+
* This example demonstrates how to use the managed streaming feature with
|
6
|
+
* automatic re-streaming to platforms like YouTube, Twitch, and Facebook.
|
7
|
+
*
|
8
|
+
* The cloud handles all RTMP endpoints and automatically forwards your stream
|
9
|
+
* to the specified destinations.
|
10
|
+
*/
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
+
const __1 = require("../");
|
13
|
+
class MultiPlatformStreamingApp extends __1.AppServer {
|
14
|
+
constructor() {
|
15
|
+
super({
|
16
|
+
packageName: 'com.example.multiplatform-streaming',
|
17
|
+
apiKey: process.env.MENTRAOS_API_KEY || 'your-api-key',
|
18
|
+
port: 3000
|
19
|
+
});
|
20
|
+
}
|
21
|
+
async onSession(session, sessionId, userId) {
|
22
|
+
console.log(`New session started: ${sessionId} for user ${userId}`);
|
23
|
+
// Subscribe to managed stream status updates
|
24
|
+
const managedStreamCleanup = session.camera.onManagedStreamStatus((status) => {
|
25
|
+
console.log(`Stream status: ${status.status}`);
|
26
|
+
// Check output statuses
|
27
|
+
if (status.outputs && status.outputs.length > 0) {
|
28
|
+
console.log('Re-stream outputs:');
|
29
|
+
status.outputs.forEach(output => {
|
30
|
+
console.log(`- ${output.name || output.url}: ${output.status}`);
|
31
|
+
if (output.error) {
|
32
|
+
console.error(` Error: ${output.error}`);
|
33
|
+
}
|
34
|
+
});
|
35
|
+
}
|
36
|
+
if (status.status === 'active') {
|
37
|
+
console.log('Stream is live!');
|
38
|
+
console.log('HLS URL:', status.hlsUrl);
|
39
|
+
console.log('DASH URL:', status.dashUrl);
|
40
|
+
session.layouts.showTextWall('Multi-platform stream is live!');
|
41
|
+
}
|
42
|
+
});
|
43
|
+
// Start managed stream when glasses connect
|
44
|
+
const connectCleanup = session.events.onConnected(async () => {
|
45
|
+
console.log('Glasses connected! Starting multi-platform stream...');
|
46
|
+
session.layouts.showTextWall('Starting multi-platform stream...');
|
47
|
+
try {
|
48
|
+
const streamResult = await session.camera.startManagedStream({
|
49
|
+
quality: '720p',
|
50
|
+
enableWebRTC: true,
|
51
|
+
// NEW: Add re-streaming destinations
|
52
|
+
restreamDestinations: [
|
53
|
+
{
|
54
|
+
url: 'rtmp://a.rtmp.youtube.com/live2/YOUR-YOUTUBE-STREAM-KEY',
|
55
|
+
name: 'YouTube'
|
56
|
+
},
|
57
|
+
{
|
58
|
+
url: 'rtmp://live.twitch.tv/app/YOUR-TWITCH-STREAM-KEY',
|
59
|
+
name: 'Twitch'
|
60
|
+
},
|
61
|
+
{
|
62
|
+
url: 'rtmps://live-api-s.facebook.com:443/rtmp/YOUR-FACEBOOK-STREAM-KEY',
|
63
|
+
name: 'Facebook'
|
64
|
+
}
|
65
|
+
],
|
66
|
+
// Optional: Custom encoding settings
|
67
|
+
video: {
|
68
|
+
width: 1280,
|
69
|
+
height: 720,
|
70
|
+
bitrate: 2000000, // 2 Mbps
|
71
|
+
frameRate: 30
|
72
|
+
},
|
73
|
+
audio: {
|
74
|
+
bitrate: 128000, // 128 kbps
|
75
|
+
sampleRate: 48000,
|
76
|
+
echoCancellation: true,
|
77
|
+
noiseSuppression: true
|
78
|
+
}
|
79
|
+
});
|
80
|
+
console.log('Managed stream started successfully!');
|
81
|
+
console.log('Stream ID:', streamResult.streamId);
|
82
|
+
console.log('HLS URL:', streamResult.hlsUrl);
|
83
|
+
console.log('DASH URL:', streamResult.dashUrl);
|
84
|
+
console.log('WebRTC URL:', streamResult.webrtcUrl);
|
85
|
+
// The stream is now being:
|
86
|
+
// 1. Sent from glasses to the RTMP relay
|
87
|
+
// 2. Forwarded to Cloudflare for HLS/DASH distribution
|
88
|
+
// 3. Re-streamed to YouTube, Twitch, and Facebook automatically
|
89
|
+
}
|
90
|
+
catch (error) {
|
91
|
+
console.error('Failed to start managed stream:', error);
|
92
|
+
session.layouts.showTextWall(`Failed to start stream: ${error instanceof Error ? error.message : String(error)}`);
|
93
|
+
}
|
94
|
+
});
|
95
|
+
// Stop stream when disconnected
|
96
|
+
const disconnectCleanup = session.events.onDisconnected(async () => {
|
97
|
+
console.log('Glasses disconnected, stopping stream...');
|
98
|
+
try {
|
99
|
+
await session.camera.stopManagedStream();
|
100
|
+
}
|
101
|
+
catch (error) {
|
102
|
+
console.error('Error stopping stream:', error);
|
103
|
+
}
|
104
|
+
});
|
105
|
+
// Register cleanup handlers
|
106
|
+
this.addCleanupHandler(managedStreamCleanup);
|
107
|
+
this.addCleanupHandler(connectCleanup);
|
108
|
+
this.addCleanupHandler(disconnectCleanup);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
// Start the app server
|
112
|
+
const app = new MultiPlatformStreamingApp();
|
113
|
+
app.start().catch(console.error);
|
114
|
+
// Important notes:
|
115
|
+
//
|
116
|
+
// 1. Stream Keys: Replace YOUR-*-STREAM-KEY with actual stream keys from each platform
|
117
|
+
// 2. Platform Requirements: Each platform has specific requirements:
|
118
|
+
// - YouTube: Requires 720p+ resolution, 30fps+, 2.5-4 Mbps bitrate
|
119
|
+
// - Twitch: Flexible, but recommends 3-6 Mbps for 1080p
|
120
|
+
// - Facebook: Supports up to 1080p, recommends 4 Mbps
|
121
|
+
//
|
122
|
+
// 3. The RTMP relay automatically transcodes your stream to meet platform requirements
|
123
|
+
// 4. You can monitor the status of each output in the ManagedStreamStatus updates
|
124
|
+
// 5. If an output fails, the main stream and other outputs continue working
|
package/dist/index.d.ts
CHANGED
@@ -4,8 +4,10 @@ export * from './types/messages/base';
|
|
4
4
|
export * from './types/messages/glasses-to-cloud';
|
5
5
|
export * from './types/messages/cloud-to-glasses';
|
6
6
|
export * from './types/messages/app-to-cloud';
|
7
|
+
export * from "./utils/bitmap-utils";
|
8
|
+
export * from "./utils/animation-utils";
|
7
9
|
export { AppConnectionAck, AppConnectionError, AppStopped, SettingsUpdate as AppSettingsUpdate, // Alias to avoid conflict with cloud-to-glasses SettingsUpdate
|
8
|
-
DataStream, CloudToAppMessage, TranslationData, ToolCall, StandardConnectionError, CustomMessage, ManagedStreamStatus, MentraosSettingsUpdate, TranscriptionData, AudioChunk, PermissionError, PermissionErrorDetail, AudioPlayResponse, isAppConnectionAck, isAppConnectionError, isAppStopped, isSettingsUpdate, isDataStream, isAudioChunk, isDashboardModeChanged, isDashboardAlwaysOnChanged, isManagedStreamStatus, isPhotoResponse as isPhotoResponseFromCloud, isRtmpStreamStatus as isRtmpStreamStatusFromCloud } from './types/messages/cloud-to-app';
|
10
|
+
DataStream, CloudToAppMessage, TranslationData, ToolCall, StandardConnectionError, CustomMessage, ManagedStreamStatus, OutputStatus, MentraosSettingsUpdate, TranscriptionData, AudioChunk, PermissionError, PermissionErrorDetail, AudioPlayResponse, isAppConnectionAck, isAppConnectionError, isAppStopped, isSettingsUpdate, isDataStream, isAudioChunk, isDashboardModeChanged, isDashboardAlwaysOnChanged, isManagedStreamStatus, isPhotoResponse as isPhotoResponseFromCloud, isRtmpStreamStatus as isRtmpStreamStatusFromCloud } from './types/messages/cloud-to-app';
|
9
11
|
export * from './types/streams';
|
10
12
|
export * from './types/layouts';
|
11
13
|
export * from './types/dashboard';
|
@@ -17,11 +19,11 @@ export * from './types/webhooks';
|
|
17
19
|
export * from './types/capabilities';
|
18
20
|
export * from "./app/index";
|
19
21
|
export * from "./logging/logger";
|
20
|
-
export { ButtonPress, HeadPosition, GlassesBatteryUpdate, PhoneBatteryUpdate, GlassesConnectionState, LocationUpdate, CalendarEvent, Vad, PhoneNotification,
|
22
|
+
export { ButtonPress, HeadPosition, GlassesBatteryUpdate, PhoneBatteryUpdate, GlassesConnectionState, LocationUpdate, CalendarEvent, Vad, PhoneNotification, PhoneNotificationDismissed, StartApp, StopApp, ConnectionInit, DashboardState, OpenDashboard, GlassesToCloudMessage, PhotoResponse, RtmpStreamStatus, KeepAliveAck } from './types/messages/glasses-to-cloud';
|
21
23
|
export { ConnectionAck, ConnectionError, AuthError, DisplayEvent, AppStateChange, MicrophoneStateChange, CloudToGlassesMessage, PhotoRequestToGlasses, SettingsUpdate, StartRtmpStream, StopRtmpStream, KeepRtmpStreamAlive } from './types/messages/cloud-to-glasses';
|
22
24
|
export { AppConnectionInit, AppSubscriptionUpdate, RtmpStreamRequest, RtmpStreamStopRequest, AppToCloudMessage, PhotoRequest } from './types/messages/app-to-cloud';
|
23
|
-
export { TextWall, DoubleTextWall, DashboardCard, ReferenceCard, Layout, DisplayRequest } from './types/layouts';
|
24
|
-
export { isButtonPress, isHeadPosition, isConnectionInit, isStartApp, isStopApp, isPhotoResponse as isPhotoResponseFromGlasses, isRtmpStreamStatus as isRtmpStreamStatusFromGlasses, isKeepAliveAck } from './types/messages/glasses-to-cloud';
|
25
|
+
export { TextWall, DoubleTextWall, DashboardCard, ReferenceCard, Layout, DisplayRequest, BitmapView, ClearView, } from './types/layouts';
|
26
|
+
export { isButtonPress, isHeadPosition, isConnectionInit, isStartApp, isStopApp, isPhotoResponse as isPhotoResponseFromGlasses, isRtmpStreamStatus as isRtmpStreamStatusFromGlasses, isKeepAliveAck, isPhoneNotificationDismissed } from './types/messages/glasses-to-cloud';
|
25
27
|
export { isConnectionAck, isDisplayEvent, isAppStateChange, isPhotoRequest, isSettingsUpdate as isSettingsUpdateToGlasses, isStartRtmpStream, isStopRtmpStream, isKeepRtmpStreamAlive } from './types/messages/cloud-to-glasses';
|
26
28
|
export { isAppConnectionInit, isAppSubscriptionUpdate, isDisplayRequest, isRtmpStreamRequest, isRtmpStreamStopRequest, isPhotoRequest as isPhotoRequestFromApp } from './types/messages/app-to-cloud';
|
27
29
|
export { BaseAppSetting, AppSetting, AppSettings, AppConfig, validateAppConfig, ToolSchema, ToolParameterSchema } from './types/models';
|
package/dist/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,eAAe,CAAC;AAG9B,cAAc,uBAAuB,CAAC;AAGtC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAG9C,OAAO,EAEL,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,cAAc,IAAI,iBAAiB,EAAG,+DAA+D;AACrG,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,uBAAuB,EACvB,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EAEjB,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACtB,0BAA0B,EAC1B,qBAAqB,EAGrB,eAAe,IAAI,wBAAwB,EAC3C,kBAAkB,IAAI,2BAA2B,EAClD,MAAM,+BAA+B,CAAC;AAGvC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,eAAe,CAAC;AAG9B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,sBAAsB,CAAC;AAGrC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,aAAa,CAAC;AAG5B,cAAc,kBAAkB,CAAC;AAOjC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,EACd,aAAa,EACb,GAAG,EACH,iBAAiB,EACjB,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
@@ -15,7 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
15
15
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
16
16
|
};
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
18
|
-
exports.validateAppConfig = exports.isPhotoRequestFromApp = exports.isRtmpStreamStopRequest = exports.isRtmpStreamRequest = exports.isDisplayRequest = exports.isAppSubscriptionUpdate = exports.isAppConnectionInit = exports.isKeepRtmpStreamAlive = exports.isStopRtmpStream = exports.isStartRtmpStream = exports.isSettingsUpdateToGlasses = exports.isPhotoRequest = exports.isAppStateChange = exports.isDisplayEvent = exports.isConnectionAck = exports.isKeepAliveAck = exports.isRtmpStreamStatusFromGlasses = exports.isPhotoResponseFromGlasses = exports.isStopApp = exports.isStartApp = exports.isConnectionInit = exports.isHeadPosition = exports.isButtonPress = exports.isRtmpStreamStatusFromCloud = exports.isPhotoResponseFromCloud = exports.isManagedStreamStatus = exports.isDashboardAlwaysOnChanged = exports.isDashboardModeChanged = exports.isAudioChunk = exports.isDataStream = exports.isSettingsUpdate = exports.isAppStopped = exports.isAppConnectionError = exports.isAppConnectionAck = void 0;
|
18
|
+
exports.validateAppConfig = exports.isPhotoRequestFromApp = exports.isRtmpStreamStopRequest = exports.isRtmpStreamRequest = exports.isDisplayRequest = exports.isAppSubscriptionUpdate = exports.isAppConnectionInit = exports.isKeepRtmpStreamAlive = exports.isStopRtmpStream = exports.isStartRtmpStream = exports.isSettingsUpdateToGlasses = exports.isPhotoRequest = exports.isAppStateChange = exports.isDisplayEvent = exports.isConnectionAck = exports.isPhoneNotificationDismissed = exports.isKeepAliveAck = exports.isRtmpStreamStatusFromGlasses = exports.isPhotoResponseFromGlasses = exports.isStopApp = exports.isStartApp = exports.isConnectionInit = exports.isHeadPosition = exports.isButtonPress = exports.isRtmpStreamStatusFromCloud = exports.isPhotoResponseFromCloud = exports.isManagedStreamStatus = exports.isDashboardAlwaysOnChanged = exports.isDashboardModeChanged = exports.isAudioChunk = exports.isDataStream = exports.isSettingsUpdate = exports.isAppStopped = exports.isAppConnectionError = exports.isAppConnectionAck = void 0;
|
19
19
|
__exportStar(require("./types/token"), exports);
|
20
20
|
// Message type enums
|
21
21
|
__exportStar(require("./types/message-types"), exports);
|
@@ -25,6 +25,9 @@ __exportStar(require("./types/messages/base"), exports);
|
|
25
25
|
__exportStar(require("./types/messages/glasses-to-cloud"), exports);
|
26
26
|
__exportStar(require("./types/messages/cloud-to-glasses"), exports);
|
27
27
|
__exportStar(require("./types/messages/app-to-cloud"), exports);
|
28
|
+
// Utility exports
|
29
|
+
__exportStar(require("./utils/bitmap-utils"), exports);
|
30
|
+
__exportStar(require("./utils/animation-utils"), exports);
|
28
31
|
// Export cloud-to-app but exclude the conflicting type guards
|
29
32
|
var cloud_to_app_1 = require("./types/messages/cloud-to-app");
|
30
33
|
// Type guards (excluding isPhotoResponse and isRtmpStreamStatus which conflict)
|
@@ -73,6 +76,7 @@ Object.defineProperty(exports, "isStopApp", { enumerable: true, get: function ()
|
|
73
76
|
Object.defineProperty(exports, "isPhotoResponseFromGlasses", { enumerable: true, get: function () { return glasses_to_cloud_1.isPhotoResponse; } });
|
74
77
|
Object.defineProperty(exports, "isRtmpStreamStatusFromGlasses", { enumerable: true, get: function () { return glasses_to_cloud_1.isRtmpStreamStatus; } });
|
75
78
|
Object.defineProperty(exports, "isKeepAliveAck", { enumerable: true, get: function () { return glasses_to_cloud_1.isKeepAliveAck; } });
|
79
|
+
Object.defineProperty(exports, "isPhoneNotificationDismissed", { enumerable: true, get: function () { return glasses_to_cloud_1.isPhoneNotificationDismissed; } });
|
76
80
|
var cloud_to_glasses_1 = require("./types/messages/cloud-to-glasses");
|
77
81
|
Object.defineProperty(exports, "isConnectionAck", { enumerable: true, get: function () { return cloud_to_glasses_1.isConnectionAck; } });
|
78
82
|
Object.defineProperty(exports, "isDisplayEvent", { enumerable: true, get: function () { return cloud_to_glasses_1.isDisplayEvent; } });
|
package/dist/types/enums.d.ts
CHANGED
@@ -33,7 +33,9 @@ export declare enum LayoutType {
|
|
33
33
|
DOUBLE_TEXT_WALL = "double_text_wall",
|
34
34
|
DASHBOARD_CARD = "dashboard_card",
|
35
35
|
REFERENCE_CARD = "reference_card",
|
36
|
-
BITMAP_VIEW = "bitmap_view"
|
36
|
+
BITMAP_VIEW = "bitmap_view",
|
37
|
+
BITMAP_ANIMATION = "bitmap_animation",
|
38
|
+
CLEAR_VIEW = "clear_view"
|
37
39
|
}
|
38
40
|
/**
|
39
41
|
* Types of views for displaying content
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../src/types/enums.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,oBAAY,OAAO;IACf,gBAAgB,qBAAqB,CAAG,6CAA6C;IACrF,UAAU,eAAe,CAAe,0CAA0C;IAClF,QAAQ,aAAa;CACxB;AAGD;;GAEG;AACH,oBAAY,QAAQ;IAChB,aAAa,kBAAkB,CAAG,gBAAgB;IAClD,SAAS,cAAc,CAAW,0BAA0B;IAC5D,OAAO,YAAY,CAAe,cAAc;IAChD,OAAO,YAAY,CAAe,qBAAqB;IACvD,OAAO,YAAY,CAAe,mBAAmB;IACrD,KAAK,UAAU;CAClB;AAED;;GAEG;AACH,oBAAY,QAAQ;IAChB,EAAE,OAAO;IACT,EAAE,OAAO;IACT,EAAE,OAAO;CAEZ;AAED;;GAEG;AACH,oBAAY,UAAU;IAClB,SAAS,cAAc;IACvB,gBAAgB,qBAAqB;IACrC,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;IACjC,WAAW,gBAAgB;
|
1
|
+
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../src/types/enums.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,oBAAY,OAAO;IACf,gBAAgB,qBAAqB,CAAG,6CAA6C;IACrF,UAAU,eAAe,CAAe,0CAA0C;IAClF,QAAQ,aAAa;CACxB;AAGD;;GAEG;AACH,oBAAY,QAAQ;IAChB,aAAa,kBAAkB,CAAG,gBAAgB;IAClD,SAAS,cAAc,CAAW,0BAA0B;IAC5D,OAAO,YAAY,CAAe,cAAc;IAChD,OAAO,YAAY,CAAe,qBAAqB;IACvD,OAAO,YAAY,CAAe,mBAAmB;IACrD,KAAK,UAAU;CAClB;AAED;;GAEG;AACH,oBAAY,QAAQ;IAChB,EAAE,OAAO;IACT,EAAE,OAAO;IACT,EAAE,OAAO;CAEZ;AAED;;GAEG;AACH,oBAAY,UAAU;IAClB,SAAS,cAAc;IACvB,gBAAgB,qBAAqB;IACrC,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;IACjC,WAAW,gBAAgB;IAC3B,gBAAgB,qBAAqB;IACrC,UAAU,eAAe;CAC5B;AAED;;GAEG;AACH,oBAAY,QAAQ;IAChB,SAAS,cAAc,CAAI,oCAAoC;IAC/D,SAAS,cAAc,CAAI,+BAA+B;IAC1D,IAAI,SAAS;CAChB;AAGD,oBAAY,cAAc;IACtB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,KAAK,UAAU;IACf,mBAAmB,wBAAwB;IAC3C,kBAAkB,uBAAuB;IACzC,WAAW,gBAAgB;IAC3B,WAAW,eAAe;IAC1B,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;CAC9B"}
|