@pbvision/partner-sdk 0.1.15 → 0.1.17

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.
Files changed (3) hide show
  1. package/README.md +33 -58
  2. package/package.json +1 -1
  3. package/src/index.js +8 -5
package/README.md CHANGED
@@ -220,25 +220,19 @@ Folders organize the videos in your partner account's library. To put a new
220
220
  video in a folder, pass the folder's ID as the `fid` [metadata](#video-metadata)
221
221
  field.
222
222
 
223
- `getOrCreateFolder()` returns the folder in your library with exactly the name
224
- you give (inside `parent`, if you pass one), creating it if there is none.
225
- Calling it again with the same name returns the same folder, as long as you
226
- haven't renamed or moved it since, so it is safe to retry. Use a unique name
227
- for each event, such as one that includes its date; otherwise two events with
228
- the same name would share one folder. Names are 1 to 200 characters, with no
229
- leading or trailing whitespace.
223
+ `getOrCreateFolder()` returns the folder with the name you give (inside
224
+ `parent`, if you pass one), creating it if needed, so it's safe to retry. Use a
225
+ unique name for each event, such as one that includes its date. Names are 1 to
226
+ 200 characters, with no leading or trailing whitespace.
230
227
 
231
228
  ```javascript
232
229
  // a folder at the top level of your library
233
- const { fid, created } = await pbv.getOrCreateFolder('Spring Open 2026-04-18');
230
+ const { fid, created } = await pbv.getOrCreateFolder('Spring Open 2026-04-18'); // created: true if new
234
231
 
235
232
  // a folder inside it
236
233
  const { fid: day1Fid } = await pbv.getOrCreateFolder('Day 1', { parent: fid });
237
234
  ```
238
235
 
239
- `created` is `true` if the call made the folder, or `false` if it already
240
- existed.
241
-
242
236
  `updateFolder()` renames a folder, moves it, or makes it public. Fields you
243
237
  leave out stay as they are:
244
238
 
@@ -249,11 +243,9 @@ await pbv.updateFolder(fid, { public: true }); // let anyone with it
249
243
  await pbv.updateFolder(day1Fid, { public: true }); // and include Day 1 when it's viewed
250
244
  ```
251
245
 
252
- Anyone with a public folder's link can view its videos, signed in to PB Vision
253
- or not. A folder inside it is only included if it is public too, so make each
254
- folder you want shared public (the folders PB Vision makes to hold the games of
255
- a multi-game video follow their parent). `getPublicFolderUrl()` gives you the
256
- link:
246
+ Anyone with a public folder's link can view its videos, signed in or not. A
247
+ folder inside it is included only if it's public too. `getPublicFolderUrl()`
248
+ gives you the link:
257
249
 
258
250
  ```javascript
259
251
  const folderUrl = pbv.getPublicFolderUrl(fid);
@@ -262,12 +254,11 @@ const folderUrl = pbv.getPublicFolderUrl(fid);
262
254
 
263
255
  ### Recording with the PB Vision app
264
256
 
265
- The PB Vision iOS and Android apps can record a game straight into your
266
- partner account. For each game, `makeRecordingLink()` makes a video with the
257
+ For each game, `makeRecordingLink()` makes a video with the
267
258
  [metadata](#video-metadata) you give it and returns a link. Opening the link on
268
259
  a phone takes the PB Vision app straight to its camera, and the recording
269
- uploads to that video. Anyone can record from the link, whether or not they
270
- are signed in to PB Vision.
260
+ uploads to that video in your partner account. Anyone can record from the link,
261
+ signed in to PB Vision or not.
271
262
 
272
263
  A typical event goes like this:
273
264
 
@@ -307,22 +298,14 @@ await pbv.updateFolder(fid, { public: true });
307
298
  const eventUrl = pbv.getPublicFolderUrl(fid);
308
299
  ```
309
300
 
310
- `makeRecordingLink()` returns the new video's `vid`, your `uid`, and the `url`
311
- to share. It takes the same metadata as the other methods except
312
- `gameStartEpoch`: the game's time comes from its recording, and a time given
313
- in advance would override it, so passing one throws an error. It also throws
314
- if the account paying for the video can't pay for it (`hasCredits` is
315
- `false`).
316
-
317
- **One link per game.** If several people may ask for the same game's link (for
318
- example, any player on the court can tap "Record"), pass a `nonce` that
319
- identifies the game, such as your own ID for it. Every call with the same nonce
320
- returns the same video and link, even calls made at the same moment, and the
321
- first call decides the video's metadata. Until the video is uploaded, each call
322
- checks that the account paying for it can still pay; a call that can't gets no
323
- video and throws, and a later call gets the same video once the account can pay.
324
- `makeVideoId()` takes a `nonce` too (it returns `hasCredits: false` instead of
325
- throwing).
301
+ `makeRecordingLink()` returns `{ vid, uid, url }`. It takes the same metadata
302
+ as the other methods except `gameStartEpoch` (the game's time comes from its
303
+ recording). It throws if the account paying for the video can't pay for it.
304
+
305
+ **One link per game.** If several people may ask for the same game's link,
306
+ pass a `nonce` that identifies the game, such as your own ID for it. Every call
307
+ with that nonce returns the same video and link, even at the same moment, and
308
+ the first call's metadata is used. `makeVideoId()` takes a `nonce` too.
326
309
 
327
310
  ```javascript
328
311
  const { url } = await pbv.makeRecordingLink({ nonce: `${eventId}-${gameId}`, fid, playersForTagging });
@@ -330,12 +313,10 @@ const { url } = await pbv.makeRecordingLink({ nonce: `${eventId}-${gameId}`, fid
330
313
 
331
314
  **Camera settings.** By default the link records at 1080p and 30 FPS, and the
332
315
  person recording can't change either. Ask for 4K with `resolution: '4k'` or
333
- 60 FPS with `fps: 60`, and let the person recording choose with
334
- `mayChangeResolution: true` and `mayChangeFPS: true`. A phone that can't record
335
- what the link asks for steps down to the best quality it supports. The link's
336
- settings apply regardless of the recorder's own PB Vision subscription, but 4K
337
- requires your partner account to have 4K enabled; otherwise PB Vision rejects
338
- the upload.
316
+ 60 FPS with `fps: 60`; with `mayChangeResolution: true` or `mayChangeFPS: true`
317
+ the person recording may choose lower settings. Phones step down to what they
318
+ support, and recorders don't need a PB Vision subscription. 4K requires your
319
+ partner account to have 4K enabled.
339
320
 
340
321
  ```javascript
341
322
  const { url } = await pbv.makeRecordingLink({
@@ -347,22 +328,16 @@ const { url } = await pbv.makeRecordingLink({
347
328
  });
348
329
  ```
349
330
 
350
- **One recording per link.** Only the first upload to a link's video counts, so
351
- make a new link for each game.
352
-
353
- **Opening the link.** The PB Vision app opens only when the phone itself opens
354
- the link: when someone taps it (in a text message or an email, for example) or
355
- scans it as a QR code with the camera, or when your own app hands it to the
356
- operating system (for example with `UIApplication.shared.open()` on iOS or an
357
- `ACTION_VIEW` intent on Android). Don't load the link inside a webview or an
358
- in-app browser, where the app may not open. On a phone without the PB Vision
359
- app, the link shows a page for installing it.
360
-
361
- **Testing.** With the test server (`useProdServer: false`), links start with
362
- `pbvision://record` instead of `https://pb.vision/record`. Any installed PB
363
- Vision app opens them, so test on a phone with a development build of the app.
364
- The App Store or Google Play app would upload the recording to production,
365
- where the test video doesn't exist, and the recording would be lost.
331
+ **One recording per link.** Only the first upload to a link's video counts.
332
+
333
+ **Opening the link.** Let the phone open the link: a tap, a scanned QR code,
334
+ or your app handing it to the operating system (`UIApplication.shared.open()`
335
+ on iOS, an `ACTION_VIEW` intent on Android). Don't load it in a webview or an
336
+ in-app browser, where the PB Vision app may not open. Without the app, the link
337
+ shows a page for installing it.
338
+
339
+ **Testing.** Links from the test server (`useProdServer: false`) start with
340
+ `pbvision://record` and need a development build of the PB Vision app.
366
341
 
367
342
  ### Video Editors and Viewers
368
343
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pbvision/partner-sdk",
3
3
  "description": "SDK for interacting with the PB Vision pickleball AI engine.",
4
- "version": "0.1.15",
4
+ "version": "0.1.17",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "engines": {
package/src/index.js CHANGED
@@ -288,10 +288,7 @@ export class PBVision {
288
288
  * inside a webview, so that the phone can open the PB Vision app.
289
289
  *
290
290
  * With the test server (`useProdServer: false`), the link starts with
291
- * `pbvision://record`. Any installed PB Vision app opens it, so test with a
292
- * development build of the app: the App Store or Google Play app would
293
- * upload the recording to production, where the test video doesn't exist,
294
- * and the recording would be lost.
291
+ * `pbvision://record` and needs a development build of the PB Vision app.
295
292
  *
296
293
  * @param {RecordingLinkOptions} [options]
297
294
  * @returns {RecordingLink}
@@ -319,9 +316,15 @@ export class PBVision {
319
316
  if (!vid) {
320
317
  throw new Error('PB Vision did not return a video ID for this recording link')
321
318
  }
319
+ // env=test lets the app explain a test-server link it can't record,
320
+ // instead of recording a game whose video exists only on the test server
321
+ const params = { vid, uid, resolution, fps, mayChangeResolution, mayChangeFPS }
322
+ if (this.isDev) {
323
+ params.env = 'test'
324
+ }
322
325
  // encodeURIComponent() rather than URLSearchParams, which writes a space
323
326
  // as "+" and not every app reads that back as a space
324
- const query = Object.entries({ vid, uid, resolution, fps, mayChangeResolution, mayChangeFPS })
327
+ const query = Object.entries(params)
325
328
  .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
326
329
  .join('&')
327
330
  return { vid, uid, url: `${this.recordUrl}?${query}` }