livekit-client 0.18.4-RC7 → 0.18.4-RC8
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.
@@ -9848,24 +9848,47 @@ function getClientInfo() {
|
|
9848
9848
|
});
|
9849
9849
|
return info;
|
9850
9850
|
}
|
9851
|
-
let
|
9852
|
-
function
|
9853
|
-
|
9851
|
+
let emptyVideoStreamTrack;
|
9852
|
+
function getEmptyVideoStreamTrack() {
|
9853
|
+
var _a;
|
9854
|
+
|
9855
|
+
if (!emptyVideoStreamTrack) {
|
9854
9856
|
const canvas = document.createElement('canvas');
|
9855
9857
|
canvas.width = 2;
|
9856
|
-
canvas.height = 2;
|
9858
|
+
canvas.height = 2;
|
9859
|
+
(_a = canvas.getContext('2d')) === null || _a === void 0 ? void 0 : _a.fillRect(0, 0, canvas.width, canvas.height); // @ts-ignore
|
9857
9860
|
|
9858
9861
|
const emptyStream = canvas.captureStream();
|
9859
|
-
[
|
9862
|
+
[emptyVideoStreamTrack] = emptyStream.getTracks();
|
9863
|
+
|
9864
|
+
if (!emptyVideoStreamTrack) {
|
9865
|
+
throw Error('Could not get empty media stream video track');
|
9866
|
+
}
|
9867
|
+
|
9868
|
+
emptyVideoStreamTrack.enabled = false;
|
9869
|
+
}
|
9870
|
+
|
9871
|
+
return emptyVideoStreamTrack;
|
9872
|
+
}
|
9873
|
+
let emptyAudioStreamTrack;
|
9874
|
+
function getEmptyAudioStreamTrack() {
|
9875
|
+
if (!emptyAudioStreamTrack) {
|
9876
|
+
// implementation adapted from https://blog.mozilla.org/webrtc/warm-up-with-replacetrack/
|
9877
|
+
const ctx = new AudioContext();
|
9878
|
+
const oscillator = ctx.createOscillator();
|
9879
|
+
const dst = ctx.createMediaStreamDestination();
|
9880
|
+
oscillator.connect(dst);
|
9881
|
+
oscillator.start();
|
9882
|
+
[emptyAudioStreamTrack] = dst.stream.getAudioTracks();
|
9860
9883
|
|
9861
|
-
if (!
|
9862
|
-
throw Error('Could not get empty media stream track');
|
9884
|
+
if (!emptyAudioStreamTrack) {
|
9885
|
+
throw Error('Could not get empty media stream audio track');
|
9863
9886
|
}
|
9864
9887
|
|
9865
|
-
|
9888
|
+
emptyAudioStreamTrack.enabled = false;
|
9866
9889
|
}
|
9867
9890
|
|
9868
|
-
return
|
9891
|
+
return emptyAudioStreamTrack;
|
9869
9892
|
}
|
9870
9893
|
|
9871
9894
|
var events = {exports: {}};
|
@@ -10840,7 +10863,8 @@ class LocalTrack extends Track {
|
|
10840
10863
|
|
10841
10864
|
this._isUpstreamPaused = true;
|
10842
10865
|
this.emit(TrackEvent.UpstreamPaused, this);
|
10843
|
-
|
10866
|
+
const emptyTrack = this.kind === Track.Kind.Audio ? getEmptyAudioStreamTrack() : getEmptyVideoStreamTrack();
|
10867
|
+
await this.sender.replaceTrack(emptyTrack);
|
10844
10868
|
}
|
10845
10869
|
|
10846
10870
|
async resumeUpstream() {
|
@@ -11639,6 +11663,10 @@ class RemoteVideoTrack extends RemoteTrack {
|
|
11639
11663
|
this.updateDimensions();
|
11640
11664
|
}, REACTION_DELAY);
|
11641
11665
|
this.adaptiveStreamSettings = adaptiveStreamSettings;
|
11666
|
+
|
11667
|
+
if (this.isAdaptiveStream) {
|
11668
|
+
this.streamState = Track.StreamState.Paused;
|
11669
|
+
}
|
11642
11670
|
}
|
11643
11671
|
|
11644
11672
|
get isAdaptiveStream() {
|
@@ -18097,9 +18125,11 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
18097
18125
|
};
|
18098
18126
|
|
18099
18127
|
let primaryPC = this.publisher.pc;
|
18128
|
+
let secondaryPC = this.subscriber.pc;
|
18100
18129
|
|
18101
18130
|
if (joinResponse.subscriberPrimary) {
|
18102
|
-
primaryPC = this.subscriber.pc;
|
18131
|
+
primaryPC = this.subscriber.pc;
|
18132
|
+
secondaryPC = this.publisher.pc; // in subscriber primary mode, server side opens sub data channels.
|
18103
18133
|
|
18104
18134
|
this.subscriber.pc.ondatachannel = this.handleDataChannel;
|
18105
18135
|
}
|
@@ -18130,11 +18160,18 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
18130
18160
|
// on Safari, PeerConnection will switch to 'disconnected' during renegotiation
|
18131
18161
|
if (this.pcState === PCState.Connected) {
|
18132
18162
|
this.pcState = PCState.Disconnected;
|
18133
|
-
this.handleDisconnect('peerconnection');
|
18163
|
+
this.handleDisconnect('primary peerconnection');
|
18134
18164
|
}
|
18135
18165
|
}
|
18136
18166
|
};
|
18137
18167
|
|
18168
|
+
secondaryPC.onconnectionstatechange = async () => {
|
18169
|
+
// also reconnect if secondary peerconnection fails
|
18170
|
+
if (secondaryPC.connectionState === 'failed') {
|
18171
|
+
this.handleDisconnect('secondary peerconnection');
|
18172
|
+
}
|
18173
|
+
};
|
18174
|
+
|
18138
18175
|
if (isWeb()) {
|
18139
18176
|
this.subscriber.pc.ontrack = ev => {
|
18140
18177
|
this.emit(EngineEvent.MediaTrackAdded, ev.track, ev.streams[0], ev.receiver);
|