livekit-server-sdk 1.1.3 → 1.2.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/.github/banner_dark.png +0 -0
- package/.github/banner_light.png +0 -0
- package/README.md +25 -1
- package/dist/AccessToken.d.ts +56 -0
- package/dist/AccessToken.js +118 -0
- package/dist/AccessToken.js.map +1 -0
- package/dist/AccessToken.test.d.ts +1 -0
- package/dist/AccessToken.test.js +72 -0
- package/dist/AccessToken.test.js.map +1 -0
- package/dist/EgressClient.d.ts +128 -0
- package/dist/EgressClient.js +263 -0
- package/dist/EgressClient.js.map +1 -0
- package/dist/IngressClient.d.ts +84 -0
- package/dist/IngressClient.js +112 -0
- package/dist/IngressClient.js.map +1 -0
- package/dist/RoomServiceClient.d.ts +132 -0
- package/dist/RoomServiceClient.js +189 -0
- package/dist/RoomServiceClient.js.map +1 -0
- package/dist/ServiceBase.d.ts +16 -0
- package/dist/ServiceBase.js +27 -0
- package/dist/ServiceBase.js.map +1 -0
- package/dist/TwirpRPC.d.ts +16 -0
- package/dist/TwirpRPC.js +37 -0
- package/dist/TwirpRPC.js.map +1 -0
- package/dist/WebhookReceiver.d.ts +14 -0
- package/dist/WebhookReceiver.js +40 -0
- package/dist/WebhookReceiver.js.map +1 -0
- package/dist/WebhookReceiver.test.d.ts +1 -0
- package/dist/WebhookReceiver.test.js +39 -0
- package/dist/WebhookReceiver.test.js.map +1 -0
- package/dist/grants.d.ts +53 -0
- package/dist/grants.js +11 -0
- package/dist/grants.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/proto/google/protobuf/timestamp.d.ts +132 -0
- package/dist/proto/google/protobuf/timestamp.js +92 -0
- package/dist/proto/google/protobuf/timestamp.js.map +1 -0
- package/dist/proto/livekit_egress.d.ts +11266 -0
- package/dist/proto/livekit_egress.js +2869 -0
- package/dist/proto/livekit_egress.js.map +1 -0
- package/dist/proto/livekit_ingress.d.ts +2163 -0
- package/dist/proto/livekit_ingress.js +1264 -0
- package/dist/proto/livekit_ingress.js.map +1 -0
- package/dist/proto/livekit_models.d.ts +1356 -0
- package/dist/proto/livekit_models.js +2893 -0
- package/dist/proto/livekit_models.js.map +1 -0
- package/dist/proto/livekit_room.d.ts +3273 -0
- package/dist/proto/livekit_room.js +1057 -0
- package/dist/proto/livekit_room.js.map +1 -0
- package/dist/proto/livekit_webhook.d.ts +4841 -0
- package/dist/proto/livekit_webhook.js +179 -0
- package/dist/proto/livekit_webhook.js.map +1 -0
- package/package.json +7 -6
|
Binary file
|
|
Binary file
|
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
<!--BEGIN_BANNER_IMAGE-->
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="/.github/banner_dark.png">
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="/.github/banner_light.png">
|
|
5
|
+
<img style="width:100%;" alt="The LiveKit icon, the name of the repository and some sample code in the background." src="/.github/banner_light.png">
|
|
6
|
+
</picture>
|
|
7
|
+
<!--END_BANNER_IMAGE-->
|
|
8
|
+
|
|
1
9
|
# LiveKit Server API for JS
|
|
2
10
|
|
|
3
|
-
|
|
11
|
+
<!--BEGIN_DESCRIPTION-->Use this SDK to manage <a href="https://livekit.io/">LiveKit</a> rooms and create access tokens from your JavaScript/Node.js backend.<!--END_DESCRIPTION-->
|
|
4
12
|
|
|
5
13
|
## Installation
|
|
6
14
|
|
|
@@ -114,6 +122,8 @@ svc.deleteRoom('myroom').then(() => {
|
|
|
114
122
|
|
|
115
123
|
The JS SDK also provides helper functions to decode and verify webhook callbacks. While verification is optional, it ensures the authenticity of the message. See [webhooks guide](https://docs.livekit.io/guides/webhooks) for details.
|
|
116
124
|
|
|
125
|
+
LiveKit POSTs to webhook endpoints with `Content-Type: application/webhook+json`. Please ensure your server is able to receive POST body with that MIME.
|
|
126
|
+
|
|
117
127
|
Check out [example projects](examples) for full examples of webhooks integration.
|
|
118
128
|
|
|
119
129
|
```typescript
|
|
@@ -130,3 +140,17 @@ app.post('/webhook-endpoint', (req, res) => {
|
|
|
130
140
|
const event = receiver.receive(req.body, req.get('Authorization'));
|
|
131
141
|
});
|
|
132
142
|
```
|
|
143
|
+
|
|
144
|
+
<!--BEGIN_REPO_NAV-->
|
|
145
|
+
|
|
146
|
+
<br/><table>
|
|
147
|
+
|
|
148
|
+
<thead><tr><th colspan="2">LiveKit Ecosystem</th></tr></thead>
|
|
149
|
+
<tbody>
|
|
150
|
+
<tr><td>Client SDKs</td><td><a href="https://github.com/livekit/components-js">Components</a> · <a href="https://github.com/livekit/client-sdk-js">JavaScript</a> · <a href="https://github.com/livekit/client-sdk-rust">Rust</a> · <a href="https://github.com/livekit/client-sdk-swift">iOS/macOS</a> · <a href="https://github.com/livekit/client-sdk-android">Android</a> · <a href="https://github.com/livekit/client-sdk-flutter">Flutter</a> · <a href="https://github.com/livekit/client-sdk-unity-web">Unity (web)</a> · <a href="https://github.com/livekit/client-sdk-react-native">React Native (beta)</a></td></tr><tr></tr>
|
|
151
|
+
<tr><td>Server SDKs</td><td><b>Node.js</b> · <a href="https://github.com/livekit/server-sdk-go">Golang</a> · <a href="https://github.com/livekit/server-sdk-ruby">Ruby</a> · <a href="https://github.com/livekit/server-sdk-kotlin">Java/Kotlin</a> · <a href="https://github.com/agence104/livekit-server-sdk-php">PHP (community)</a> · <a href="https://github.com/tradablebits/livekit-server-sdk-python">Python (community)</a></td></tr><tr></tr>
|
|
152
|
+
<tr><td>Services</td><td><a href="https://github.com/livekit/livekit">Livekit server</a> · <a href="https://github.com/livekit/egress">Egress</a> · <a href="https://github.com/livekit/ingress">Ingress</a></td></tr><tr></tr>
|
|
153
|
+
<tr><td>Resources</td><td><a href="https://docs.livekit.io">Docs</a> · <a href="https://github.com/livekit-examples">Example apps</a> · <a href="https://livekit.io/cloud">Cloud</a> · <a href="https://docs.livekit.io/oss/deployment">Self-hosting</a> · <a href="https://github.com/livekit/livekit-cli">CLI</a></td></tr>
|
|
154
|
+
</tbody>
|
|
155
|
+
</table>
|
|
156
|
+
<!--END_REPO_NAV-->
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ClaimGrants, VideoGrant } from './grants';
|
|
2
|
+
export interface AccessTokenOptions {
|
|
3
|
+
/**
|
|
4
|
+
* amount of time before expiration
|
|
5
|
+
* expressed in seconds or a string describing a time span zeit/ms.
|
|
6
|
+
* eg: '2 days', '10h', or seconds as numeric value
|
|
7
|
+
*/
|
|
8
|
+
ttl?: number | string;
|
|
9
|
+
/**
|
|
10
|
+
* display name for the participant, available as `Participant.name`
|
|
11
|
+
*/
|
|
12
|
+
name?: string;
|
|
13
|
+
/**
|
|
14
|
+
* identity of the user, required for room join tokens
|
|
15
|
+
*/
|
|
16
|
+
identity?: string;
|
|
17
|
+
/**
|
|
18
|
+
* custom metadata to be passed to participants
|
|
19
|
+
*/
|
|
20
|
+
metadata?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class AccessToken {
|
|
23
|
+
private apiKey;
|
|
24
|
+
private apiSecret;
|
|
25
|
+
private grants;
|
|
26
|
+
identity?: string;
|
|
27
|
+
ttl?: number | string;
|
|
28
|
+
/**
|
|
29
|
+
* Creates a new AccessToken
|
|
30
|
+
* @param apiKey API Key, can be set in env LIVEKIT_API_KEY
|
|
31
|
+
* @param apiSecret Secret, can be set in env LIVEKIT_API_SECRET
|
|
32
|
+
*/
|
|
33
|
+
constructor(apiKey?: string, apiSecret?: string, options?: AccessTokenOptions);
|
|
34
|
+
/**
|
|
35
|
+
* Adds a video grant to this token.
|
|
36
|
+
* @param grant
|
|
37
|
+
*/
|
|
38
|
+
addGrant(grant: VideoGrant): void;
|
|
39
|
+
/**
|
|
40
|
+
* Set metadata to be passed to the Participant, used only when joining the room
|
|
41
|
+
*/
|
|
42
|
+
set metadata(md: string);
|
|
43
|
+
set name(name: string);
|
|
44
|
+
get sha256(): string | undefined;
|
|
45
|
+
set sha256(sha: string | undefined);
|
|
46
|
+
/**
|
|
47
|
+
* @returns JWT encoded token
|
|
48
|
+
*/
|
|
49
|
+
toJwt(): string;
|
|
50
|
+
}
|
|
51
|
+
export declare class TokenVerifier {
|
|
52
|
+
private apiKey;
|
|
53
|
+
private apiSecret;
|
|
54
|
+
constructor(apiKey: string, apiSecret: string);
|
|
55
|
+
verify(token: string): ClaimGrants;
|
|
56
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.TokenVerifier = exports.AccessToken = void 0;
|
|
23
|
+
const jwt = __importStar(require("jsonwebtoken"));
|
|
24
|
+
// 6 hours
|
|
25
|
+
const defaultTTL = 6 * 60 * 60;
|
|
26
|
+
class AccessToken {
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new AccessToken
|
|
29
|
+
* @param apiKey API Key, can be set in env LIVEKIT_API_KEY
|
|
30
|
+
* @param apiSecret Secret, can be set in env LIVEKIT_API_SECRET
|
|
31
|
+
*/
|
|
32
|
+
constructor(apiKey, apiSecret, options) {
|
|
33
|
+
if (!apiKey) {
|
|
34
|
+
apiKey = process.env.LIVEKIT_API_KEY;
|
|
35
|
+
}
|
|
36
|
+
if (!apiSecret) {
|
|
37
|
+
apiSecret = process.env.LIVEKIT_API_SECRET;
|
|
38
|
+
}
|
|
39
|
+
if (!apiKey || !apiSecret) {
|
|
40
|
+
throw Error('api-key and api-secret must be set');
|
|
41
|
+
}
|
|
42
|
+
else if (typeof document !== 'undefined') {
|
|
43
|
+
// check against document rather than window because deno provides window
|
|
44
|
+
console.error('You should not include your API secret in your web client bundle.\n\n' +
|
|
45
|
+
'Your web client should request a token from your backend server which should then use ' +
|
|
46
|
+
'the API secret to generate a token. See https://docs.livekit.io/client/connect/');
|
|
47
|
+
}
|
|
48
|
+
this.apiKey = apiKey;
|
|
49
|
+
this.apiSecret = apiSecret;
|
|
50
|
+
this.grants = {};
|
|
51
|
+
this.identity = options === null || options === void 0 ? void 0 : options.identity;
|
|
52
|
+
this.ttl = (options === null || options === void 0 ? void 0 : options.ttl) || defaultTTL;
|
|
53
|
+
if (options === null || options === void 0 ? void 0 : options.metadata) {
|
|
54
|
+
this.metadata = options.metadata;
|
|
55
|
+
}
|
|
56
|
+
if (options === null || options === void 0 ? void 0 : options.name) {
|
|
57
|
+
this.name = options.name;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Adds a video grant to this token.
|
|
62
|
+
* @param grant
|
|
63
|
+
*/
|
|
64
|
+
addGrant(grant) {
|
|
65
|
+
this.grants.video = grant;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Set metadata to be passed to the Participant, used only when joining the room
|
|
69
|
+
*/
|
|
70
|
+
set metadata(md) {
|
|
71
|
+
this.grants.metadata = md;
|
|
72
|
+
}
|
|
73
|
+
set name(name) {
|
|
74
|
+
this.grants.name = name;
|
|
75
|
+
}
|
|
76
|
+
get sha256() {
|
|
77
|
+
return this.grants.sha256;
|
|
78
|
+
}
|
|
79
|
+
set sha256(sha) {
|
|
80
|
+
this.grants.sha256 = sha;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @returns JWT encoded token
|
|
84
|
+
*/
|
|
85
|
+
toJwt() {
|
|
86
|
+
// TODO: check for video grant validity
|
|
87
|
+
var _a;
|
|
88
|
+
const opts = {
|
|
89
|
+
issuer: this.apiKey,
|
|
90
|
+
expiresIn: this.ttl,
|
|
91
|
+
notBefore: 0,
|
|
92
|
+
};
|
|
93
|
+
if (this.identity) {
|
|
94
|
+
opts.subject = this.identity;
|
|
95
|
+
opts.jwtid = this.identity;
|
|
96
|
+
}
|
|
97
|
+
else if ((_a = this.grants.video) === null || _a === void 0 ? void 0 : _a.roomJoin) {
|
|
98
|
+
throw Error('identity is required for join but not set');
|
|
99
|
+
}
|
|
100
|
+
return jwt.sign(this.grants, this.apiSecret, opts);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.AccessToken = AccessToken;
|
|
104
|
+
class TokenVerifier {
|
|
105
|
+
constructor(apiKey, apiSecret) {
|
|
106
|
+
this.apiKey = apiKey;
|
|
107
|
+
this.apiSecret = apiSecret;
|
|
108
|
+
}
|
|
109
|
+
verify(token) {
|
|
110
|
+
const decoded = jwt.verify(token, this.apiSecret, { issuer: this.apiKey });
|
|
111
|
+
if (!decoded) {
|
|
112
|
+
throw Error('invalid token');
|
|
113
|
+
}
|
|
114
|
+
return decoded;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.TokenVerifier = TokenVerifier;
|
|
118
|
+
//# sourceMappingURL=AccessToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessToken.js","sourceRoot":"","sources":["../src/AccessToken.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
const jwt = __importStar(require("jsonwebtoken"));
|
|
23
|
+
const AccessToken_1 = require("./AccessToken");
|
|
24
|
+
const testApiKey = 'abcdefg';
|
|
25
|
+
const testSecret = 'abababa';
|
|
26
|
+
describe('encoded tokens are valid', () => {
|
|
27
|
+
const t = new AccessToken_1.AccessToken(testApiKey, testSecret, {
|
|
28
|
+
identity: 'me',
|
|
29
|
+
name: 'myname',
|
|
30
|
+
});
|
|
31
|
+
t.addGrant({ room: 'myroom' });
|
|
32
|
+
const token = t.toJwt();
|
|
33
|
+
const decoded = jwt.verify(token, testSecret, { jwtid: 'me' });
|
|
34
|
+
it('can be decoded', () => {
|
|
35
|
+
expect(decoded).not.toBe(undefined);
|
|
36
|
+
});
|
|
37
|
+
it('has name set', () => {
|
|
38
|
+
expect(decoded.name).toBe('myname');
|
|
39
|
+
});
|
|
40
|
+
it('has video grants set', () => {
|
|
41
|
+
expect(decoded.video).toBeTruthy();
|
|
42
|
+
expect(decoded.video.room).toEqual('myroom');
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe('identity is required for only join grants', () => {
|
|
46
|
+
it('allows empty identity for create', () => {
|
|
47
|
+
const t = new AccessToken_1.AccessToken(testApiKey, testSecret);
|
|
48
|
+
t.addGrant({ roomCreate: true });
|
|
49
|
+
expect(t.toJwt()).toBeTruthy();
|
|
50
|
+
});
|
|
51
|
+
it('throws error when identity is not provided for join', () => {
|
|
52
|
+
const t = new AccessToken_1.AccessToken(testApiKey, testSecret);
|
|
53
|
+
t.addGrant({ roomJoin: true });
|
|
54
|
+
expect(() => {
|
|
55
|
+
t.toJwt();
|
|
56
|
+
}).toThrow();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('verify token is valid', () => {
|
|
60
|
+
it('can decode encoded token', () => {
|
|
61
|
+
var _a;
|
|
62
|
+
const t = new AccessToken_1.AccessToken(testApiKey, testSecret);
|
|
63
|
+
t.sha256 = 'abcdefg';
|
|
64
|
+
t.addGrant({ roomCreate: true });
|
|
65
|
+
const v = new AccessToken_1.TokenVerifier(testApiKey, testSecret);
|
|
66
|
+
const decoded = v.verify(t.toJwt());
|
|
67
|
+
expect(decoded).not.toBe(undefined);
|
|
68
|
+
expect(decoded.sha256).toEqual('abcdefg');
|
|
69
|
+
expect((_a = decoded.video) === null || _a === void 0 ? void 0 : _a.roomCreate).toBeTruthy();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=AccessToken.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessToken.test.js","sourceRoot":"","sources":["../src/AccessToken.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { DirectFileOutput, EgressInfo, EncodedFileOutput, EncodingOptions, EncodingOptionsPreset, SegmentedFileOutput, StreamOutput } from './proto/livekit_egress';
|
|
2
|
+
import ServiceBase from './ServiceBase';
|
|
3
|
+
export interface RoomCompositeOptions {
|
|
4
|
+
/**
|
|
5
|
+
* egress layout. optional
|
|
6
|
+
*/
|
|
7
|
+
layout?: string;
|
|
8
|
+
/**
|
|
9
|
+
* encoding options or preset. optional
|
|
10
|
+
*/
|
|
11
|
+
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
|
12
|
+
/**
|
|
13
|
+
* record audio only. optional
|
|
14
|
+
*/
|
|
15
|
+
audioOnly?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* record video only. optional
|
|
18
|
+
*/
|
|
19
|
+
videoOnly?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* custom template url. optional
|
|
22
|
+
*/
|
|
23
|
+
customBaseUrl?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface WebOptions {
|
|
26
|
+
/**
|
|
27
|
+
* encoding options or preset. optional
|
|
28
|
+
*/
|
|
29
|
+
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
|
30
|
+
/**
|
|
31
|
+
* record audio only. optional
|
|
32
|
+
*/
|
|
33
|
+
audioOnly?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* record video only. optional
|
|
36
|
+
*/
|
|
37
|
+
videoOnly?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface TrackCompositeOptions {
|
|
40
|
+
/**
|
|
41
|
+
* audio track ID
|
|
42
|
+
*/
|
|
43
|
+
audioTrackId?: string;
|
|
44
|
+
/**
|
|
45
|
+
* video track ID
|
|
46
|
+
*/
|
|
47
|
+
videoTrackId?: string;
|
|
48
|
+
/**
|
|
49
|
+
* encoding options or preset. optional
|
|
50
|
+
*/
|
|
51
|
+
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Used to supply multiple outputs with an egress request
|
|
55
|
+
*/
|
|
56
|
+
export interface EncodedOutputs {
|
|
57
|
+
file?: EncodedFileOutput | undefined;
|
|
58
|
+
stream?: StreamOutput | undefined;
|
|
59
|
+
segments?: SegmentedFileOutput | undefined;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Client to access Egress APIs
|
|
63
|
+
*/
|
|
64
|
+
export declare class EgressClient extends ServiceBase {
|
|
65
|
+
private readonly rpc;
|
|
66
|
+
/**
|
|
67
|
+
* @param host hostname including protocol. i.e. 'https://cluster.livekit.io'
|
|
68
|
+
* @param apiKey API Key, can be set in env var LIVEKIT_API_KEY
|
|
69
|
+
* @param secret API Secret, can be set in env var LIVEKIT_API_SECRET
|
|
70
|
+
*/
|
|
71
|
+
constructor(host: string, apiKey?: string, secret?: string);
|
|
72
|
+
/**
|
|
73
|
+
* @param roomName room name
|
|
74
|
+
* @param output file or stream output
|
|
75
|
+
* @param opts RoomCompositeOptions
|
|
76
|
+
*/
|
|
77
|
+
startRoomCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, opts?: RoomCompositeOptions): Promise<EgressInfo>;
|
|
78
|
+
/**
|
|
79
|
+
* @deprecated use RoomCompositeOptions instead
|
|
80
|
+
*/
|
|
81
|
+
startRoomCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, layout?: string, options?: EncodingOptionsPreset | EncodingOptions, audioOnly?: boolean, videoOnly?: boolean, customBaseUrl?: string): Promise<EgressInfo>;
|
|
82
|
+
/**
|
|
83
|
+
* @param url url
|
|
84
|
+
* @param output file or stream output
|
|
85
|
+
* @param opts WebOptions
|
|
86
|
+
*/
|
|
87
|
+
startWebEgress(url: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, opts?: WebOptions): Promise<EgressInfo>;
|
|
88
|
+
/**
|
|
89
|
+
* @param roomName room name
|
|
90
|
+
* @param output file or stream output
|
|
91
|
+
* @param opts TrackCompositeOptions
|
|
92
|
+
*/
|
|
93
|
+
startTrackCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, opts?: TrackCompositeOptions): Promise<EgressInfo>;
|
|
94
|
+
/**
|
|
95
|
+
* @deprecated use TrackCompositeOptions instead
|
|
96
|
+
*/
|
|
97
|
+
startTrackCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, audioTrackId?: string, videoTrackId?: string, options?: EncodingOptionsPreset | EncodingOptions): Promise<EgressInfo>;
|
|
98
|
+
private isEncodedOutputs;
|
|
99
|
+
private isEncodedFileOutput;
|
|
100
|
+
private isSegmentedFileOutput;
|
|
101
|
+
private isStreamOutput;
|
|
102
|
+
private getOutputParams;
|
|
103
|
+
/**
|
|
104
|
+
* @param roomName room name
|
|
105
|
+
* @param output file or websocket output
|
|
106
|
+
* @param trackId track Id
|
|
107
|
+
*/
|
|
108
|
+
startTrackEgress(roomName: string, output: DirectFileOutput | string, trackId: string): Promise<EgressInfo>;
|
|
109
|
+
/**
|
|
110
|
+
* @param egressId
|
|
111
|
+
* @param layout
|
|
112
|
+
*/
|
|
113
|
+
updateLayout(egressId: string, layout: string): Promise<EgressInfo>;
|
|
114
|
+
/**
|
|
115
|
+
* @param egressId
|
|
116
|
+
* @param addOutputUrls
|
|
117
|
+
* @param removeOutputUrls
|
|
118
|
+
*/
|
|
119
|
+
updateStream(egressId: string, addOutputUrls?: string[], removeOutputUrls?: string[]): Promise<EgressInfo>;
|
|
120
|
+
/**
|
|
121
|
+
* @param roomName list egress for one room only
|
|
122
|
+
*/
|
|
123
|
+
listEgress(roomName?: string): Promise<Array<EgressInfo>>;
|
|
124
|
+
/**
|
|
125
|
+
* @param egressId
|
|
126
|
+
*/
|
|
127
|
+
stopEgress(egressId: string): Promise<EgressInfo>;
|
|
128
|
+
}
|