@flashphoner/sfusdk-examples 2.0.255 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flashphoner/sfusdk-examples",
3
- "version": "2.0.255",
3
+ "version": "2.0.256",
4
4
  "description": "Official Flashphoner WebCallServer SFU SDK usage examples",
5
5
  "main": "dist/sfu.js",
6
6
  "types": "src/sfu.ts",
@@ -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
- initDefaultRemoteDisplay(room, remoteDisplay, {quality: true},{thresholds: [
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
- ], abrKeepOnGoodQuality: ABR_KEEP_ON_QUALITY, abrTryForUpperQuality: ABR_TRY_UPPER_QUALITY, interval: ABR_QUALITY_CHECK_PERIOD});
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.remove();
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 stream = new MediaStream();
551
- stream.addTrack(audioTrack);
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.remove();
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 = "mute";
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 === "mute") {
714
+ if (newVideoMuteBtn.innerText === "Mute video") {
734
715
  await onMute(true);
735
- newVideoMuteBtn.innerText = "unmute";
736
- } else if (newVideoMuteBtn.innerText === "unmute") {
716
+ newVideoMuteBtn.innerText = "Unmute video";
717
+ } else if (newVideoMuteBtn.innerText === "Unmute video") {
737
718
  await onMute(false);
738
- newVideoMuteBtn.innerText = "mute";
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.remove();
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 stream = new MediaStream();
904
- stream.addTrack(audioTrack);
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.remove();
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 display = initRemoteDisplay(state.room, document.getElementById("remoteVideo"), {quality:true, autoAbr: true}, {thresholds: [
199
- {parameter: "nackCount", maxLeap: 10},
200
- {parameter: "freezeCount", maxLeap: 10},
201
- {parameter: "packetsLost", maxLeap: 10}
202
- ], abrKeepOnGoodQuality: ABR_KEEP_ON_QUALITY, abrTryForUpperQuality: ABR_TRY_UPPER_QUALITY, interval: ABR_QUALITY_CHECK_PERIOD},createDefaultMeetingController, createDefaultMeetingModel, createDefaultMeetingView, oneToOneParticipantFactory(remoteTrackProvider(state.room)));
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);