@livekit/rtc-node 0.8.1 → 0.9.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/dist/audio_source.d.ts +16 -1
- package/dist/audio_source.d.ts.map +1 -1
- package/dist/audio_source.js +49 -3
- package/dist/audio_source.js.map +1 -1
- package/dist/audio_stream.d.ts +10 -13
- package/dist/audio_stream.d.ts.map +1 -1
- package/dist/audio_stream.js +34 -8
- package/dist/audio_stream.js.map +1 -1
- package/dist/ffi_client.d.ts +1 -1
- package/dist/ffi_client.d.ts.map +1 -1
- package/dist/ffi_client.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/napi/native.d.ts +5 -8
- package/dist/participant.d.ts +2 -1
- package/dist/participant.d.ts.map +1 -1
- package/dist/participant.js +3 -0
- package/dist/participant.js.map +1 -1
- package/dist/proto/audio_frame_pb.d.ts +32 -2
- package/dist/proto/audio_frame_pb.d.ts.map +1 -1
- package/dist/proto/audio_frame_pb.js +59 -1
- package/dist/proto/audio_frame_pb.js.map +1 -1
- package/dist/proto/ffi_pb.d.ts +21 -9
- package/dist/proto/ffi_pb.d.ts.map +1 -1
- package/dist/proto/ffi_pb.js +11 -9
- package/dist/proto/ffi_pb.js.map +1 -1
- package/dist/room.d.ts +1 -1
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +0 -3
- package/dist/room.js.map +1 -1
- package/dist/utils.d.ts +7 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +41 -0
- package/dist/utils.js.map +1 -0
- package/dist/video_stream.d.ts +10 -10
- package/dist/video_stream.d.ts.map +1 -1
- package/dist/video_stream.js +35 -11
- package/dist/video_stream.js.map +1 -1
- package/package.json +7 -7
- package/src/audio_source.ts +69 -2
- package/src/audio_stream.ts +36 -17
- package/src/ffi_client.ts +1 -1
- package/src/index.ts +3 -2
- package/src/napi/native.d.ts +5 -8
- package/src/participant.ts +5 -1
- package/src/proto/audio_frame_pb.ts +71 -3
- package/src/proto/ffi_pb.ts +31 -17
- package/src/room.ts +1 -1
- package/src/utils.ts +36 -0
- package/src/video_stream.ts +37 -13
package/src/proto/ffi_pb.ts
CHANGED
|
@@ -22,7 +22,7 @@ import { Message, proto3, protoInt64 } from "@bufbuild/protobuf";
|
|
|
22
22
|
import { ConnectCallback, ConnectRequest, ConnectResponse, DisconnectCallback, DisconnectRequest, DisconnectResponse, GetSessionStatsCallback, GetSessionStatsRequest, GetSessionStatsResponse, PublishDataCallback, PublishDataRequest, PublishDataResponse, PublishSipDtmfCallback, PublishSipDtmfRequest, PublishSipDtmfResponse, PublishTrackCallback, PublishTrackRequest, PublishTrackResponse, PublishTranscriptionCallback, PublishTranscriptionRequest, PublishTranscriptionResponse, RoomEvent, SetLocalAttributesCallback, SetLocalAttributesRequest, SetLocalAttributesResponse, SetLocalMetadataCallback, SetLocalMetadataRequest, SetLocalMetadataResponse, SetLocalNameCallback, SetLocalNameRequest, SetLocalNameResponse, SetSubscribedRequest, SetSubscribedResponse, UnpublishTrackCallback, UnpublishTrackRequest, UnpublishTrackResponse } from "./room_pb.js";
|
|
23
23
|
import { CreateAudioTrackRequest, CreateAudioTrackResponse, CreateVideoTrackRequest, CreateVideoTrackResponse, EnableRemoteTrackRequest, EnableRemoteTrackResponse, GetStatsCallback, GetStatsRequest, GetStatsResponse, LocalTrackMuteRequest, LocalTrackMuteResponse, TrackEvent } from "./track_pb.js";
|
|
24
24
|
import { CaptureVideoFrameRequest, CaptureVideoFrameResponse, NewVideoSourceRequest, NewVideoSourceResponse, NewVideoStreamRequest, NewVideoStreamResponse, VideoConvertRequest, VideoConvertResponse, VideoStreamEvent, VideoStreamFromParticipantRequest, VideoStreamFromParticipantResponse } from "./video_frame_pb.js";
|
|
25
|
-
import { AudioStreamEvent, AudioStreamFromParticipantRequest, AudioStreamFromParticipantResponse, CaptureAudioFrameCallback, CaptureAudioFrameRequest, CaptureAudioFrameResponse, NewAudioResamplerRequest, NewAudioResamplerResponse, NewAudioSourceRequest, NewAudioSourceResponse, NewAudioStreamRequest, NewAudioStreamResponse, RemixAndResampleRequest, RemixAndResampleResponse } from "./audio_frame_pb.js";
|
|
25
|
+
import { AudioStreamEvent, AudioStreamFromParticipantRequest, AudioStreamFromParticipantResponse, CaptureAudioFrameCallback, CaptureAudioFrameRequest, CaptureAudioFrameResponse, ClearAudioBufferRequest, ClearAudioBufferResponse, NewAudioResamplerRequest, NewAudioResamplerResponse, NewAudioSourceRequest, NewAudioSourceResponse, NewAudioStreamRequest, NewAudioStreamResponse, RemixAndResampleRequest, RemixAndResampleResponse } from "./audio_frame_pb.js";
|
|
26
26
|
import { E2eeRequest, E2eeResponse } from "./e2ee_pb.js";
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -239,25 +239,31 @@ export class FfiRequest extends Message<FfiRequest> {
|
|
|
239
239
|
case: "captureAudioFrame";
|
|
240
240
|
} | {
|
|
241
241
|
/**
|
|
242
|
-
* @generated from field: livekit.proto.
|
|
242
|
+
* @generated from field: livekit.proto.ClearAudioBufferRequest clear_audio_buffer = 28;
|
|
243
|
+
*/
|
|
244
|
+
value: ClearAudioBufferRequest;
|
|
245
|
+
case: "clearAudioBuffer";
|
|
246
|
+
} | {
|
|
247
|
+
/**
|
|
248
|
+
* @generated from field: livekit.proto.NewAudioResamplerRequest new_audio_resampler = 29;
|
|
243
249
|
*/
|
|
244
250
|
value: NewAudioResamplerRequest;
|
|
245
251
|
case: "newAudioResampler";
|
|
246
252
|
} | {
|
|
247
253
|
/**
|
|
248
|
-
* @generated from field: livekit.proto.RemixAndResampleRequest remix_and_resample =
|
|
254
|
+
* @generated from field: livekit.proto.RemixAndResampleRequest remix_and_resample = 30;
|
|
249
255
|
*/
|
|
250
256
|
value: RemixAndResampleRequest;
|
|
251
257
|
case: "remixAndResample";
|
|
252
258
|
} | {
|
|
253
259
|
/**
|
|
254
|
-
* @generated from field: livekit.proto.E2eeRequest e2ee =
|
|
260
|
+
* @generated from field: livekit.proto.E2eeRequest e2ee = 31;
|
|
255
261
|
*/
|
|
256
262
|
value: E2eeRequest;
|
|
257
263
|
case: "e2ee";
|
|
258
264
|
} | {
|
|
259
265
|
/**
|
|
260
|
-
* @generated from field: livekit.proto.AudioStreamFromParticipantRequest audio_stream_from_participant =
|
|
266
|
+
* @generated from field: livekit.proto.AudioStreamFromParticipantRequest audio_stream_from_participant = 32;
|
|
261
267
|
*/
|
|
262
268
|
value: AudioStreamFromParticipantRequest;
|
|
263
269
|
case: "audioStreamFromParticipant";
|
|
@@ -297,10 +303,11 @@ export class FfiRequest extends Message<FfiRequest> {
|
|
|
297
303
|
{ no: 25, name: "new_audio_stream", kind: "message", T: NewAudioStreamRequest, oneof: "message" },
|
|
298
304
|
{ no: 26, name: "new_audio_source", kind: "message", T: NewAudioSourceRequest, oneof: "message" },
|
|
299
305
|
{ no: 27, name: "capture_audio_frame", kind: "message", T: CaptureAudioFrameRequest, oneof: "message" },
|
|
300
|
-
{ no: 28, name: "
|
|
301
|
-
{ no: 29, name: "
|
|
302
|
-
{ no: 30, name: "
|
|
303
|
-
{ no: 31, name: "
|
|
306
|
+
{ no: 28, name: "clear_audio_buffer", kind: "message", T: ClearAudioBufferRequest, oneof: "message" },
|
|
307
|
+
{ no: 29, name: "new_audio_resampler", kind: "message", T: NewAudioResamplerRequest, oneof: "message" },
|
|
308
|
+
{ no: 30, name: "remix_and_resample", kind: "message", T: RemixAndResampleRequest, oneof: "message" },
|
|
309
|
+
{ no: 31, name: "e2ee", kind: "message", T: E2eeRequest, oneof: "message" },
|
|
310
|
+
{ no: 32, name: "audio_stream_from_participant", kind: "message", T: AudioStreamFromParticipantRequest, oneof: "message" },
|
|
304
311
|
]);
|
|
305
312
|
|
|
306
313
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): FfiRequest {
|
|
@@ -495,25 +502,31 @@ export class FfiResponse extends Message<FfiResponse> {
|
|
|
495
502
|
case: "captureAudioFrame";
|
|
496
503
|
} | {
|
|
497
504
|
/**
|
|
498
|
-
* @generated from field: livekit.proto.
|
|
505
|
+
* @generated from field: livekit.proto.ClearAudioBufferResponse clear_audio_buffer = 28;
|
|
506
|
+
*/
|
|
507
|
+
value: ClearAudioBufferResponse;
|
|
508
|
+
case: "clearAudioBuffer";
|
|
509
|
+
} | {
|
|
510
|
+
/**
|
|
511
|
+
* @generated from field: livekit.proto.NewAudioResamplerResponse new_audio_resampler = 29;
|
|
499
512
|
*/
|
|
500
513
|
value: NewAudioResamplerResponse;
|
|
501
514
|
case: "newAudioResampler";
|
|
502
515
|
} | {
|
|
503
516
|
/**
|
|
504
|
-
* @generated from field: livekit.proto.RemixAndResampleResponse remix_and_resample =
|
|
517
|
+
* @generated from field: livekit.proto.RemixAndResampleResponse remix_and_resample = 30;
|
|
505
518
|
*/
|
|
506
519
|
value: RemixAndResampleResponse;
|
|
507
520
|
case: "remixAndResample";
|
|
508
521
|
} | {
|
|
509
522
|
/**
|
|
510
|
-
* @generated from field: livekit.proto.AudioStreamFromParticipantResponse audio_stream_from_participant =
|
|
523
|
+
* @generated from field: livekit.proto.AudioStreamFromParticipantResponse audio_stream_from_participant = 31;
|
|
511
524
|
*/
|
|
512
525
|
value: AudioStreamFromParticipantResponse;
|
|
513
526
|
case: "audioStreamFromParticipant";
|
|
514
527
|
} | {
|
|
515
528
|
/**
|
|
516
|
-
* @generated from field: livekit.proto.E2eeResponse e2ee =
|
|
529
|
+
* @generated from field: livekit.proto.E2eeResponse e2ee = 32;
|
|
517
530
|
*/
|
|
518
531
|
value: E2eeResponse;
|
|
519
532
|
case: "e2ee";
|
|
@@ -553,10 +566,11 @@ export class FfiResponse extends Message<FfiResponse> {
|
|
|
553
566
|
{ no: 25, name: "new_audio_stream", kind: "message", T: NewAudioStreamResponse, oneof: "message" },
|
|
554
567
|
{ no: 26, name: "new_audio_source", kind: "message", T: NewAudioSourceResponse, oneof: "message" },
|
|
555
568
|
{ no: 27, name: "capture_audio_frame", kind: "message", T: CaptureAudioFrameResponse, oneof: "message" },
|
|
556
|
-
{ no: 28, name: "
|
|
557
|
-
{ no: 29, name: "
|
|
558
|
-
{ no: 30, name: "
|
|
559
|
-
{ no: 31, name: "
|
|
569
|
+
{ no: 28, name: "clear_audio_buffer", kind: "message", T: ClearAudioBufferResponse, oneof: "message" },
|
|
570
|
+
{ no: 29, name: "new_audio_resampler", kind: "message", T: NewAudioResamplerResponse, oneof: "message" },
|
|
571
|
+
{ no: 30, name: "remix_and_resample", kind: "message", T: RemixAndResampleResponse, oneof: "message" },
|
|
572
|
+
{ no: 31, name: "audio_stream_from_participant", kind: "message", T: AudioStreamFromParticipantResponse, oneof: "message" },
|
|
573
|
+
{ no: 32, name: "e2ee", kind: "message", T: E2eeResponse, oneof: "message" },
|
|
560
574
|
]);
|
|
561
575
|
|
|
562
576
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): FfiResponse {
|
package/src/room.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';
|
|
4
5
|
import EventEmitter from 'events';
|
|
5
|
-
import type TypedEmitter from 'typed-emitter';
|
|
6
6
|
import type { E2EEOptions } from './e2ee.js';
|
|
7
7
|
import { E2EEManager } from './e2ee.js';
|
|
8
8
|
import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
export class Mutex {
|
|
5
|
+
#locking: Promise<void>;
|
|
6
|
+
#locks: number;
|
|
7
|
+
#limit: number;
|
|
8
|
+
|
|
9
|
+
constructor(limit = 1) {
|
|
10
|
+
this.#locking = Promise.resolve();
|
|
11
|
+
this.#locks = 0;
|
|
12
|
+
this.#limit = limit;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
isLocked(): boolean {
|
|
16
|
+
return this.#locks >= this.#limit;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async lock(): Promise<() => void> {
|
|
20
|
+
this.#locks += 1;
|
|
21
|
+
|
|
22
|
+
let unlockNext: () => void;
|
|
23
|
+
|
|
24
|
+
const willLock = new Promise<void>(
|
|
25
|
+
(resolve) =>
|
|
26
|
+
(unlockNext = () => {
|
|
27
|
+
this.#locks -= 1;
|
|
28
|
+
resolve();
|
|
29
|
+
}),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const willUnlock = this.#locking.then(() => unlockNext);
|
|
33
|
+
this.#locking = this.#locking.then(() => willLock);
|
|
34
|
+
return willUnlock;
|
|
35
|
+
}
|
|
36
|
+
}
|
package/src/video_stream.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
import EventEmitter from 'events';
|
|
5
|
-
import type TypedEmitter from 'typed-emitter';
|
|
6
4
|
import type { FfiEvent } from './ffi_client.js';
|
|
7
5
|
import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
|
|
8
6
|
import type {
|
|
@@ -12,6 +10,7 @@ import type {
|
|
|
12
10
|
} from './proto/video_frame_pb.js';
|
|
13
11
|
import { NewVideoStreamRequest, VideoStreamType } from './proto/video_frame_pb.js';
|
|
14
12
|
import type { Track } from './track.js';
|
|
13
|
+
import { Mutex } from './utils.js';
|
|
15
14
|
import { VideoFrame } from './video_frame.js';
|
|
16
15
|
|
|
17
16
|
export type VideoFrameEvent = {
|
|
@@ -20,24 +19,21 @@ export type VideoFrameEvent = {
|
|
|
20
19
|
rotation: VideoRotation;
|
|
21
20
|
};
|
|
22
21
|
|
|
23
|
-
export
|
|
24
|
-
frameReceived: (evt: VideoFrameEvent) => void;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export enum VideoStreamEvent {
|
|
28
|
-
FrameReceived = 'frameReceived',
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export class VideoStream extends (EventEmitter as new () => TypedEmitter<VideoStreamCallbacks>) {
|
|
22
|
+
export class VideoStream implements AsyncIterableIterator<VideoFrameEvent> {
|
|
32
23
|
/** @internal */
|
|
33
24
|
info: VideoStreamInfo;
|
|
34
25
|
/** @internal */
|
|
35
26
|
ffiHandle: FfiHandle;
|
|
27
|
+
/** @internal */
|
|
28
|
+
eventQueue: (VideoFrameEvent | null)[] = [];
|
|
29
|
+
/** @internal */
|
|
30
|
+
queueResolve: ((value: IteratorResult<VideoFrameEvent>) => void) | null = null;
|
|
31
|
+
/** @internal */
|
|
32
|
+
mutex = new Mutex();
|
|
36
33
|
|
|
37
34
|
track: Track;
|
|
38
35
|
|
|
39
36
|
constructor(track: Track) {
|
|
40
|
-
super();
|
|
41
37
|
this.track = track;
|
|
42
38
|
|
|
43
39
|
const req = new NewVideoStreamRequest({
|
|
@@ -72,7 +68,12 @@ export class VideoStream extends (EventEmitter as new () => TypedEmitter<VideoSt
|
|
|
72
68
|
const rotation = streamEvent.value.rotation;
|
|
73
69
|
const timestampUs = streamEvent.value.timestampUs;
|
|
74
70
|
const frame = VideoFrame.fromOwnedInfo(streamEvent.value.buffer);
|
|
75
|
-
|
|
71
|
+
const value = { rotation, timestampUs, frame };
|
|
72
|
+
if (this.queueResolve) {
|
|
73
|
+
this.queueResolve({ done: false, value });
|
|
74
|
+
} else {
|
|
75
|
+
this.eventQueue.push(value);
|
|
76
|
+
}
|
|
76
77
|
break;
|
|
77
78
|
case 'eos':
|
|
78
79
|
FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);
|
|
@@ -80,7 +81,30 @@ export class VideoStream extends (EventEmitter as new () => TypedEmitter<VideoSt
|
|
|
80
81
|
}
|
|
81
82
|
};
|
|
82
83
|
|
|
84
|
+
async next(): Promise<IteratorResult<VideoFrameEvent>> {
|
|
85
|
+
const unlock = await this.mutex.lock();
|
|
86
|
+
if (this.eventQueue.length > 0) {
|
|
87
|
+
unlock();
|
|
88
|
+
const value = this.eventQueue.shift();
|
|
89
|
+
if (value) {
|
|
90
|
+
return { done: false, value };
|
|
91
|
+
} else {
|
|
92
|
+
return { done: true, value: undefined };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const promise = new Promise<IteratorResult<VideoFrameEvent>>(
|
|
96
|
+
(resolve) => (this.queueResolve = resolve),
|
|
97
|
+
);
|
|
98
|
+
unlock();
|
|
99
|
+
return promise;
|
|
100
|
+
}
|
|
101
|
+
|
|
83
102
|
close() {
|
|
103
|
+
this.eventQueue.push(null);
|
|
84
104
|
this.ffiHandle.dispose();
|
|
85
105
|
}
|
|
106
|
+
|
|
107
|
+
[Symbol.asyncIterator](): VideoStream {
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
86
110
|
}
|