@flashphoner/sfusdk-examples 2.0.250 → 2.0.256
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/package.json +1 -1
- package/src/client/main.js +12 -2
- package/src/commons/js/display.js +81 -73
- package/src/webrtc-abr-player/player.js +23 -5
package/package.json
CHANGED
package/src/client/main.js
CHANGED
|
@@ -100,11 +100,21 @@ async function connect() {
|
|
|
100
100
|
|
|
101
101
|
//setup remote display for showing remote audio/video tracks
|
|
102
102
|
const remoteDisplay = document.getElementById("display");
|
|
103
|
-
|
|
103
|
+
const displayOptions = {
|
|
104
|
+
quality: true,
|
|
105
|
+
autoAbr: false
|
|
106
|
+
};
|
|
107
|
+
const abrOptions = {
|
|
108
|
+
thresholds: [
|
|
104
109
|
{parameter: "nackCount", maxLeap: 10},
|
|
105
110
|
{parameter: "freezeCount", maxLeap: 10},
|
|
106
111
|
{parameter: "packetsLost", maxLeap: 10}
|
|
107
|
-
],
|
|
112
|
+
],
|
|
113
|
+
abrKeepOnGoodQuality: ABR_KEEP_ON_QUALITY,
|
|
114
|
+
abrTryForUpperQuality: ABR_TRY_UPPER_QUALITY,
|
|
115
|
+
interval: ABR_QUALITY_CHECK_PERIOD
|
|
116
|
+
};
|
|
117
|
+
initDefaultRemoteDisplay(room, remoteDisplay, displayOptions, abrOptions);
|
|
108
118
|
|
|
109
119
|
//get configured local video streams
|
|
110
120
|
let streams = cControls.getVideoStreams();
|
|
@@ -522,7 +522,7 @@ const createOneToManyParticipantView = function () {
|
|
|
522
522
|
dispose: function () {
|
|
523
523
|
player.dispose();
|
|
524
524
|
for (const element of audioElements.values()) {
|
|
525
|
-
element.
|
|
525
|
+
element.dispose();
|
|
526
526
|
}
|
|
527
527
|
audioElements.clear();
|
|
528
528
|
},
|
|
@@ -547,32 +547,13 @@ const createOneToManyParticipantView = function () {
|
|
|
547
547
|
player.showVideoTrack(track);
|
|
548
548
|
},
|
|
549
549
|
addAudioTrack: function (track, audioTrack, show) {
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
const audioElement = document.createElement("audio");
|
|
553
|
-
if (!show) {
|
|
554
|
-
hideItem(audioElement);
|
|
555
|
-
}
|
|
556
|
-
audioElement.controls = "controls";
|
|
557
|
-
audioElement.muted = true;
|
|
558
|
-
audioElement.autoplay = true;
|
|
559
|
-
audioElement.onloadedmetadata = function (e) {
|
|
560
|
-
audioElement.play().then(function () {
|
|
561
|
-
if (Browser().isSafariWebRTC() && Browser().isiOS()) {
|
|
562
|
-
console.warn("Audio track should be manually unmuted in iOS Safari");
|
|
563
|
-
} else {
|
|
564
|
-
audioElement.muted = false;
|
|
565
|
-
}
|
|
566
|
-
});
|
|
567
|
-
};
|
|
568
|
-
audioElements.set(track.mid, audioElement);
|
|
569
|
-
audioDisplay.appendChild(audioElement);
|
|
570
|
-
audioElement.srcObject = stream;
|
|
550
|
+
const audioPlayer = createAudioPlayer(audioDisplay, track, audioTrack, show);
|
|
551
|
+
audioElements.set(track.mid, audioPlayer);
|
|
571
552
|
},
|
|
572
553
|
removeAudioTrack: function (track) {
|
|
573
554
|
const audioElement = audioElements.get(track.mid);
|
|
574
555
|
if (audioElement) {
|
|
575
|
-
audioElement.
|
|
556
|
+
audioElement.dispose();
|
|
576
557
|
audioElements.delete(track.mid);
|
|
577
558
|
}
|
|
578
559
|
},
|
|
@@ -725,17 +706,17 @@ const createVideoPlayer = function (participantDiv) {
|
|
|
725
706
|
if (!this.muteButton) {
|
|
726
707
|
const newVideoMuteBtn = document.createElement("button");
|
|
727
708
|
this.muteButton = newVideoMuteBtn;
|
|
728
|
-
newVideoMuteBtn.innerText = "
|
|
709
|
+
newVideoMuteBtn.innerText = "Mute video";
|
|
729
710
|
newVideoMuteBtn.setAttribute("style", "display:inline-block; border: solid; border-width: 1px");
|
|
730
711
|
newVideoMuteBtn.addEventListener('click', async function () {
|
|
731
712
|
newVideoMuteBtn.disabled = true;
|
|
732
713
|
try {
|
|
733
|
-
if (newVideoMuteBtn.innerText === "
|
|
714
|
+
if (newVideoMuteBtn.innerText === "Mute video") {
|
|
734
715
|
await onMute(true);
|
|
735
|
-
newVideoMuteBtn.innerText = "
|
|
736
|
-
} else if (newVideoMuteBtn.innerText === "
|
|
716
|
+
newVideoMuteBtn.innerText = "Unmute video";
|
|
717
|
+
} else if (newVideoMuteBtn.innerText === "Unmute video") {
|
|
737
718
|
await onMute(false);
|
|
738
|
-
newVideoMuteBtn.innerText = "
|
|
719
|
+
newVideoMuteBtn.innerText = "Mute video";
|
|
739
720
|
}
|
|
740
721
|
} finally {
|
|
741
722
|
newVideoMuteBtn.disabled = false;
|
|
@@ -848,6 +829,74 @@ const createVideoPlayer = function (participantDiv) {
|
|
|
848
829
|
}
|
|
849
830
|
}
|
|
850
831
|
|
|
832
|
+
const createAudioPlayer = function (audioDisplay, track, audioTrack, show) {
|
|
833
|
+
let audioElement;
|
|
834
|
+
let audioMuteButton
|
|
835
|
+
|
|
836
|
+
const displayMute = function (audioTag) {
|
|
837
|
+
let text = "";
|
|
838
|
+
if (audioTag.muted) {
|
|
839
|
+
text = "Unmute audio";
|
|
840
|
+
} else {
|
|
841
|
+
text = "Mute audio";
|
|
842
|
+
}
|
|
843
|
+
return text;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
const createAudioElement = function () {
|
|
847
|
+
const div = document.createElement("audio");
|
|
848
|
+
div.controls = "controls";
|
|
849
|
+
div.muted = true;
|
|
850
|
+
div.autoplay = true;
|
|
851
|
+
return div;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
const createAudioMuteButton = function (trackId, audioTag) {
|
|
855
|
+
const div = document.createElement("button");
|
|
856
|
+
div.innerText = displayMute(audioTag) + " " + trackId;
|
|
857
|
+
div.setAttribute("style", "display:inline-block; border: solid; border-width: 1px");
|
|
858
|
+
div.onclick = function (e) {
|
|
859
|
+
audioTag.muted = !audioTag.muted;
|
|
860
|
+
div.innerText = displayMute(audioTag) + " " + trackId;
|
|
861
|
+
};
|
|
862
|
+
return div;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
const create = function (audioDisplay, track, audioTrack, show) {
|
|
866
|
+
const stream = new MediaStream();
|
|
867
|
+
stream.addTrack(audioTrack);
|
|
868
|
+
audioElement = createAudioElement();
|
|
869
|
+
audioMuteButton = createAudioMuteButton(track.mid, audioElement);
|
|
870
|
+
audioElement.onloadedmetadata = function (e) {
|
|
871
|
+
audioElement.play().then(function () {
|
|
872
|
+
if (Browser().isSafariWebRTC() && Browser().isiOS()) {
|
|
873
|
+
console.warn("Audio track should be manually unmuted in iOS Safari");
|
|
874
|
+
} else {
|
|
875
|
+
audioElement.muted = false;
|
|
876
|
+
audioMuteButton.innerText = displayMute(audioElement) + " " + track.mid;
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
};
|
|
880
|
+
if (show) {
|
|
881
|
+
hideItem(audioMuteButton);
|
|
882
|
+
} else {
|
|
883
|
+
hideItem(audioElement);
|
|
884
|
+
}
|
|
885
|
+
audioDisplay.appendChild(audioElement);
|
|
886
|
+
audioDisplay.appendChild(audioMuteButton);
|
|
887
|
+
audioElement.srcObject = stream;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
create(audioDisplay, track, audioTrack, show);
|
|
891
|
+
|
|
892
|
+
return {
|
|
893
|
+
dispose() {
|
|
894
|
+
audioElement.remove();
|
|
895
|
+
audioMuteButton.remove();
|
|
896
|
+
}
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
|
|
851
900
|
const createOneToOneParticipantView = function () {
|
|
852
901
|
|
|
853
902
|
const participantDiv = createContainer(null);
|
|
@@ -867,7 +916,7 @@ const createOneToOneParticipantView = function () {
|
|
|
867
916
|
}
|
|
868
917
|
videoPlayers.clear();
|
|
869
918
|
for (const element of audioElements.values()) {
|
|
870
|
-
element.
|
|
919
|
+
element.dispose();
|
|
871
920
|
}
|
|
872
921
|
audioElements.clear();
|
|
873
922
|
},
|
|
@@ -900,32 +949,13 @@ const createOneToOneParticipantView = function () {
|
|
|
900
949
|
}
|
|
901
950
|
},
|
|
902
951
|
addAudioTrack: function (track, audioTrack, show) {
|
|
903
|
-
const
|
|
904
|
-
|
|
905
|
-
const audioElement = document.createElement("audio");
|
|
906
|
-
if (!show) {
|
|
907
|
-
hideItem(audioElement);
|
|
908
|
-
}
|
|
909
|
-
audioElement.controls = "controls";
|
|
910
|
-
audioElement.muted = true;
|
|
911
|
-
audioElement.autoplay = true;
|
|
912
|
-
audioElement.onloadedmetadata = function (e) {
|
|
913
|
-
audioElement.play().then(function () {
|
|
914
|
-
if (Browser().isSafariWebRTC() && Browser().isiOS()) {
|
|
915
|
-
console.warn("Audio track should be manually unmuted in iOS Safari");
|
|
916
|
-
} else {
|
|
917
|
-
audioElement.muted = false;
|
|
918
|
-
}
|
|
919
|
-
});
|
|
920
|
-
};
|
|
921
|
-
audioElements.set(track.mid, audioElement);
|
|
922
|
-
audioDisplay.appendChild(audioElement);
|
|
923
|
-
audioElement.srcObject = stream;
|
|
952
|
+
const audioPlayer = createAudioPlayer(audioDisplay, track, audioTrack, show);
|
|
953
|
+
audioElements.set(track.mid, audioPlayer);
|
|
924
954
|
},
|
|
925
955
|
removeAudioTrack: function (track) {
|
|
926
956
|
const audioElement = audioElements.get(track.mid);
|
|
927
957
|
if (audioElement) {
|
|
928
|
-
audioElement.
|
|
958
|
+
audioElement.dispose();
|
|
929
959
|
audioElements.delete(track.mid);
|
|
930
960
|
}
|
|
931
961
|
},
|
|
@@ -1745,28 +1775,6 @@ const createContainer = function (parent) {
|
|
|
1745
1775
|
return div;
|
|
1746
1776
|
}
|
|
1747
1777
|
|
|
1748
|
-
const createQualityButton = function (qualityName, buttonsList, parent) {
|
|
1749
|
-
const div = document.createElement("button");
|
|
1750
|
-
div.innerText = qualityName;
|
|
1751
|
-
div.setAttribute("style", "display:inline-block; border: solid; border-width: 1px");
|
|
1752
|
-
div.style.color = QUALITY_COLORS.UNAVAILABLE;
|
|
1753
|
-
if (buttonsList) {
|
|
1754
|
-
buttonsList.push(div);
|
|
1755
|
-
}
|
|
1756
|
-
if (parent) {
|
|
1757
|
-
parent.appendChild(div);
|
|
1758
|
-
}
|
|
1759
|
-
return div;
|
|
1760
|
-
}
|
|
1761
|
-
|
|
1762
|
-
const setQualityButtonsColor = function (qualityDivs) {
|
|
1763
|
-
for (let c = 0; c < qualityDivs.length; c++) {
|
|
1764
|
-
if (qualityDivs[c].style.color !== QUALITY_COLORS.UNAVAILABLE) {
|
|
1765
|
-
qualityDivs[c].style.color = QUALITY_COLORS.AVAILABLE;
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
}
|
|
1769
|
-
|
|
1770
1778
|
// Helper functions to display/hide an element
|
|
1771
1779
|
const showItem = function (tag) {
|
|
1772
1780
|
if (tag) {
|
|
@@ -195,11 +195,29 @@ const onOperationFailed = function(state, event) {
|
|
|
195
195
|
const playStreams = async function (state) {
|
|
196
196
|
try {
|
|
197
197
|
// Create remote display item to show remote streams
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
198
|
+
const displayOptions = {
|
|
199
|
+
quality:true,
|
|
200
|
+
autoAbr: true
|
|
201
|
+
};
|
|
202
|
+
const abrOptions = {
|
|
203
|
+
thresholds: [
|
|
204
|
+
{parameter: "nackCount", maxLeap: 10},
|
|
205
|
+
{parameter: "freezeCount", maxLeap: 10},
|
|
206
|
+
{parameter: "packetsLost", maxLeap: 10}
|
|
207
|
+
],
|
|
208
|
+
abrKeepOnGoodQuality: ABR_KEEP_ON_QUALITY,
|
|
209
|
+
abrTryForUpperQuality: ABR_TRY_UPPER_QUALITY,
|
|
210
|
+
interval: ABR_QUALITY_CHECK_PERIOD
|
|
211
|
+
};
|
|
212
|
+
const display = initRemoteDisplay(
|
|
213
|
+
state.room,
|
|
214
|
+
document.getElementById("remoteVideo"),
|
|
215
|
+
displayOptions, abrOptions,
|
|
216
|
+
createDefaultMeetingController,
|
|
217
|
+
createDefaultMeetingModel,
|
|
218
|
+
createDefaultMeetingView,
|
|
219
|
+
oneToOneParticipantFactory(remoteTrackProvider(state.room))
|
|
220
|
+
);
|
|
203
221
|
state.setDisplay(display);
|
|
204
222
|
// Start WebRTC negotiation
|
|
205
223
|
await state.room.join(state.pc, null, null, 1);
|