@mentra/bluetooth-sdk 0.1.6 → 0.1.8
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 +26 -22
- package/android/.project +28 -0
- package/android/build.gradle +5 -9
- package/android/lc3Lib/.project +28 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +54 -33
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +48 -10
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +27 -36
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +8 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +170 -14
- package/android/src/main/java/com/mentra/bluetoothsdk/audio/AudioModels.kt +6 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +69 -10
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +5 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +2 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/debug/BleTraceLogger.kt +149 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +13 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoUploadServer.kt +297 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/MentraPhotoReceiverModule.kt +120 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +13 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +269 -28
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +8 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +4 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/status/DeviceStatus.kt +14 -12
- package/android/src/main/java/com/mentra/bluetoothsdk/status/RuntimeState.kt +4 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +131 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +1 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunkReassembler.java +105 -0
- package/build/BluetoothSdk.types.d.ts +107 -48
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js +4 -0
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts +8 -6
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js +58 -9
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/build/index.d.ts +2 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +6 -5
- package/build/index.js.map +1 -1
- package/build/photo-receiver/MentraPhotoReceiver.types.d.ts +18 -0
- package/build/photo-receiver/MentraPhotoReceiver.types.d.ts.map +1 -0
- package/build/photo-receiver/MentraPhotoReceiver.types.js +2 -0
- package/build/photo-receiver/MentraPhotoReceiver.types.js.map +1 -0
- package/build/photo-receiver/MentraPhotoReceiverModule.d.ts +10 -0
- package/build/photo-receiver/MentraPhotoReceiverModule.d.ts.map +1 -0
- package/build/photo-receiver/MentraPhotoReceiverModule.js +3 -0
- package/build/photo-receiver/MentraPhotoReceiverModule.js.map +1 -0
- package/build/photo-receiver/MentraPhotoReceiverModule.web.d.ts +10 -0
- package/build/photo-receiver/MentraPhotoReceiverModule.web.d.ts.map +1 -0
- package/build/photo-receiver/MentraPhotoReceiverModule.web.js +12 -0
- package/build/photo-receiver/MentraPhotoReceiverModule.web.js.map +1 -0
- package/build/photo-receiver/index.d.ts +3 -0
- package/build/photo-receiver/index.d.ts.map +1 -0
- package/build/photo-receiver/index.js +3 -0
- package/build/photo-receiver/index.js.map +1 -0
- package/build/react/useMentraBluetooth.d.ts +5 -3
- package/build/react/useMentraBluetooth.d.ts.map +1 -1
- package/build/react/useMentraBluetooth.js +15 -4
- package/build/react/useMentraBluetooth.js.map +1 -1
- package/expo-module.config.json +5 -2
- package/ios/BluetoothSdkModule.swift +59 -26
- package/ios/LocalPhotoUploadServer.swift +411 -0
- package/ios/MentraBluetoothSDK.podspec +8 -5
- package/ios/MentraPhotoReceiverModule.swift +147 -0
- package/ios/Source/Audio/AudioModels.swift +10 -10
- package/ios/Source/Bridge.swift +42 -12
- package/ios/Source/Camera/CameraModels.swift +74 -19
- package/ios/Source/DeviceManager.swift +23 -98
- package/ios/Source/DeviceStore.swift +12 -4
- package/ios/Source/Events/BluetoothEvents.swift +37 -0
- package/ios/Source/MentraBluetoothSDK.swift +135 -14
- package/ios/Source/Status/DeviceStatus.swift +12 -4
- package/ios/Source/Status/RuntimeState.swift +22 -13
- package/ios/Source/Streaming/StreamModels.swift +239 -45
- package/ios/Source/controllers/ControllerManager.swift +3 -3
- package/ios/Source/controllers/R1.swift +9 -3
- package/ios/Source/sgcs/G1.swift +5 -4
- package/ios/Source/sgcs/G2.swift +5 -6
- package/ios/Source/sgcs/Mach1.swift +1 -1
- package/ios/Source/sgcs/MentraLive.swift +183 -22
- package/ios/Source/sgcs/MentraNex.swift +1 -1
- package/ios/Source/sgcs/SGCManager.swift +11 -3
- package/ios/Source/sgcs/Simulated.swift +2 -2
- package/ios/Source/stt/SherpaOnnxTranscriber.swift +1 -4
- package/ios/Source/utils/MessageChunkReassembler.swift +89 -0
- package/package.json +6 -1
- package/src/BluetoothSdk.types.ts +133 -62
- package/src/_private/BluetoothSdkModule.ts +79 -26
- package/src/index.ts +15 -8
- package/src/photo-receiver/MentraPhotoReceiver.types.ts +20 -0
- package/src/photo-receiver/MentraPhotoReceiverModule.ts +14 -0
- package/src/photo-receiver/MentraPhotoReceiverModule.web.ts +20 -0
- package/src/photo-receiver/index.ts +2 -0
- package/src/react/useMentraBluetooth.ts +19 -7
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/VadGateSpeechPolicy.kt +0 -221
- package/ios/Packages/VAD/Common/VAD/VADQuality.swift +0 -41
- package/ios/Packages/VAD/Common/VAD/VADState.swift +0 -26
- package/ios/Packages/VAD/Common/VAD/VADStrategy.swift +0 -29
- package/ios/Packages/VAD/Common/VAD/VADType.swift +0 -14
- package/ios/Packages/VAD/Data/Configuration.swift +0 -68
- package/ios/Packages/VAD/Data/FrameSize.swift +0 -39
- package/ios/Packages/VAD/Data/Record.swift +0 -13
- package/ios/Packages/VAD/Data/Result.swift +0 -22
- package/ios/Packages/VAD/Data/SampleRate.swift +0 -48
- package/ios/Packages/VAD/Silero/Model/silero_vad.onnx +0 -0
- package/ios/Packages/VAD/Silero/SileroVAD.swift +0 -284
- package/ios/Packages/VAD/Silero/SileroVADStrategy.swift +0 -64
|
@@ -4,18 +4,18 @@ public struct StreamVideoConfig {
|
|
|
4
4
|
public let width: Int?
|
|
5
5
|
public let height: Int?
|
|
6
6
|
public let bitrate: Int?
|
|
7
|
-
public let
|
|
7
|
+
public let fps: Int?
|
|
8
8
|
|
|
9
9
|
public init(
|
|
10
10
|
width: Int? = nil,
|
|
11
11
|
height: Int? = nil,
|
|
12
12
|
bitrate: Int? = nil,
|
|
13
|
-
|
|
13
|
+
fps: Int? = nil
|
|
14
14
|
) {
|
|
15
15
|
self.width = width
|
|
16
16
|
self.height = height
|
|
17
17
|
self.bitrate = bitrate
|
|
18
|
-
self.
|
|
18
|
+
self.fps = fps
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
var dictionary: [String: Any] {
|
|
@@ -23,7 +23,7 @@ public struct StreamVideoConfig {
|
|
|
23
23
|
if let width { values["width"] = width }
|
|
24
24
|
if let height { values["height"] = height }
|
|
25
25
|
if let bitrate { values["bitrate"] = bitrate }
|
|
26
|
-
if let
|
|
26
|
+
if let fps { values["frameRate"] = fps }
|
|
27
27
|
return values
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -33,7 +33,7 @@ public struct StreamVideoConfig {
|
|
|
33
33
|
width: intValue(values["width"]),
|
|
34
34
|
height: intValue(values["height"]),
|
|
35
35
|
bitrate: intValue(values["bitrate"]),
|
|
36
|
-
|
|
36
|
+
fps: intValue(values["fps"])
|
|
37
37
|
)
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -76,6 +76,139 @@ public struct StreamAudioConfig {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
public struct StreamResolvedVideoConfig: Equatable {
|
|
80
|
+
public let width: Int
|
|
81
|
+
public let height: Int
|
|
82
|
+
public let captureWidth: Int?
|
|
83
|
+
public let captureHeight: Int?
|
|
84
|
+
public let bitrate: Int
|
|
85
|
+
public let fps: Int
|
|
86
|
+
|
|
87
|
+
public init(
|
|
88
|
+
width: Int,
|
|
89
|
+
height: Int,
|
|
90
|
+
captureWidth: Int? = nil,
|
|
91
|
+
captureHeight: Int? = nil,
|
|
92
|
+
bitrate: Int,
|
|
93
|
+
fps: Int
|
|
94
|
+
) {
|
|
95
|
+
self.width = width
|
|
96
|
+
self.height = height
|
|
97
|
+
self.captureWidth = captureWidth
|
|
98
|
+
self.captureHeight = captureHeight
|
|
99
|
+
self.bitrate = bitrate
|
|
100
|
+
self.fps = fps
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
init?(values: [String: Any]?) {
|
|
104
|
+
guard let values,
|
|
105
|
+
let width = intValue(values["width"]),
|
|
106
|
+
let height = intValue(values["height"]),
|
|
107
|
+
let bitrate = intValue(values["bitrate"]),
|
|
108
|
+
let fps = intValue(values["fps"])
|
|
109
|
+
else {
|
|
110
|
+
return nil
|
|
111
|
+
}
|
|
112
|
+
self.init(
|
|
113
|
+
width: width,
|
|
114
|
+
height: height,
|
|
115
|
+
captureWidth: intValue(values["captureWidth"]),
|
|
116
|
+
captureHeight: intValue(values["captureHeight"]),
|
|
117
|
+
bitrate: bitrate,
|
|
118
|
+
fps: fps
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
var values: [String: Any] {
|
|
123
|
+
var values: [String: Any] = [
|
|
124
|
+
"width": width,
|
|
125
|
+
"height": height,
|
|
126
|
+
"bitrate": bitrate,
|
|
127
|
+
"fps": fps,
|
|
128
|
+
]
|
|
129
|
+
if let captureWidth { values["captureWidth"] = captureWidth }
|
|
130
|
+
if let captureHeight { values["captureHeight"] = captureHeight }
|
|
131
|
+
return values
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public struct StreamResolvedAudioConfig: Equatable {
|
|
136
|
+
public let bitrate: Int?
|
|
137
|
+
public let sampleRate: Int?
|
|
138
|
+
public let echoCancellation: Bool?
|
|
139
|
+
public let noiseSuppression: Bool?
|
|
140
|
+
|
|
141
|
+
public init(
|
|
142
|
+
bitrate: Int? = nil,
|
|
143
|
+
sampleRate: Int? = nil,
|
|
144
|
+
echoCancellation: Bool? = nil,
|
|
145
|
+
noiseSuppression: Bool? = nil
|
|
146
|
+
) {
|
|
147
|
+
self.bitrate = bitrate
|
|
148
|
+
self.sampleRate = sampleRate
|
|
149
|
+
self.echoCancellation = echoCancellation
|
|
150
|
+
self.noiseSuppression = noiseSuppression
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
init?(values: [String: Any]?) {
|
|
154
|
+
guard let values else { return nil }
|
|
155
|
+
self.init(
|
|
156
|
+
bitrate: intValue(values["bitrate"]),
|
|
157
|
+
sampleRate: intValue(values["sampleRate"]),
|
|
158
|
+
echoCancellation: boolValue(values, "echoCancellation"),
|
|
159
|
+
noiseSuppression: boolValue(values, "noiseSuppression")
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
var values: [String: Any] {
|
|
164
|
+
var values: [String: Any] = [:]
|
|
165
|
+
if let bitrate { values["bitrate"] = bitrate }
|
|
166
|
+
if let sampleRate { values["sampleRate"] = sampleRate }
|
|
167
|
+
if let echoCancellation { values["echoCancellation"] = echoCancellation }
|
|
168
|
+
if let noiseSuppression { values["noiseSuppression"] = noiseSuppression }
|
|
169
|
+
return values
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public enum StreamTransport: String, Equatable {
|
|
174
|
+
case rtmp
|
|
175
|
+
case srt
|
|
176
|
+
case whip
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public struct StreamResolvedConfig: Equatable {
|
|
180
|
+
public let transport: StreamTransport?
|
|
181
|
+
public let video: StreamResolvedVideoConfig?
|
|
182
|
+
public let audio: StreamResolvedAudioConfig?
|
|
183
|
+
|
|
184
|
+
public init(
|
|
185
|
+
transport: StreamTransport? = nil,
|
|
186
|
+
video: StreamResolvedVideoConfig? = nil,
|
|
187
|
+
audio: StreamResolvedAudioConfig? = nil
|
|
188
|
+
) {
|
|
189
|
+
self.transport = transport
|
|
190
|
+
self.video = video
|
|
191
|
+
self.audio = audio
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
init?(values: [String: Any]?) {
|
|
195
|
+
guard let values else { return nil }
|
|
196
|
+
self.init(
|
|
197
|
+
transport: stringValue(values, "transport").flatMap(StreamTransport.init(rawValue:)),
|
|
198
|
+
video: StreamResolvedVideoConfig(values: values["video"] as? [String: Any]),
|
|
199
|
+
audio: StreamResolvedAudioConfig(values: values["audio"] as? [String: Any])
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
var values: [String: Any] {
|
|
204
|
+
var values: [String: Any] = [:]
|
|
205
|
+
if let transport { values["transport"] = transport.rawValue }
|
|
206
|
+
if let video { values["video"] = video.values }
|
|
207
|
+
if let audio { values["audio"] = audio.values }
|
|
208
|
+
return values
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
79
212
|
public struct StreamRequest {
|
|
80
213
|
public let streamUrl: String
|
|
81
214
|
public let streamId: String
|
|
@@ -90,7 +223,7 @@ public struct StreamRequest {
|
|
|
90
223
|
streamUrl: String,
|
|
91
224
|
streamId: String = "",
|
|
92
225
|
keepAlive: Bool = true,
|
|
93
|
-
keepAliveIntervalSeconds: Int =
|
|
226
|
+
keepAliveIntervalSeconds: Int = 5,
|
|
94
227
|
sound: Bool = true,
|
|
95
228
|
video: StreamVideoConfig? = nil,
|
|
96
229
|
audio: StreamAudioConfig? = nil,
|
|
@@ -115,7 +248,7 @@ public struct StreamRequest {
|
|
|
115
248
|
?? "",
|
|
116
249
|
streamId: values["streamId"] as? String ?? "",
|
|
117
250
|
keepAlive: values["keepAlive"] as? Bool ?? true,
|
|
118
|
-
keepAliveIntervalSeconds: intValue(values["keepAliveIntervalSeconds"]) ??
|
|
251
|
+
keepAliveIntervalSeconds: intValue(values["keepAliveIntervalSeconds"]) ?? 5,
|
|
119
252
|
sound: values["sound"] as? Bool ?? true,
|
|
120
253
|
video: StreamVideoConfig(values: values["video"] as? [String: Any]),
|
|
121
254
|
audio: StreamAudioConfig(values: values["audio"] as? [String: Any]),
|
|
@@ -125,6 +258,7 @@ public struct StreamRequest {
|
|
|
125
258
|
|
|
126
259
|
public var values: [String: Any] {
|
|
127
260
|
var values = extraValues
|
|
261
|
+
values.removeValue(forKey: "keepAliveMode")
|
|
128
262
|
values["type"] = "start_stream"
|
|
129
263
|
values["streamUrl"] = streamUrl
|
|
130
264
|
values["streamId"] = streamId
|
|
@@ -143,12 +277,18 @@ public struct StreamRequest {
|
|
|
143
277
|
}
|
|
144
278
|
}
|
|
145
279
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
280
|
+
extension StreamRequest {
|
|
281
|
+
var isExternallyManagedKeepAlive: Bool {
|
|
282
|
+
stringValue(extraValues, "keepAliveMode") == "external"
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
struct StreamKeepAliveRequest {
|
|
287
|
+
let streamId: String
|
|
288
|
+
let ackId: String
|
|
289
|
+
let extraValues: [String: Any]
|
|
150
290
|
|
|
151
|
-
|
|
291
|
+
init(streamId: String, ackId: String, extraValues: [String: Any] = [:]) {
|
|
152
292
|
self.streamId = streamId
|
|
153
293
|
self.ackId = ackId
|
|
154
294
|
self.extraValues = extraValues
|
|
@@ -162,7 +302,7 @@ public struct StreamKeepAliveRequest {
|
|
|
162
302
|
)
|
|
163
303
|
}
|
|
164
304
|
|
|
165
|
-
|
|
305
|
+
var values: [String: Any] {
|
|
166
306
|
var values = extraValues
|
|
167
307
|
values["type"] = "keep_stream_alive"
|
|
168
308
|
values["streamId"] = streamId
|
|
@@ -213,17 +353,33 @@ public enum StreamStatusKind: String, Equatable {
|
|
|
213
353
|
}
|
|
214
354
|
|
|
215
355
|
public enum StreamStatus: CustomStringConvertible, Equatable {
|
|
216
|
-
case lifecycle(state: StreamState, streamId: String?, timestamp: Int?)
|
|
217
|
-
case reconnecting(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
356
|
+
case lifecycle(state: StreamState, streamId: String?, timestamp: Int?, resolvedConfig: StreamResolvedConfig?)
|
|
357
|
+
case reconnecting(
|
|
358
|
+
streamId: String?,
|
|
359
|
+
attempt: Int,
|
|
360
|
+
maxAttempts: Int,
|
|
361
|
+
reason: String,
|
|
362
|
+
timestamp: Int?,
|
|
363
|
+
resolvedConfig: StreamResolvedConfig?
|
|
364
|
+
)
|
|
365
|
+
case reconnected(streamId: String?, attempt: Int, timestamp: Int?, resolvedConfig: StreamResolvedConfig?)
|
|
366
|
+
case reconnectFailed(streamId: String?, maxAttempts: Int, timestamp: Int?, resolvedConfig: StreamResolvedConfig?)
|
|
367
|
+
case error(streamId: String?, errorDetails: String, timestamp: Int?, resolvedConfig: StreamResolvedConfig?)
|
|
368
|
+
case snapshot(
|
|
369
|
+
state: StreamState,
|
|
370
|
+
streaming: Bool,
|
|
371
|
+
reconnecting: Bool,
|
|
372
|
+
streamId: String?,
|
|
373
|
+
attempt: Int?,
|
|
374
|
+
timestamp: Int?,
|
|
375
|
+
resolvedConfig: StreamResolvedConfig?
|
|
376
|
+
)
|
|
222
377
|
|
|
223
378
|
public init(values: [String: Any]) {
|
|
224
379
|
let rawState = stringValue(values, "status")
|
|
225
380
|
let streamId = stringValue(values, "streamId")
|
|
226
381
|
let timestamp = intValue(values["timestamp"])
|
|
382
|
+
let resolvedConfig = StreamResolvedConfig(values: values["resolvedConfig"] as? [String: Any])
|
|
227
383
|
let attempt = optionalIntValue(values, "attempt")
|
|
228
384
|
let maxAttempts = optionalIntValue(values, "maxAttempts") ?? 0
|
|
229
385
|
|
|
@@ -237,7 +393,8 @@ public enum StreamStatus: CustomStringConvertible, Equatable {
|
|
|
237
393
|
reconnecting: reconnecting,
|
|
238
394
|
streamId: streamId,
|
|
239
395
|
attempt: attempt,
|
|
240
|
-
timestamp: timestamp
|
|
396
|
+
timestamp: timestamp,
|
|
397
|
+
resolvedConfig: resolvedConfig
|
|
241
398
|
)
|
|
242
399
|
return
|
|
243
400
|
}
|
|
@@ -246,7 +403,8 @@ public enum StreamStatus: CustomStringConvertible, Equatable {
|
|
|
246
403
|
self = .error(
|
|
247
404
|
streamId: streamId,
|
|
248
405
|
errorDetails: rawState.map { "Unknown stream status: \($0)" } ?? "Missing stream status",
|
|
249
|
-
timestamp: timestamp
|
|
406
|
+
timestamp: timestamp,
|
|
407
|
+
resolvedConfig: resolvedConfig
|
|
250
408
|
)
|
|
251
409
|
return
|
|
252
410
|
}
|
|
@@ -258,21 +416,38 @@ public enum StreamStatus: CustomStringConvertible, Equatable {
|
|
|
258
416
|
attempt: attempt ?? 0,
|
|
259
417
|
maxAttempts: maxAttempts,
|
|
260
418
|
reason: stringValue(values, "reason") ?? "",
|
|
261
|
-
timestamp: timestamp
|
|
419
|
+
timestamp: timestamp,
|
|
420
|
+
resolvedConfig: resolvedConfig
|
|
262
421
|
)
|
|
263
422
|
case .reconnected:
|
|
264
|
-
self = .reconnected(
|
|
423
|
+
self = .reconnected(
|
|
424
|
+
streamId: streamId,
|
|
425
|
+
attempt: attempt ?? 0,
|
|
426
|
+
timestamp: timestamp,
|
|
427
|
+
resolvedConfig: resolvedConfig
|
|
428
|
+
)
|
|
265
429
|
case .reconnectFailed:
|
|
266
|
-
self = .reconnectFailed(
|
|
430
|
+
self = .reconnectFailed(
|
|
431
|
+
streamId: streamId,
|
|
432
|
+
maxAttempts: maxAttempts,
|
|
433
|
+
timestamp: timestamp,
|
|
434
|
+
resolvedConfig: resolvedConfig
|
|
435
|
+
)
|
|
267
436
|
case .error:
|
|
268
437
|
self = .error(
|
|
269
438
|
streamId: streamId,
|
|
270
439
|
errorDetails: stringValue(values, "errorDetails")
|
|
271
440
|
?? (rawState == "error_not_streaming" ? "not_streaming" : "Unknown stream error"),
|
|
272
|
-
timestamp: timestamp
|
|
441
|
+
timestamp: timestamp,
|
|
442
|
+
resolvedConfig: resolvedConfig
|
|
273
443
|
)
|
|
274
444
|
default:
|
|
275
|
-
self = .lifecycle(
|
|
445
|
+
self = .lifecycle(
|
|
446
|
+
state: state,
|
|
447
|
+
streamId: streamId,
|
|
448
|
+
timestamp: timestamp,
|
|
449
|
+
resolvedConfig: resolvedConfig
|
|
450
|
+
)
|
|
276
451
|
}
|
|
277
452
|
}
|
|
278
453
|
|
|
@@ -291,7 +466,7 @@ public enum StreamStatus: CustomStringConvertible, Equatable {
|
|
|
291
466
|
|
|
292
467
|
public var state: StreamState {
|
|
293
468
|
switch self {
|
|
294
|
-
case let .lifecycle(state, _, _):
|
|
469
|
+
case let .lifecycle(state, _, _, _):
|
|
295
470
|
state
|
|
296
471
|
case .reconnecting:
|
|
297
472
|
.reconnecting
|
|
@@ -301,35 +476,47 @@ public enum StreamStatus: CustomStringConvertible, Equatable {
|
|
|
301
476
|
.reconnectFailed
|
|
302
477
|
case .error:
|
|
303
478
|
.error
|
|
304
|
-
case let .snapshot(state, _, _, _, _, _):
|
|
479
|
+
case let .snapshot(state, _, _, _, _, _, _):
|
|
305
480
|
state
|
|
306
481
|
}
|
|
307
482
|
}
|
|
308
483
|
|
|
309
484
|
public var streamId: String? {
|
|
310
485
|
switch self {
|
|
311
|
-
case let .lifecycle(_, streamId, _),
|
|
312
|
-
let .reconnecting(streamId, _, _, _, _),
|
|
313
|
-
let .reconnected(streamId, _, _),
|
|
314
|
-
let .reconnectFailed(streamId, _, _),
|
|
315
|
-
let .error(streamId, _, _),
|
|
316
|
-
let .snapshot(_, _, _, streamId, _, _):
|
|
486
|
+
case let .lifecycle(_, streamId, _, _),
|
|
487
|
+
let .reconnecting(streamId, _, _, _, _, _),
|
|
488
|
+
let .reconnected(streamId, _, _, _),
|
|
489
|
+
let .reconnectFailed(streamId, _, _, _),
|
|
490
|
+
let .error(streamId, _, _, _),
|
|
491
|
+
let .snapshot(_, _, _, streamId, _, _, _):
|
|
317
492
|
streamId
|
|
318
493
|
}
|
|
319
494
|
}
|
|
320
495
|
|
|
321
496
|
public var timestamp: Int? {
|
|
322
497
|
switch self {
|
|
323
|
-
case let .lifecycle(_, _, timestamp),
|
|
324
|
-
let .reconnecting(_, _, _, _, timestamp),
|
|
325
|
-
let .reconnected(_, _, timestamp),
|
|
326
|
-
let .reconnectFailed(_, _, timestamp),
|
|
327
|
-
let .error(_, _, timestamp),
|
|
328
|
-
let .snapshot(_, _, _, _, _, timestamp):
|
|
498
|
+
case let .lifecycle(_, _, timestamp, _),
|
|
499
|
+
let .reconnecting(_, _, _, _, timestamp, _),
|
|
500
|
+
let .reconnected(_, _, timestamp, _),
|
|
501
|
+
let .reconnectFailed(_, _, timestamp, _),
|
|
502
|
+
let .error(_, _, timestamp, _),
|
|
503
|
+
let .snapshot(_, _, _, _, _, timestamp, _):
|
|
329
504
|
timestamp
|
|
330
505
|
}
|
|
331
506
|
}
|
|
332
507
|
|
|
508
|
+
public var resolvedConfig: StreamResolvedConfig? {
|
|
509
|
+
switch self {
|
|
510
|
+
case let .lifecycle(_, _, _, resolvedConfig),
|
|
511
|
+
let .reconnecting(_, _, _, _, _, resolvedConfig),
|
|
512
|
+
let .reconnected(_, _, _, resolvedConfig),
|
|
513
|
+
let .reconnectFailed(_, _, _, resolvedConfig),
|
|
514
|
+
let .error(_, _, _, resolvedConfig),
|
|
515
|
+
let .snapshot(_, _, _, _, _, _, resolvedConfig):
|
|
516
|
+
resolvedConfig
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
333
520
|
public var values: [String: Any] {
|
|
334
521
|
var values: [String: Any] = [
|
|
335
522
|
"kind": kind.rawValue,
|
|
@@ -341,21 +528,24 @@ public enum StreamStatus: CustomStringConvertible, Equatable {
|
|
|
341
528
|
if let timestamp {
|
|
342
529
|
values["timestamp"] = timestamp
|
|
343
530
|
}
|
|
531
|
+
if let resolvedConfig {
|
|
532
|
+
values["resolvedConfig"] = resolvedConfig.values
|
|
533
|
+
}
|
|
344
534
|
|
|
345
535
|
switch self {
|
|
346
536
|
case .lifecycle:
|
|
347
537
|
break
|
|
348
|
-
case let .reconnecting(_, attempt, maxAttempts, reason, _):
|
|
538
|
+
case let .reconnecting(_, attempt, maxAttempts, reason, _, _):
|
|
349
539
|
values["attempt"] = attempt
|
|
350
540
|
values["maxAttempts"] = maxAttempts
|
|
351
541
|
values["reason"] = reason
|
|
352
|
-
case let .reconnected(_, attempt, _):
|
|
542
|
+
case let .reconnected(_, attempt, _, _):
|
|
353
543
|
values["attempt"] = attempt
|
|
354
|
-
case let .reconnectFailed(_, maxAttempts, _):
|
|
544
|
+
case let .reconnectFailed(_, maxAttempts, _, _):
|
|
355
545
|
values["maxAttempts"] = maxAttempts
|
|
356
|
-
case let .error(_, errorDetails, _):
|
|
546
|
+
case let .error(_, errorDetails, _, _):
|
|
357
547
|
values["errorDetails"] = errorDetails
|
|
358
|
-
case let .snapshot(_, streaming, reconnecting, _, attempt, _):
|
|
548
|
+
case let .snapshot(_, streaming, reconnecting, _, attempt, _, _):
|
|
359
549
|
values["streaming"] = streaming
|
|
360
550
|
values["reconnecting"] = reconnecting
|
|
361
551
|
if let attempt {
|
|
@@ -390,6 +580,10 @@ public struct StreamStatusEvent: CustomStringConvertible {
|
|
|
390
580
|
status.streamId
|
|
391
581
|
}
|
|
392
582
|
|
|
583
|
+
public var resolvedConfig: StreamResolvedConfig? {
|
|
584
|
+
status.resolvedConfig
|
|
585
|
+
}
|
|
586
|
+
|
|
393
587
|
public var values: [String: Any] {
|
|
394
588
|
var values = status.values
|
|
395
589
|
values["type"] = "stream_status"
|
|
@@ -20,7 +20,7 @@ protocol ControllerManager {
|
|
|
20
20
|
|
|
21
21
|
func requestPhoto(
|
|
22
22
|
_ requestId: String, appId: String, size: String?, webhookUrl: String?, authToken: String?,
|
|
23
|
-
compress: String?, flash: Bool, sound: Bool
|
|
23
|
+
compress: String?, flash: Bool, sound: Bool, exposureTimeNs: Double?, iso: Int?
|
|
24
24
|
)
|
|
25
25
|
func startStream(_ message: [String: Any])
|
|
26
26
|
func stopStream()
|
|
@@ -153,8 +153,8 @@ extension ControllerManager {
|
|
|
153
153
|
DeviceStore.shared.get("glasses", "micEnabled") as? Bool ?? false
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
var
|
|
157
|
-
DeviceStore.shared.get("glasses", "
|
|
156
|
+
var voiceActivityDetectionEnabled: Bool {
|
|
157
|
+
DeviceStore.shared.get("glasses", "voiceActivityDetectionEnabled") as? Bool ?? true
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
var batteryLevel: Int {
|
|
@@ -499,11 +499,14 @@ class R1: NSObject, ControllerManager {
|
|
|
499
499
|
|
|
500
500
|
func sendIncidentId(_: String, apiBaseUrl _: String?) {}
|
|
501
501
|
func setMicEnabled(_: Bool) {}
|
|
502
|
-
func sortMicRanking(list: [String]) -> [String] {
|
|
502
|
+
func sortMicRanking(list: [String]) -> [String] {
|
|
503
|
+
return list
|
|
504
|
+
}
|
|
505
|
+
|
|
503
506
|
func sendJson(_: [String: Any], wakeUp _: Bool, requireAck _: Bool) {}
|
|
504
507
|
func requestPhoto(
|
|
505
508
|
_: String, appId _: String, size _: String?, webhookUrl _: String?, authToken _: String?,
|
|
506
|
-
compress _: String?, flash _: Bool, sound _: Bool
|
|
509
|
+
compress _: String?, flash _: Bool, sound _: Bool, exposureTimeNs _: Double?, iso _: Int?
|
|
507
510
|
) {}
|
|
508
511
|
func startVideoRecording(requestId _: String, save _: Bool, flash _: Bool, sound _: Bool) {}
|
|
509
512
|
func stopVideoRecording(requestId _: String) {}
|
|
@@ -518,7 +521,10 @@ class R1: NSObject, ControllerManager {
|
|
|
518
521
|
func clearDisplay() {}
|
|
519
522
|
func sendTextWall(_: String) {}
|
|
520
523
|
func sendDoubleTextWall(_: String, _: String) {}
|
|
521
|
-
func displayBitmap(base64ImageData _: String) async -> Bool {
|
|
524
|
+
func displayBitmap(base64ImageData _: String) async -> Bool {
|
|
525
|
+
return false
|
|
526
|
+
}
|
|
527
|
+
|
|
522
528
|
func showDashboard() {}
|
|
523
529
|
func setDashboardPosition(_: Int, _: Int) {}
|
|
524
530
|
func setHeadUpAngle(_: Int) {}
|
package/ios/Source/sgcs/G1.swift
CHANGED
|
@@ -278,7 +278,7 @@ class G1: NSObject, SGCManager {
|
|
|
278
278
|
|
|
279
279
|
func requestPhoto(
|
|
280
280
|
_: String, appId _: String, size _: String?, webhookUrl _: String?, authToken _: String?,
|
|
281
|
-
compress _: String?, flash _: Bool, sound _: Bool
|
|
281
|
+
compress _: String?, flash _: Bool, sound _: Bool, exposureTimeNs _: Double?, iso _: Int?
|
|
282
282
|
) {}
|
|
283
283
|
|
|
284
284
|
func startStream(_: [String: Any]) {}
|
|
@@ -1813,7 +1813,8 @@ extension G1 {
|
|
|
1813
1813
|
ctx.draw(cgImage, in: CGRect(x: offsetX, y: offsetY, width: scaledW, height: scaledH))
|
|
1814
1814
|
|
|
1815
1815
|
guard let renderedImage = ctx.makeImage(),
|
|
1816
|
-
let pixels = renderedImage.dataProvider?.data as Data?
|
|
1816
|
+
let pixels = renderedImage.dataProvider?.data as Data?
|
|
1817
|
+
else {
|
|
1817
1818
|
Bridge.log("G1: convertToG1Bmp - failed to get pixel data")
|
|
1818
1819
|
return nil
|
|
1819
1820
|
}
|
|
@@ -1850,9 +1851,9 @@ extension G1 {
|
|
|
1850
1851
|
bmp.append(contentsOf: [0xFF, 0xFF, 0xFF, 0x00]) // white
|
|
1851
1852
|
|
|
1852
1853
|
// Pixel data (bottom-up row order for BMP)
|
|
1853
|
-
for row in (0..<height).reversed() {
|
|
1854
|
+
for row in (0 ..< height).reversed() {
|
|
1854
1855
|
var rowData = [UInt8](repeating: 0, count: rowBytes)
|
|
1855
|
-
for col in 0..<width {
|
|
1856
|
+
for col in 0 ..< width {
|
|
1856
1857
|
let pixelIndex = row * width + col
|
|
1857
1858
|
let gray = pixels[pixelIndex]
|
|
1858
1859
|
if gray >= 128 {
|
package/ios/Source/sgcs/G2.swift
CHANGED
|
@@ -1454,8 +1454,7 @@ class G2: NSObject, SGCManager {
|
|
|
1454
1454
|
DeviceStore.shared.apply("glasses", "bluetoothName", btName)
|
|
1455
1455
|
DeviceStore.shared.apply("glasses", "deviceModel", DeviceTypes.G2)
|
|
1456
1456
|
|
|
1457
|
-
|
|
1458
|
-
DeviceStore.shared.apply("glasses", "fullyBooted", true)
|
|
1457
|
+
self.setFullyConnected()
|
|
1459
1458
|
|
|
1460
1459
|
// connnect a controller if we have one:
|
|
1461
1460
|
self.connectController()
|
|
@@ -2332,8 +2331,8 @@ class G2: NSObject, SGCManager {
|
|
|
2332
2331
|
if useNativeDashboard && dashboardShowing > 0 {
|
|
2333
2332
|
return
|
|
2334
2333
|
}
|
|
2335
|
-
if
|
|
2336
|
-
DeviceManager.shared.sendCurrentState()// should re-create the page if needed
|
|
2334
|
+
if !pageCreated || !pageHasTextContainer {
|
|
2335
|
+
DeviceManager.shared.sendCurrentState() // should re-create the page if needed
|
|
2337
2336
|
}
|
|
2338
2337
|
let msg = EvenHubProto.audioControlMessage(enable: true)
|
|
2339
2338
|
self.sendEvenHubCommand(msg)
|
|
@@ -2648,7 +2647,7 @@ class G2: NSObject, SGCManager {
|
|
|
2648
2647
|
|
|
2649
2648
|
func requestPhoto(
|
|
2650
2649
|
_: String, appId _: String, size _: String?, webhookUrl _: String?, authToken _: String?,
|
|
2651
|
-
compress _: String?, flash _: Bool, sound _: Bool
|
|
2650
|
+
compress _: String?, flash _: Bool, sound _: Bool, exposureTimeNs _: Double?, iso _: Int?
|
|
2652
2651
|
) {}
|
|
2653
2652
|
func startVideoRecording(requestId _: String, save _: Bool, flash _: Bool, sound _: Bool) {}
|
|
2654
2653
|
func startStream(_: [String: Any]) {}
|
|
@@ -3442,7 +3441,7 @@ class G2: NSObject, SGCManager {
|
|
|
3442
3441
|
}
|
|
3443
3442
|
// do nothing this time since we just closed the dashboard
|
|
3444
3443
|
dashboardShowing -= 1
|
|
3445
|
-
if
|
|
3444
|
+
if dashboardShowing < 0 {
|
|
3446
3445
|
dashboardShowing = 0
|
|
3447
3446
|
}
|
|
3448
3447
|
}
|
|
@@ -17,7 +17,7 @@ class Mach1: UltraliteBaseViewController, SGCManager {
|
|
|
17
17
|
|
|
18
18
|
func requestPhoto(
|
|
19
19
|
_: String, appId _: String, size _: String?, webhookUrl _: String?, authToken _: String?,
|
|
20
|
-
compress _: String?, flash _: Bool, sound _: Bool
|
|
20
|
+
compress _: String?, flash _: Bool, sound _: Bool, exposureTimeNs _: Double?, iso _: Int?
|
|
21
21
|
) {}
|
|
22
22
|
|
|
23
23
|
func sendGalleryMode() {}
|