@flashphoner/websdk 2.0.210 → 2.0.215
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/docTemplate/README.md +1 -1
- package/examples/demo/streaming/conference/conference.html +10 -0
- package/examples/demo/streaming/conference/conference.js +236 -35
- package/examples/demo/streaming/video-chat/video-chat.html +5 -0
- package/flashphoner-no-flash.js +331 -231
- package/flashphoner-no-flash.min.js +2 -2
- package/flashphoner-no-webrtc.js +322 -224
- package/flashphoner-no-webrtc.min.js +2 -2
- package/flashphoner-no-wsplayer.js +331 -231
- package/flashphoner-no-wsplayer.min.js +2 -2
- package/flashphoner-room-api.js +340 -223
- package/flashphoner-room-api.min.js +2 -2
- package/flashphoner-temasys-flash-websocket-without-adapterjs.js +329 -226
- package/flashphoner-temasys-flash-websocket.js +328 -225
- package/flashphoner-temasys-flash-websocket.min.js +1 -1
- package/flashphoner-webrtc-only.js +325 -230
- package/flashphoner-webrtc-only.min.js +1 -1
- package/flashphoner.js +337 -232
- package/flashphoner.min.js +2 -2
- package/package.json +1 -1
- package/src/flash-media-provider.js +5 -0
- package/src/flashphoner-core.d.ts +7 -4
- package/src/flashphoner-core.js +98 -29
- package/src/room-module.js +9 -2
- package/src/temasys-media-provider.js +5 -0
- package/src/util.js +204 -185
- package/src/webrtc-media-provider.js +14 -7
- package/src/websocket-media-provider.js +5 -0
package/docTemplate/README.md
CHANGED
|
@@ -66,6 +66,11 @@
|
|
|
66
66
|
<div class="text-center" style="margin-top: 20px">
|
|
67
67
|
<div id="participant1Status"></div>
|
|
68
68
|
</div>
|
|
69
|
+
<div class="input-group text-center" style="margin: 5px auto 0 auto;">
|
|
70
|
+
<button id="participant1Btn" type="button" class="btn btn-default">Play</button>
|
|
71
|
+
<button id="participant1AudioBtn" type="button" class="btn btn-default">Audio</button>
|
|
72
|
+
<div id="participant1AudioState"></div>
|
|
73
|
+
</div>
|
|
69
74
|
</div>
|
|
70
75
|
|
|
71
76
|
<div class="col-sm-6">
|
|
@@ -76,6 +81,11 @@
|
|
|
76
81
|
<div class="text-center" style="margin-top: 20px">
|
|
77
82
|
<div id="participant2Status"></div>
|
|
78
83
|
</div>
|
|
84
|
+
<div class="input-group text-center" style="margin: 5px auto 0 auto;">
|
|
85
|
+
<button id="participant2Btn" type="button" class="btn btn-default">Play</button>
|
|
86
|
+
<button id="participant2AudioBtn" type="button" class="btn btn-default">Audio</button>
|
|
87
|
+
<div id="participant2AudioState"></div>
|
|
88
|
+
</div>
|
|
79
89
|
</div>
|
|
80
90
|
|
|
81
91
|
</div>
|
|
@@ -5,6 +5,7 @@ var ROOM_EVENT = RoomApi.events;
|
|
|
5
5
|
var PRELOADER_URL = "../../dependencies/media/preloader.mp4";
|
|
6
6
|
var Browser = Flashphoner.Browser;
|
|
7
7
|
var connection;
|
|
8
|
+
var participantStateList;
|
|
8
9
|
|
|
9
10
|
//initialize interface
|
|
10
11
|
function init_page() {
|
|
@@ -21,6 +22,7 @@ function init_page() {
|
|
|
21
22
|
$("#notifyFlash").text("Your browser doesn't support WebRTC technology needed for this example");
|
|
22
23
|
return;
|
|
23
24
|
}
|
|
25
|
+
participantStateList = new ParticipantLocalStateList();
|
|
24
26
|
$("#url").val(setURL());
|
|
25
27
|
onLeft();
|
|
26
28
|
}
|
|
@@ -47,6 +49,10 @@ function onLeft() {
|
|
|
47
49
|
$("[id$=Name]").not(":contains('NONE')").each(function(index,value) {
|
|
48
50
|
$(value).text('NONE');
|
|
49
51
|
});
|
|
52
|
+
participantStateList.clean();
|
|
53
|
+
for (var i = 0; i < _participants; i++) {
|
|
54
|
+
resetParticipantButtons("participant" + i);
|
|
55
|
+
};
|
|
50
56
|
$("#joinBtn").text("Join").off('click').click(function(){
|
|
51
57
|
if (validateForm()) {
|
|
52
58
|
$(this).prop('disabled', true);
|
|
@@ -75,14 +81,6 @@ function start() {
|
|
|
75
81
|
return;
|
|
76
82
|
}
|
|
77
83
|
}
|
|
78
|
-
if (Browser.isSafariWebRTC()) {
|
|
79
|
-
for (var i = 1; i < _participants; i++){
|
|
80
|
-
Flashphoner.playFirstVideo(document.getElementById("participant" + i + "Display"), false, PRELOADER_URL).then(function() {
|
|
81
|
-
createConnection(url, username);
|
|
82
|
-
});
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
84
|
createConnection(url, username);
|
|
87
85
|
}
|
|
88
86
|
|
|
@@ -123,14 +121,7 @@ function joinRoom() {
|
|
|
123
121
|
} else {
|
|
124
122
|
addMessage("chat", " room is empty");
|
|
125
123
|
}
|
|
126
|
-
|
|
127
|
-
Flashphoner.playFirstVideo(document.getElementById("localDisplay"), true, PRELOADER_URL).then(function() {
|
|
128
|
-
publishLocalMedia(room);
|
|
129
|
-
onJoined(room);
|
|
130
|
-
});
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
publishLocalMedia(room);
|
|
124
|
+
publishLocalStream(room);
|
|
134
125
|
onJoined(room);
|
|
135
126
|
}).on(ROOM_EVENT.JOINED, function(participant){
|
|
136
127
|
installParticipant(participant);
|
|
@@ -162,38 +153,131 @@ function installParticipant(participant) {
|
|
|
162
153
|
if (($("[id$=Name]").not(":contains('NONE')").length + 1) == _participants) {
|
|
163
154
|
console.warn("More than " + _participants + " participants, ignore participant " + participant.name());
|
|
164
155
|
} else {
|
|
165
|
-
var
|
|
166
|
-
var pName = '#' +
|
|
167
|
-
var pDisplay = p + 'Display';
|
|
156
|
+
var pBase = $("[id$=Name]:contains('NONE')")[0].id.replace('Name','');
|
|
157
|
+
var pName = '#' + pBase + 'Name';
|
|
168
158
|
$(pName).text(participant.name());
|
|
159
|
+
participantStateList.add(participant, pBase);
|
|
169
160
|
playParticipantsStream(participant);
|
|
170
161
|
}
|
|
171
162
|
}
|
|
172
163
|
|
|
173
164
|
function removeParticipant(participant) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
165
|
+
var participantState = participantStateList.getState(participant);
|
|
166
|
+
if (participantState) {
|
|
167
|
+
participantStateList.remove(participant);
|
|
168
|
+
$(participantState.getName()).text('NONE');
|
|
169
|
+
resetParticipantButtons(participantState.getBaseId());
|
|
170
|
+
} else {
|
|
171
|
+
console.log("Cannot remove " + participant.name() + " from participants list: not found");
|
|
172
|
+
}
|
|
179
173
|
}
|
|
180
174
|
|
|
181
175
|
function playParticipantsStream(participant) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
participant
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
176
|
+
var participantState = participantStateList.getState(participant);
|
|
177
|
+
if (participantState && participant.getStreams().length > 0) {
|
|
178
|
+
var pDisplay = participantState.getDisplay();
|
|
179
|
+
if (Browser.isSafariWebRTC()) {
|
|
180
|
+
Flashphoner.playFirstVideo(pDisplay, false, PRELOADER_URL).then(function() {
|
|
181
|
+
playStream(participant, pDisplay);
|
|
182
|
+
}).catch(function (error) {
|
|
183
|
+
// Low Power Mode detected, user action is needed to start playback in this mode #WCS-2639
|
|
184
|
+
console.log("Can't atomatically play participant" + participant.name() + " stream, use Play button");
|
|
185
|
+
for (var i = 0; i < pDisplay.children.length; i++) {
|
|
186
|
+
if (pDisplay.children[i]) {
|
|
187
|
+
console.log("remove cached instance id " + pDisplay.children[i].id);
|
|
188
|
+
pDisplay.removeChild(pDisplay.children[i]);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
onParticipantStopped(participant);
|
|
192
|
+
});
|
|
193
|
+
} else {
|
|
194
|
+
playStream(participant, pDisplay);
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
console.log("Cannot play participant " + participant.name() + " stream: participant not found");
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function playStream(participant, display) {
|
|
202
|
+
var participantState = participantStateList.getState(participant);
|
|
203
|
+
if (participantState) {
|
|
204
|
+
var playBtn = participantState.getPlayButton();
|
|
205
|
+
var audioBtn = participantState.getAudioButton();
|
|
206
|
+
var options = {
|
|
207
|
+
unmutePlayOnStart: true,
|
|
208
|
+
constraints: {
|
|
209
|
+
audio: {
|
|
210
|
+
deviceId: 'default'
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
// Leave participant stream muted in Android Edge browser #WCS-3445
|
|
215
|
+
if (Browser.isChromiumEdge() && Browser.isAndroid()) {
|
|
216
|
+
options.unmutePlayOnStart = false;
|
|
217
|
+
}
|
|
218
|
+
participant.getStreams()[0].play(display, options).on(STREAM_STATUS.PLAYING, function (playingStream) {
|
|
219
|
+
var video = document.getElementById(playingStream.id())
|
|
220
|
+
video.addEventListener('resize', function (event) {
|
|
221
|
+
resizeVideo(event.target);
|
|
222
|
+
});
|
|
223
|
+
// Set up participant Stop/Play button
|
|
224
|
+
if (playBtn) {
|
|
225
|
+
$(playBtn).text("Stop").off('click').click(function() {
|
|
226
|
+
$(this).prop('disabled', true);
|
|
227
|
+
playingStream.stop();
|
|
228
|
+
}).prop('disabled', false);
|
|
192
229
|
}
|
|
230
|
+
// Set up participant audio toggle button #WCS-3445
|
|
231
|
+
if (audioBtn) {
|
|
232
|
+
$(audioBtn).text("Audio").off('click').click(function() {
|
|
233
|
+
if (playingStream.isRemoteAudioMuted()) {
|
|
234
|
+
playingStream.unmuteRemoteAudio();
|
|
235
|
+
} else {
|
|
236
|
+
playingStream.muteRemoteAudio();
|
|
237
|
+
}
|
|
238
|
+
}).prop('disabled', false);
|
|
239
|
+
}
|
|
240
|
+
// Start participant audio state checking timer #WCS-3445
|
|
241
|
+
participantState.startMutedCheck(playingStream);
|
|
242
|
+
}).on(STREAM_STATUS.STOPPED, function () {
|
|
243
|
+
onParticipantStopped(participant);
|
|
244
|
+
}).on(STREAM_STATUS.FAILED, function () {
|
|
245
|
+
onParticipantStopped(participant);
|
|
193
246
|
});
|
|
247
|
+
} else {
|
|
248
|
+
console.log("Cannot play stream: participant " + participant.name() + " not found");
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function onParticipantStopped(participant) {
|
|
253
|
+
var participantState = participantStateList.getState(participant);
|
|
254
|
+
if (participantState) {
|
|
255
|
+
var playBtn = participantState.getPlayButton();
|
|
256
|
+
var audioBtn = participantState.getAudioButton();
|
|
257
|
+
var audioState = participantState.getAudioState();
|
|
258
|
+
if (playBtn) {
|
|
259
|
+
$(playBtn).text("Play").off('click').click(function() {
|
|
260
|
+
playParticipantsStream(participant);
|
|
261
|
+
}).prop('disabled', false);
|
|
262
|
+
}
|
|
263
|
+
if (audioBtn) {
|
|
264
|
+
$(audioBtn).text("Audio").off('click').prop('disabled', true);
|
|
265
|
+
}
|
|
266
|
+
if (audioState) {
|
|
267
|
+
participantState.stopMutedCheck();
|
|
268
|
+
$(audioState).text("");
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
console.log("Cannot perfom onStopped actions: " + participant.name() + " not found");
|
|
194
272
|
}
|
|
195
273
|
}
|
|
196
274
|
|
|
275
|
+
function resetParticipantButtons(id) {
|
|
276
|
+
$("#" + id + 'Btn').text("Play").off('click').prop('disabled', true);
|
|
277
|
+
$("#" + id + 'AudioBtn').text("Audio").off('click').prop('disabled', true);
|
|
278
|
+
$("#" + id + 'AudioState').text("");
|
|
279
|
+
}
|
|
280
|
+
|
|
197
281
|
function getRoomName() {
|
|
198
282
|
var name = getUrlParam("roomName");
|
|
199
283
|
if (name && name !== '') {
|
|
@@ -239,7 +323,7 @@ function onMediaPublished(stream) {
|
|
|
239
323
|
function onMediaStopped(room) {
|
|
240
324
|
$("#localStopBtn").text("Publish").off('click').click(function(){
|
|
241
325
|
$(this).prop('disabled', true);
|
|
242
|
-
|
|
326
|
+
publishLocalStream(room);
|
|
243
327
|
}).prop('disabled', (connection.getRooms().length == 0));
|
|
244
328
|
$("#localAudioToggle").prop("disabled", true);
|
|
245
329
|
$("#localVideoToggle").prop("disabled", true);
|
|
@@ -274,6 +358,26 @@ function publishLocalMedia(room) {
|
|
|
274
358
|
});
|
|
275
359
|
}
|
|
276
360
|
|
|
361
|
+
function publishLocalStream(room) {
|
|
362
|
+
if (Browser.isSafariWebRTC()) {
|
|
363
|
+
var display = document.getElementById("localDisplay");
|
|
364
|
+
Flashphoner.playFirstVideo(display, true, PRELOADER_URL).then(function() {
|
|
365
|
+
publishLocalMedia(room);
|
|
366
|
+
}).catch(function (error) {
|
|
367
|
+
console.log("Can't atomatically publish local stream, use Publish button");
|
|
368
|
+
for (var i = 0; i < display.children.length; i++) {
|
|
369
|
+
if (display.children[i]) {
|
|
370
|
+
console.log("remove cached instance id " + display.children[i].id);
|
|
371
|
+
display.removeChild(display.children[i]);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
onMediaStopped(room);
|
|
375
|
+
});
|
|
376
|
+
} else {
|
|
377
|
+
publishLocalMedia(room);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
277
381
|
function muteConnectInputs() {
|
|
278
382
|
$(':text').each(function(){
|
|
279
383
|
$(this).prop('disabled', true);
|
|
@@ -317,3 +421,100 @@ function setStatus(selector, status) {
|
|
|
317
421
|
statusField.attr("class","text-danger");
|
|
318
422
|
}
|
|
319
423
|
}
|
|
424
|
+
|
|
425
|
+
// Object to store local state to display participant #WCS-3445
|
|
426
|
+
function ParticipantLocalState(participant, id) {
|
|
427
|
+
var state = {
|
|
428
|
+
participant: participant,
|
|
429
|
+
baseId: id,
|
|
430
|
+
audioTimer: null,
|
|
431
|
+
getBaseId: function() {
|
|
432
|
+
return state.baseId;
|
|
433
|
+
},
|
|
434
|
+
getName: function() {
|
|
435
|
+
return document.getElementById(state.baseId + 'Name');
|
|
436
|
+
},
|
|
437
|
+
getDisplay: function() {
|
|
438
|
+
return document.getElementById(state.baseId + 'Display');
|
|
439
|
+
},
|
|
440
|
+
getPlayButton: function() {
|
|
441
|
+
return document.getElementById(state.baseId + 'Btn');
|
|
442
|
+
},
|
|
443
|
+
getAudioButton: function() {
|
|
444
|
+
return document.getElementById(state.baseId + 'AudioBtn');
|
|
445
|
+
},
|
|
446
|
+
getAudioState: function() {
|
|
447
|
+
return document.getElementById(state.baseId + 'AudioState');
|
|
448
|
+
},
|
|
449
|
+
startMutedCheck: function(stream) {
|
|
450
|
+
var audioState = state.getAudioState();
|
|
451
|
+
state.stopMutedCheck();
|
|
452
|
+
state.audioTimer = setInterval(function () {
|
|
453
|
+
if (stream.isRemoteAudioMuted()) {
|
|
454
|
+
$(audioState).text("Muted");
|
|
455
|
+
} else {
|
|
456
|
+
$(audioState).text("Unmuted");
|
|
457
|
+
}
|
|
458
|
+
}, 500);
|
|
459
|
+
},
|
|
460
|
+
stopMutedCheck: function() {
|
|
461
|
+
if (state.audioTimer) {
|
|
462
|
+
clearInterval(state.audioTimer);
|
|
463
|
+
state.audioTimer = null;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return state;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Array object to store local participant states #WCS-3445
|
|
472
|
+
function ParticipantLocalStateList() {
|
|
473
|
+
var stateList = {
|
|
474
|
+
list: [],
|
|
475
|
+
add: function(participant, id) {
|
|
476
|
+
var state = new ParticipantLocalState(participant, id);
|
|
477
|
+
stateList.list.push(state);
|
|
478
|
+
},
|
|
479
|
+
remove: function(participant) {
|
|
480
|
+
for (var i = 0; i < stateList.list.length; i++) {
|
|
481
|
+
if (stateList.list[i].participant && (stateList.list[i].participant.name() === participant.name())) {
|
|
482
|
+
stateList.list[i].stopMutedCheck();
|
|
483
|
+
stateList.list.splice(i, 1);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
clean: function() {
|
|
488
|
+
while (stateList.list.length) {
|
|
489
|
+
var state = stateList.list.pop();
|
|
490
|
+
state.stopMutedCheck();
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
getState: function(participant) {
|
|
494
|
+
for (var i = 0; i < stateList.list.length; i++) {
|
|
495
|
+
if (stateList.list[i].participant && (stateList.list[i].participant.name() === participant.name())) {
|
|
496
|
+
return stateList.list[i];
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return null;
|
|
500
|
+
},
|
|
501
|
+
startMutedCheck: function(participant, stream) {
|
|
502
|
+
var item = stateList.getState(participant);
|
|
503
|
+
if (item) {
|
|
504
|
+
item.startMutedCheck(stream);
|
|
505
|
+
} else {
|
|
506
|
+
console.error("Cannot start muted check timer for participant " + participant);
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
stopMutedCheck: function(participant) {
|
|
510
|
+
var item = stateList.getState(participant);
|
|
511
|
+
if (item) {
|
|
512
|
+
item.stopMutedCheck();
|
|
513
|
+
} else {
|
|
514
|
+
console.error("Cannot stop muted check timer for participant " + participant);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return stateList;
|
|
520
|
+
}
|
|
@@ -61,6 +61,11 @@
|
|
|
61
61
|
<div class="text-center" style="margin-top: 20px">
|
|
62
62
|
<div id="participant1Status"></div>
|
|
63
63
|
</div>
|
|
64
|
+
<div class="input-group text-center" style="margin: 5px auto 0 auto;">
|
|
65
|
+
<button id="participant1Btn" type="button" class="btn btn-default">Play</button>
|
|
66
|
+
<button id="participant1AudioBtn" type="button" class="btn btn-default">Audio</button>
|
|
67
|
+
<div id="participant1AudioState"></div>
|
|
68
|
+
</div>
|
|
64
69
|
</div>
|
|
65
70
|
|
|
66
71
|
<div class="col-sm-7">
|