diff --git a/README.md b/README.md index 1006889c0..b3f6fd77a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# SKYLINK WEB SDK 2.1.5 +# SKYLINK WEB SDK 2.2.0 > Temasys SkylinkJS Web SDK is an open-source client-side library for your web-browser that enables any website to easily leverage the capabilities of WebRTC and its direct data streaming powers between peers for audio/video conferencing or file transfer. You'll need a Temasys Account, and an App key to use this. [Register here to get your App key](https://console.temasys.io). @@ -6,7 +6,7 @@ You'll need a Temasys Account, and an App key to use this. [Register here to get #### Supported Browsers | Features | Chrome | Firefox | Safari | Edge (Chromium) | |-------------------------------|--------------------------|--------------------------|--------------------------|-----------------| -| Platforms: | Win, Mac, Linux, Android | Win, Mac, Linux, Android | Mac | Win, Mac | +| Platforms: | Win, Mac, Linux, Android | Win, Mac, Linux, Android | Mac, iOS | Win, Mac | | Minimum Recommended Versions: | 72 | 66 | 13 | 80 | | Screensharing | Yes | Yes | Yes | Yes | | Video Call | Yes | Yes | Yes | Yes | @@ -35,7 +35,7 @@ You'll need a Temasys Account, and an App key to use this. [Register here to get #### Current versions and stability - We recommend that you always use the latest versions of the Temasys SkylinkJS Web SDK as WebRTC is still evolving and we adapt to changes very frequently. -[Latest version: 2.1.5](https://github.com/Temasys/SkylinkJS/releases/tag/2.1.5) +[Latest version: 2.2.0](https://github.com/Temasys/SkylinkJS/releases/tag/2.2.0) ## How to build your own Temasys SkylinkJS Web SDK diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 952838cbd..597c630f1 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -8,7 +8,7 @@ pipelines: - npm install - npm run build branches: - staging-2-0: + "{staging-2-0,pre-prod-2-0}": - step: name: Build and Test script: diff --git a/configs/app.js b/configs/app.js index 6b7fdda2e..9e7100b50 100644 --- a/configs/app.js +++ b/configs/app.js @@ -1,11 +1,10 @@ const config = { - apiBase: 'https://api.temasys.io', stats: { endPoints: { client: '/client', session: '/session', auth: '/auth', - signaling: '/signaling', + signaling: '/client/signaling', iceConnection: '/client/iceconnection', iceCandidate: '/client/icecandidate', iceGathering: '/client/icegathering', @@ -13,10 +12,11 @@ const config = { bandwidth: '/client/bandwidth', recording: '/client/recording', dataChannel: '/client/datachannel', + userMedia: '/client/usermedia', }, }, }; -config.stats.statsBase = `${config.apiBase}/rest/stats`; +config.stats.statsBase = '/rest/stats'; export default config; diff --git a/configs/rollup/rollup.dev.config.js b/configs/rollup/rollup.dev.config.js index 4006fb3ae..8d115b89c 100644 --- a/configs/rollup/rollup.dev.config.js +++ b/configs/rollup/rollup.dev.config.js @@ -5,6 +5,7 @@ import commonJS from 'rollup-plugin-commonjs'; import { terser } from 'rollup-plugin-terser'; import externalGlobals from 'rollup-plugin-external-globals'; import del from 'rollup-plugin-delete'; +import replace from '@rollup/plugin-replace'; import paths from '../paths'; import pkg from '../../package.json'; import CONSTANTS from './constants'; @@ -58,6 +59,9 @@ const config = { warn(warning); }, plugins: [ + replace({ + __sdkVersion__: JSON.stringify(pkg.version), + }), resolve({ only: ['webrtc-adapter', 'clone', 'crypto-js', 'sdp', 'rtcpeerconnection-shim'], }), diff --git a/demos/collection/config.example.js b/demos/collection/config.example.js index b7380651c..d41dc7078 100644 --- a/demos/collection/config.example.js +++ b/demos/collection/config.example.js @@ -3,6 +3,12 @@ Save your api settings like appKey, defaultRoom and room and save it in a file called [config.js] *********************************************************************/ + +let APPKEYS = { + P2P: 'XXX-XXX-XXX-XXX-XXX', + MCU: 'XXX-XXX-XXX-XXX-XXX' +}; + function getParameterByName(name, url) { if (!url) url = window.location.href; name = name.replace(/[\[\]]/g, "\\$&"); @@ -18,7 +24,7 @@ if (!getParameterByName('room')) { } const config = { - appKey: getParameterByName('appKey') || 'XXX-XXX-XXX-XXX-XXX', + appKey: getParameterByName('appKey') || APPKEYS.P2P, defaultRoom: getParameterByName('room'), enableIceTrickle: !getParameterByName('enableIceTrickle'), audioFallback: !!getParameterByName('audioFallback'), @@ -44,4 +50,4 @@ if (secret) { }; } -export default config; +export { config, APPKEYS }; diff --git a/demos/collection/kitchensink/main.js b/demos/collection/kitchensink/main.js index dbd904916..a78bff5b3 100644 --- a/demos/collection/kitchensink/main.js +++ b/demos/collection/kitchensink/main.js @@ -1,6 +1,6 @@ /* eslint-disable import/extensions */ import Skylink, { SkylinkLogger, SkylinkEventManager, SkylinkConstants } from '../../../build/skylink.complete.js'; -import config from '../config.js'; +import { config, APPKEYS } from '../config.js'; /******************************************************** API Settings @@ -19,16 +19,17 @@ Demo.isMCU = false; window.Demo = Demo; -const APPKEYS = { - p2p: 'c7ae7e8a-2e24-43a5-85c6-d4dafbdfecb6', - mcu: '6198a7fa-b8b0-4b0a-8079-4642198c8601', -}; let selectedPeers = []; let _peerId = null; let selectedAppKey = null; const { $, document } = window; +if (window.location.href.indexOf("appKey=") > -1) { + $('#join_room_p2p_key').prop('disabled', true); + $('#join_room_mcu_key').prop('disabled', true); +} + //----- join room options const displayName = `name_user_${ Math.floor((Math.random() * 1000) + 1)}`; $('#display_user_info').val(displayName); @@ -38,6 +39,16 @@ const joinRoomOptions = { userData: displayName, }; +if (config.bandwidth && config.bandwidth.video) { + joinRoomOptions.bandwidth = joinRoomOptions.bandwidth || {}; + joinRoomOptions.bandwidth.video = parseInt(config.bandwidth.video); +} + +if (config.bandwidth && config.bandwidth.audio) { + joinRoomOptions.bandwidth = joinRoomOptions.bandwidth || {}; + joinRoomOptions.bandwidth.audio = parseInt(config.bandwidth.audio); +} + //----- set logging ----- SkylinkLogger.setLevel(SkylinkLogger.logLevels.DEBUG, true); @@ -239,17 +250,6 @@ SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.PEER_JOINED, (evt) newListEntry += ''; $('#presence_list').append(newListEntry); $('#user' + peerId + ' .0').css('color', 'green'); - - // LOGGING - setTimeout(() => { - console.log("***** START *****") - console.log("getPeersCustomSettings", Demo.Skylink.getPeersCustomSettings(config.defaultRoom)); - console.log("getPeerInfo", Demo.Skylink.getPeerInfo(config.defaultRoom, peerId)); - console.log("getPeersDataChannels", Demo.Skylink.getPeersDataChannels(config.defaultRoom)); - console.log("getStreams", Demo.Skylink.getStreams(config.defaultRoom)); - console.log("getUserData", Demo.Skylink.getUserData(config.defaultRoom)); - console.log("***** END *****") - }, 5000); } // create the peer video element @@ -471,7 +471,7 @@ SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.STREAM_ENDED, (evt) screenElm.parentNode.removeChild(screenElm); } - Demo.Methods.updateStreams(); + setTimeout(Demo.Methods.updateStreams, 1000); }); SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.STREAM_MUTED, (evt) => { @@ -489,10 +489,6 @@ SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.ROOM_LOCK, (evt) => Demo.Methods.logToConsoleDOM(`Room is ${(isLocked ? 'locked' : 'unlocked')}`); }); -SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.ROOM_REJOIN, (evt) => { - Demo.Skylink.joinRoom(joinRoomOptions) -}); - // //--------------------------------------------------- // // MESSAGING EVENTS // //--------------------------------------------------- @@ -549,15 +545,54 @@ SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.STORED_MESSAGES, (e }); // //--------------------------------------------------- -// // RECONNECT +// // SOCKET EVENTS // //--------------------------------------------------- +SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.SESSION_DISCONNECT, (evt) => { + Demo.Methods.logToConsoleDOM(`SOCKET_SESSION_DISCONNECTED - ${evt.detail.reason}`, 'error'); + let onlineInterval = null; + const reconnect = () => { + if (window.navigator.onLine) { + clearInterval(onlineInterval); + Demo.Methods.logToConsoleDOM(`Online now. Attempting to join room.`, 'info'); + Demo.Skylink.leaveRoom(config.defaultRoom) + .then(() => { + Demo.Peers = 0; + Demo.PeerIds = []; + Demo.Skylink.joinRoom(joinRoomOptions) + }) + .catch((err) =>{ + Demo.Methods.logToConsoleDOM(`Failed to reconnect`, 'error'); + }) + } else { + Demo.Methods.logToConsoleDOM(`Still offline...`, 'error'); + } + } + + if (!onlineInterval) { + onlineInterval = setInterval(reconnect, 1000); + } +}); + +SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.CHANNEL_ERROR, (evt) => { + const eventDetail = evt.detail; + const { error } = eventDetail; + Demo.Methods.logToConsoleDOM(`CHANNEL_ERROR - ${error}`, 'error'); +}); + +SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.SOCKET_ERROR, (evt) => { + const eventDetail = evt.detail; + const { error, errorCode } = eventDetail; + Demo.Methods.logToConsoleDOM(`CHANNEL_ERROR - ${errorCode} - ${error}`, 'error'); +}); + +SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.CHANNEL_RETRY, (evt) => { + const eventDetail = evt.detail; + const { currentAttempt } = eventDetail; + Demo.Methods.logToConsoleDOM(`CHANNEL_RETRY - ${currentAttempt}`, 'error'); +}); + SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.CHANNEL_REOPEN, (evt) => { - Demo.Skylink.leaveRoom(config.defaultRoom) - .then(() => { - Demo.Peers = 0; - Demo.PeerIds = []; - Demo.Skylink.joinRoom(joinRoomOptions) - }) + Demo.Methods.logToConsoleDOM(`CHANNEL_REOPEN`, 'info'); }); // //--------------------------------------------------- @@ -619,6 +654,12 @@ SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.ICE_CONNECTION_STAT } $(`#user${peerId} .${5}`).css('color', color); + if (state === SkylinkConstants.ICE_CONNECTION_STATE.FAILED || state === SkylinkConstants.ICE_CONNECTION_STATE.DISCONNECTED || state === SkylinkConstants.ICE_CONNECTION_STATE.CLOSED) { + Demo.Methods.logToConsoleDOM(`ICE_CONNECTION_STATE - ${state}`, 'error'); + } else { + Demo.Methods.logToConsoleDOM(`ICE_CONNECTION_STATE - ${state}`, 'info'); + } + if (state === SkylinkConstants.ICE_CONNECTION_STATE.CHECKING) { setTimeout(() => { if ($(`#user${peerId} .${5}`).css('color') === 'orange') { @@ -643,6 +684,7 @@ SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.CANDIDATE_GENERATIO SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.PEER_CONNECTION_STATE, (evt) => { const { peerId, state } = evt.detail; let color = 'red'; + switch (state) { case SkylinkConstants.PEER_CONNECTION_STATE.HAVE_LOCAL_OFFER: case SkylinkConstants.PEER_CONNECTION_STATE.HAVE_REMOTE_OFFER: @@ -657,7 +699,14 @@ SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.PEER_CONNECTION_STA color = 'green'; break; } + $(`#user${peerId} .${6}`).css('color', color); + + if (state === SkylinkConstants.PEER_CONNECTION_STATE.FAILED || state === SkylinkConstants.PEER_CONNECTION_STATE.DISCONNECTED || state === SkylinkConstants.PEER_CONNECTION_STATE.CLOSED) { + Demo.Methods.logToConsoleDOM(`PEER_CONNECTION_STATE - ${state}`, 'error'); + } else { + Demo.Methods.logToConsoleDOM(`PEER_CONNECTION_STATE - ${state}`, 'info'); + } }); SkylinkEventManager.addEventListener(SkylinkConstants.EVENTS.DATA_CHANNEL_STATE, (evt) => { @@ -981,14 +1030,14 @@ $(document).ready(function() { video: true, }; - if (Demo.Streams && Demo.Streams[_peerId] && (Demo.Streams[_peerId].streams.video)) { - const clonedVideoStream = Object.values(Demo.Streams[_peerId].streams.video)[0].clone(); - console.log("Cloned mediaStream", clonedVideoStream); + if (Demo.Streams && Demo.Streams[_peerId] && (Demo.Streams[_peerId].streams.audio || Demo.Streams[_peerId].streams.video)) { Demo.Skylink.stopStreams(config.defaultRoom) - .then(() => startSendStream(clonedVideoStream)) + .then(() => startSendStream(mediaOptions)) .catch((err) => console.error("stopStreams rejected", err)); } else { - startSendStream(mediaOptions); + console.log("sending as prefetched stream"); + Demo.Skylink.getUserMedia(mediaOptions) + .then((streams) => startSendStream(streams[1])); } }); //--------------------------------------------------- @@ -1143,8 +1192,10 @@ $(document).ready(function() { console.log(appKey); if (appKey === 'mcu') { Demo.isMCU = true; + appKey = 'MCU'; } else { Demo.isMCU = false; + appKey = 'P2P'; } selectedAppKey = APPKEYS[appKey]; $('#display_app_id').html(selectedAppKey); diff --git a/docs/Skylink.html b/docs/Skylink.html index c1635232b..c9ca1904b 100644 --- a/docs/Skylink.html +++ b/docs/Skylink.html @@ -76,7 +76,7 @@

-

Classes

Namespaces

+

Classes

Namespaces

@@ -469,7 +469,7 @@
Parameters:
@@ -569,7 +569,7 @@

@@ -774,7 +774,7 @@

Parameters:
@@ -963,7 +963,7 @@
Parameters:
@@ -1118,7 +1118,7 @@
Parameters:
@@ -1335,7 +1335,7 @@
Parameters:
@@ -1580,7 +1580,7 @@
Parameters:
@@ -1780,7 +1780,7 @@
Parameters:
@@ -1951,7 +1951,7 @@
Parameters:
@@ -2113,7 +2113,7 @@
Parameters:
@@ -2289,7 +2289,7 @@
Parameters:
@@ -2337,6 +2337,106 @@
Example
+ + + + + + +

+ getSdkVersion() +

+
+ + + + + +
+

Method that retrieves the sdk version.

+
+ + + + + + + + + + +
+ + + + +
Since:
+
+
    +
  • + 2.1.6 +
  • +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -2489,7 +2589,7 @@
Parameters:
@@ -2644,7 +2744,7 @@
Parameters:
@@ -2895,7 +2995,7 @@
Parameters:
@@ -3002,7 +3102,7 @@

@@ -3027,6 +3127,38 @@

+
+ + + + + +
Example
+ + +
Example 1: Get media sources before joinRoom - only available on Chrome browsers
+
+const audioInputDevices = [];
+const videoInputDevices = [];
+
+skylink.getStreamSources.then((sources) => {
+  audioInputDevices = sources.audio.input;
+  videoInputDevices = sources.video.input;
+}).catch((error) => // handle error);
+
+skylink.getUserMedia(roomName, {
+  audio: {
+    deviceId: audioInputDevices[0].deviceId,
+  },
+  video: {
+    deviceId: videoInputDevices[0].deviceId,
+  }
+}).then((streams) => // do something)
+.catch((error) => // handle error);
+ + +
+ @@ -3201,7 +3333,7 @@

Parameters:
@@ -3453,7 +3585,7 @@
Parameters:
@@ -3556,34 +3688,6 @@
Examples
.catch((error) => // handle error); -
Example 6: Get media sources before joinRoom - only available on Chrome browsers
-
-const audioInputDevices = [];
-const videoInputDevices = [];
-
-navigator.mediaDevices.enumerateDevices().then((devices) => {
-  devices.forEach((device) => {
-    if (device.kind === "audioinput") {
-      audioInputDevices.push(device);
-    }
-
-    if (device.kind === "videoinput") {
-      videoInputDevices.push(device);
-    }
-  })
-}).catch((error) => // handle error);
-
-skylink.getUserMedia(roomName, {
-  audio: {
-    deviceId: audioInputDevices[0].deviceId,
-  },
-  video: {
-    deviceId: videoInputDevices[0].deviceId,
-  }
-}).then((streams) => // do something)
-.catch((error) => // handle error);
- -
@@ -3761,7 +3865,7 @@
Parameters:
@@ -3823,9 +3927,16 @@
Examples
Example 2: Retrieving a pre-fetched stream before calling joinRoom
 
 // REF: getUserMedia
-const prefetchedStream = skylink.getUserMedia();
+const prefetchedStreams = skylink.getUserMedia();
 
-skylink.joinRoom(prefetchedStream)
+const joinRoomOptions = {
+   roomName: "Room_1",
+   userData: {
+       username: "GuestUser_1"
+   },
+};
+
+skylink.joinRoom(joinRoomOptions, prefetchedStreams)
    .catch((error) => {
    // handle error
    });
@@ -3908,7 +4019,7 @@

@@ -4063,7 +4174,7 @@

Parameters:
@@ -4253,7 +4364,7 @@
Parameters:
@@ -4658,7 +4769,7 @@
Properties
@@ -5111,7 +5222,7 @@
Properties
@@ -5340,7 +5451,7 @@
Parameters:
@@ -5614,7 +5725,7 @@
Parameters:
@@ -5918,7 +6029,7 @@
Parameters:
@@ -6039,8 +6150,9 @@

Method that sends a new userMedia stream to all connected peers in a room.

-

Resolves with an array of MediaStreams. First item in array is MediaStream of kind audio and second item is -MediaStream of kind video.

+

If options are passed as argument into the method, it resolves with an array of MediaStreams. First item in array is +MediaStream of kind audio and second item is MediaStream of kind video. Otherwise it resolves with the array or +MediaStream

@@ -6118,6 +6230,12 @@

Parameters:
MediaStream + | + + + Array.<MediaStream> + + @@ -6129,7 +6247,8 @@
Parameters:
-

The getUserMedia options parameter settings. The MediaStream to send to the remote peer.

+

The getUserMedia options parameter +settings. The MediaStream to send to the remote peer or array of MediaStreams.