@flashphoner/websdk 2.0.206 → 2.0.210
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/2players/2players.js +0 -5
- package/examples/demo/streaming/canvas_streaming/canvas_streaming.js +0 -12
- package/examples/demo/streaming/embed_player/player.js +127 -198
- package/examples/demo/streaming/firewall-traversal-streaming/firewall-traversal-streaming.js +0 -12
- package/examples/demo/streaming/mcu_client/mcu_client.js +0 -8
- package/examples/demo/streaming/media_devices_manager/manager.js +2 -17
- package/examples/demo/streaming/player/player.js +10 -9
- package/examples/demo/streaming/screen-sharing/screen-sharing.html +1 -1
- package/examples/demo/streaming/screen-sharing/screen-sharing.js +1 -1
- package/examples/demo/streaming/stream-auto-restore/stream-auto-restore.css +23 -0
- package/examples/demo/streaming/stream-auto-restore/stream-auto-restore.html +152 -0
- package/examples/demo/streaming/stream-auto-restore/stream-auto-restore.js +744 -0
- package/examples/demo/streaming/stream-diagnostic/stream-diagnostic.js +0 -8
- package/examples/demo/streaming/stream-local-snapshot/stream-local-snapshot.js +0 -6
- package/examples/demo/streaming/stream-snapshot/stream-snapshot.js +0 -6
- package/examples/demo/streaming/stream_recording/recording.js +0 -6
- package/examples/demo/streaming/streamer/streamer.js +0 -8
- package/examples/demo/streaming/two_way_streaming/two_way_streaming.js +0 -11
- package/examples/demo/streaming/webrtc-as-rtmp-republishing/webrtc-as-rtmp-republishing.js +0 -6
- package/flashphoner-no-flash.js +131 -29
- package/flashphoner-no-flash.min.js +2 -2
- package/flashphoner-no-webrtc.js +103 -19
- package/flashphoner-no-webrtc.min.js +1 -1
- package/flashphoner-no-wsplayer.js +132 -30
- package/flashphoner-no-wsplayer.min.js +2 -2
- package/flashphoner-room-api.js +105 -12
- package/flashphoner-room-api.min.js +2 -2
- package/flashphoner-temasys-flash-websocket-without-adapterjs.js +105 -21
- package/flashphoner-temasys-flash-websocket.js +105 -21
- package/flashphoner-temasys-flash-websocket.min.js +1 -1
- package/flashphoner-webrtc-only.js +129 -27
- package/flashphoner-webrtc-only.min.js +1 -1
- package/flashphoner.js +132 -30
- package/flashphoner.min.js +2 -2
- package/package.json +1 -1
- package/src/flashphoner-core.d.ts +22 -5
- package/src/flashphoner-core.js +79 -3
- package/src/webrtc-media-provider.js +26 -9
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ export declare class Call {
|
|
|
6
6
|
receiveAudio?: boolean | undefined;
|
|
7
7
|
receiveVideo?: boolean | undefined;
|
|
8
8
|
constraints?: string | undefined;
|
|
9
|
-
stripCodecs?:
|
|
9
|
+
stripCodecs?: string | undefined;
|
|
10
10
|
sipSDP?: Array<string> | undefined;
|
|
11
11
|
sipHeaders?: Array<string> | undefined;
|
|
12
12
|
}) => void;
|
|
@@ -91,12 +91,25 @@ export declare class Session {
|
|
|
91
91
|
cacheLocalResources?: boolean | undefined;
|
|
92
92
|
playWidth?: number | undefined;
|
|
93
93
|
playHeight?: number | undefined;
|
|
94
|
-
|
|
94
|
+
record?: boolean | undefined;
|
|
95
|
+
display: any;
|
|
96
|
+
custom?: any | undefined;
|
|
97
|
+
stripCodecs?: string | undefined;
|
|
98
|
+
rtmpUrl?: string | undefined;
|
|
99
|
+
mediaConnectionConstraints?: any | undefined;
|
|
100
|
+
flashShowFullScreenButton?: boolean | undefined;
|
|
101
|
+
transport?: string | undefined;
|
|
102
|
+
cvoExtension?: boolean | undefined;
|
|
103
|
+
playoutDelay?: number | undefined;
|
|
104
|
+
useCanvasMediaStream?: boolean | undefined;
|
|
105
|
+
videoContentHint?: string | undefined;
|
|
106
|
+
unmutePlayOnStart?: boolean | undefined;
|
|
107
|
+
sdpHook?: any | undefined
|
|
95
108
|
}) => Stream;
|
|
96
109
|
createCall: (options: {
|
|
97
110
|
callee: string;
|
|
98
111
|
visibleName?: string | undefined;
|
|
99
|
-
constraints
|
|
112
|
+
constraints?: any | undefined;
|
|
100
113
|
mediaProvider: string;
|
|
101
114
|
receiveAudio?: boolean | undefined;
|
|
102
115
|
receiveVideo?: boolean | undefined;
|
|
@@ -104,10 +117,11 @@ export declare class Session {
|
|
|
104
117
|
localVideoDisplay: HTMLElement;
|
|
105
118
|
remoteVideoDisplay: HTMLElement;
|
|
106
119
|
custom?: any | undefined;
|
|
107
|
-
stripCodecs?:
|
|
120
|
+
stripCodecs?: string | undefined;
|
|
108
121
|
sipSDP?: Array<string> | undefined;
|
|
109
122
|
sipHeaders?: Array<string> | undefined;
|
|
110
123
|
videoContentHint?: string | undefined;
|
|
124
|
+
toStream?: string | undefined;
|
|
111
125
|
}) => Call;
|
|
112
126
|
getStream: (streamId: string) => any;
|
|
113
127
|
getStreams: () => any[];
|
|
@@ -179,7 +193,10 @@ export function createSession(options: {
|
|
|
179
193
|
custom?: any | undefined;
|
|
180
194
|
sipOptions?: any | undefined;
|
|
181
195
|
mediaOptions?: any | undefined;
|
|
182
|
-
timeout?:
|
|
196
|
+
timeout?: number | undefined;
|
|
197
|
+
pingInterval?: number | undefined;
|
|
198
|
+
receiveProbes?: number | undefined;
|
|
199
|
+
probesInterval?: number | undefined;
|
|
183
200
|
}): Session;
|
|
184
201
|
export function playFirstSound (noise?: boolean): any;
|
|
185
202
|
export function playFirstVideo (display: any, isLocal: boolean, src: any): any;
|
package/src/flashphoner-core.js
CHANGED
|
@@ -403,6 +403,9 @@ var getSession = function (id) {
|
|
|
403
403
|
* @param {Object=} options.sipOptions Sip configuration
|
|
404
404
|
* @param {Object=} options.mediaOptions Media connection configuration
|
|
405
405
|
* @param {Integer=} options.timeout Connection timeout in milliseconds
|
|
406
|
+
* @param {Integer=} options.pingInterval Server ping interval in milliseconds [0]
|
|
407
|
+
* @param {Integer=} options.receiveProbes A maximum subsequental pings received missing count [0]
|
|
408
|
+
* @param {Integer=} options.probesInterval Interval to check subsequental pings received [0]
|
|
406
409
|
* @returns {Session} Created session
|
|
407
410
|
* @throws {Error} Error if API is not initialized
|
|
408
411
|
* @throws {TypeError} Error if options.urlServer is not specified
|
|
@@ -427,6 +430,8 @@ var createSession = function (options) {
|
|
|
427
430
|
var mediaOptions = options.mediaOptions;
|
|
428
431
|
var keepAlive = options.keepAlive;
|
|
429
432
|
var timeout = options.timeout;
|
|
433
|
+
var wsPingSender = new WSPingSender(options.pingInterval || 0);
|
|
434
|
+
var wsPingReceiver = new WSPingReceiver(options.receiveProbes || 0, options.probesInterval || 0);
|
|
430
435
|
var connectionTimeout;
|
|
431
436
|
|
|
432
437
|
var cConfig;
|
|
@@ -534,7 +539,7 @@ var createSession = function (options) {
|
|
|
534
539
|
mediaProviders: Object.keys(MediaProvider),
|
|
535
540
|
keepAlive: keepAlive,
|
|
536
541
|
authToken:authToken,
|
|
537
|
-
clientVersion: "2.0.
|
|
542
|
+
clientVersion: "2.0.210",
|
|
538
543
|
clientOSVersion: window.navigator.appVersion,
|
|
539
544
|
clientBrowserVersion: window.navigator.userAgent,
|
|
540
545
|
msePacketizationVersion: 2,
|
|
@@ -546,6 +551,10 @@ var createSession = function (options) {
|
|
|
546
551
|
//connect to REST App
|
|
547
552
|
send("connection", cConfig);
|
|
548
553
|
logger.setConnection(wsConnection);
|
|
554
|
+
// Send ping messages to server to check if connection is still alive #WCS-3410
|
|
555
|
+
wsPingSender.start();
|
|
556
|
+
// Check subsequintel pings received from server to check if connection is still alive #WCS-3410
|
|
557
|
+
wsPingReceiver.start();
|
|
549
558
|
};
|
|
550
559
|
wsConnection.onmessage = function (event) {
|
|
551
560
|
var data = {};
|
|
@@ -558,6 +567,7 @@ var createSession = function (options) {
|
|
|
558
567
|
switch (data.message) {
|
|
559
568
|
case 'ping':
|
|
560
569
|
send("pong", null);
|
|
570
|
+
wsPingReceiver.success();
|
|
561
571
|
break;
|
|
562
572
|
case 'getUserData':
|
|
563
573
|
authToken = obj.authToken;
|
|
@@ -684,6 +694,10 @@ var createSession = function (options) {
|
|
|
684
694
|
function onSessionStatusChange(newStatus, obj) {
|
|
685
695
|
sessionStatus = newStatus;
|
|
686
696
|
if (sessionStatus == SESSION_STATUS.DISCONNECTED || sessionStatus == SESSION_STATUS.FAILED) {
|
|
697
|
+
// Stop pinging server #WCS-3410
|
|
698
|
+
wsPingSender.stop();
|
|
699
|
+
// Stop checking pings received #WCS-3410
|
|
700
|
+
wsPingReceiver.stop();
|
|
687
701
|
//remove streams
|
|
688
702
|
for (var prop in streamRefreshHandlers) {
|
|
689
703
|
if (streamRefreshHandlers.hasOwnProperty(prop) && typeof streamRefreshHandlers[prop] === 'function') {
|
|
@@ -698,6 +712,65 @@ var createSession = function (options) {
|
|
|
698
712
|
}
|
|
699
713
|
}
|
|
700
714
|
|
|
715
|
+
// Websocket periodic ping sender
|
|
716
|
+
function WSPingSender(interval) {
|
|
717
|
+
this.interval = interval || 0;
|
|
718
|
+
this.intervalId = null;
|
|
719
|
+
this.start = function() {
|
|
720
|
+
if (this.interval > 0) {
|
|
721
|
+
this.intervalId = setInterval(function() {
|
|
722
|
+
send("ping", null);
|
|
723
|
+
}, this.interval);
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
this.stop = function() {
|
|
727
|
+
if (this.intervalId) {
|
|
728
|
+
clearInterval(this.intervalId);
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
return(this);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// Websocket ping receive prober
|
|
736
|
+
function WSPingReceiver(receiveProbes, probesInterval) {
|
|
737
|
+
this.maxPings = receiveProbes || 0;
|
|
738
|
+
this.interval = probesInterval || 0;
|
|
739
|
+
this.intervalId = null;
|
|
740
|
+
this.pingsMissing = 0;
|
|
741
|
+
this.start = function() {
|
|
742
|
+
if (this.maxPings > 0 && this.interval > 0) {
|
|
743
|
+
let receiver = this;
|
|
744
|
+
this.intervalId = setInterval(function() {
|
|
745
|
+
receiver.checkPingsReceived();
|
|
746
|
+
}, this.interval);
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
this.stop = function() {
|
|
750
|
+
if (this.intervalId) {
|
|
751
|
+
clearInterval(this.intervalId);
|
|
752
|
+
}
|
|
753
|
+
this.pingsMissing = 0;
|
|
754
|
+
};
|
|
755
|
+
this.checkPingsReceived = function() {
|
|
756
|
+
this.pingsMissing++;
|
|
757
|
+
if (this.pingsMissing >= this.maxPings) {
|
|
758
|
+
this.failure();
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
this.success = function() {
|
|
762
|
+
this.pingsMissing = 0;
|
|
763
|
+
};
|
|
764
|
+
this.failure = function() {
|
|
765
|
+
logger.info(LOG_PREFIX, "Missing " + this.pingsMissing + " pings from server, connection seems to be down");
|
|
766
|
+
onSessionStatusChange(SESSION_STATUS.FAILED);
|
|
767
|
+
wsConnection.close();
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
return(this);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
|
|
701
774
|
/**
|
|
702
775
|
* @callback sdpHook
|
|
703
776
|
* @param {Object} sdp Callback options
|
|
@@ -1472,7 +1545,7 @@ var createSession = function (options) {
|
|
|
1472
1545
|
* @param {HTMLElement} options.display Div element stream should be displayed in
|
|
1473
1546
|
* @param {Object=} options.custom User provided custom object that will be available in REST App code
|
|
1474
1547
|
* @param {Integer} [options.flashBufferTime=0] Specifies how long to buffer messages before starting to display the stream (Flash-only)
|
|
1475
|
-
* @param {
|
|
1548
|
+
* @param {string=} options.stripCodecs Comma separated string of codecs which should be stripped from WebRTC SDP (ex. "H264,PCMA,PCMU,G722")
|
|
1476
1549
|
* @param {string=} options.rtmpUrl Rtmp url stream should be forwarded to
|
|
1477
1550
|
* @param {Object=} options.mediaConnectionConstraints Stream specific constraints for underlying RTCPeerConnection
|
|
1478
1551
|
* @param {Boolean=} options.flashShowFullScreenButton Show full screen button in flash
|
|
@@ -1481,6 +1554,7 @@ var createSession = function (options) {
|
|
|
1481
1554
|
* @param {Integer=} options.playoutDelay Time delay between network reception of media and playout
|
|
1482
1555
|
* @param {string=} options.useCanvasMediaStream EXPERIMENTAL: when publish bind browser's media stream to the canvas. It can be useful for image filtering
|
|
1483
1556
|
* @param {string=} options.videoContentHint Video content hint for browser ('detail' by default to maintain resolution), {@link Flashphoner.constants.CONTENT_HINT_TYPE}
|
|
1557
|
+
* @param {Boolean=} options.unmutePlayOnStart Unmute playback on start. May be used after user gesture only, so set 'unmutePlayOnStart: false' for autoplay
|
|
1484
1558
|
* @param {sdpHook} sdpHook The callback that handles sdp from the server
|
|
1485
1559
|
* @returns {Stream} Stream
|
|
1486
1560
|
* @throws {TypeError} Error if no options provided
|
|
@@ -1584,6 +1658,7 @@ var createSession = function (options) {
|
|
|
1584
1658
|
var playoutDelay = options.playoutDelay;
|
|
1585
1659
|
var useCanvasMediaStream = options.useCanvasMediaStream;
|
|
1586
1660
|
var videoContentHint = options.videoContentHint;
|
|
1661
|
+
var unmutePlayOnStart = options.unmutePlayOnStart;
|
|
1587
1662
|
|
|
1588
1663
|
var audioState_;
|
|
1589
1664
|
var videoState_;
|
|
@@ -1758,7 +1833,8 @@ var createSession = function (options) {
|
|
|
1758
1833
|
connectionConstraints: mediaConnectionConstraints,
|
|
1759
1834
|
audioOutputId: audioOutputId,
|
|
1760
1835
|
remoteVideo: remoteVideo,
|
|
1761
|
-
playoutDelay: playoutDelay
|
|
1836
|
+
playoutDelay: playoutDelay,
|
|
1837
|
+
unmutePlayOnStart: unmutePlayOnStart
|
|
1762
1838
|
}, streamRefreshHandlers[id_]).then(function (newConnection) {
|
|
1763
1839
|
mediaConnection = newConnection;
|
|
1764
1840
|
try {
|
|
@@ -52,6 +52,8 @@ var createConnection = function (options) {
|
|
|
52
52
|
var playoutDelay = options.playoutDelay;
|
|
53
53
|
// Set video track contentHint to `detail` by default to workaround Chromium 91 bug #WCS-3257
|
|
54
54
|
var videoContentHint = options.videoContentHint ? options.videoContentHint : 'detail';
|
|
55
|
+
// Pass the option to unmute automatically (true by default) #WCS-2425
|
|
56
|
+
var unmutePlayOnStart = options.unmutePlayOnStart !== undefined ? options.unmutePlayOnStart : true;
|
|
55
57
|
|
|
56
58
|
if (bidirectional) {
|
|
57
59
|
localVideo = getCacheInstance(localDisplay);
|
|
@@ -67,7 +69,7 @@ var createConnection = function (options) {
|
|
|
67
69
|
}
|
|
68
70
|
remoteVideo = getCacheInstance(remoteDisplay);
|
|
69
71
|
if (!remoteVideo) {
|
|
70
|
-
remoteVideo =
|
|
72
|
+
remoteVideo = createVideoElement();
|
|
71
73
|
remoteDisplay.appendChild(remoteVideo);
|
|
72
74
|
}
|
|
73
75
|
remoteVideo.id = id + "-remote";
|
|
@@ -88,7 +90,7 @@ var createConnection = function (options) {
|
|
|
88
90
|
if (cachedVideo) {
|
|
89
91
|
remoteVideo = cachedVideo;
|
|
90
92
|
} else {
|
|
91
|
-
remoteVideo =
|
|
93
|
+
remoteVideo = createVideoElement();
|
|
92
94
|
display.appendChild(remoteVideo);
|
|
93
95
|
}
|
|
94
96
|
remoteVideo.id = id;
|
|
@@ -141,7 +143,12 @@ var createConnection = function (options) {
|
|
|
141
143
|
remoteVideo.srcObject = event.streams[0];
|
|
142
144
|
remoteVideo.onloadedmetadata = function (e) {
|
|
143
145
|
if (remoteVideo) {
|
|
144
|
-
remoteVideo.play().
|
|
146
|
+
remoteVideo.play().then(function() {
|
|
147
|
+
// Automatically unmute video if needed #WCS-2425
|
|
148
|
+
if (unmutePlayOnStart) {
|
|
149
|
+
remoteVideo.muted = false;
|
|
150
|
+
}
|
|
151
|
+
}).catch(function (e) {
|
|
145
152
|
if (validBrowsers.includes(browserDetails.browser)) {
|
|
146
153
|
//WCS-1698. fixed autoplay in chromium based browsers
|
|
147
154
|
//WCS-2375. fixed autoplay in ios safari
|
|
@@ -417,14 +424,14 @@ var createConnection = function (options) {
|
|
|
417
424
|
if (!report.isRemote) {
|
|
418
425
|
if (report.type == 'outbound-rtp') {
|
|
419
426
|
fillStatObject(result.outboundStream, report);
|
|
420
|
-
if (report.mediaType == 'video') {
|
|
427
|
+
if (report.mediaType == 'video' && localVideo != undefined && localVideo != null) {
|
|
421
428
|
var vSettings = localVideo.srcObject.getVideoTracks()[0].getSettings();
|
|
422
429
|
result.outboundStream[report.mediaType].height = vSettings.height;
|
|
423
430
|
result.outboundStream[report.mediaType].width = vSettings.width;
|
|
424
431
|
}
|
|
425
432
|
} else if (report.type == 'inbound-rtp') {
|
|
426
433
|
fillStatObject(result.inboundStream, report);
|
|
427
|
-
if (report.mediaType == 'video' && remoteVideo != undefined) {
|
|
434
|
+
if (report.mediaType == 'video' && remoteVideo != undefined && remoteVideo != null) {
|
|
428
435
|
result.inboundStream[report.mediaType].height = remoteVideo.videoHeight;
|
|
429
436
|
result.inboundStream[report.mediaType].width = remoteVideo.videoWidth;
|
|
430
437
|
}
|
|
@@ -585,7 +592,7 @@ var createConnection = function (options) {
|
|
|
585
592
|
if (browserDetails.browser === 'firefox') {
|
|
586
593
|
clonedConstraints.video.mediaSource = source;
|
|
587
594
|
}
|
|
588
|
-
if (
|
|
595
|
+
if (woExtension) {
|
|
589
596
|
getScreenDeviceIdWoExtension(clonedConstraints).then(function (screenSharingConstraints) {
|
|
590
597
|
navigator.mediaDevices.getDisplayMedia(screenSharingConstraints).then(
|
|
591
598
|
(stream) => {
|
|
@@ -714,6 +721,7 @@ var createConnection = function (options) {
|
|
|
714
721
|
};
|
|
715
722
|
|
|
716
723
|
|
|
724
|
+
|
|
717
725
|
var mixAudioTracks = function (stream1, stream2) {
|
|
718
726
|
var stream1Sound = audioContext.createMediaStreamSource(stream1);
|
|
719
727
|
var stream2Sound = audioContext.createMediaStreamSource(stream2);
|
|
@@ -845,13 +853,11 @@ var getMediaAccess = function (constraints, display, disableConstraintsNormaliza
|
|
|
845
853
|
var loadOrdinaryVideo = function(display, stream, screenShare, constraints, video) {
|
|
846
854
|
let vEl = video;
|
|
847
855
|
if (!vEl) {
|
|
848
|
-
vEl =
|
|
856
|
+
vEl = createVideoElement();
|
|
849
857
|
display.appendChild(vEl);
|
|
850
858
|
}
|
|
851
859
|
vEl.id = uuid_v1() + LOCAL_CACHED_VIDEO;
|
|
852
860
|
vEl.srcObject = stream;
|
|
853
|
-
//mute audio
|
|
854
|
-
vEl.muted = true;
|
|
855
861
|
vEl.onloadedmetadata = function (e) {
|
|
856
862
|
//WCS-2751 Add screen capture using getDisplayMedia in Safari
|
|
857
863
|
if (screenShare && !screenCaptureSupportedBrowsers()) {
|
|
@@ -1185,6 +1191,17 @@ function getCacheInstance(display) {
|
|
|
1185
1191
|
}
|
|
1186
1192
|
}
|
|
1187
1193
|
|
|
1194
|
+
function createVideoElement() {
|
|
1195
|
+
let video = document.createElement('video');
|
|
1196
|
+
// Prepare video tag to auto play and add specific Safari tweaks #WCS-2425
|
|
1197
|
+
video.muted = true;
|
|
1198
|
+
if(util.Browser.isSafariWebRTC()) {
|
|
1199
|
+
video.setAttribute("playsinline", "");
|
|
1200
|
+
video.setAttribute("webkit-playsinline", "");
|
|
1201
|
+
}
|
|
1202
|
+
return(video);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1188
1205
|
function removeVideoElement(video) {
|
|
1189
1206
|
if (video.srcObject) {
|
|
1190
1207
|
//pause
|