livekit-client 2.1.1 → 2.1.2
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/livekit-client.esm.mjs +159 -7
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +2 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +5 -2
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +20 -1
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +2 -1
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrack.d.ts +1 -0
- package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +4 -0
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/TrackPublication.d.ts +3 -1
- package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
- package/dist/src/room/types.d.ts +8 -0
- package/dist/src/room/types.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +3 -1
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/index.d.ts +1 -1
- package/dist/ts4.2/src/room/RTCEngine.d.ts +2 -1
- package/dist/ts4.2/src/room/Room.d.ts +5 -2
- package/dist/ts4.2/src/room/events.d.ts +20 -1
- package/dist/ts4.2/src/room/participant/Participant.d.ts +2 -1
- package/dist/ts4.2/src/room/track/RemoteTrack.d.ts +1 -0
- package/dist/ts4.2/src/room/track/Track.d.ts +4 -0
- package/dist/ts4.2/src/room/track/TrackPublication.d.ts +3 -1
- package/dist/ts4.2/src/room/types.d.ts +8 -0
- package/dist/ts4.2/src/room/utils.d.ts +3 -1
- package/package.json +8 -8
- package/src/index.ts +1 -1
- package/src/room/RTCEngine.ts +4 -0
- package/src/room/Room.ts +27 -1
- package/src/room/events.ts +23 -0
- package/src/room/participant/Participant.ts +5 -1
- package/src/room/track/RemoteTrack.ts +13 -0
- package/src/room/track/Track.ts +9 -0
- package/src/room/track/TrackPublication.ts +3 -1
- package/src/room/types.ts +9 -0
- package/src/room/utils.ts +17 -2
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "livekit-client",
|
3
|
-
"version": "2.1.
|
3
|
+
"version": "2.1.2",
|
4
4
|
"description": "JavaScript/TypeScript client SDK for LiveKit",
|
5
5
|
"main": "./dist/livekit-client.umd.js",
|
6
6
|
"unpkg": "./dist/livekit-client.umd.js",
|
@@ -36,7 +36,7 @@
|
|
36
36
|
"author": "David Zhao <david@davidzhao.com>",
|
37
37
|
"license": "Apache-2.0",
|
38
38
|
"dependencies": {
|
39
|
-
"@livekit/protocol": "1.
|
39
|
+
"@livekit/protocol": "1.15.0",
|
40
40
|
"events": "^3.3.0",
|
41
41
|
"loglevel": "^1.8.0",
|
42
42
|
"sdp-transform": "^2.14.1",
|
@@ -46,8 +46,8 @@
|
|
46
46
|
"webrtc-adapter": "^8.1.1"
|
47
47
|
},
|
48
48
|
"devDependencies": {
|
49
|
-
"@babel/core": "7.24.
|
50
|
-
"@babel/preset-env": "7.24.
|
49
|
+
"@babel/core": "7.24.5",
|
50
|
+
"@babel/preset-env": "7.24.5",
|
51
51
|
"@bufbuild/protoc-gen-es": "^1.3.0",
|
52
52
|
"@changesets/cli": "2.27.1",
|
53
53
|
"@livekit/changesets-changelog-github": "^0.0.4",
|
@@ -73,15 +73,15 @@
|
|
73
73
|
"gh-pages": "6.1.1",
|
74
74
|
"jsdom": "^24.0.0",
|
75
75
|
"prettier": "^3.0.0",
|
76
|
-
"rollup": "4.
|
76
|
+
"rollup": "4.17.2",
|
77
77
|
"rollup-plugin-delete": "^2.0.0",
|
78
78
|
"rollup-plugin-re": "1.0.7",
|
79
79
|
"rollup-plugin-typescript2": "0.36.0",
|
80
80
|
"size-limit": "^8.2.4",
|
81
|
-
"typedoc": "0.25.
|
81
|
+
"typedoc": "0.25.13",
|
82
82
|
"typedoc-plugin-no-inherit": "1.4.0",
|
83
|
-
"typescript": "5.4.
|
84
|
-
"vite": "5.
|
83
|
+
"typescript": "5.4.5",
|
84
|
+
"vite": "5.2.10",
|
85
85
|
"vitest": "^1.0.0"
|
86
86
|
},
|
87
87
|
"scripts": {
|
package/src/index.ts
CHANGED
@@ -44,7 +44,7 @@ export { facingModeFromDeviceLabel, facingModeFromLocalTrack } from './room/trac
|
|
44
44
|
export * from './room/track/options';
|
45
45
|
export * from './room/track/processor/types';
|
46
46
|
export * from './room/track/types';
|
47
|
-
export type { DataPublishOptions, SimulationScenario } from './room/types';
|
47
|
+
export type { DataPublishOptions, SimulationScenario, TranscriptionSegment } from './room/types';
|
48
48
|
export * from './version';
|
49
49
|
export {
|
50
50
|
ConnectionQuality,
|
package/src/room/RTCEngine.ts
CHANGED
@@ -23,6 +23,7 @@ import {
|
|
23
23
|
TrackInfo,
|
24
24
|
type TrackPublishedResponse,
|
25
25
|
TrackUnpublishedResponse,
|
26
|
+
Transcription,
|
26
27
|
UpdateSubscription,
|
27
28
|
UserPacket,
|
28
29
|
} from '@livekit/protocol';
|
@@ -634,6 +635,8 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
634
635
|
this.emit(EngineEvent.ActiveSpeakersUpdate, dp.value.value.speakers);
|
635
636
|
} else if (dp.value?.case === 'user') {
|
636
637
|
this.emit(EngineEvent.DataPacketReceived, dp.value.value, dp.kind);
|
638
|
+
} else if (dp.value?.case === 'transcription') {
|
639
|
+
this.emit(EngineEvent.TranscriptionReceived, dp.value.value);
|
637
640
|
}
|
638
641
|
} finally {
|
639
642
|
unlock();
|
@@ -1357,6 +1360,7 @@ export type EngineEventCallbacks = {
|
|
1357
1360
|
) => void;
|
1358
1361
|
activeSpeakersUpdate: (speakers: Array<SpeakerInfo>) => void;
|
1359
1362
|
dataPacketReceived: (userPacket: UserPacket, kind: DataPacket_Kind) => void;
|
1363
|
+
transcriptionReceived: (transcription: Transcription) => void;
|
1360
1364
|
transportsCreated: (publisher: PCTransport, subscriber: PCTransport) => void;
|
1361
1365
|
/** @internal */
|
1362
1366
|
trackSenderAdded: (track: Track, sender: RTCRtpSender) => void;
|
package/src/room/Room.ts
CHANGED
@@ -18,6 +18,8 @@ import {
|
|
18
18
|
TrackInfo,
|
19
19
|
TrackSource,
|
20
20
|
TrackType,
|
21
|
+
Transcription as TranscriptionModel,
|
22
|
+
TranscriptionSegment as TranscriptionSegmentModel,
|
21
23
|
UserPacket,
|
22
24
|
protoInt64,
|
23
25
|
} from '@livekit/protocol';
|
@@ -61,11 +63,12 @@ import type { TrackPublication } from './track/TrackPublication';
|
|
61
63
|
import type { TrackProcessor } from './track/processor/types';
|
62
64
|
import type { AdaptiveStreamSettings } from './track/types';
|
63
65
|
import { getNewAudioContext, sourceToKind } from './track/utils';
|
64
|
-
import type { SimulationOptions, SimulationScenario } from './types';
|
66
|
+
import type { SimulationOptions, SimulationScenario, TranscriptionSegment } from './types';
|
65
67
|
import {
|
66
68
|
Future,
|
67
69
|
Mutex,
|
68
70
|
createDummyVideoStreamTrack,
|
71
|
+
extractTranscriptionSegments,
|
69
72
|
getEmptyAudioStreamTrack,
|
70
73
|
isBrowserSupported,
|
71
74
|
isCloud,
|
@@ -330,6 +333,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
330
333
|
})
|
331
334
|
.on(EngineEvent.ActiveSpeakersUpdate, this.handleActiveSpeakersUpdate)
|
332
335
|
.on(EngineEvent.DataPacketReceived, this.handleDataPacket)
|
336
|
+
.on(EngineEvent.TranscriptionReceived, this.handleTranscription)
|
333
337
|
.on(EngineEvent.Resuming, () => {
|
334
338
|
this.clearConnectionReconcile();
|
335
339
|
this.isResuming = true;
|
@@ -1471,6 +1475,23 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
1471
1475
|
participant?.emit(ParticipantEvent.DataReceived, userPacket.payload, kind);
|
1472
1476
|
};
|
1473
1477
|
|
1478
|
+
bufferedSegments: Map<string, TranscriptionSegmentModel> = new Map();
|
1479
|
+
|
1480
|
+
private handleTranscription = (transcription: TranscriptionModel) => {
|
1481
|
+
// find the participant
|
1482
|
+
const participant =
|
1483
|
+
transcription.participantIdentity === this.localParticipant.identity
|
1484
|
+
? this.localParticipant
|
1485
|
+
: this.remoteParticipants.get(transcription.participantIdentity);
|
1486
|
+
const publication = participant?.trackPublications.get(transcription.trackId);
|
1487
|
+
|
1488
|
+
const segments = extractTranscriptionSegments(transcription);
|
1489
|
+
|
1490
|
+
publication?.emit(TrackEvent.TranscriptionReceived, segments);
|
1491
|
+
participant?.emit(ParticipantEvent.TranscriptionReceived, segments, publication);
|
1492
|
+
this.emit(RoomEvent.TranscriptionReceived, segments, participant, publication);
|
1493
|
+
};
|
1494
|
+
|
1474
1495
|
private handleAudioPlaybackStarted = () => {
|
1475
1496
|
if (this.canPlaybackAudio) {
|
1476
1497
|
return;
|
@@ -2071,6 +2092,11 @@ export type RoomEventCallbacks = {
|
|
2071
2092
|
kind?: DataPacket_Kind,
|
2072
2093
|
topic?: string,
|
2073
2094
|
) => void;
|
2095
|
+
transcriptionReceived: (
|
2096
|
+
transcription: TranscriptionSegment[],
|
2097
|
+
participant?: Participant,
|
2098
|
+
publication?: TrackPublication,
|
2099
|
+
) => void;
|
2074
2100
|
connectionQualityChanged: (quality: ConnectionQuality, participant: Participant) => void;
|
2075
2101
|
mediaDevicesError: (error: Error) => void;
|
2076
2102
|
trackStreamStateChanged: (
|
package/src/room/events.ts
CHANGED
@@ -197,6 +197,12 @@ export enum RoomEvent {
|
|
197
197
|
*/
|
198
198
|
DataReceived = 'dataReceived',
|
199
199
|
|
200
|
+
/**
|
201
|
+
* Transcription received from a participant's track.
|
202
|
+
* @beta
|
203
|
+
*/
|
204
|
+
TranscriptionReceived = 'transcriptionReceived',
|
205
|
+
|
200
206
|
/**
|
201
207
|
* Connection quality was changed for a Participant. It'll receive updates
|
202
208
|
* from the local participant, as well as any [[RemoteParticipant]]s that we are
|
@@ -402,6 +408,12 @@ export enum ParticipantEvent {
|
|
402
408
|
*/
|
403
409
|
DataReceived = 'dataReceived',
|
404
410
|
|
411
|
+
/**
|
412
|
+
* Transcription received from this participant as data source.
|
413
|
+
* @beta
|
414
|
+
*/
|
415
|
+
TranscriptionReceived = 'transcriptionReceived',
|
416
|
+
|
405
417
|
/**
|
406
418
|
* Has speaking status changed for the current participant
|
407
419
|
*
|
@@ -479,6 +491,7 @@ export enum EngineEvent {
|
|
479
491
|
MediaTrackAdded = 'mediaTrackAdded',
|
480
492
|
ActiveSpeakersUpdate = 'activeSpeakersUpdate',
|
481
493
|
DataPacketReceived = 'dataPacketReceived',
|
494
|
+
TranscriptionReceived = 'transcriptionReceived',
|
482
495
|
RTPVideoMapUpdate = 'rtpVideoMapUpdate',
|
483
496
|
DCBufferStatusChanged = 'dcBufferStatusChanged',
|
484
497
|
ParticipantUpdate = 'participantUpdate',
|
@@ -562,4 +575,14 @@ export enum TrackEvent {
|
|
562
575
|
* @internal
|
563
576
|
*/
|
564
577
|
AudioTrackFeatureUpdate = 'audioTrackFeatureUpdate',
|
578
|
+
|
579
|
+
/**
|
580
|
+
* @beta
|
581
|
+
*/
|
582
|
+
TranscriptionReceived = 'transcriptionReceived',
|
583
|
+
|
584
|
+
/**
|
585
|
+
* @experimental
|
586
|
+
*/
|
587
|
+
TimeSyncUpdate = 'timeSyncUpdate',
|
565
588
|
}
|
@@ -16,7 +16,7 @@ import type RemoteTrack from '../track/RemoteTrack';
|
|
16
16
|
import type RemoteTrackPublication from '../track/RemoteTrackPublication';
|
17
17
|
import { Track } from '../track/Track';
|
18
18
|
import type { TrackPublication } from '../track/TrackPublication';
|
19
|
-
import type { LoggerOptions } from '../types';
|
19
|
+
import type { LoggerOptions, TranscriptionSegment } from '../types';
|
20
20
|
|
21
21
|
export enum ConnectionQuality {
|
22
22
|
Excellent = 'excellent',
|
@@ -329,6 +329,10 @@ export type ParticipantEventCallbacks = {
|
|
329
329
|
participantMetadataChanged: (prevMetadata: string | undefined, participant?: any) => void;
|
330
330
|
participantNameChanged: (name: string) => void;
|
331
331
|
dataReceived: (payload: Uint8Array, kind: DataPacket_Kind) => void;
|
332
|
+
transcriptionReceived: (
|
333
|
+
transcription: TranscriptionSegment[],
|
334
|
+
publication?: TrackPublication,
|
335
|
+
) => void;
|
332
336
|
isSpeakingChanged: (speaking: boolean) => void;
|
333
337
|
connectionQualityChanged: (connectionQuality: ConnectionQuality) => void;
|
334
338
|
trackStreamStateChanged: (
|
@@ -77,7 +77,20 @@ export default abstract class RemoteTrack<
|
|
77
77
|
if (!this.monitorInterval) {
|
78
78
|
this.monitorInterval = setInterval(() => this.monitorReceiver(), monitorFrequency);
|
79
79
|
}
|
80
|
+
this.registerTimeSyncUpdate();
|
80
81
|
}
|
81
82
|
|
82
83
|
protected abstract monitorReceiver(): void;
|
84
|
+
|
85
|
+
registerTimeSyncUpdate() {
|
86
|
+
const loop = () => {
|
87
|
+
this.timeSyncHandle = requestAnimationFrame(() => loop());
|
88
|
+
const newTime = this.receiver?.getSynchronizationSources()[0]?.rtpTimestamp;
|
89
|
+
if (newTime && this.rtpTimestamp !== newTime) {
|
90
|
+
this.emit(TrackEvent.TimeSyncUpdate, newTime);
|
91
|
+
this.rtpTimestamp = newTime;
|
92
|
+
}
|
93
|
+
};
|
94
|
+
loop();
|
95
|
+
}
|
83
96
|
}
|
package/src/room/track/Track.ts
CHANGED
@@ -53,6 +53,9 @@ export abstract class Track<
|
|
53
53
|
*/
|
54
54
|
streamState: Track.StreamState = Track.StreamState.Active;
|
55
55
|
|
56
|
+
/** @internal */
|
57
|
+
rtpTimestamp: number | undefined;
|
58
|
+
|
56
59
|
protected _mediaStreamTrack: MediaStreamTrack;
|
57
60
|
|
58
61
|
protected _mediaStreamID: string;
|
@@ -63,6 +66,8 @@ export abstract class Track<
|
|
63
66
|
|
64
67
|
private loggerContextCb: LoggerOptions['loggerContextCb'];
|
65
68
|
|
69
|
+
protected timeSyncHandle: number | undefined;
|
70
|
+
|
66
71
|
protected _currentBitrate: number = 0;
|
67
72
|
|
68
73
|
protected monitorInterval?: ReturnType<typeof setInterval>;
|
@@ -255,6 +260,9 @@ export abstract class Track<
|
|
255
260
|
if (this.monitorInterval) {
|
256
261
|
clearInterval(this.monitorInterval);
|
257
262
|
}
|
263
|
+
if (this.timeSyncHandle) {
|
264
|
+
cancelAnimationFrame(this.timeSyncHandle);
|
265
|
+
}
|
258
266
|
}
|
259
267
|
|
260
268
|
/** @internal */
|
@@ -517,4 +525,5 @@ export type TrackEventCallbacks = {
|
|
517
525
|
upstreamResumed: (track: any) => void;
|
518
526
|
trackProcessorUpdate: (processor?: TrackProcessor<Track.Kind, any>) => void;
|
519
527
|
audioTrackFeatureUpdate: (track: any, feature: AudioTrackFeature, enabled: boolean) => void;
|
528
|
+
timeSyncUpdate: (timestamp: number) => void;
|
520
529
|
};
|
@@ -9,7 +9,7 @@ import { EventEmitter } from 'events';
|
|
9
9
|
import type TypedEventEmitter from 'typed-emitter';
|
10
10
|
import log, { LoggerNames, getLogger } from '../../logger';
|
11
11
|
import { TrackEvent } from '../events';
|
12
|
-
import type { LoggerOptions } from '../types';
|
12
|
+
import type { LoggerOptions, TranscriptionSegment } from '../types';
|
13
13
|
import LocalAudioTrack from './LocalAudioTrack';
|
14
14
|
import LocalVideoTrack from './LocalVideoTrack';
|
15
15
|
import RemoteAudioTrack from './RemoteAudioTrack';
|
@@ -174,4 +174,6 @@ export type PublicationEventCallbacks = {
|
|
174
174
|
prevStatus: TrackPublication.SubscriptionStatus,
|
175
175
|
) => void;
|
176
176
|
subscriptionFailed: (error: SubscriptionError) => void;
|
177
|
+
transcriptionReceived: (transcription: TranscriptionSegment[]) => void;
|
178
|
+
timeSyncUpdate: (timestamp: number) => void;
|
177
179
|
};
|
package/src/room/types.ts
CHANGED
@@ -55,3 +55,12 @@ export type LoggerOptions = {
|
|
55
55
|
loggerName?: string;
|
56
56
|
loggerContextCb?: () => Record<string, unknown>;
|
57
57
|
};
|
58
|
+
|
59
|
+
export interface TranscriptionSegment {
|
60
|
+
id: string;
|
61
|
+
text: string;
|
62
|
+
language: string;
|
63
|
+
startTime: number;
|
64
|
+
endTime: number;
|
65
|
+
final: boolean;
|
66
|
+
}
|
package/src/room/utils.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ClientInfo, ClientInfo_SDK } from '@livekit/protocol';
|
1
|
+
import { ClientInfo, ClientInfo_SDK, Transcription as TranscriptionModel } from '@livekit/protocol';
|
2
2
|
import { getBrowser } from '../utils/browserParser';
|
3
3
|
import { protocolVersion, version } from '../version';
|
4
4
|
import CriticalTimers from './timers';
|
@@ -6,7 +6,7 @@ import type LocalAudioTrack from './track/LocalAudioTrack';
|
|
6
6
|
import type RemoteAudioTrack from './track/RemoteAudioTrack';
|
7
7
|
import { VideoCodec, videoCodecs } from './track/options';
|
8
8
|
import { getNewAudioContext } from './track/utils';
|
9
|
-
import type { LiveKitReactNativeInfo } from './types';
|
9
|
+
import type { LiveKitReactNativeInfo, TranscriptionSegment } from './types';
|
10
10
|
|
11
11
|
const separator = '|';
|
12
12
|
export const ddExtensionURI =
|
@@ -527,3 +527,18 @@ export function toHttpUrl(url: string): string {
|
|
527
527
|
}
|
528
528
|
return url;
|
529
529
|
}
|
530
|
+
|
531
|
+
export function extractTranscriptionSegments(
|
532
|
+
transcription: TranscriptionModel,
|
533
|
+
): TranscriptionSegment[] {
|
534
|
+
return transcription.segments.map(({ id, text, language, startTime, endTime, final }) => {
|
535
|
+
return {
|
536
|
+
id,
|
537
|
+
text,
|
538
|
+
startTime: Number.parseInt(startTime.toString()),
|
539
|
+
endTime: Number.parseInt(endTime.toString()),
|
540
|
+
final,
|
541
|
+
language,
|
542
|
+
};
|
543
|
+
});
|
544
|
+
}
|