@pbvision/partner-sdk 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -29
- package/package.json +5 -2
- package/src/index.js +6 -5
- package/src/video-object-name.js +4 -1
package/README.md
CHANGED
|
@@ -4,24 +4,43 @@ The easiest way to use the PB Vision AI Engine is to simply share a link to
|
|
|
4
4
|
your video file. Our AI usually works on each video for about an hour for a
|
|
5
5
|
standard length game, so we'll notify your servers when the results are ready.
|
|
6
6
|
|
|
7
|
-
- [
|
|
7
|
+
- [Installation](#installation)
|
|
8
8
|
- [Step 1: Get API Access](#step-1-get-api-access)
|
|
9
|
-
- [Step 2:
|
|
10
|
-
|
|
9
|
+
- [Step 2: SDK Setup](#step-2-sdk-setup)
|
|
10
|
+
- [Using the API](#using-the-api)
|
|
11
|
+
- [Webhook Setup](#webhook-setup)
|
|
12
|
+
- [Send Videos](#send-videos)
|
|
11
13
|
- [Option 1: PBV Downloads your video from a URL](#option-1-pbv-downloads-your-video-from-a-url)
|
|
12
14
|
- [Option 2: Upload your video](#option-2-upload-your-video)
|
|
13
|
-
|
|
14
|
-
- [SDK Setup](#sdk-setup)
|
|
15
|
+
- [After Video Processing is Done](#after-video-processing-is-done)
|
|
15
16
|
- [Video Guidelines](#video-guidelines)
|
|
17
|
+
- [Reference Guide](#reference-guide)
|
|
16
18
|
|
|
17
|
-
##
|
|
19
|
+
## Installation
|
|
18
20
|
|
|
19
21
|
### Step 1: Get API Access
|
|
20
22
|
|
|
21
23
|
Email **[dev@pb.vision](mailto:dev@pb.vision)** to request API access for your
|
|
22
24
|
account. We'll send you an API Key.
|
|
23
25
|
|
|
24
|
-
### Step 2:
|
|
26
|
+
### Step 2: SDK Setup
|
|
27
|
+
|
|
28
|
+
1. Install [node](https://nodejs.org/en/download)
|
|
29
|
+
2. Install the SDK: `npm i @pbvision/partner-sdk`
|
|
30
|
+
3. In your package.json, make sure you're configured to use ESM (modules): `"type": "module"`
|
|
31
|
+
4. Initialize the SDK:
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
import { PBVision } from '@pbvision/partner-sdk'
|
|
35
|
+
const pbv = new PBVision(YOUR_API_KEY)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
5. Use its methods as described to [send us video URLs](#send-videos) to
|
|
39
|
+
to process, or [tell us your webhook's URL](#webhook-setup).
|
|
40
|
+
|
|
41
|
+
## Using the API
|
|
42
|
+
|
|
43
|
+
### Webhook Setup
|
|
25
44
|
|
|
26
45
|
Each time our AI finishes processing a video, it will notify your servers via
|
|
27
46
|
an HTTP POST request to a URL ("webhook") of your choice. You can use our SDK
|
|
@@ -44,7 +63,7 @@ curl -X POST \
|
|
|
44
63
|
https://api-ko3kowqi6a-uc.a.run.app/partner/webhook/set
|
|
45
64
|
```
|
|
46
65
|
|
|
47
|
-
###
|
|
66
|
+
### Send Videos
|
|
48
67
|
|
|
49
68
|
#### Option 1: PBV Downloads your video from a URL
|
|
50
69
|
|
|
@@ -57,8 +76,14 @@ Next, tell us to download and work on the video. You can do this using our SDK:
|
|
|
57
76
|
import { PBVision } from '@pbvision/partner-sdk'
|
|
58
77
|
|
|
59
78
|
const pbv = new PBVision(YOUR_API_KEY)
|
|
60
|
-
|
|
61
|
-
|
|
79
|
+
// you can omit this metadata, or provide some or all of this object-- whatever you'd like!
|
|
80
|
+
const optionalMetadata = {
|
|
81
|
+
userEmails: [],
|
|
82
|
+
name: 'Dink Championship 2024',
|
|
83
|
+
desc: 'A longer description, if you want',
|
|
84
|
+
gameStartEpoch: 1711393200 // when the game was played
|
|
85
|
+
}
|
|
86
|
+
await pbv.sendVideoUrlToDownload(YOUR_VIDEO_URL, optionalMetadata)
|
|
62
87
|
```
|
|
63
88
|
|
|
64
89
|
Alternatively, you can just use `curl`:
|
|
@@ -79,7 +104,7 @@ You can directly upload your video from a file using the SDK too:
|
|
|
79
104
|
import { PBVision } from '@pbvision/partner-sdk'
|
|
80
105
|
|
|
81
106
|
const pbv = new PBVision(YOUR_API_KEY)
|
|
82
|
-
// you can omit this metadata, or provide
|
|
107
|
+
// you can omit this metadata, or provide some or all of this object-- whatever you'd like!
|
|
83
108
|
const optionalMetadata = {
|
|
84
109
|
userEmails: [],
|
|
85
110
|
name: 'Dink Championship 2024',
|
|
@@ -89,12 +114,12 @@ const optionalMetadata = {
|
|
|
89
114
|
await pbv.uploadVideo(YOUR_VIDEO_FILENAME, optionalMetadata)
|
|
90
115
|
```
|
|
91
116
|
|
|
92
|
-
|
|
117
|
+
## After Video Processing is Done
|
|
93
118
|
|
|
94
119
|
When our AI is done processing your video, we will email the players in the
|
|
95
120
|
game (_if_ their email addresses were provided).
|
|
96
121
|
|
|
97
|
-
If you provided a webhook
|
|
122
|
+
If you [provided a webhook](#webhook-setup), then we'll send
|
|
98
123
|
an HTTP POST request to your server. Your server should acknowledge this
|
|
99
124
|
callback with a standard 200 (OK) response. If it does not, we will attempt to
|
|
100
125
|
retry sending this request later (up to some maximum number of attempts).
|
|
@@ -113,7 +138,7 @@ The HTTP POST body will contain JSON which looks like this:
|
|
|
113
138
|
}
|
|
114
139
|
```
|
|
115
140
|
|
|
116
|
-
- `from_url` is the video url you sent us in [step 3](#
|
|
141
|
+
- `from_url` is the video url you sent us in [step 3](#send-videos)
|
|
117
142
|
- `webpage` is a link to our web app where the stats can be explored
|
|
118
143
|
- `error` is only present if your video could not be processed
|
|
119
144
|
- `events` - describes the pickleball game in detailed, low-level events
|
|
@@ -123,21 +148,6 @@ The HTTP POST body will contain JSON which looks like this:
|
|
|
123
148
|
- Explore the _insights_ schema at <https://pbv-public.github.io/insights/dev>
|
|
124
149
|
- Schema changes and diffs are in our [`pbv-public/insights` repo](https://github.com/pbv-public/insights/blob/dev/CHANGELOG.md)
|
|
125
150
|
|
|
126
|
-
## SDK Setup
|
|
127
|
-
|
|
128
|
-
1. Install [node](https://nodejs.org/en/download)
|
|
129
|
-
2. Install the SDK: `npm i @pbvision/partner-sdk`
|
|
130
|
-
3. In your package.json, make sure you're configured to use ESM (modules): `"type": "module"`
|
|
131
|
-
4. Initialize the SDK:
|
|
132
|
-
|
|
133
|
-
```javascript
|
|
134
|
-
import { PBVision } from '@pbvision/partner-sdk'
|
|
135
|
-
const pbv = new PBVision(YOUR_API_KEY)
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
5. Use its methods as described to [send us video URLs](#step-3-send-videos) to
|
|
139
|
-
to process, or [tell us your webhook's URL](#step-2-webhook-setup).
|
|
140
|
-
|
|
141
151
|
## Video Guidelines
|
|
142
152
|
|
|
143
153
|
Requirements:
|
|
@@ -154,3 +164,7 @@ For best results, we also recommend:
|
|
|
154
164
|
- Max bitrate: 2 Mbps
|
|
155
165
|
- Max file size: 1GB
|
|
156
166
|
- Max duration: 30 minutes
|
|
167
|
+
|
|
168
|
+
## Reference Guide
|
|
169
|
+
|
|
170
|
+
- [JSDocs](https://pbv-public.github.io/partner-sdk-nodejs/)
|
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.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -18,5 +18,8 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"node-fetch": "^3.3.2"
|
|
20
20
|
},
|
|
21
|
-
"devDependencies": {
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"jsdoc": "3.6.4",
|
|
23
|
+
"tui-jsdoc-template": "^1.2.2"
|
|
24
|
+
}
|
|
22
25
|
}
|
package/src/index.js
CHANGED
|
@@ -43,14 +43,15 @@ export class PBVision {
|
|
|
43
43
|
* processing is complete, your webhook URL will receive a callback.
|
|
44
44
|
*
|
|
45
45
|
* @param {string} videoUrl the publicly available URL of the video
|
|
46
|
-
* @param {
|
|
47
|
-
* this video; they'll be notified when the video is done processing
|
|
46
|
+
* @param {VideoMetadata} [metadata]
|
|
48
47
|
*/
|
|
49
|
-
async sendVideoUrlToDownload (videoUrl, userEmails = []) {
|
|
48
|
+
async sendVideoUrlToDownload (videoUrl, { userEmails = [], name, desc, gameStartEpoch } = {}) {
|
|
50
49
|
assert(typeof videoUrl === 'string' && videoUrl.startsWith('http'),
|
|
51
50
|
'URL must be a string beginning with http')
|
|
52
|
-
assert(videoUrl.endsWith('.mp4'), 'video URL must have the .mp4 extension')
|
|
53
|
-
this.__callAPI(
|
|
51
|
+
assert(videoUrl.split('?')[0].endsWith('.mp4'), 'video URL must have the .mp4 extension')
|
|
52
|
+
this.__callAPI(
|
|
53
|
+
'add_video_by_url',
|
|
54
|
+
{ url: videoUrl, userEmails, name, desc, gameStartEpoch })
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
async __callAPI (path, body) {
|
package/src/video-object-name.js
CHANGED
|
@@ -16,7 +16,7 @@ import crypto from 'node:crypto'
|
|
|
16
16
|
* @param {string} [opts.fileExt] the video's file extension
|
|
17
17
|
* @param {string} [opts.bucket] the GCS bucket to upload to
|
|
18
18
|
* @returns {string} the signed GCS object filename
|
|
19
|
-
* @
|
|
19
|
+
* @protected
|
|
20
20
|
*/
|
|
21
21
|
export function makeSignedGoogleCloudStorageVideoObjectName ({
|
|
22
22
|
uploaderUID,
|
|
@@ -37,6 +37,7 @@ export function makeSignedGoogleCloudStorageVideoObjectName ({
|
|
|
37
37
|
*
|
|
38
38
|
* The hash includes all elements of the file's unique path (including the
|
|
39
39
|
* bucket) except for the hash itself.
|
|
40
|
+
* @private
|
|
40
41
|
*/
|
|
41
42
|
function getHash (uploaderUID, signingKey, uploadId, fileExt, bucket) {
|
|
42
43
|
const nameWithEmptyHash = makeObjectNameGivenHash(
|
|
@@ -48,6 +49,7 @@ function getHash (uploaderUID, signingKey, uploadId, fileExt, bucket) {
|
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
51
|
* Returns the full GCS object name (including hash) for the given parameters.
|
|
52
|
+
* @private
|
|
51
53
|
*/
|
|
52
54
|
function makeObjectName (uploaderUID, signingKey, uploadId, fileExt, bucket) {
|
|
53
55
|
const hash = getHash(uploaderUID, signingKey, uploadId, fileExt, bucket)
|
|
@@ -58,6 +60,7 @@ function makeObjectName (uploaderUID, signingKey, uploadId, fileExt, bucket) {
|
|
|
58
60
|
|
|
59
61
|
/**
|
|
60
62
|
* Returns the full GCS object name using the specified hash string.
|
|
63
|
+
* @private
|
|
61
64
|
*/
|
|
62
65
|
function makeObjectNameGivenHash (uploaderUID, uploadId, fileExt, hash) {
|
|
63
66
|
assert(uploaderUID.indexOf('/') === -1)
|