crowdplaysdk 0.6.0 → 0.6.2

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 CHANGED
@@ -165,6 +165,7 @@ CrowdPlay.addListener('phase', …) // idle / connecting / connected / f
165
165
  CrowdPlay.addListener('participants', …) // who to render tiles for
166
166
  CrowdPlay.addListener('uploads', …) // per-session progress
167
167
  CrowdPlay.addListener('warning', …) // micSilent / clipping / crossTalk: show these
168
+ CrowdPlay.addListener('storageWarning', …) // optional: message set = storage low (audio only or stopped)
168
169
  CrowdPlay.addListener('recording', …) // error means NOT capturing; offer retryRecording()
169
170
  CrowdPlay.addListener('audioRoute', …) // current output device, for the output menu
170
171
  CrowdPlay.setAudioOutput('speaker') // or 'automatic' (the connected device)
@@ -223,29 +224,39 @@ backend reachability and your app key. Every failing check names its own
223
224
  fix. Then record a one-minute session on a real device and confirm the
224
225
  upload finishes.
225
226
 
226
- ## Accessing your recordings
227
+ ## Checking your sessions
227
228
 
228
- Your app key is also your data-access credential: plain HTTPS, no AWS
229
+ Your app key also lists the sessions it recorded, over plain HTTPS: no AWS
229
230
  account, no SDK required.
230
231
 
231
232
  ```bash
232
- BASE=https://dashboard.crowdplay.ai
233
-
234
- curl -H "x-liva-key: $APP_KEY" $BASE/sessions
235
- curl -H "x-liva-key: $APP_KEY" $BASE/sessions/<sessionId>/files
233
+ curl -H "x-liva-key: $APP_KEY" https://dashboard.crowdplay.ai/sessions
236
234
  ```
237
235
 
238
- `deliverable/` holds what you actually use: one clean audio file per
239
- person, aligned so they play together with no offset, plus a mixed version
240
- and a quality report. You can only reach sessions recorded with your key.
236
+ Each row carries the session id, its state (`uploading`, `ok`, `partial`
237
+ or `failed`), the participants, participant minutes and any quality
238
+ warnings. You only see sessions recorded with your key, and the dashboard
239
+ shows the same list. Use it to confirm that sessions upload and render.
240
+
241
+ The recordings themselves stay in CrowdPlay's storage. There is no
242
+ download endpoint for builders: `GET /sessions/<sessionId>/files` answers
243
+ 403 to an app key, and the dashboard does not offer downloads either.
241
244
 
242
245
  ## Things to know
243
246
 
244
247
  - **Don't force-quit the app** after a session: iOS pauses background
245
248
  transfers until next launch. They resume automatically and nothing is
246
249
  lost.
247
- - Sessions are roughly 2 GB per participant-hour, dominated by video. The
248
- SDK refuses to join below 8 GB free disk.
250
+ - With video, a session uses about 6.8 GB per participant-hour on the phone
251
+ (1080p HEVC at 14 Mbps plus 24-bit audio); audio-only is about 0.5 GB.
252
+ Files are deleted as each one uploads. Video waits for WiFi, so on
253
+ cellular it stays on the phone until then. The SDK never fills the phone
254
+ (0.6.2+, engine 0.5.4): under 2 GB free the recording continues audio
255
+ only, under 500 MB it stops, and the call itself always continues. This
256
+ happens silently: the SDK shows nothing on screen. The `storageWarning`
257
+ event says when it happens, if you want to ask the user to free up space.
258
+ `doctor()` also checks free disk (8 GiB by default); joining never
259
+ refuses for storage.
249
260
  - Participants should wear **wired or closed-back headphones**. A
250
261
  loudspeaker pipes the far end into the local mic and contaminates the
251
262
  track; the SDK surfaces this live through the `warning` event.
@@ -63,6 +63,15 @@ final class CrowdPlayRNCore {
63
63
  ])
64
64
  }.store(in: &cancellables)
65
65
 
66
+ // Storage (D-148): its own event, not a 'warning' kind, so an app
67
+ // that renders every warning does not start showing it. Sent on
68
+ // every change, since the text moves from audio-only to stopped.
69
+ engine.$storageWarning
70
+ .removeDuplicates()
71
+ .sink { [weak self] message in
72
+ self?.send("crowdplay:storageWarning", ["message": message as Any])
73
+ }.store(in: &cancellables)
74
+
66
75
  engine.$uploads
67
76
  .combineLatest(engine.$uploadsOnWiFi)
68
77
  .sink { [weak self] uploads, onWifi in
@@ -231,7 +240,7 @@ public final class CrowdPlayRNModule: RCTEventEmitter {
231
240
  public override static func requiresMainQueueSetup() -> Bool { true }
232
241
 
233
242
  public override func supportedEvents() -> [String]! {
234
- ["crowdplay:phase", "crowdplay:recording", "crowdplay:uploads", "crowdplay:participants", "crowdplay:warning", "crowdplay:audioRoute", "crowdplay:voiceActivity", "crowdplay:caption", "crowdplay:agentToolCall"]
243
+ ["crowdplay:phase", "crowdplay:recording", "crowdplay:uploads", "crowdplay:participants", "crowdplay:warning", "crowdplay:storageWarning", "crowdplay:audioRoute", "crowdplay:voiceActivity", "crowdplay:caption", "crowdplay:agentToolCall"]
235
244
  }
236
245
 
237
246
  @objc public func startVoiceActivityUpdates() {
package/ios/wire.rb CHANGED
@@ -30,7 +30,8 @@ SDK_URL = 'https://github.com/symbiateam/crowdplaysdk'
30
30
  # D-103 the bridge calls 0.5.0 APIs, and npm 0.5.0 to 0.5.2 shipped with
31
31
  # this still at 0.4.0, which broke every install (D-121). publish_rn.sh now
32
32
  # compiles the bridge against exactly this release before publishing.
33
- SDK_VERSION = '0.5.2'
33
+ # 0.5.4: the storage guard and engine.storageWarning (D-148).
34
+ SDK_VERSION = '0.5.4'
34
35
  BRIDGE_FILES = ['CrowdPlayRNModule.swift', 'CrowdPlayRNVideoView.swift', 'CrowdPlayReactNative.m'].freeze
35
36
 
36
37
  project_name = ARGV[0] or abort 'usage: ruby wire.rb <YourProjectName>'
package/lib/index.d.ts CHANGED
@@ -62,7 +62,7 @@ export interface CrowdPlayConfig {
62
62
  }
63
63
  /** The CrowdPlay Terms of Use and Privacy Notice every participant accepts,
64
64
  * as a PDF. CrowdPlayConsentScreen links here; a custom consent UI must too. */
65
- export declare const CROWDPLAY_TERMS_URL = "https://dashboard.crowdplay.ai/legal/terms.pdf";
65
+ export declare const CROWDPLAY_TERMS_URL = "https://www.crowdplay.ai/legal/consumer-terms";
66
66
  /** Proof the participant agreed. Produce it with CrowdPlayConsentScreen, or,
67
67
  * if you render your own consent UI, call CrowdPlay.consentText() to show the
68
68
  * REQUIRED wording and construct the grant at the moment of agreement. */
@@ -177,6 +177,14 @@ export interface CrowdPlayEvents {
177
177
  active: boolean;
178
178
  message: string;
179
179
  };
180
+ /** This iPhone is running out of storage (D-148): under 2 GB free the
181
+ * recording continues audio only, under 500 MB it stops; the call always
182
+ * continues. `message` is null when storage is fine. The SDK shows
183
+ * nothing on screen; listening is optional. Separate from `warning` so
184
+ * apps that render every warning do not start showing it. */
185
+ storageWarning: {
186
+ message: string | null;
187
+ };
180
188
  /** The audio output route: current device by name ("AirPods Pro",
181
189
  * "iPhone speaker"), connected candidates, and whether headphones are
182
190
  * attached. Drive the call screen's output menu from this (D-079). */
package/lib/index.js CHANGED
@@ -26,7 +26,7 @@ exports.useLatestCaption = exports.useVoiceActivity = exports.VoiceReactive = ex
26
26
  const react_native_1 = require("react-native");
27
27
  /** The CrowdPlay Terms of Use and Privacy Notice every participant accepts,
28
28
  * as a PDF. CrowdPlayConsentScreen links here; a custom consent UI must too. */
29
- exports.CROWDPLAY_TERMS_URL = 'https://dashboard.crowdplay.ai/legal/terms.pdf';
29
+ exports.CROWDPLAY_TERMS_URL = 'https://www.crowdplay.ai/legal/consumer-terms';
30
30
  function native() {
31
31
  const module = react_native_1.NativeModules.CrowdPlayReactNative;
32
32
  if (!module) {
package/llms.txt CHANGED
@@ -141,11 +141,6 @@ BARE REACT NATIVE (no Expo):
141
141
  detail names its own fix. NOTE: on a fresh install the "permissions"
142
142
  check reports "not requested yet (NORMAL)"; iOS prompts at first join.
143
143
  That is not an integration bug; only a DENIED state needs action.
144
- KNOWN ENGINE BUG: on engine 0.5.1 and 0.5.2 the "consent_terms" check
145
- fails on every device (the engine's own hash bookkeeping, fixed in
146
- engine 0.5.3 / crowdplaysdk 0.6.1). Nothing in your app causes it and
147
- nothing in your app fixes it; the consent screen and the recorded
148
- consent are correct. Every other check in that run is valid.
149
144
  11. Hand off (REQUIRED final message): the Simulator has no camera or
150
145
  mic, so nothing is proven until the app runs on a real iPhone. Do
151
146
  not end with "the implementation is complete"; your FINAL message
@@ -329,22 +324,40 @@ Events (CrowdPlay.addListener):
329
324
  // mic; crossTalk = loudspeaker leaking the far end into
330
325
  // this mic (wear headphones); micPolicy = unexpected
331
326
  // input device.
327
+ 'storageWarning' { message: string | null }
328
+ // 0.6.2+: non-null = the phone is low on storage: under
329
+ // 2 GB free the recording is audio only, under 500 MB it
330
+ // stopped. The call continues. The SDK shows nothing
331
+ // itself; listening is optional. Kept out of 'warning' so
332
+ // apps that render every warning do not show it.
332
333
 
333
- ## Accessing recordings (no AWS, no SDK, plain HTTPS)
334
+ ## Checking sessions (no AWS, no SDK, plain HTTPS)
334
335
 
335
- The app key doubles as the data credential:
336
+ The app key lists the sessions it recorded, metadata only:
336
337
  GET https://dashboard.crowdplay.ai/sessions (x-liva-key header)
337
- GET https://dashboard.crowdplay.ai/sessions/<id>/files (x-liva-key header)
338
- -> [{path, bytes, url}] // url = 1-hour presigned download
339
- deliverable/ holds the usable output: speaker-<name>.wav per participant
340
- (drift-corrected; all files play together with NO offset),
341
- conversation.wav, qc.json. raw/ is the untouched per-device capture.
342
- Humans use https://dashboard.crowdplay.ai directly (sign in, download).
338
+ -> [{sessionId, state ("uploading"|"ok"|"partial"|"failed"),
339
+ participants, participantMinutes, warnings, warningNotes,
340
+ uploadedAt}]
341
+ A key sees only its own app's sessions; `state: "ok"` proves the
342
+ integration works end to end. The dashboard shows the same list.
343
+
344
+ Recordings NEVER leave CrowdPlay's storage. There is no download endpoint
345
+ for builders: GET /sessions/<id>/files answers 403 to an app key and to
346
+ dashboard accounts, and the dashboard has no download button. Do NOT
347
+ build any feature that fetches, plays, shows, or analyses a recording
348
+ after the session; the app has no way to obtain one. During the session
349
+ the app can use the `caption` event (voice-AI transcript lines) and
350
+ `snapshot()` (capture health).
343
351
 
344
352
  ## Facts, limits, troubleshooting
345
353
 
346
- - iOS 17+, React Native >= 0.71. Storage ~2 GB per participant-hour;
347
- join refuses below 8 GB free.
354
+ - iOS 17+, React Native >= 0.71. Storage ~6.8 GB per participant-hour with
355
+ video, ~0.5 GB audio-only (deleted as files upload; video waits for WiFi,
356
+ so on cellular it stays on the phone until then). The SDK never fills the
357
+ phone (0.6.2+): under 2 GB free the recording continues audio only, under
358
+ 500 MB it stops, the call always continues, silently ('storageWarning'
359
+ says so if you listen). doctor() also checks free disk (8 GiB default);
360
+ join never refuses for storage.
348
361
  - Keep the screen awake during sessions (e.g. react-native-keep-awake or
349
362
  the idle-timer API); a locked phone suspends capture. Force-quitting
350
363
  pauses uploads until next launch (nothing lost).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crowdplaysdk",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "CrowdPlay lossless conversation capture for React Native (iOS). Studio-grade per-participant recording during live video calls, delivered to CrowdPlay automatically.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
package/src/index.ts CHANGED
@@ -71,7 +71,7 @@ export interface CrowdPlayConfig {
71
71
 
72
72
  /** The CrowdPlay Terms of Use and Privacy Notice every participant accepts,
73
73
  * as a PDF. CrowdPlayConsentScreen links here; a custom consent UI must too. */
74
- export const CROWDPLAY_TERMS_URL = 'https://dashboard.crowdplay.ai/legal/terms.pdf';
74
+ export const CROWDPLAY_TERMS_URL = 'https://www.crowdplay.ai/legal/consumer-terms';
75
75
 
76
76
  /** Proof the participant agreed. Produce it with CrowdPlayConsentScreen, or,
77
77
  * if you render your own consent UI, call CrowdPlay.consentText() to show the
@@ -180,6 +180,12 @@ export interface CrowdPlayEvents {
180
180
  * micSilent (dead mic), clipping (too-hot mic), crossTalk (loudspeaker
181
181
  * leaking the far end into this mic), micPolicy (unexpected input). */
182
182
  warning: { kind: 'audioStalled' | 'micSilent' | 'clipping' | 'crossTalk' | 'micPolicy'; active: boolean; message: string };
183
+ /** This iPhone is running out of storage (D-148): under 2 GB free the
184
+ * recording continues audio only, under 500 MB it stops; the call always
185
+ * continues. `message` is null when storage is fine. The SDK shows
186
+ * nothing on screen; listening is optional. Separate from `warning` so
187
+ * apps that render every warning do not start showing it. */
188
+ storageWarning: { message: string | null };
183
189
  /** The audio output route: current device by name ("AirPods Pro",
184
190
  * "iPhone speaker"), connected candidates, and whether headphones are
185
191
  * attached. Drive the call screen's output menu from this (D-079). */