Skip to content

Commit 41e571c

Browse files
Merge pull request #7 from apivideo/progressive-upload
feat: Progressive uploads
2 parents 3089979 + 7217e1b commit 41e571c

18 files changed

+2632
-8297
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog
22
All changes to this project will be documented in this file.
33

4+
## [0.0.6] - 2021-11-10
5+
- Add progressive upload feature
6+
47
## [0.0.5] - 2021-08-12
58
- Fix chunk size (default 50MB, min 5MB, max 128MB)
69
- Fix upload progress listener

README.md

Lines changed: 142 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
[![badge](https://img.shields.io/twitter/follow/api_video?style=social)](https://twitter.com/intent/follow?screen_name=api_video)
22

3-
[![badge](https://img.shields.io/github/stars/apivideo/typescript-video-uploader?style=social)](https://github.com/apivideo/typescript-video-uploader)
3+
[![badge](https://img.shields.io/github/stars/apivideo/php-api-client?style=social)](https://github.com/apivideo/php-api-client)
44

55
[![badge](https://img.shields.io/discourse/topics?server=https%3A%2F%2Fcommunity.api.video)](https://community.api.video)
66

77
![](https://github.com/apivideo/API_OAS_file/blob/master/apivideo_banner.png)
88

9-
api.video is an API that encodes on the go to facilitate immediate playback, enhancing viewer streaming experiences across multiple devices and platforms. You can stream live or on-demand online videos within minutes.
9+
[api.video](https://api.video) is an API that encodes on the go to facilitate immediate playback, enhancing viewer streaming experiences across multiple devices and platforms. You can stream live or on-demand online videos within minutes.
1010

11-
# api.video video uploader
11+
# api.video typescript video uploader
1212
![npm](https://img.shields.io/npm/v/@api.video/video-uploader) ![ts](https://badgen.net/badge/-/TypeScript/blue?icon=typescript&label)
1313

14-
Typescript library to upload videos to api.video using delegated upload token (or usual access token) from the front-end.
14+
Typescript library to upload videos to api.video using delegated upload token (or usual access token) from the front-end.
1515

16-
# Usage
16+
It allows you to upload videos in two ways:
17+
- standard upload: to send a whole video file in one go
18+
- progressive upload: to send a video file by chunks, without needing to know the final size of the video file
19+
20+
21+
# Installation
1722

1823
## Installation method #1: requirejs
1924

@@ -26,12 +31,18 @@ $ npm install --save @api.video/video-uploader
2631
You can then use the library in your script:
2732

2833
```javascript
34+
// standard upload:
2935
var { VideoUploader } = require('@api.video/video-uploader');
3036

3137
var uploader = new VideoUploader({
32-
file: files[0],
33-
uploadToken: "YOUR_DELEGATED_TOKEN"
34-
// ... other optional options
38+
// ... (see bellow)
39+
});
40+
41+
// progressive upload:
42+
var { ProgressiveUploader } = require('@api.video/video-uploader');
43+
44+
var uploader = new ProgressiveUploader({
45+
// ... (see bellow)
3546
});
3647
```
3748

@@ -46,12 +57,18 @@ $ npm install --save @api.video/video-uploader
4657
You can then use the library in your script:
4758

4859
```typescript
60+
// standard upload:
4961
import { VideoUploader } from '@api.video/video-uploader'
5062

5163
const uploader = new VideoUploader({
52-
file: files[0],
53-
uploadToken: "YOUR_DELEGATED_TOKEN"
54-
// ... other optional options
64+
// ... (see bellow)
65+
});
66+
67+
// progressive upload:
68+
import { ProgressiveUploader } from '@api.video/video-uploader'
69+
70+
const uploader = new ProgressiveUploader({
71+
// ... (see bellow)
5572
});
5673
```
5774

@@ -83,13 +100,15 @@ Then, once the `window.onload` event has been trigered, create your player using
83100
</script>
84101
```
85102

86-
# Instanciation
103+
# Usage - Standard upload
104+
105+
## Instanciation
87106

88-
## Options
107+
### Options
89108

90109
The upload library is instanciated using an `options` object. Options to provide depend on the way you want to authenticate to the API: either using a delegated upload token (recommanded), or using a usual access token.
91110

92-
### Using a delegated upload token (recommended):
111+
#### Using a delegated upload token (recommended):
93112

94113
Using delegated upload tokens for authentication is best options when uploading from the client side. To know more about delegated upload token, read the dedicated article on api.video's blog: [Delegated Uploads](https://api.video/blog/tutorials/delegated-uploads).
95114

@@ -100,7 +119,7 @@ Using delegated upload tokens for authentication is best options when uploading
100119
| videoId | no | string | id of an existing video |
101120
| _common options (see bellow)_ | | | |
102121

103-
### Using an access token (discouraged):
122+
#### Using an access token (discouraged):
104123

105124
**Warning**: be aware that exposing your access token client-side can lead to huge security issues. Use this method only if you know what you're doing :).
106125

@@ -112,7 +131,7 @@ Using delegated upload tokens for authentication is best options when uploading
112131
| _common options (see bellow)_ | | | |
113132

114133

115-
### Common options
134+
#### Common options
116135

117136

118137
| Option name | Mandatory | Type | Description |
@@ -123,7 +142,7 @@ Using delegated upload tokens for authentication is best options when uploading
123142
| retries | no | number | number of retries when an API call fails (default: 5) |
124143

125144

126-
## Example
145+
### Example
127146

128147
```javascript
129148
const uploader = new VideoUploader({
@@ -134,15 +153,15 @@ Using delegated upload tokens for authentication is best options when uploading
134153
});
135154
```
136155

137-
# Methods
156+
## Methods
138157

139-
## `upload()`
158+
### `upload()`
140159

141160
The upload() method starts the upload. It takes no parameter. It returns a Promise that resolves once the file is uploaded. If an API call fails more than the specified number of retries, then the promise is rejected.
142161
On success, the promise embeds the `video` object returned by the API.
143162
On fail, the promise embeds the status code & error message returned by the API.
144163

145-
### Example
164+
#### Example
146165

147166
```javascript
148167
// ... uploader instanciation
@@ -152,7 +171,7 @@ On fail, the promise embeds the status code & error message returned by the API.
152171
.catch((error) => console.log(error.status, error.message));
153172
```
154173

155-
## `onProgress()`
174+
### `onProgress()`
156175

157176
The onProgress() method let you defined an upload progress listener. It takes a callback function with one parameter: the onProgress events.
158177
An onProgress event contains the following attributes:
@@ -163,7 +182,7 @@ An onProgress event contains the following attributes:
163182
- currentChunk (number): index of the chunk being uploaded
164183
- currentChunkUploadedBytes (number): number of bytes uploaded for the current chunk
165184

166-
### Example
185+
#### Example
167186

168187
```javascript
169188
// ... uploader instanciation
@@ -177,3 +196,104 @@ An onProgress event contains the following attributes:
177196
console.log(`number of bytes uploaded for the current chunk: ${event.currentChunkUploadedBytes}.`);
178197
});
179198
```
199+
200+
# Usage - Progressive upload
201+
202+
203+
## Instanciation
204+
205+
### Options
206+
207+
The progressive upload object is instanciated using an `options` object. Options to provide depend on the way you want to authenticate to the API: either using a delegated upload token (recommanded), or using a usual access token.
208+
209+
#### Using a delegated upload token (recommended):
210+
211+
Using delegated upload tokens for authentication is best options when uploading from the client side. To know more about delegated upload token, read the dedicated article on api.video's blog: [Delegated Uploads](https://api.video/blog/tutorials/delegated-uploads).
212+
213+
214+
| Option name | Mandatory | Type | Description |
215+
| ----------------------------: | --------- | ------ | ----------------------- |
216+
| uploadToken | **yes** | string | your upload token |
217+
| videoId | no | string | id of an existing video |
218+
| _common options (see bellow)_ | | | |
219+
220+
#### Using an access token (discouraged):
221+
222+
**Warning**: be aware that exposing your access token client-side can lead to huge security issues. Use this method only if you know what you're doing :).
223+
224+
225+
| Option name | Mandatory | Type | Description |
226+
| ----------------------------: | --------- | ------ | ----------------------- |
227+
| accessToken | **yes** | string | your access token |
228+
| videoId | **yes** | string | id of an existing video |
229+
| _common options (see bellow)_ | | | |
230+
231+
232+
#### Common options
233+
234+
235+
| Option name | Mandatory | Type | Description |
236+
| ----------: | --------- | ------ | -------------------------------------------------------------------------- |
237+
| apiHost | no | string | api.video host (default: ws.api.video) |
238+
| retries | no | number | number of retries when an API call fails (default: 5) |
239+
240+
241+
### Example
242+
243+
```javascript
244+
const uploader = new ProgressiveUploader({
245+
uploadToken: "YOUR_DELEGATED_TOKEN",
246+
retries: 10,
247+
});
248+
```
249+
250+
## Methods
251+
252+
### `uploadPart(file: Blob)`
253+
254+
The upload() method starts the upload. It takes no parameter. It returns a Promise that resolves once the file is uploaded. If an API call fails more than the specified number of retries, then the promise is rejected.
255+
On success, the promise embeds the `video` object returned by the API.
256+
On fail, the promise embeds the status code & error message returned by the API.
257+
258+
#### Example
259+
260+
```javascript
261+
// ... uploader instanciation
262+
263+
uploader.uploadPart(blob)
264+
.catch((error) => console.log(error.status, error.message));
265+
```
266+
267+
### `uploadLastPart(file: Blob)`
268+
269+
The upload() method starts the upload. It takes no parameter. It returns a Promise that resolves once the file is uploaded. If an API call fails more than the specified number of retries, then the promise is rejected.
270+
On success, the promise embeds the `video` object returned by the API.
271+
On fail, the promise embeds the status code & error message returned by the API.
272+
273+
#### Example
274+
275+
```javascript
276+
// ... uploader instanciation
277+
278+
uploader.uploadLastPart(blob)
279+
.then((video) => console.log(video))
280+
.catch((error) => console.log(error.status, error.message));
281+
```
282+
283+
### `onProgress()`
284+
285+
The onProgress() method let you defined an upload progress listener. It takes a callback function with one parameter: the onProgress events.
286+
An onProgress event contains the following attributes:
287+
- uploadedBytes (number): total number of bytes uploaded for this upload
288+
- totalBytes (number): total size of the file
289+
290+
#### Example
291+
292+
```javascript
293+
// ... uploader instanciation
294+
295+
uploader.onProgress((event) => {
296+
console.log(`total number of bytes uploaded for this upload: ${event.uploadedBytes}.`);
297+
console.log(`total size of the file: ${event.totalBytes}.`);
298+
});
299+
```

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/src/common.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export declare const MIN_CHUNK_SIZE: number;
2+
export declare const DEFAULT_CHUNK_SIZE: number;
3+
export declare const MAX_CHUNK_SIZE: number;
4+
export declare const DEFAULT_RETRIES = 5;
5+
export declare const DEFAULT_API_HOST = "ws.api.video";

dist/src/index.d.ts

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,3 @@
1-
interface OptionsWithUploadToken extends Options {
2-
uploadToken: string;
3-
videoId?: string;
4-
}
5-
interface OptionsWithAccessToken extends Options {
6-
accessToken: string;
7-
videoId: string;
8-
}
9-
interface Options {
10-
file: File;
11-
chunkSize?: number;
12-
apiHost?: string;
13-
retries?: number;
14-
}
15-
export interface UploadProgressEvent {
16-
uploadedBytes: number;
17-
totalBytes: number;
18-
chunksCount: number;
19-
chunksBytes: number;
20-
currentChunk: number;
21-
currentChunkUploadedBytes: number;
22-
}
23-
export declare class VideoUploader {
24-
private file;
25-
private chunkSize;
26-
private uploadEndpoint;
27-
private currentChunk;
28-
private chunksCount;
29-
private fileSize;
30-
private fileName;
31-
private videoId?;
32-
private retries;
33-
private onProgressCallbacks;
34-
private headers;
35-
constructor(options: OptionsWithAccessToken | OptionsWithUploadToken);
36-
onProgress(cb: (e: UploadProgressEvent) => void): void;
37-
upload(): Promise<any>;
38-
private sleep;
39-
private createFormData;
40-
private uploadCurrentChunk;
41-
}
42-
export {};
1+
export { UploadProgressEvent, VideoUploader, VideoUploaderOptionsWithAccessToken, VideoUploaderOptionsWithUploadToken } from "./video-uploader";
2+
export { ProgressiveUploadProgressEvent, ProgressiveUploader, ProgressiveUploaderOptionsWithAccessToken, ProgressiveUploaderOptionsWithUploadToken } from './progressive-video-uploader';
3+
export { MIN_CHUNK_SIZE, MAX_CHUNK_SIZE } from './common';
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export interface ProgressiveUploaderOptionsWithUploadToken extends Options {
2+
uploadToken: string;
3+
videoId?: string;
4+
}
5+
export interface ProgressiveUploaderOptionsWithAccessToken extends Options {
6+
accessToken: string;
7+
videoId: string;
8+
}
9+
interface Options {
10+
apiHost?: string;
11+
retries?: number;
12+
}
13+
export interface ProgressiveUploadProgressEvent {
14+
uploadedBytes: number;
15+
totalBytes: number;
16+
}
17+
export interface ProgressiveProgressEvent {
18+
uploadedBytes: number;
19+
totalBytes: number;
20+
}
21+
export declare class ProgressiveUploader {
22+
private uploadEndpoint;
23+
private videoId?;
24+
private retries;
25+
private onProgressCallbacks;
26+
private headers;
27+
private currentPartNum;
28+
private currentPartBlobs;
29+
private currentPartBlobsSize;
30+
constructor(options: ProgressiveUploaderOptionsWithAccessToken | ProgressiveUploaderOptionsWithUploadToken);
31+
onProgress(cb: (e: ProgressiveProgressEvent) => void): void;
32+
uploadPart(file: Blob): Promise<void>;
33+
uploadLastPart(file: Blob): Promise<any>;
34+
private createFormData;
35+
private sleep;
36+
private upload;
37+
}
38+
export {};

0 commit comments

Comments
 (0)