@afosecure/meetingsdk 1.3.1 → 1.3.3
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/index.d.mts +2 -21
- package/dist/index.d.ts +2 -21
- package/dist/index.js +64 -163
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -163
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -130,7 +130,7 @@ declare class VideoSDKCore {
|
|
|
130
130
|
private localStream;
|
|
131
131
|
private screenStream;
|
|
132
132
|
private isScreenSharing;
|
|
133
|
-
private
|
|
133
|
+
private screenSenders;
|
|
134
134
|
private pingInterval;
|
|
135
135
|
private pendingIceCandidates;
|
|
136
136
|
private pendingOffers;
|
|
@@ -159,32 +159,13 @@ declare class VideoSDKCore {
|
|
|
159
159
|
private reset;
|
|
160
160
|
private handleJoinApproved;
|
|
161
161
|
private handle;
|
|
162
|
-
/**
|
|
163
|
-
* Create a peer connection with pre-established transceiver layout:
|
|
164
|
-
* - Audio transceiver (sendrecv)
|
|
165
|
-
* - Camera video transceiver (sendrecv)
|
|
166
|
-
* - Screen video transceiver (initially recvonly, becomes sendrecv when sharing)
|
|
167
|
-
*
|
|
168
|
-
* This fixed layout ensures late joiners get the screen transceiver m-line
|
|
169
|
-
* negotiated from the very first offer, even if no one is sharing yet.
|
|
170
|
-
*/
|
|
171
162
|
private createPeer;
|
|
172
|
-
/**
|
|
173
|
-
* Capture the screen transceiver's MID after SDP negotiation completes.
|
|
174
|
-
* The MID is assigned during negotiation and is stable for the life of the connection.
|
|
175
|
-
*/
|
|
176
|
-
private captureScreenMid;
|
|
177
163
|
private createOffer;
|
|
178
164
|
private shouldInitiate;
|
|
179
165
|
private handleOffer;
|
|
180
166
|
private closePeer;
|
|
181
|
-
/**
|
|
182
|
-
* Start screen sharing using replaceTrack on the pre-established screen transceiver.
|
|
183
|
-
* No need to add/remove tracks, no renegotiation needed (transceiver already in SDP).
|
|
184
|
-
* Just swap the track and update direction if needed.
|
|
185
|
-
*/
|
|
186
167
|
startScreenShare(): Promise<MediaStream>;
|
|
187
|
-
stopScreenShare():
|
|
168
|
+
stopScreenShare(): void;
|
|
188
169
|
sendChatMessage(payload: ChatInput): void;
|
|
189
170
|
disconnect(): void;
|
|
190
171
|
private flushIce;
|
package/dist/index.d.ts
CHANGED
|
@@ -130,7 +130,7 @@ declare class VideoSDKCore {
|
|
|
130
130
|
private localStream;
|
|
131
131
|
private screenStream;
|
|
132
132
|
private isScreenSharing;
|
|
133
|
-
private
|
|
133
|
+
private screenSenders;
|
|
134
134
|
private pingInterval;
|
|
135
135
|
private pendingIceCandidates;
|
|
136
136
|
private pendingOffers;
|
|
@@ -159,32 +159,13 @@ declare class VideoSDKCore {
|
|
|
159
159
|
private reset;
|
|
160
160
|
private handleJoinApproved;
|
|
161
161
|
private handle;
|
|
162
|
-
/**
|
|
163
|
-
* Create a peer connection with pre-established transceiver layout:
|
|
164
|
-
* - Audio transceiver (sendrecv)
|
|
165
|
-
* - Camera video transceiver (sendrecv)
|
|
166
|
-
* - Screen video transceiver (initially recvonly, becomes sendrecv when sharing)
|
|
167
|
-
*
|
|
168
|
-
* This fixed layout ensures late joiners get the screen transceiver m-line
|
|
169
|
-
* negotiated from the very first offer, even if no one is sharing yet.
|
|
170
|
-
*/
|
|
171
162
|
private createPeer;
|
|
172
|
-
/**
|
|
173
|
-
* Capture the screen transceiver's MID after SDP negotiation completes.
|
|
174
|
-
* The MID is assigned during negotiation and is stable for the life of the connection.
|
|
175
|
-
*/
|
|
176
|
-
private captureScreenMid;
|
|
177
163
|
private createOffer;
|
|
178
164
|
private shouldInitiate;
|
|
179
165
|
private handleOffer;
|
|
180
166
|
private closePeer;
|
|
181
|
-
/**
|
|
182
|
-
* Start screen sharing using replaceTrack on the pre-established screen transceiver.
|
|
183
|
-
* No need to add/remove tracks, no renegotiation needed (transceiver already in SDP).
|
|
184
|
-
* Just swap the track and update direction if needed.
|
|
185
|
-
*/
|
|
186
167
|
startScreenShare(): Promise<MediaStream>;
|
|
187
|
-
stopScreenShare():
|
|
168
|
+
stopScreenShare(): void;
|
|
188
169
|
sendChatMessage(payload: ChatInput): void;
|
|
189
170
|
disconnect(): void;
|
|
190
171
|
private flushIce;
|
package/dist/index.js
CHANGED
|
@@ -210,8 +210,7 @@ var VideoSDKCore = class {
|
|
|
210
210
|
this.localStream = null;
|
|
211
211
|
this.screenStream = null;
|
|
212
212
|
this.isScreenSharing = false;
|
|
213
|
-
|
|
214
|
-
this.peerTransceivers = {};
|
|
213
|
+
this.screenSenders = {};
|
|
215
214
|
this.pingInterval = null;
|
|
216
215
|
this.pendingIceCandidates = {};
|
|
217
216
|
this.pendingOffers = {};
|
|
@@ -240,7 +239,7 @@ var VideoSDKCore = class {
|
|
|
240
239
|
this.joinRejecter = void 0;
|
|
241
240
|
console.error("[MeetingSDK Error]", err);
|
|
242
241
|
}
|
|
243
|
-
// STREAM
|
|
242
|
+
// ---------------- STREAM ----------------
|
|
244
243
|
async initLocal(video, name) {
|
|
245
244
|
this.participantName = name;
|
|
246
245
|
try {
|
|
@@ -277,7 +276,7 @@ var VideoSDKCore = class {
|
|
|
277
276
|
throw err;
|
|
278
277
|
}
|
|
279
278
|
}
|
|
280
|
-
// CONNECT
|
|
279
|
+
// ---------------- CONNECT ----------------
|
|
281
280
|
async connect(roomId, name) {
|
|
282
281
|
this.room.id = roomId;
|
|
283
282
|
this.reset();
|
|
@@ -423,11 +422,10 @@ var VideoSDKCore = class {
|
|
|
423
422
|
this.pingInterval = null;
|
|
424
423
|
}
|
|
425
424
|
}
|
|
426
|
-
// RESET
|
|
425
|
+
// ---------------- RESET ----------------
|
|
427
426
|
reset() {
|
|
428
427
|
Object.values(this.peers).forEach((pc) => pc.close());
|
|
429
428
|
this.peers = {};
|
|
430
|
-
this.peerTransceivers = {};
|
|
431
429
|
this.initiators.clear();
|
|
432
430
|
this.pendingIceCandidates = {};
|
|
433
431
|
this.state.resetRemoteState();
|
|
@@ -482,7 +480,6 @@ var VideoSDKCore = class {
|
|
|
482
480
|
type: "answer",
|
|
483
481
|
sdp: msg.payload
|
|
484
482
|
});
|
|
485
|
-
this.captureScreenMid(msg.sender);
|
|
486
483
|
await this.flushIce(msg.sender, pc);
|
|
487
484
|
} catch (err) {
|
|
488
485
|
console.error("[Signaling] Failed to apply answer:", err);
|
|
@@ -519,6 +516,7 @@ var VideoSDKCore = class {
|
|
|
519
516
|
if (msg.presenterId) {
|
|
520
517
|
this.state.setPresenterId(msg.presenterId);
|
|
521
518
|
this.events.onScreenShareStarted?.(msg.presenterId, null);
|
|
519
|
+
this.state.setPresenterId(msg.presenterId);
|
|
522
520
|
}
|
|
523
521
|
for (const p of msg.participants || []) {
|
|
524
522
|
if (!p?.id || p.id === this.myId) continue;
|
|
@@ -601,10 +599,12 @@ var VideoSDKCore = class {
|
|
|
601
599
|
});
|
|
602
600
|
break;
|
|
603
601
|
}
|
|
602
|
+
// ============ NEW: HANDLE JOIN_APPROVED WITH RECONNECT ============
|
|
604
603
|
case "JOIN_APPROVED": {
|
|
605
604
|
await this.handleJoinApproved(msg);
|
|
606
605
|
break;
|
|
607
606
|
}
|
|
607
|
+
// ============ END: JOIN_APPROVED ============
|
|
608
608
|
case "JOIN_REJECTED": {
|
|
609
609
|
const decision = "rejected";
|
|
610
610
|
console.log("JOIN_REJECTED - user not allowed to join");
|
|
@@ -657,7 +657,8 @@ var VideoSDKCore = class {
|
|
|
657
657
|
if (!this.state.presenterId) {
|
|
658
658
|
this.state.setPresenterId(peerId2);
|
|
659
659
|
}
|
|
660
|
-
this.
|
|
660
|
+
const screenStream = this.state.getParticipant(peerId2)?.media?.screenStream;
|
|
661
|
+
this.events.onScreenShareStarted?.(peerId2, screenStream || null);
|
|
661
662
|
break;
|
|
662
663
|
}
|
|
663
664
|
case "SCREEN_SHARE_STOP": {
|
|
@@ -684,17 +685,8 @@ var VideoSDKCore = class {
|
|
|
684
685
|
}
|
|
685
686
|
}
|
|
686
687
|
}
|
|
687
|
-
// PEER
|
|
688
|
-
|
|
689
|
-
* Create a peer connection with pre-established transceiver layout:
|
|
690
|
-
* - Audio transceiver (sendrecv)
|
|
691
|
-
* - Camera video transceiver (sendrecv)
|
|
692
|
-
* - Screen video transceiver (initially recvonly, becomes sendrecv when sharing)
|
|
693
|
-
*
|
|
694
|
-
* This fixed layout ensures late joiners get the screen transceiver m-line
|
|
695
|
-
* negotiated from the very first offer, even if no one is sharing yet.
|
|
696
|
-
*/
|
|
697
|
-
async createPeer(id) {
|
|
688
|
+
// ---------------- PEER ----------------
|
|
689
|
+
createPeer(id) {
|
|
698
690
|
if (!this.localStream) throw new Error("No local stream");
|
|
699
691
|
if (!this.iceServers || this.iceServers.length === 0) {
|
|
700
692
|
throw new Error(
|
|
@@ -702,9 +694,7 @@ var VideoSDKCore = class {
|
|
|
702
694
|
);
|
|
703
695
|
}
|
|
704
696
|
console.log(
|
|
705
|
-
"
|
|
706
|
-
id,
|
|
707
|
-
"with tracks:",
|
|
697
|
+
"Adding tracks",
|
|
708
698
|
this.localStream.getTracks().map((t) => ({
|
|
709
699
|
kind: t.kind,
|
|
710
700
|
enabled: t.enabled,
|
|
@@ -714,52 +704,25 @@ var VideoSDKCore = class {
|
|
|
714
704
|
const pc = new RTCPeerConnection({
|
|
715
705
|
iceServers: this.iceServers
|
|
716
706
|
});
|
|
717
|
-
const audioTransceiver = pc.addTransceiver("audio", {
|
|
718
|
-
direction: "sendrecv"
|
|
719
|
-
});
|
|
720
|
-
const audioTrack = this.localStream.getAudioTracks()[0];
|
|
721
|
-
if (audioTrack) {
|
|
722
|
-
await audioTransceiver.sender.replaceTrack(audioTrack);
|
|
723
|
-
}
|
|
724
|
-
const cameraTransceiver = pc.addTransceiver("video", {
|
|
725
|
-
direction: "sendrecv"
|
|
726
|
-
});
|
|
727
|
-
const videoTrack = this.localStream.getVideoTracks()[0];
|
|
728
|
-
if (videoTrack) {
|
|
729
|
-
await cameraTransceiver.sender.replaceTrack(videoTrack);
|
|
730
|
-
}
|
|
731
|
-
const screenTransceiver = pc.addTransceiver("video", {
|
|
732
|
-
direction: this.isScreenSharing ? "sendrecv" : "recvonly"
|
|
733
|
-
});
|
|
734
|
-
if (this.isScreenSharing && this.screenStream) {
|
|
735
|
-
const screenTrack = this.screenStream.getVideoTracks()[0];
|
|
736
|
-
if (screenTrack) {
|
|
737
|
-
await screenTransceiver.sender.replaceTrack(screenTrack);
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
this.peerTransceivers[id] = {
|
|
741
|
-
cameraTransceiver,
|
|
742
|
-
screenTransceiver,
|
|
743
|
-
screenMid: null
|
|
744
|
-
// will be populated after negotiation
|
|
745
|
-
};
|
|
746
707
|
pc.ontrack = (event) => {
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
console.log(
|
|
750
|
-
|
|
751
|
-
);
|
|
708
|
+
console.log("ontrack");
|
|
709
|
+
console.log("kind:", event.track.kind);
|
|
710
|
+
console.log("mid:", event.transceiver.mid);
|
|
711
|
+
console.log("streams:", event.streams);
|
|
712
|
+
console.log("stream id:", event.streams[0]?.id);
|
|
752
713
|
const incomingStream = event.streams?.[0] || new MediaStream([event.track]);
|
|
714
|
+
const participant = this.state.getParticipant(id);
|
|
715
|
+
const isScreenStream = participant?.media?.isScreenSharing && incomingStream.id === participant?.media?.remoteScreenStreamId;
|
|
753
716
|
if (event.track.muted) {
|
|
754
717
|
event.track.onunmute = () => {
|
|
755
|
-
console.log(
|
|
718
|
+
console.log(`${event.track.kind} track unmuted for ${id}`);
|
|
756
719
|
};
|
|
757
720
|
}
|
|
758
|
-
if (
|
|
759
|
-
const
|
|
721
|
+
if (isScreenStream) {
|
|
722
|
+
const videoTrack = event.track.kind === "video" ? event.track : incomingStream.getVideoTracks()[0] || participant?.media?.screenTrack;
|
|
760
723
|
this.state.updateParticipantMedia(id, {
|
|
761
724
|
screenStream: incomingStream,
|
|
762
|
-
screenTrack:
|
|
725
|
+
screenTrack: videoTrack,
|
|
763
726
|
isScreenSharing: true
|
|
764
727
|
});
|
|
765
728
|
if (!this.state.presenterId) {
|
|
@@ -785,41 +748,29 @@ var VideoSDKCore = class {
|
|
|
785
748
|
});
|
|
786
749
|
};
|
|
787
750
|
pc.oniceconnectionstatechange = () => {
|
|
788
|
-
console.log(`
|
|
751
|
+
console.log(`ICE Connection State: ${pc.iceConnectionState}`);
|
|
789
752
|
};
|
|
790
753
|
pc.onconnectionstatechange = () => {
|
|
791
|
-
console.log(`[Connection] ${id}: ${pc.connectionState}`);
|
|
792
754
|
if (pc.connectionState === "failed") {
|
|
793
755
|
try {
|
|
794
756
|
pc.restartIce();
|
|
795
|
-
} catch
|
|
796
|
-
console.warn("Failed to restart ICE:", e);
|
|
757
|
+
} catch {
|
|
797
758
|
}
|
|
798
759
|
}
|
|
799
760
|
};
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
const transceivers = pc.getTransceivers();
|
|
810
|
-
const screenTransceiver = this.peerTransceivers[peerId]?.screenTransceiver;
|
|
811
|
-
if (!screenTransceiver) return;
|
|
812
|
-
const negotiatedTransceiver = transceivers.find(
|
|
813
|
-
(t) => t === screenTransceiver
|
|
814
|
-
);
|
|
815
|
-
if (negotiatedTransceiver?.mid) {
|
|
816
|
-
this.peerTransceivers[peerId].screenMid = negotiatedTransceiver.mid;
|
|
817
|
-
console.log(
|
|
818
|
-
`[Negotiation] Captured screenMid for ${peerId}: ${negotiatedTransceiver.mid}`
|
|
819
|
-
);
|
|
761
|
+
this.localStream.getTracks().forEach((track) => {
|
|
762
|
+
pc.addTrack(track, this.localStream);
|
|
763
|
+
});
|
|
764
|
+
if (this.isScreenSharing && this.screenStream) {
|
|
765
|
+
this.screenSenders[id] = [];
|
|
766
|
+
this.screenStream.getTracks().forEach((track) => {
|
|
767
|
+
const sender = pc.addTrack(track, this.screenStream);
|
|
768
|
+
this.screenSenders[id].push(sender);
|
|
769
|
+
});
|
|
820
770
|
}
|
|
771
|
+
return pc;
|
|
821
772
|
}
|
|
822
|
-
// OFFER
|
|
773
|
+
// ---------------- OFFER ----------------
|
|
823
774
|
async createOffer(id, isRenegotiation = false) {
|
|
824
775
|
if (!isRenegotiation && !this.shouldInitiate(id)) {
|
|
825
776
|
console.debug(
|
|
@@ -837,13 +788,12 @@ var VideoSDKCore = class {
|
|
|
837
788
|
this.initiators.add(id);
|
|
838
789
|
}
|
|
839
790
|
if (!this.peers[id]) {
|
|
840
|
-
this.peers[id] =
|
|
791
|
+
this.peers[id] = this.createPeer(id);
|
|
841
792
|
}
|
|
842
793
|
const pc = this.peers[id];
|
|
843
794
|
try {
|
|
844
795
|
const offer = await pc.createOffer();
|
|
845
796
|
await pc.setLocalDescription(offer);
|
|
846
|
-
this.captureScreenMid(id);
|
|
847
797
|
this.send({
|
|
848
798
|
type: "OFFER",
|
|
849
799
|
payload: offer.sdp,
|
|
@@ -853,18 +803,12 @@ var VideoSDKCore = class {
|
|
|
853
803
|
console.debug(`[Offer] Sent to ${id}`);
|
|
854
804
|
} catch (err) {
|
|
855
805
|
console.error(`[Offer] Failed for ${id}:`, err);
|
|
856
|
-
this.emitError(
|
|
857
|
-
"OFFER_CREATION_FAILED",
|
|
858
|
-
`Failed to create offer for ${id}`,
|
|
859
|
-
err,
|
|
860
|
-
true
|
|
861
|
-
);
|
|
862
806
|
}
|
|
863
807
|
}
|
|
864
808
|
shouldInitiate(peerId) {
|
|
865
809
|
return this.myId < peerId;
|
|
866
810
|
}
|
|
867
|
-
// ANSWER
|
|
811
|
+
// ---------------- ANSWER ----------------
|
|
868
812
|
async handleOffer(sdp, id) {
|
|
869
813
|
if (!this.iceServers || this.iceServers.length === 0) {
|
|
870
814
|
console.warn("[Offer] Waiting for iceServers, queuing offer from", id);
|
|
@@ -872,7 +816,7 @@ var VideoSDKCore = class {
|
|
|
872
816
|
return;
|
|
873
817
|
}
|
|
874
818
|
if (!this.peers[id]) {
|
|
875
|
-
this.peers[id] =
|
|
819
|
+
this.peers[id] = this.createPeer(id);
|
|
876
820
|
}
|
|
877
821
|
const pc = this.peers[id];
|
|
878
822
|
try {
|
|
@@ -888,9 +832,8 @@ var VideoSDKCore = class {
|
|
|
888
832
|
);
|
|
889
833
|
pc.close();
|
|
890
834
|
delete this.peers[id];
|
|
891
|
-
delete this.peerTransceivers[id];
|
|
892
835
|
this.initiators.delete(id);
|
|
893
|
-
this.peers[id] =
|
|
836
|
+
this.peers[id] = this.createPeer(id);
|
|
894
837
|
}
|
|
895
838
|
}
|
|
896
839
|
if (this.peers[id].signalingState !== "stable" && this.peers[id].signalingState !== "have-local-offer") {
|
|
@@ -903,7 +846,6 @@ var VideoSDKCore = class {
|
|
|
903
846
|
type: "offer",
|
|
904
847
|
sdp
|
|
905
848
|
});
|
|
906
|
-
this.captureScreenMid(id);
|
|
907
849
|
const pending = this.pendingIceCandidates[id] || [];
|
|
908
850
|
for (const candidate of pending) {
|
|
909
851
|
try {
|
|
@@ -933,26 +875,18 @@ var VideoSDKCore = class {
|
|
|
933
875
|
);
|
|
934
876
|
}
|
|
935
877
|
}
|
|
936
|
-
// CLEANUP
|
|
878
|
+
// ---------------- CLEANUP ----------------
|
|
937
879
|
closePeer(id) {
|
|
938
880
|
const pc = this.peers[id];
|
|
939
881
|
if (!pc) return;
|
|
940
882
|
pc.ontrack = null;
|
|
941
883
|
pc.onicecandidate = null;
|
|
942
884
|
pc.onconnectionstatechange = null;
|
|
943
|
-
pc.oniceconnectionstatechange = null;
|
|
944
885
|
pc.close();
|
|
945
886
|
delete this.peers[id];
|
|
946
|
-
delete this.peerTransceivers[id];
|
|
947
887
|
this.initiators.delete(id);
|
|
948
888
|
this.state.removeParticipant(id);
|
|
949
889
|
}
|
|
950
|
-
// SCREEN SHARE (TRANSCEIVER-BASED)
|
|
951
|
-
/**
|
|
952
|
-
* Start screen sharing using replaceTrack on the pre-established screen transceiver.
|
|
953
|
-
* No need to add/remove tracks, no renegotiation needed (transceiver already in SDP).
|
|
954
|
-
* Just swap the track and update direction if needed.
|
|
955
|
-
*/
|
|
956
890
|
async startScreenShare() {
|
|
957
891
|
try {
|
|
958
892
|
if (this.state.presenterId && this.state.presenterId !== this.myId) {
|
|
@@ -963,55 +897,34 @@ var VideoSDKCore = class {
|
|
|
963
897
|
}
|
|
964
898
|
this.screenStream = await navigator.mediaDevices.getDisplayMedia({
|
|
965
899
|
video: true
|
|
900
|
+
// audio: true,
|
|
966
901
|
});
|
|
967
|
-
const screenTrack = this.screenStream.getVideoTracks()[0];
|
|
968
|
-
if (!screenTrack) {
|
|
969
|
-
throw new Error("No video track in screen stream");
|
|
970
|
-
}
|
|
971
902
|
this.isScreenSharing = true;
|
|
972
903
|
this.state.updateLocalParticipant({
|
|
973
904
|
media: {
|
|
974
905
|
isScreenSharing: true,
|
|
975
906
|
screenStream: this.screenStream,
|
|
976
|
-
screenTrack
|
|
907
|
+
screenTrack: this.screenStream.getVideoTracks()[0]
|
|
977
908
|
}
|
|
978
909
|
});
|
|
979
910
|
this.state.setPresenterId(this.myId);
|
|
980
|
-
|
|
981
|
-
console.log("[Screen Share] User stopped via browser button");
|
|
911
|
+
this.screenStream.getVideoTracks()[0].onended = () => {
|
|
982
912
|
this.stopScreenShare();
|
|
983
913
|
};
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
try {
|
|
993
|
-
await txInfo.screenTransceiver.sender.replaceTrack(screenTrack);
|
|
994
|
-
if (txInfo.screenTransceiver.currentDirection === "recvonly") {
|
|
995
|
-
txInfo.screenTransceiver.direction = "sendrecv";
|
|
996
|
-
console.log(
|
|
997
|
-
`[Screen Share] Flipped ${peerId} screen transceiver to sendrecv`
|
|
998
|
-
);
|
|
999
|
-
await this.createOffer(peerId, true);
|
|
1000
|
-
}
|
|
1001
|
-
} catch (err) {
|
|
1002
|
-
console.error(
|
|
1003
|
-
`[Screen Share] Failed to update transceiver for ${peerId}:`,
|
|
1004
|
-
err
|
|
1005
|
-
);
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
914
|
+
Object.entries(this.peers).forEach(([peerId, pc]) => {
|
|
915
|
+
this.screenSenders[peerId] = [];
|
|
916
|
+
this.screenStream.getTracks().forEach((track) => {
|
|
917
|
+
const sender = pc.addTrack(track, this.screenStream);
|
|
918
|
+
this.screenSenders[peerId].push(sender);
|
|
919
|
+
});
|
|
920
|
+
this.createOffer(peerId, true);
|
|
921
|
+
});
|
|
1008
922
|
this.send({
|
|
1009
923
|
type: "SCREEN_SHARE_START",
|
|
1010
924
|
sender: this.myId,
|
|
1011
925
|
room_id: this.room.id,
|
|
1012
926
|
stream_id: this.screenStream.id.replace(/[{}]/g, "")
|
|
1013
927
|
});
|
|
1014
|
-
console.log("[Screen Share] Started successfully");
|
|
1015
928
|
return this.screenStream;
|
|
1016
929
|
} catch (err) {
|
|
1017
930
|
this.emitError(
|
|
@@ -1025,29 +938,21 @@ var VideoSDKCore = class {
|
|
|
1025
938
|
throw err;
|
|
1026
939
|
}
|
|
1027
940
|
}
|
|
1028
|
-
|
|
941
|
+
stopScreenShare() {
|
|
1029
942
|
if (!this.screenStream) return;
|
|
1030
|
-
console.log("[Screen Share] Stopping...");
|
|
1031
943
|
this.screenStream.getTracks().forEach((t) => t.stop());
|
|
1032
|
-
|
|
1033
|
-
const
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
console.log(
|
|
1040
|
-
`[Screen Share] Flipped ${peerId} screen transceiver to recvonly`
|
|
1041
|
-
);
|
|
1042
|
-
await this.createOffer(peerId, true);
|
|
944
|
+
Object.entries(this.peers).forEach(([peerId, pc]) => {
|
|
945
|
+
const senders = this.screenSenders[peerId] || [];
|
|
946
|
+
senders.forEach((sender) => {
|
|
947
|
+
try {
|
|
948
|
+
pc.removeTrack(sender);
|
|
949
|
+
} catch (err) {
|
|
950
|
+
console.warn(err);
|
|
1043
951
|
}
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
);
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
952
|
+
});
|
|
953
|
+
delete this.screenSenders[peerId];
|
|
954
|
+
this.createOffer(peerId, true);
|
|
955
|
+
});
|
|
1051
956
|
this.screenStream = null;
|
|
1052
957
|
this.isScreenSharing = false;
|
|
1053
958
|
this.state.updateLocalParticipant({
|
|
@@ -1065,9 +970,7 @@ var VideoSDKCore = class {
|
|
|
1065
970
|
sender: this.myId,
|
|
1066
971
|
room_id: this.room.id
|
|
1067
972
|
});
|
|
1068
|
-
console.log("[Screen Share] Stopped");
|
|
1069
973
|
}
|
|
1070
|
-
// CHAT
|
|
1071
974
|
sendChatMessage(payload) {
|
|
1072
975
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
1073
976
|
console.warn("WS not connected");
|
|
@@ -1100,13 +1003,11 @@ var VideoSDKCore = class {
|
|
|
1100
1003
|
client_ts: Date.now()
|
|
1101
1004
|
});
|
|
1102
1005
|
}
|
|
1103
|
-
// DISCONNECT
|
|
1104
1006
|
disconnect() {
|
|
1105
1007
|
this.intentionalDisconnect = true;
|
|
1106
1008
|
this.stopScreenShare();
|
|
1107
1009
|
Object.values(this.peers).forEach((pc) => pc.close());
|
|
1108
1010
|
this.peers = {};
|
|
1109
|
-
this.peerTransceivers = {};
|
|
1110
1011
|
this.initiators.clear();
|
|
1111
1012
|
this.stopHeartbeat();
|
|
1112
1013
|
if (this.ws?.readyState === WebSocket.OPEN) {
|