livekit-client
Advanced tools
Comparing version 0.6.6 to 0.6.7
import 'webrtc-adapter'; | ||
import { ParticipantInfo, TrackType } from '../proto/livekit_models'; | ||
import { JoinResponse, SignalRequest, SignalTarget, SpeakerInfo, TrackPublishedResponse, UpdateSubscription, UpdateTrackSettings } from '../proto/livekit_rtc'; | ||
interface SignalOptions { | ||
usePlanB?: boolean; | ||
reconnect?: boolean; | ||
} | ||
/** | ||
@@ -9,3 +13,3 @@ * RTCClient is the signaling layer of WebRTC, it's LiveKit's signaling protocol | ||
export interface SignalClient { | ||
join(url: string, token: string): Promise<JoinResponse>; | ||
join(url: string, token: string, usePlanB?: boolean): Promise<JoinResponse>; | ||
reconnect(url: string, token: string): Promise<void>; | ||
@@ -29,2 +33,3 @@ sendOffer(offer: RTCSessionDescriptionInit): void; | ||
onActiveSpeakersChanged?: (res: SpeakerInfo[]) => void; | ||
onLeave?: () => void; | ||
} | ||
@@ -42,7 +47,8 @@ export declare class WSSignalClient { | ||
onActiveSpeakersChanged?: (res: SpeakerInfo[]) => void; | ||
onLeave?: () => void; | ||
ws?: WebSocket; | ||
constructor(useJSON?: boolean); | ||
join(url: string, token: string, planB?: boolean): Promise<JoinResponse>; | ||
reconnect(url: string, token: string): Promise<void>; | ||
join(url: string, token: string): Promise<JoinResponse>; | ||
join(url: string, token: string, reconnect: boolean): Promise<void>; | ||
connect(url: string, token: string, opts: SignalOptions): Promise<JoinResponse | void>; | ||
close(): void; | ||
@@ -61,1 +67,2 @@ sendOffer(offer: RTCSessionDescriptionInit): void; | ||
} | ||
export {}; |
@@ -19,2 +19,3 @@ "use strict"; | ||
const livekit_rtc_1 = require("../proto/livekit_rtc"); | ||
const version_1 = require("../version"); | ||
class WSSignalClient { | ||
@@ -25,12 +26,25 @@ constructor(useJSON = false) { | ||
} | ||
join(url, token, planB = false) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const res = yield this.connect(url, token, { | ||
usePlanB: planB, | ||
}); | ||
return res; | ||
}); | ||
} | ||
reconnect(url, token) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this.join(url, token, true); | ||
yield this.connect(url, token, { | ||
reconnect: true, | ||
}); | ||
}); | ||
} | ||
join(url, token, reconnect = false) { | ||
url += `/rtc?access_token=${token}`; | ||
if (reconnect) { | ||
connect(url, token, opts) { | ||
url += `/rtc?access_token=${token}&protocol=${version_1.protocolVersion}`; | ||
if (opts.reconnect) { | ||
url += '&reconnect=1'; | ||
} | ||
if (opts.usePlanB) { | ||
url += '&planb=1'; | ||
} | ||
return new Promise((resolve, reject) => { | ||
@@ -51,3 +65,3 @@ loglevel_1.default.debug('connecting to', url); | ||
this.ws = ws; | ||
if (reconnect) { | ||
if (opts.reconnect) { | ||
// upon reconnection, there will not be additional handshake | ||
@@ -196,2 +210,7 @@ this.isConnected = true; | ||
} | ||
else if (msg.leave) { | ||
if (this.onLeave) { | ||
this.onLeave(); | ||
} | ||
} | ||
else { | ||
@@ -198,0 +217,0 @@ console.warn('unsupported message', msg); |
@@ -50,2 +50,4 @@ import _m0 from 'protobufjs/minimal'; | ||
speaker?: ActiveSpeakerUpdate | undefined; | ||
/** Immediately terminate session */ | ||
leave?: LeaveRequest | undefined; | ||
} | ||
@@ -52,0 +54,0 @@ export interface AddTrackRequest { |
@@ -314,2 +314,5 @@ "use strict"; | ||
} | ||
if (message.leave !== undefined) { | ||
exports.LeaveRequest.encode(message.leave, writer.uint32(66).fork()).ldelim(); | ||
} | ||
return writer; | ||
@@ -345,2 +348,5 @@ }, | ||
break; | ||
case 8: | ||
message.leave = exports.LeaveRequest.decode(reader, reader.uint32()); | ||
break; | ||
default: | ||
@@ -397,2 +403,8 @@ reader.skipType(tag & 7); | ||
} | ||
if (object.leave !== undefined && object.leave !== null) { | ||
message.leave = exports.LeaveRequest.fromJSON(object.leave); | ||
} | ||
else { | ||
message.leave = undefined; | ||
} | ||
return message; | ||
@@ -428,2 +440,6 @@ }, | ||
: undefined); | ||
message.leave !== undefined && | ||
(obj.leave = message.leave | ||
? exports.LeaveRequest.toJSON(message.leave) | ||
: undefined); | ||
return obj; | ||
@@ -475,2 +491,8 @@ }, | ||
} | ||
if (object.leave !== undefined && object.leave !== null) { | ||
message.leave = exports.LeaveRequest.fromPartial(object.leave); | ||
} | ||
else { | ||
message.leave = undefined; | ||
} | ||
return message; | ||
@@ -477,0 +499,0 @@ }, |
@@ -118,2 +118,3 @@ "use strict"; | ||
if (track.kind === Track_1.Track.Kind.Video) { | ||
// TODO: support react native, which doesn't expose getSettings | ||
const settings = track.mediaStreamTrack.getSettings(); | ||
@@ -120,0 +121,0 @@ encodings = this.computeVideoEncodings(settings.width, settings.height, options); |
@@ -32,2 +32,4 @@ /// <reference types="node" /> | ||
getTracks(): TrackPublication[]; | ||
/** when participant joined the room */ | ||
get joinedAt(): Date | undefined; | ||
/** @internal */ | ||
@@ -34,0 +36,0 @@ updateInfo(info: ParticipantInfo): void; |
@@ -23,2 +23,8 @@ "use strict"; | ||
} | ||
/** when participant joined the room */ | ||
get joinedAt() { | ||
if (this.participantInfo) { | ||
return new Date(this.participantInfo.joinedAt * 1000); | ||
} | ||
} | ||
/** @internal */ | ||
@@ -25,0 +31,0 @@ updateInfo(info) { |
@@ -19,3 +19,3 @@ import { SignalClient } from '../../api/SignalClient'; | ||
/** @internal */ | ||
addSubscribedMediaTrack(mediaTrack: MediaStreamTrack, sid: Track.SID, receiver: RTCRtpReceiver, triesLeft?: number): RemoteTrackPublication | undefined; | ||
addSubscribedMediaTrack(mediaTrack: MediaStreamTrack, sid: Track.SID, receiver?: RTCRtpReceiver, triesLeft?: number): RemoteTrackPublication | undefined; | ||
/** @internal */ | ||
@@ -22,0 +22,0 @@ addSubscribedDataTrack(dataChannel: RTCDataChannel, sid: Track.SID, name: string): RemoteTrackPublication; |
@@ -65,3 +65,3 @@ "use strict"; | ||
this.localParticipant = new LocalParticipant_1.LocalParticipant(pi.sid, pi.identity, this.engine); | ||
this.localParticipant.setMetadata(pi.metadata); | ||
this.localParticipant.updateInfo(pi); | ||
// forward metadata changed for the local participant | ||
@@ -97,4 +97,4 @@ this.localParticipant.on(events_2.ParticipantEvent.MetadataChanged, (metadata, p) => { | ||
this.engine = new RTCEngine_1.RTCEngine(client, config); | ||
this.engine.on(events_2.EngineEvent.MediaTrackAdded, (mediaTrack, receiver, streams) => { | ||
this.onTrackAdded(mediaTrack, receiver, streams); | ||
this.engine.on(events_2.EngineEvent.MediaTrackAdded, (mediaTrack, stream, receiver) => { | ||
this.onTrackAdded(mediaTrack, stream, receiver); | ||
}); | ||
@@ -123,5 +123,8 @@ this.engine.on(events_2.EngineEvent.DataChannelAdded, (dataChannel) => { | ||
} | ||
onTrackAdded(mediaTrack, receiver, streams) { | ||
const participantId = streams[0].id; | ||
const trackId = mediaTrack.id; | ||
onTrackAdded(mediaTrack, stream, receiver) { | ||
const parts = utils_1.unpackStreamId(stream.id); | ||
const participantId = parts[0]; | ||
let trackId = parts[1]; | ||
if (!trackId || trackId === '') | ||
trackId = mediaTrack.id; | ||
const participant = this.getOrCreateParticipant(participantId); | ||
@@ -128,0 +131,0 @@ participant.addSubscribedMediaTrack(mediaTrack, trackId, receiver); |
@@ -13,2 +13,3 @@ /// <reference types="node" /> | ||
rtcConfig: RTCConfiguration; | ||
useLegacy: boolean; | ||
privateDC?: RTCDataChannel; | ||
@@ -33,2 +34,3 @@ rtcConnected: boolean; | ||
private onRTCConnected; | ||
private emitTrackEvent; | ||
} |
@@ -23,2 +23,3 @@ "use strict"; | ||
const Track_1 = require("./track/Track"); | ||
const utils_1 = require("./utils"); | ||
const placeholderDataChannel = '_private'; | ||
@@ -59,5 +60,10 @@ const maxWSRetries = 10; | ||
}; | ||
this.emitTrackEvent = (track, stream, receiver) => { | ||
this.emit(events_2.EngineEvent.MediaTrackAdded, track, stream, receiver); | ||
}; | ||
this.client = client; | ||
this.rtcConfig = config || {}; | ||
this.numRetries = 0; | ||
this.useLegacy = utils_1.useLegacyAPI(); | ||
loglevel_1.default.trace('creating RTCEngine', 'useLegacy', this.useLegacy); | ||
} | ||
@@ -68,3 +74,3 @@ join(url, token) { | ||
this.token = token; | ||
const joinResponse = yield this.client.join(url, token); | ||
const joinResponse = yield this.client.join(url, token, this.useLegacy); | ||
if (joinResponse.iceServers && !this.rtcConfig.iceServers) { | ||
@@ -85,2 +91,6 @@ this.rtcConfig.iceServers = []; | ||
if (!this.publisher) { | ||
const conf = this.rtcConfig; | ||
if (this.useLegacy) { | ||
conf.sdpSemantics = 'plan-b'; | ||
} | ||
this.publisher = new PCTransport_1.PCTransport(this.rtcConfig); | ||
@@ -174,9 +184,18 @@ this.subscriber = new PCTransport_1.PCTransport(this.rtcConfig); | ||
}; | ||
this.subscriber.pc.ontrack = (ev) => { | ||
loglevel_1.default.debug('engine fired track added', ev.track); | ||
this.emit(events_2.EngineEvent.MediaTrackAdded, ev.track, ev.receiver, ev.streams); | ||
}; | ||
this.subscriber.pc.ondatachannel = (ev) => { | ||
this.emit(events_2.EngineEvent.DataChannelAdded, ev.channel); | ||
}; | ||
if (this.useLegacy) { | ||
this.subscriber.pc.addEventListener('addstream', (ev) => { | ||
const stream = ev.stream; | ||
for (let t of stream.getTracks()) { | ||
this.emitTrackEvent(t, stream); | ||
} | ||
}); | ||
} | ||
else { | ||
this.subscriber.pc.ontrack = (ev) => { | ||
this.emitTrackEvent(ev.track, ev.streams[0], ev.receiver); | ||
}; | ||
this.subscriber.pc.ondatachannel = (ev) => { | ||
this.emit(events_2.EngineEvent.DataChannelAdded, ev.channel); | ||
}; | ||
} | ||
// always have a blank data channel, to ensure there isn't an empty ice-ufrag | ||
@@ -236,2 +255,6 @@ this.privateDC = this.publisher.pc.createDataChannel(placeholderDataChannel); | ||
this.client.onClose = this.handleWSClose; | ||
this.client.onLeave = () => { | ||
this.close(); | ||
this.emit(events_2.EngineEvent.Disconnected); | ||
}; | ||
} | ||
@@ -238,0 +261,0 @@ negotiate() { |
@@ -5,5 +5,5 @@ import { AudioTrack } from './AudioTrack'; | ||
receiver?: RTCRtpReceiver; | ||
constructor(mediaTrack: MediaStreamTrack, sid: string, receiver: RTCRtpReceiver); | ||
constructor(mediaTrack: MediaStreamTrack, sid: string, receiver?: RTCRtpReceiver); | ||
/** @internal */ | ||
setMuted(muted: boolean): void; | ||
} |
@@ -7,3 +7,3 @@ import { VideoReceiverStats } from '../stats'; | ||
private prevStats?; | ||
constructor(mediaTrack: MediaStreamTrack, sid: string, receiver: RTCRtpReceiver); | ||
constructor(mediaTrack: MediaStreamTrack, sid: string, receiver?: RTCRtpReceiver); | ||
/** @internal */ | ||
@@ -10,0 +10,0 @@ setMuted(muted: boolean): void; |
@@ -14,7 +14,12 @@ "use strict"; | ||
this.mediaStreamTrack = mediaTrack; | ||
const { width, height } = mediaTrack.getSettings(); | ||
if (width && height) { | ||
this.dimensions.width = width; | ||
this.dimensions.height = height; | ||
try { | ||
const { width, height } = mediaTrack.getSettings(); | ||
if (width && height) { | ||
this.dimensions.width = width; | ||
this.dimensions.height = height; | ||
} | ||
} | ||
catch (e) { | ||
// ignore, react native doesn't support getSettings | ||
} | ||
} | ||
@@ -21,0 +26,0 @@ attach(element) { |
@@ -1,2 +0,3 @@ | ||
export declare function unpackTrackId(packed: string): string[]; | ||
export declare function unpackStreamId(packed: string): string[]; | ||
export declare function unpackDataTrackLabel(packed: string): string[]; | ||
export declare function useLegacyAPI(): boolean; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.unpackDataTrackLabel = exports.unpackTrackId = void 0; | ||
exports.useLegacyAPI = exports.unpackDataTrackLabel = exports.unpackStreamId = void 0; | ||
const separator = '|'; | ||
function unpackTrackId(packed) { | ||
function unpackStreamId(packed) { | ||
const parts = packed.split(separator); | ||
@@ -10,5 +10,5 @@ if (parts.length > 1) { | ||
} | ||
return ['', packed]; | ||
return [packed, '']; | ||
} | ||
exports.unpackTrackId = unpackTrackId; | ||
exports.unpackStreamId = unpackStreamId; | ||
function unpackDataTrackLabel(packed) { | ||
@@ -22,2 +22,7 @@ const parts = packed.split(separator); | ||
exports.unpackDataTrackLabel = unpackDataTrackLabel; | ||
function useLegacyAPI() { | ||
// react native is using old stream based API | ||
return typeof navigator != 'undefined' && navigator.product == 'ReactNative'; | ||
} | ||
exports.useLegacyAPI = useLegacyAPI; | ||
//# sourceMappingURL=utils.js.map |
@@ -1,2 +0,2 @@ | ||
declare const version = "0.6.6"; | ||
export { version }; | ||
export declare const version = "0.6.7"; | ||
export declare const protocolVersion = 1; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.version = void 0; | ||
const version = '0.6.6'; | ||
exports.version = version; | ||
exports.protocolVersion = exports.version = void 0; | ||
exports.version = '0.6.7'; | ||
exports.protocolVersion = 1; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "livekit-client", | ||
"version": "0.6.6", | ||
"version": "0.6.7", | ||
"description": "JavaScript/TypeScript client SDK for LiveKit", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
559600
9028