@afosecure/meetingsdk 1.3.2 → 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 +3 -16
- package/dist/index.d.ts +3 -16
- package/dist/index.js +66 -158
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +66 -158
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -177,8 +177,7 @@ var VideoSDKCore = class {
|
|
|
177
177
|
this.localStream = null;
|
|
178
178
|
this.screenStream = null;
|
|
179
179
|
this.isScreenSharing = false;
|
|
180
|
-
|
|
181
|
-
this.peerTransceivers = {};
|
|
180
|
+
this.screenSenders = {};
|
|
182
181
|
this.pingInterval = null;
|
|
183
182
|
this.pendingIceCandidates = {};
|
|
184
183
|
this.pendingOffers = {};
|
|
@@ -207,7 +206,7 @@ var VideoSDKCore = class {
|
|
|
207
206
|
this.joinRejecter = void 0;
|
|
208
207
|
console.error("[MeetingSDK Error]", err);
|
|
209
208
|
}
|
|
210
|
-
// STREAM
|
|
209
|
+
// ---------------- STREAM ----------------
|
|
211
210
|
async initLocal(video, name) {
|
|
212
211
|
this.participantName = name;
|
|
213
212
|
try {
|
|
@@ -244,7 +243,7 @@ var VideoSDKCore = class {
|
|
|
244
243
|
throw err;
|
|
245
244
|
}
|
|
246
245
|
}
|
|
247
|
-
// CONNECT
|
|
246
|
+
// ---------------- CONNECT ----------------
|
|
248
247
|
async connect(roomId, name) {
|
|
249
248
|
this.room.id = roomId;
|
|
250
249
|
this.reset();
|
|
@@ -390,11 +389,10 @@ var VideoSDKCore = class {
|
|
|
390
389
|
this.pingInterval = null;
|
|
391
390
|
}
|
|
392
391
|
}
|
|
393
|
-
// RESET
|
|
392
|
+
// ---------------- RESET ----------------
|
|
394
393
|
reset() {
|
|
395
394
|
Object.values(this.peers).forEach((pc) => pc.close());
|
|
396
395
|
this.peers = {};
|
|
397
|
-
this.peerTransceivers = {};
|
|
398
396
|
this.initiators.clear();
|
|
399
397
|
this.pendingIceCandidates = {};
|
|
400
398
|
this.state.resetRemoteState();
|
|
@@ -449,7 +447,6 @@ var VideoSDKCore = class {
|
|
|
449
447
|
type: "answer",
|
|
450
448
|
sdp: msg.payload
|
|
451
449
|
});
|
|
452
|
-
this.captureScreenMid(msg.sender);
|
|
453
450
|
await this.flushIce(msg.sender, pc);
|
|
454
451
|
} catch (err) {
|
|
455
452
|
console.error("[Signaling] Failed to apply answer:", err);
|
|
@@ -486,6 +483,7 @@ var VideoSDKCore = class {
|
|
|
486
483
|
if (msg.presenterId) {
|
|
487
484
|
this.state.setPresenterId(msg.presenterId);
|
|
488
485
|
this.events.onScreenShareStarted?.(msg.presenterId, null);
|
|
486
|
+
this.state.setPresenterId(msg.presenterId);
|
|
489
487
|
}
|
|
490
488
|
for (const p of msg.participants || []) {
|
|
491
489
|
if (!p?.id || p.id === this.myId) continue;
|
|
@@ -568,10 +566,12 @@ var VideoSDKCore = class {
|
|
|
568
566
|
});
|
|
569
567
|
break;
|
|
570
568
|
}
|
|
569
|
+
// ============ NEW: HANDLE JOIN_APPROVED WITH RECONNECT ============
|
|
571
570
|
case "JOIN_APPROVED": {
|
|
572
571
|
await this.handleJoinApproved(msg);
|
|
573
572
|
break;
|
|
574
573
|
}
|
|
574
|
+
// ============ END: JOIN_APPROVED ============
|
|
575
575
|
case "JOIN_REJECTED": {
|
|
576
576
|
const decision = "rejected";
|
|
577
577
|
console.log("JOIN_REJECTED - user not allowed to join");
|
|
@@ -624,7 +624,8 @@ var VideoSDKCore = class {
|
|
|
624
624
|
if (!this.state.presenterId) {
|
|
625
625
|
this.state.setPresenterId(peerId2);
|
|
626
626
|
}
|
|
627
|
-
this.
|
|
627
|
+
const screenStream = this.state.getParticipant(peerId2)?.media?.screenStream;
|
|
628
|
+
this.events.onScreenShareStarted?.(peerId2, screenStream || null);
|
|
628
629
|
break;
|
|
629
630
|
}
|
|
630
631
|
case "SCREEN_SHARE_STOP": {
|
|
@@ -651,7 +652,8 @@ var VideoSDKCore = class {
|
|
|
651
652
|
}
|
|
652
653
|
}
|
|
653
654
|
}
|
|
654
|
-
|
|
655
|
+
// ---------------- PEER ----------------
|
|
656
|
+
createPeer(id) {
|
|
655
657
|
if (!this.localStream) throw new Error("No local stream");
|
|
656
658
|
if (!this.iceServers || this.iceServers.length === 0) {
|
|
657
659
|
throw new Error(
|
|
@@ -659,9 +661,7 @@ var VideoSDKCore = class {
|
|
|
659
661
|
);
|
|
660
662
|
}
|
|
661
663
|
console.log(
|
|
662
|
-
"
|
|
663
|
-
id,
|
|
664
|
-
"with tracks:",
|
|
664
|
+
"Adding tracks",
|
|
665
665
|
this.localStream.getTracks().map((t) => ({
|
|
666
666
|
kind: t.kind,
|
|
667
667
|
enabled: t.enabled,
|
|
@@ -671,52 +671,25 @@ var VideoSDKCore = class {
|
|
|
671
671
|
const pc = new RTCPeerConnection({
|
|
672
672
|
iceServers: this.iceServers
|
|
673
673
|
});
|
|
674
|
-
const audioTransceiver = pc.addTransceiver("audio", {
|
|
675
|
-
direction: "sendrecv"
|
|
676
|
-
});
|
|
677
|
-
const audioTrack = this.localStream.getAudioTracks()[0];
|
|
678
|
-
if (audioTrack) {
|
|
679
|
-
await audioTransceiver.sender.replaceTrack(audioTrack);
|
|
680
|
-
}
|
|
681
|
-
const cameraTransceiver = pc.addTransceiver("video", {
|
|
682
|
-
direction: "sendrecv"
|
|
683
|
-
});
|
|
684
|
-
const videoTrack = this.localStream.getVideoTracks()[0];
|
|
685
|
-
if (videoTrack) {
|
|
686
|
-
await cameraTransceiver.sender.replaceTrack(videoTrack);
|
|
687
|
-
}
|
|
688
|
-
const screenTransceiver = pc.addTransceiver("video", {
|
|
689
|
-
direction: this.isScreenSharing ? "sendrecv" : "recvonly"
|
|
690
|
-
});
|
|
691
|
-
if (this.isScreenSharing && this.screenStream) {
|
|
692
|
-
const screenTrack = this.screenStream.getVideoTracks()[0];
|
|
693
|
-
if (screenTrack) {
|
|
694
|
-
await screenTransceiver.sender.replaceTrack(screenTrack);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
this.peerTransceivers[id] = {
|
|
698
|
-
cameraTransceiver,
|
|
699
|
-
screenTransceiver,
|
|
700
|
-
screenMid: null
|
|
701
|
-
// will be populated after negotiation
|
|
702
|
-
};
|
|
703
674
|
pc.ontrack = (event) => {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
console.log(
|
|
707
|
-
|
|
708
|
-
);
|
|
675
|
+
console.log("ontrack");
|
|
676
|
+
console.log("kind:", event.track.kind);
|
|
677
|
+
console.log("mid:", event.transceiver.mid);
|
|
678
|
+
console.log("streams:", event.streams);
|
|
679
|
+
console.log("stream id:", event.streams[0]?.id);
|
|
709
680
|
const incomingStream = event.streams?.[0] || new MediaStream([event.track]);
|
|
681
|
+
const participant = this.state.getParticipant(id);
|
|
682
|
+
const isScreenStream = participant?.media?.isScreenSharing && incomingStream.id === participant?.media?.remoteScreenStreamId;
|
|
710
683
|
if (event.track.muted) {
|
|
711
684
|
event.track.onunmute = () => {
|
|
712
|
-
console.log(
|
|
685
|
+
console.log(`${event.track.kind} track unmuted for ${id}`);
|
|
713
686
|
};
|
|
714
687
|
}
|
|
715
|
-
if (
|
|
716
|
-
const
|
|
688
|
+
if (isScreenStream) {
|
|
689
|
+
const videoTrack = event.track.kind === "video" ? event.track : incomingStream.getVideoTracks()[0] || participant?.media?.screenTrack;
|
|
717
690
|
this.state.updateParticipantMedia(id, {
|
|
718
691
|
screenStream: incomingStream,
|
|
719
|
-
screenTrack:
|
|
692
|
+
screenTrack: videoTrack,
|
|
720
693
|
isScreenSharing: true
|
|
721
694
|
});
|
|
722
695
|
if (!this.state.presenterId) {
|
|
@@ -742,41 +715,29 @@ var VideoSDKCore = class {
|
|
|
742
715
|
});
|
|
743
716
|
};
|
|
744
717
|
pc.oniceconnectionstatechange = () => {
|
|
745
|
-
console.log(`
|
|
718
|
+
console.log(`ICE Connection State: ${pc.iceConnectionState}`);
|
|
746
719
|
};
|
|
747
720
|
pc.onconnectionstatechange = () => {
|
|
748
|
-
console.log(`[Connection] ${id}: ${pc.connectionState}`);
|
|
749
721
|
if (pc.connectionState === "failed") {
|
|
750
722
|
try {
|
|
751
723
|
pc.restartIce();
|
|
752
|
-
} catch
|
|
753
|
-
console.warn("Failed to restart ICE:", e);
|
|
724
|
+
} catch {
|
|
754
725
|
}
|
|
755
726
|
}
|
|
756
727
|
};
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
const transceivers = pc.getTransceivers();
|
|
767
|
-
const screenTransceiver = this.peerTransceivers[peerId]?.screenTransceiver;
|
|
768
|
-
if (!screenTransceiver) return;
|
|
769
|
-
const negotiatedTransceiver = transceivers.find(
|
|
770
|
-
(t) => t === screenTransceiver
|
|
771
|
-
);
|
|
772
|
-
if (negotiatedTransceiver?.mid) {
|
|
773
|
-
this.peerTransceivers[peerId].screenMid = negotiatedTransceiver.mid;
|
|
774
|
-
console.log(
|
|
775
|
-
`[Negotiation] Captured screenMid for ${peerId}: ${negotiatedTransceiver.mid}`
|
|
776
|
-
);
|
|
728
|
+
this.localStream.getTracks().forEach((track) => {
|
|
729
|
+
pc.addTrack(track, this.localStream);
|
|
730
|
+
});
|
|
731
|
+
if (this.isScreenSharing && this.screenStream) {
|
|
732
|
+
this.screenSenders[id] = [];
|
|
733
|
+
this.screenStream.getTracks().forEach((track) => {
|
|
734
|
+
const sender = pc.addTrack(track, this.screenStream);
|
|
735
|
+
this.screenSenders[id].push(sender);
|
|
736
|
+
});
|
|
777
737
|
}
|
|
738
|
+
return pc;
|
|
778
739
|
}
|
|
779
|
-
// OFFER
|
|
740
|
+
// ---------------- OFFER ----------------
|
|
780
741
|
async createOffer(id, isRenegotiation = false) {
|
|
781
742
|
if (!isRenegotiation && !this.shouldInitiate(id)) {
|
|
782
743
|
console.debug(
|
|
@@ -794,13 +755,12 @@ var VideoSDKCore = class {
|
|
|
794
755
|
this.initiators.add(id);
|
|
795
756
|
}
|
|
796
757
|
if (!this.peers[id]) {
|
|
797
|
-
this.peers[id] =
|
|
758
|
+
this.peers[id] = this.createPeer(id);
|
|
798
759
|
}
|
|
799
760
|
const pc = this.peers[id];
|
|
800
761
|
try {
|
|
801
762
|
const offer = await pc.createOffer();
|
|
802
763
|
await pc.setLocalDescription(offer);
|
|
803
|
-
this.captureScreenMid(id);
|
|
804
764
|
this.send({
|
|
805
765
|
type: "OFFER",
|
|
806
766
|
payload: offer.sdp,
|
|
@@ -810,18 +770,12 @@ var VideoSDKCore = class {
|
|
|
810
770
|
console.debug(`[Offer] Sent to ${id}`);
|
|
811
771
|
} catch (err) {
|
|
812
772
|
console.error(`[Offer] Failed for ${id}:`, err);
|
|
813
|
-
this.emitError(
|
|
814
|
-
"OFFER_CREATION_FAILED",
|
|
815
|
-
`Failed to create offer for ${id}`,
|
|
816
|
-
err,
|
|
817
|
-
true
|
|
818
|
-
);
|
|
819
773
|
}
|
|
820
774
|
}
|
|
821
775
|
shouldInitiate(peerId) {
|
|
822
776
|
return this.myId < peerId;
|
|
823
777
|
}
|
|
824
|
-
// ANSWER
|
|
778
|
+
// ---------------- ANSWER ----------------
|
|
825
779
|
async handleOffer(sdp, id) {
|
|
826
780
|
if (!this.iceServers || this.iceServers.length === 0) {
|
|
827
781
|
console.warn("[Offer] Waiting for iceServers, queuing offer from", id);
|
|
@@ -829,7 +783,7 @@ var VideoSDKCore = class {
|
|
|
829
783
|
return;
|
|
830
784
|
}
|
|
831
785
|
if (!this.peers[id]) {
|
|
832
|
-
this.peers[id] =
|
|
786
|
+
this.peers[id] = this.createPeer(id);
|
|
833
787
|
}
|
|
834
788
|
const pc = this.peers[id];
|
|
835
789
|
try {
|
|
@@ -845,9 +799,8 @@ var VideoSDKCore = class {
|
|
|
845
799
|
);
|
|
846
800
|
pc.close();
|
|
847
801
|
delete this.peers[id];
|
|
848
|
-
delete this.peerTransceivers[id];
|
|
849
802
|
this.initiators.delete(id);
|
|
850
|
-
this.peers[id] =
|
|
803
|
+
this.peers[id] = this.createPeer(id);
|
|
851
804
|
}
|
|
852
805
|
}
|
|
853
806
|
if (this.peers[id].signalingState !== "stable" && this.peers[id].signalingState !== "have-local-offer") {
|
|
@@ -860,7 +813,6 @@ var VideoSDKCore = class {
|
|
|
860
813
|
type: "offer",
|
|
861
814
|
sdp
|
|
862
815
|
});
|
|
863
|
-
this.captureScreenMid(id);
|
|
864
816
|
const pending = this.pendingIceCandidates[id] || [];
|
|
865
817
|
for (const candidate of pending) {
|
|
866
818
|
try {
|
|
@@ -890,26 +842,18 @@ var VideoSDKCore = class {
|
|
|
890
842
|
);
|
|
891
843
|
}
|
|
892
844
|
}
|
|
893
|
-
// CLEANUP
|
|
845
|
+
// ---------------- CLEANUP ----------------
|
|
894
846
|
closePeer(id) {
|
|
895
847
|
const pc = this.peers[id];
|
|
896
848
|
if (!pc) return;
|
|
897
849
|
pc.ontrack = null;
|
|
898
850
|
pc.onicecandidate = null;
|
|
899
851
|
pc.onconnectionstatechange = null;
|
|
900
|
-
pc.oniceconnectionstatechange = null;
|
|
901
852
|
pc.close();
|
|
902
853
|
delete this.peers[id];
|
|
903
|
-
delete this.peerTransceivers[id];
|
|
904
854
|
this.initiators.delete(id);
|
|
905
855
|
this.state.removeParticipant(id);
|
|
906
856
|
}
|
|
907
|
-
// SCREEN SHARE (TRANSCEIVER-BASED)
|
|
908
|
-
/**
|
|
909
|
-
* Start screen sharing using replaceTrack on the pre-established screen transceiver.
|
|
910
|
-
* No need to add/remove tracks, no renegotiation needed (transceiver already in SDP).
|
|
911
|
-
* Just swap the track and update direction if needed.
|
|
912
|
-
*/
|
|
913
857
|
async startScreenShare() {
|
|
914
858
|
try {
|
|
915
859
|
if (this.state.presenterId && this.state.presenterId !== this.myId) {
|
|
@@ -920,55 +864,34 @@ var VideoSDKCore = class {
|
|
|
920
864
|
}
|
|
921
865
|
this.screenStream = await navigator.mediaDevices.getDisplayMedia({
|
|
922
866
|
video: true
|
|
867
|
+
// audio: true,
|
|
923
868
|
});
|
|
924
|
-
const screenTrack = this.screenStream.getVideoTracks()[0];
|
|
925
|
-
if (!screenTrack) {
|
|
926
|
-
throw new Error("No video track in screen stream");
|
|
927
|
-
}
|
|
928
869
|
this.isScreenSharing = true;
|
|
929
870
|
this.state.updateLocalParticipant({
|
|
930
871
|
media: {
|
|
931
872
|
isScreenSharing: true,
|
|
932
873
|
screenStream: this.screenStream,
|
|
933
|
-
screenTrack
|
|
874
|
+
screenTrack: this.screenStream.getVideoTracks()[0]
|
|
934
875
|
}
|
|
935
876
|
});
|
|
936
877
|
this.state.setPresenterId(this.myId);
|
|
937
|
-
|
|
938
|
-
console.log("[Screen Share] User stopped via browser button");
|
|
878
|
+
this.screenStream.getVideoTracks()[0].onended = () => {
|
|
939
879
|
this.stopScreenShare();
|
|
940
880
|
};
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
try {
|
|
950
|
-
await txInfo.screenTransceiver.sender.replaceTrack(screenTrack);
|
|
951
|
-
if (txInfo.screenTransceiver.currentDirection === "recvonly") {
|
|
952
|
-
txInfo.screenTransceiver.direction = "sendrecv";
|
|
953
|
-
console.log(
|
|
954
|
-
`[Screen Share] Flipped ${peerId} screen transceiver to sendrecv`
|
|
955
|
-
);
|
|
956
|
-
await this.createOffer(peerId, true);
|
|
957
|
-
}
|
|
958
|
-
} catch (err) {
|
|
959
|
-
console.error(
|
|
960
|
-
`[Screen Share] Failed to update transceiver for ${peerId}:`,
|
|
961
|
-
err
|
|
962
|
-
);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
881
|
+
Object.entries(this.peers).forEach(([peerId, pc]) => {
|
|
882
|
+
this.screenSenders[peerId] = [];
|
|
883
|
+
this.screenStream.getTracks().forEach((track) => {
|
|
884
|
+
const sender = pc.addTrack(track, this.screenStream);
|
|
885
|
+
this.screenSenders[peerId].push(sender);
|
|
886
|
+
});
|
|
887
|
+
this.createOffer(peerId, true);
|
|
888
|
+
});
|
|
965
889
|
this.send({
|
|
966
890
|
type: "SCREEN_SHARE_START",
|
|
967
891
|
sender: this.myId,
|
|
968
892
|
room_id: this.room.id,
|
|
969
893
|
stream_id: this.screenStream.id.replace(/[{}]/g, "")
|
|
970
894
|
});
|
|
971
|
-
console.log("[Screen Share] Started successfully");
|
|
972
895
|
return this.screenStream;
|
|
973
896
|
} catch (err) {
|
|
974
897
|
this.emitError(
|
|
@@ -982,32 +905,21 @@ var VideoSDKCore = class {
|
|
|
982
905
|
throw err;
|
|
983
906
|
}
|
|
984
907
|
}
|
|
985
|
-
|
|
986
|
-
* Stop screen sharing: clear the screen transceiver track and flip direction back to recvonly.
|
|
987
|
-
*/
|
|
988
|
-
async stopScreenShare() {
|
|
908
|
+
stopScreenShare() {
|
|
989
909
|
if (!this.screenStream) return;
|
|
990
|
-
console.log("[Screen Share] Stopping...");
|
|
991
910
|
this.screenStream.getTracks().forEach((t) => t.stop());
|
|
992
|
-
|
|
993
|
-
const
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
console.log(
|
|
1000
|
-
`[Screen Share] Flipped ${peerId} screen transceiver to recvonly`
|
|
1001
|
-
);
|
|
1002
|
-
await this.createOffer(peerId, true);
|
|
911
|
+
Object.entries(this.peers).forEach(([peerId, pc]) => {
|
|
912
|
+
const senders = this.screenSenders[peerId] || [];
|
|
913
|
+
senders.forEach((sender) => {
|
|
914
|
+
try {
|
|
915
|
+
pc.removeTrack(sender);
|
|
916
|
+
} catch (err) {
|
|
917
|
+
console.warn(err);
|
|
1003
918
|
}
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
919
|
+
});
|
|
920
|
+
delete this.screenSenders[peerId];
|
|
921
|
+
this.createOffer(peerId, true);
|
|
922
|
+
});
|
|
1011
923
|
this.screenStream = null;
|
|
1012
924
|
this.isScreenSharing = false;
|
|
1013
925
|
this.state.updateLocalParticipant({
|
|
@@ -1025,9 +937,7 @@ var VideoSDKCore = class {
|
|
|
1025
937
|
sender: this.myId,
|
|
1026
938
|
room_id: this.room.id
|
|
1027
939
|
});
|
|
1028
|
-
console.log("[Screen Share] Stopped");
|
|
1029
940
|
}
|
|
1030
|
-
// CHAT
|
|
1031
941
|
sendChatMessage(payload) {
|
|
1032
942
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
1033
943
|
console.warn("WS not connected");
|
|
@@ -1060,13 +970,11 @@ var VideoSDKCore = class {
|
|
|
1060
970
|
client_ts: Date.now()
|
|
1061
971
|
});
|
|
1062
972
|
}
|
|
1063
|
-
|
|
1064
|
-
async disconnect() {
|
|
973
|
+
disconnect() {
|
|
1065
974
|
this.intentionalDisconnect = true;
|
|
1066
|
-
|
|
975
|
+
this.stopScreenShare();
|
|
1067
976
|
Object.values(this.peers).forEach((pc) => pc.close());
|
|
1068
977
|
this.peers = {};
|
|
1069
|
-
this.peerTransceivers = {};
|
|
1070
978
|
this.initiators.clear();
|
|
1071
979
|
this.stopHeartbeat();
|
|
1072
980
|
if (this.ws?.readyState === WebSocket.OPEN) {
|