diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 65be158cd..a09fc7647 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,4 +1,4 @@
-## Committing to the Temasys SkylinkJS branch
+## Committing to the Temasys Web SDK branch
For developers who wants to contribute to the source code, you would require to fork your own repostiory and create a pull-request to a new branch.
@@ -35,12 +35,12 @@ Commit message format examples:
- Commit that's a bug fix that has been completed
`[#15][BUG]: Fix for new bug found.`
-## Temasys SkylinkJS code demos
+## Temasys Web SDK code demos
In the `demo` folder, it contains the following code samples for developers to test and try on. You will require to create your own `config.js` file and setup with your own App Key CORS url tied to the `localhost` or your own local network IP address (whichever way you like it). Check the `config-example.js` file in the `demo` folder on how to configure the `config.js` file. Once you are done, save it in the `demo` folder.
Here's the list of sample demos available:
-- `app`: The demo that tests all of Temasys SkylinkJS functionalities.
+- `app`: The demo that tests all of Temasys Web SDK functionalities.
- `simple-app`: The demo that tests a simple peer-to-peer video call functionalities.
- `chat-room`: The demo that tests on the chat functionality.
- `file-transfer`: The demo that tests on the data transfers functionality.
diff --git a/README.md b/README.md
index 26f8eda58..f71532428 100644
--- a/README.md
+++ b/README.md
@@ -7,13 +7,18 @@ We've gone to great length to make this library work in as many browsers as poss
You'll need a Temasys Account and an App key to use this. [Register here to get your App key](https://console.temasys.io).
#### Supported Browsers
-| Features | Chrome `45`-`51`+ | Firefox `40`-`48`+ | Opera `32`-`36`+ | IE `9`-`11`+ | Safari `7`-`9` |
-| -------------- | ---------- | ----------- | --------- | ---------- | ---------- |
-| **Screensharing** | Yes with [Chrome Extension**](https://chrome.google.com/webstore/detail/skylink-webrtc-tools/ljckddiekopnnjoeaiofddfhgnbdoafc) | Yes with [Firefox Extension**](https://addons.mozilla.org/en-US/firefox/addon/skylink-webrtc-tools/) | - | Yes with [Commercial Temasys Plugin*](https://temasys.io/plugin/#commercial-licensing) | Yes with [Commercial Temasys Plugin*](https://temasys.io/plugin/#commercial-licensing) |
-| **Video Call** | Yes | Yes | Yes | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes [Temasys Plugin](http://skylink.io/plugin/) |
-| **Audio Call** | Yes | Yes | Yes | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes with [Temasys Plugin](http://skylink.io/plugin/) |
-| **File Transfers** | Yes | Yes | Yes | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes with [Temasys Plugin](http://skylink.io/plugin/) |
-| **Chat Messaging** | Yes | Yes | Yes | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes with [Temasys Plugin](http://skylink.io/plugin/) |
+
+> ##### Browsers in Beta (Edge/Bowser):
+> _Please note that MCU functionality, data channel file transfer, and P2P messaging are not supported by the Temasys Web SDK in Edge browser due to current compatibility limitations. Older versions of Edge may require you to enable experimental support for H.264 to interop with Chrome and Firefox browsers. Edge support should be considered experimental in this release._
+
+| Features | Chrome `52`-`55`+ | Firefox `48`-`50`+ | Opera `38`-`42`+ | IE `9`-`11`+ | Safari `7`-`9` | Edge `14.14352` | Bowser (iOS `9.x` and below) |
+| -------------- | ---------- | ----------- | --------- | ---------- | ---------- | ---- | ----- |
+| **Platforms:** | Win/Mac/Ubuntu/Android | Win/Mac/Ubuntu/Android | Win/Mac/Ubuntu/Android | Win/Mac | Win | Mac | Win | iOS (`9.x` and below) |
+| **Screensharing** | Yes with [Chrome Extension**](https://chrome.google.com/webstore/detail/skylink-webrtc-tools/ljckddiekopnnjoeaiofddfhgnbdoafc) | Yes with [Firefox Extension**](https://addons.mozilla.org/en-US/firefox/addon/skylink-webrtc-tools/) | - | Yes with [Commercial Temasys Plugin*](https://temasys.io/plugin/#commercial-licensing) | Yes with [Commercial Temasys Plugin*](https://temasys.io/plugin/#commercial-licensing) | No | No |
+| **Video Call** | Yes | Yes | Yes | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes [Temasys Plugin](http://skylink.io/plugin/) | Yes (with H264 flag enabled) | Yes |
+| **Audio Call** | Yes | Yes | Yes | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes (no MCU) | Yes (no MCU) |
+| **File Transfers** | Yes | Yes | Yes | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes with [Temasys Plugin](http://skylink.io/plugin/) | No | No |
+| **Chat Messaging** | Yes | Yes | Yes | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes with [Temasys Plugin](http://skylink.io/plugin/) | Yes (Signaling only) | Yes (Signaling only) |
- (+) Latest browser versions indicates the last tested browser version. It should work with the updated next versions, but if it doesn't, open a bug ticket.
- (*) Custom Branded Temasys WebRTC Plugin incorporates additional features not available in the free plugin.
diff --git a/bower.json b/bower.json
index ba7b68ca4..f2f199639 100644
--- a/bower.json
+++ b/bower.json
@@ -1,7 +1,7 @@
{
"name": "skylinkjs",
"description": "WebRTC real-time video conversation library",
- "version": "0.6.17",
+ "version": "0.6.18",
"homepage": "https://skylink.io",
"author": {
"name": "Temasys Communications Pte. Ltd.",
@@ -24,7 +24,7 @@
"doc-style/**"
],
"dependencies": {
- "adapterjs": "0.14.0",
+ "adapterjs": "0.14.1",
"socket.io-client": "1.4.8"
},
"keywords": ["webrtc", "real-time", "p2p"]
diff --git a/demo/README.md b/demo/README.md
index d8c25d844..03a704f54 100644
--- a/demo/README.md
+++ b/demo/README.md
@@ -63,7 +63,7 @@ In this demo, you can find an example of how you can do a simple file transfer t
`peerJoined`, `peerLeft`, `dataTransferState`
### demo/gridster-integration
-In this demo, you can find an example of an integration of [gridster](http://gridster.net/), a drag-and-drop grid like UI with Skylink functionalities that enables users to send files, send text messages and make video calls.
+In this demo, you can find an example of an integration of [gridster](http://gridster.net/), a drag-and-drop grid like UI with the Temasys Web SDK functionalities that enables users to send files, send text messages and make video calls.
##### Functionalities covered
`getPeerInfo()`, `getUserData()`, `init()`, `getUserMedia()`, `joinRoom()`, `on()`, `respondBlobRequest()`, `sendBlobData()`, `sendMessage()`, `sendP2PMessage()`
@@ -72,7 +72,7 @@ In this demo, you can find an example of an integration of [gridster](http://gri
`dataTransferState`, `incomingMessage`, `peerJoined`, `incomingStream`, `mediaAccessSuccess`, `mediaAccessError`, `peerLeft`, `channelError`, `mediaAccessError`
### demo/messaging
-In this demo, you can find an example of all the ways to do messaging with Skylink - P2P (secure) or socket. Private (targeted) or public (broadcasted) messages.
+In this demo, you can find an example of all the ways to do messaging with the Temasys Web SDK - P2P (secure) or socket. Private (targeted) or public (broadcasted) messages.
##### Functionalities covered
`sendP2PMessage()`, `sendMessage()`, `setUserData()`, `init()`, `joinRoom()`, `on()`
@@ -99,7 +99,7 @@ In this demo, you can find an example of the overview of all types of stream set
`peerJoined`, `peerLeft`, `incomingStream`, `mediaAccessSuccess`, `incomingMessage`
### demo/video-call
-In this demo, you can find an example of how you can create a simple video call with Skylink.
+In this demo, you can find an example of how you can create a simple video call with the Temasys Web SDK.
##### Functionalities covered
`init()`, `joinRoom()`, `on()`, `getPeerInfo()`
@@ -117,4 +117,22 @@ In this demo, you can find an example of how to utilize the privileged key conce
`getPeersStateChange`, `introduceStateChange`
##### How to use
-First, open the index page of the privileged demo. Each button there when being clicked will open another browser tab for the corresponding type of user, with corresponding functionalities available. For example privileged users have getPeers() and introduce() options while the rest do not. To introduce two peers, enter the peer ID of each peer to the textbox then hit "Introduce".
\ No newline at end of file
+First, open the index page of the privileged demo. Each button there when clicked will open another browser tab for the corresponding type of user, with corresponding functionalities available. For example, privileged users have getPeers() and introduce() options while the rest do not. To introduce two peers, enter the peer ID of each peer to the text box then hit "Introduce".
+
+### demo/data-streaming
+In this demo, you can find an example of how you can share video (mp4) with peers with the Temasys Web SDK.
+
+##### Functionalities covered
+`init()`, `joinRoom()`, `on()`, `streamData()`, `sendP2PMessage()`
+
+##### Events used
+`incomingDataStream`, `incomingMessage`, `peerLeft`, `dataChannelState`
+
+### demo/screenshare-and-camera
+In this demo, you can find an example of how you can share both camera and screenshare to peers with the Temasys Web SDK.
+
+##### Functionalities covered
+`init()`, `joinRoom()`, `on()`, `shareScreen()`
+
+##### Events used
+`incomingStream`, `peerLeft`
\ No newline at end of file
diff --git a/demo/app/css/style.css b/demo/app/css/style.css
index 88d24d213..1294c1994 100644
--- a/demo/app/css/style.css
+++ b/demo/app/css/style.css
@@ -184,6 +184,12 @@ footer {
text-transform: capitalize;
}
+.panel .panel-heading small {
+ display: block;
+ color: #888;
+ font-size: 10px;
+}
+
@media screen and (max-width:1999px){
#credential_panel .panel-body {
margin-bottom:15px;
diff --git a/demo/app/index.html b/demo/app/index.html
index f68a51a41..198940e7b 100644
--- a/demo/app/index.html
+++ b/demo/app/index.html
@@ -1,7 +1,7 @@
- This demo presents the different possibilities to send messages with Temasys SkylinkJS.
+ This demo presents the different possibilities to send messages with Temasys Web SDK.
@@ -228,7 +228,7 @@
File Transfer (/file-transfer)
- This demo presents the different possibilities to send files with Temasys SkylinkJS.
+ This demo presents the different possibilities to send files with Temasys Web SDK.
@@ -260,7 +260,7 @@
Chat room (/chat-room)
- This demo presents an IRC like chat powered by Temasys SkylinkJS.
+ This demo presents an IRC like chat powered by Temasys Web SDK.
@@ -288,7 +288,7 @@
Click-to-call Lobby (/request-call)
- This demo presents the use-case to stimulate a call-like environment with Temasys SkylinkJS.
+ This demo presents the use-case to stimulate a call-like environment with Temasys Web SDK.
@@ -318,7 +318,7 @@
Agent-client Call-center - Privileged use case (/privileged)
- This demo presents the use of privileged concept
+ This demo presents the use of privileged concept. This demo requires special demo config.js settings for various Privileged App Key and Auto-Introduce settings.
@@ -337,7 +337,16 @@
Agent-client Call-center - Privileged use case (/privileged)
- This demo shows you most of the functionality Temasys SkylinkJS can provide.
+ This demo shows you most of the functionality Temasys Web SDK can provide.
All the states and information provided by the API are displayed.
@@ -418,6 +427,70 @@
Demo (/app)
+
+
+
+
+
+
+
Data Streaming (/data-streaming)
+
+
+
Warning! This works only in Chrome browsers!
+
+
+ This demo presents the ability to stream and share video mp4 files with friends.
+
+
diff --git a/demo/messaging/index.html b/demo/messaging/index.html
index c613fbb8b..cb7fd9f51 100644
--- a/demo/messaging/index.html
+++ b/demo/messaging/index.html
@@ -1,6 +1,6 @@
- Temasys SkylinkJS Demo : Message Type
+ Temasys Web SDK Demo : Message Type
@@ -28,6 +28,7 @@
+
diff --git a/demo/privileged/auto-priv/index.html b/demo/privileged/auto-priv/index.html
index 92b558fc6..d3b64fa59 100644
--- a/demo/privileged/auto-priv/index.html
+++ b/demo/privileged/auto-priv/index.html
@@ -1,7 +1,7 @@
- Temasys SkylinkJS Demo: Privileged User Feature (for Privileged App Key + Auto Introduce Enabled)
+ Temasys Web SDK Demo: Privileged User Feature (for Privileged App Key + Auto Introduce Enabled)
@@ -22,7 +22,7 @@
- Temasys SkylinkJS Demo: Privileged User Feature (for Privileged App Key + Auto Introduce Enabled)
+ Temasys Web SDK Demo: Privileged User Feature (for Privileged App Key + Auto Introduce Enabled)
@@ -231,7 +231,8 @@
Targeted peers to message / file transfer to
-
+
+
diff --git a/demo/privileged/auto-unpriv/index.html b/demo/privileged/auto-unpriv/index.html
index 68ab867ab..4c26cf681 100644
--- a/demo/privileged/auto-unpriv/index.html
+++ b/demo/privileged/auto-unpriv/index.html
@@ -1,7 +1,7 @@
- Temasys SkylinkJS Demo: Privileged User Feature (for non-Privileged App Key + Auto Introduce Enabled)
+ Temasys Web SDK Demo: Privileged User Feature (for non-Privileged App Key + Auto Introduce Enabled)
@@ -22,7 +22,7 @@
- Temasys SkylinkJS Demo: Privileged User Feature (for non-Privileged App Key + Auto Introduce Enabled)
+ Temasys Web SDK Demo: Privileged User Feature (for non-Privileged App Key + Auto Introduce Enabled)
@@ -215,7 +215,8 @@
Targeted peers to message / file transfer to
-
+
+
diff --git a/demo/privileged/index.html b/demo/privileged/index.html
index 829e33383..e063642b7 100644
--- a/demo/privileged/index.html
+++ b/demo/privileged/index.html
@@ -1,12 +1,12 @@
- Temasys SkylinkJS Demo: Privileged User Feature
+ Temasys Web SDK Demo: Privileged User Feature
-
Temasys SkylinkJS Demo: Privileged User Feature
+
Temasys Web SDK Demo: Privileged User Feature
Click on the buttons below to open the corresponding type of peer in a new tab
diff --git a/demo/privileged/unauto-priv/index.html b/demo/privileged/unauto-priv/index.html
index fd0973e86..645b0e724 100644
--- a/demo/privileged/unauto-priv/index.html
+++ b/demo/privileged/unauto-priv/index.html
@@ -1,7 +1,7 @@
- Temasys SkylinkJS Demo: Privileged User Feature (for Privileged App Key + Auto Introduce Disabled)
+ Temasys Web SDK Demo: Privileged User Feature (for Privileged App Key + Auto Introduce Disabled)
@@ -22,7 +22,7 @@
- Temasys SkylinkJS Demo: Privileged User Feature (for Privileged App Key + Auto Introduce Disabled)
+ Temasys Web SDK Demo: Privileged User Feature (for Privileged App Key + Auto Introduce Disabled)
@@ -231,7 +231,8 @@
Targeted peers to message / file transfer to
-
+
+
diff --git a/demo/privileged/unauto-priv/js/main.js b/demo/privileged/unauto-priv/js/main.js
index 79d4fb8cb..ac85e8824 100644
--- a/demo/privileged/unauto-priv/js/main.js
+++ b/demo/privileged/unauto-priv/js/main.js
@@ -431,10 +431,7 @@ Demo.Skylink.on('channelError', function (error) {
//------------- join room ---------------------------
var displayName = 'name_' + 'user_' + Math.floor((Math.random() * 1000) + 1);
-Demo.Skylink.init({
- appKey: config.privKey,
- defaultRoom: 'test'
-}, function (error, success) {
+Demo.Skylink.init(config, function (error, success) {
if (success) {
Demo.Skylink.joinRoom({
userData: displayName,
diff --git a/demo/privileged/unauto-unpriv/index.html b/demo/privileged/unauto-unpriv/index.html
index 504a0fccc..f7c68ed1d 100644
--- a/demo/privileged/unauto-unpriv/index.html
+++ b/demo/privileged/unauto-unpriv/index.html
@@ -1,7 +1,7 @@
- Temasys SkylinkJS Demo: Privileged User Feature (for non-Privileged App Key + Auto Introduce Disabled)
+ Temasys Web SDK Demo: Privileged User Feature (for non-Privileged App Key + Auto Introduce Disabled)
@@ -22,7 +22,7 @@
- Temasys SkylinkJS Demo: Privileged User Feature (for non-Privileged App Key + Auto Introduce Disabled)
+ Temasys Web SDK Demo: Privileged User Feature (for non-Privileged App Key + Auto Introduce Disabled)
Function that handles the "inRoom" socket message received.
-See confluence docs for the "inRoom" expected properties to be received
- based on the current SM_PROTOCOL_VERSION.
Function that handles the "introduceError" socket message received.
-See confluence docs for the "introduceError" expected properties to be received
- based on the current SM_PROTOCOL_VERSION.
+
Function that modifies the session description to handle the connection settings.
+This is experimental and never recommended to end-users.
Loads and checks the dependencies if they are loaded correctly.
+
Function that handles the "inRoom" socket message received.
+See confluence docs for the "inRoom" expected properties to be received
+ based on the current SM_PROTOCOL_VERSION.
Function that handles the logs received and prints in the Web Console interface according to the log level set.
+
Function that handles the "introduceError" socket message received.
+See confluence docs for the "introduceError" expected properties to be received
+ based on the current SM_PROTOCOL_VERSION.
Function that handles the "muteAudioEvent" socket message received.
-See confluence docs for the "muteAudioEvent" expected properties to be received
- based on the current SM_PROTOCOL_VERSION.
+
Loads and checks the dependencies if they are loaded correctly.
Function that handles the "muteVideoEvent" socket message received.
-See confluence docs for the "muteVideoEvent" expected properties to be received
- based on the current SM_PROTOCOL_VERSION.
+
Function that handles the "MESSAGE" data transfer protocol.
Function that handles the "offer" socket message received.
-See confluence docs for the "offer" expected properties to be received
+
Function that handles the "muteAudioEvent" socket message received.
+See confluence docs for the "muteAudioEvent" expected properties to be received
based on the current SM_PROTOCOL_VERSION.
Function that handles the RTCPeerConnection.onaddstream remote MediaStream received.
+
Function that handles the "muteVideoEvent" socket message received.
+See confluence docs for the "muteVideoEvent" expected properties to be received
+ based on the current SM_PROTOCOL_VERSION.
Function that handles the native navigator.getUserMedia() API failure callback result.
+
Function that handles the "offer" socket message received.
+See confluence docs for the "offer" expected properties to be received
+ based on the current SM_PROTOCOL_VERSION.
Function that starts the socket connection to the Signaling.
-This starts creating the socket connection and called at first not when requiring to fallback.
+
Function that handles the RTCPeerConnection.onaddstream remote MediaStream received.
Function that parses the getUserMedia() settings provided.
+
Function that starts the socket connection to the Signaling.
+This starts creating the socket connection and called at first not when requiring to fallback.
Function that handles the "peerList" socket message received.
-See confluence docs for the "peerList" expected properties to be received
- based on the current SM_PROTOCOL_VERSION.
Function that handles the "private" socket message received.
-See confluence docs for the "private" expected properties to be received
+
Function that handles the "peerList" socket message received.
+See confluence docs for the "peerList" expected properties to be received
based on the current SM_PROTOCOL_VERSION.
Function that handles and processes the socket message received.
+
Function that handles the "private" socket message received.
+See confluence docs for the "private" expected properties to be received
+ based on the current SM_PROTOCOL_VERSION.
Function that handles the "roomLockEvent" socket message received.
-See confluence docs for the "roomLockEvent" expected properties to be received
- based on the current SM_PROTOCOL_VERSION.
Function that sends a socket message over the socket connection to the Signaling.
+
Function that handles the "roomLockEvent" socket message received.
+See confluence docs for the "roomLockEvent" expected properties to be received
+ based on the current SM_PROTOCOL_VERSION.
Function that filters and configures the ICE servers received from Signaling
- based on the init() configuration and returns the updated
- list of ICE servers to be used when constructing Peer connection.
+
Function that sends data over the Datachannel connection.
Function that sets the local session description and sends to Peer.
-If trickle ICE is disabled, the local session description will be sent after
- ICE gathering has been completed.
+
Function that filters and configures the ICE servers received from Signaling
+ based on the init() configuration and returns the updated
+ list of ICE servers to be used when constructing Peer connection.
Function that modifies the session description to limit the maximum sending bandwidth.
-Setting this may not necessarily work in Firefox.
+
Function that sets the local session description and sends to Peer.
+If trickle ICE is disabled, the local session description will be sent after
+ ICE gathering has been completed.
Function that handles the "stream" socket message received.
-See confluence docs for the "stream" expected properties to be received
- based on the current SM_PROTOCOL_VERSION.
+
Function that starts or listens the data transfer status to Peer.
+This reacts differently during MCU environment.
Function that throttles a method function to prevent multiple invokes over a specified amount of time.
-Returns a function to be invoked ._throttle(fn, 1000)() to make throttling functionality work.
Function that handles the "stream" socket message received.
+See confluence docs for the "stream" expected properties to be received
+ based on the current SM_PROTOCOL_VERSION.
Function that throttles a method function to prevent multiple invokes over a specified amount of time.
+Returns a function to be invoked ._throttle(fn, 1000)() to make throttling functionality work.
Function that gets the list of current data streaming sessions.
+
+
+
+
+
+
Example:
+
+
// Example 1: Get the list of current data streaming sessions in the same Room
+ var currentDataStreams = skylinkDemo.getCurrentDataStreamsSession();
+
+
+
+
+
+
+
+
+
+
Events Sequence:
+ There is no event sequence for this method.
+
+
+
+
+
+
+
+
Returns:
+
+
+
+
+ {JSON}
+
+
The list of Peers Stream.
+
#streamId{JSON}
The data streaming session.
+
streamInfo{JSON}
The data streaming information.
+ Object signature matches the streamInfo parameter payload received in the
+ dataStreamState event
+ except without the chunk amd chunkSize property.
Function that gets the list of current data transfers.
+
+
+
+
+
+
Example:
+
+
// Example 1: Get the list of current data transfers in the same Room
+ var currentTransfers = skylinkDemo.getCurrentDataTransfers();
+
+
+
+
+
+
+
+
+
+
Events Sequence:
+ There is no event sequence for this method.
+
+
+
+
+
+
+
+
Returns:
+
+
+
+
+ {JSON}
+
+
The list of Peers Stream.
+
#transferId{JSON}
The data transfer session.
+
transferInfo{JSON}
The data transfer information.
+ Object signature matches the transferInfo parameter payload received in the
+ dataTransferState event
+ except without the data property.
Function that gets the current list of connected Peers Datachannel connections in the Room.
+
+
+
+
+
+
Example:
+
+
// Example 1: Get the list of current Peers Datachannels in the same Room
+ var channels = skylinkDemo.getPeersDatachannels();
+
+
+
+
+
+
+
+
+
+
Events Sequence:
+ There is no event sequence for this method.
+
+
+
+
+
+
+
+
Returns:
+
+
+
+
+ {JSON}
+
+
The list of Peers Stream.
+
#peerId{JSON}
The Peer Datachannels information.
+
#channelName{JSON}
The Datachannel information.
+
channelName{String}
The Datachannel ID..
+
channelType{String}
The Datachannel type.
+ [Rel: Skylink.DATA_CHANNEL_TYPE]
+
channelProp{String}
The Datachannel property.
+
currentTransferId{String}
The Datachannel connection
+ current progressing transfer session. Defined as null when there is
+ currently no transfer session progressing on the Datachannel connection.
+
currentStreamId{String}
The Datachannel connection
+ current data streaming session ID. Defined as null when there is currently
+ no data streaming session on the Datachannel connection.
+
readyState{String}
The Datachannel connection readyState.
+ [Rel: Skylink.DATA_CHANNEL_STATE]
DEFAULT: false
- The flag if stereo band should be configured
- when encoding audio codec is OPUS for sending / receiving audio data.
- Note that Peers may override the "receiving" stereo config depending on the Peers configuration.
+
Deprecation Warning!
+ This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo
+ parameter in the init() method instead. If the
+ options.codecParams.audio.opus.stereo is configured, this overrides the
+ options.audio.stereo setting.
+ The flag if OPUS audio codec stereo band should be configured for sending encoded audio data.
+ When not provided, the default browser configuration is used.
@@ -13987,13 +15039,17 @@
Parameters:
-
- Note that this feature might not work depending on the browser support and implementation.
- The flag if DTX (Discontinuous Transmission) should be configured when encoding audio codec
- is OPUS for sending / receiving audio data.
- This might help to reduce bandwidth it reduces the bitrate during silence or background noise.
+
Deprecation Warning!
+ This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo
+ parameter in the init() method instead. If the
+ options.codecParams.audio.opus.stereo is configured, this overrides the
+ options.audio.stereo setting. Note that this feature might
+ not work depending on the browser support and implementation.
+ The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.
+ This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and
+ goes hand-in-hand with the options.voiceActivityDetection flag in
+ joinRoom() method.
When not provided, the default browser configuration is used.
- Note that Peers may override the "receiving" usedtx config depending on the Peers configuration.
@@ -14006,13 +15062,16 @@
Parameters:
-
- Note that this feature might not work depending on the browser support and implementation.
- The flag if capability to take advantage of in-band FEC (Forward Error Correction) should be
- configured when encoding audio codec is OPUS for sending / receiving audio data.
- This might help to reduce the harm of packet loss by encoding information about the previous packet.
+
Deprecation Warning!
+ This property has been deprecated. Configure this with the options.codecParams.audio.opus.useinbandfec
+ parameter in the init() method instead. If the
+ options.codecParams.audio.opus.useinbandfec is configured, this overrides the
+ options.audio.useinbandfec setting. Note that this parameter should only be used
+ for debugging purposes only.
+ The flag if OPUS audio codec has the capability to take advantage of the in-band FEC
+ (Forward Error Correction) when sending encoded audio data.
+ This helps to reduce the harm of packet loss by encoding information about the previous packet loss.
When not provided, the default browser configuration is used.
- Note that Peers may override the "receiving" useinbandfec config depending on the Peers configuration.
@@ -14025,13 +15084,18 @@
Parameters:
-
- Note that this feature might not work depending on the browser support and implementation.
- The maximum output sampling rate rendered in Hertz (Hz) when encoding audio codec is
- OPUS for sending / receiving audio data.
+
Deprecation Warning!
+ This property has been deprecated. Configure this with the options.codecParams.audio.opus.maxplaybackrate
+ parameter in the init() method instead. If the
+ options.codecParams.audio.opus.maxplaybackrate is configured, this overrides the
+ options.audio.maxplaybackrate setting. Note that this feature might
+ not work depending on the browser support and implementation.
+ Note that this parameter should only be used for debugging purposes only.
+ The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving
+ decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data
+ would not encode at a higher sampling rate specified by this.
This value must be between 8000 to 48000.
When not provided, the default browser configuration is used.
- Note that Peers may override the "receiving" maxplaybackrate config depending on the Peers configuration.
@@ -14095,8 +15159,11 @@
Parameters:
- DEFAULT: false
- The flag to enable audio tracks echo cancellation.
+ DEFAULT: true
+
+ For Chrome/Opera/IE/Safari/Bowser, the echo cancellation functionality may not work and may produce a terrible
+ feedback. It is recommended to use headphones or other microphone devices rather than the device
+ in-built microphones.
The flag to enable echo cancellation for audio track.
+
+ The video codec to prefer to encode sending audio data when available.
+ The value must not be AUTO.
+ [Rel: Skylink.VIDEO_CODEC]
+
+
+
+
+ samplingRate
+ {Number}
+
+ Optional
+
+
+
+
+ The video codec sampling to prefer to encode sending video data when available.
+
+
+
+
+
@@ -14957,7 +16099,9 @@
Parameters:
DEFAULT: 20000
The timeout for each attempts for socket connection
with the Signaling server to indicate that connection has timed out and has failed to establish.
- Note that the mininum timeout value is 5000. If less, this value will be 5000.
+ Note that the mininum timeout value is 5000. If less, this value will be 5000.
+ Note that it is recommended to use 12000 as the lowest timeout value if Peers are connecting
+ using Polling transports to prevent connection errors.
@@ -15151,6 +16295,465 @@
Parameters:
+
+ iceServer
+ {String | Array}
+
+ Optional
+
+
+
+
+
The ICE servers for debugging purposes to use.
+
+
When defined as string, the value is considered as [options.iceServer].
+Note that this is a debugging feature and is only used when instructed for debugging purposes.
+
+
+
+
+
+
+
+
+ #index
+ {String}
+
+ Optional
+
+
+
+
+ The ICE server url for debugging purposes to use.
+
The Signaling server for debugging purposes to use.
+
+
When defined as string, the value is considered as { url: options.socketServer }.
+Note that this is a debugging feature and is only used when instructed for debugging purposes.
+
+
+
+
+
+
+
+
+ url
+ {String}
+
+
+
+
+
+
+ The Signaling server URL for debugging purposes to use.
+
+
+
+
+ ports
+ {Array}
+
+ Optional
+
+
+
+
+ The list of Signaling server ports for debugging purposes to use.
+ If not defined, it will use the default list of ports specified.
+
+
+
+
+ ports.#index
+ {Number}
+
+
+
+
+
+
+ The Signaling server port to fallback and use for debugging purposes.
+
+
+
+
+ protocol
+ {String}
+
+ Optional
+
+
+
+
+ The Signaling server protocol for debugging purposes to use.
+ If not defined, it will use the default protocol specified.
+
+
+
+
+
+
+
+
+ codecParams
+ {JSON}
+
+ Optional
+
+
+
+
+
+ Note that some of these parameters are mainly used for experimental or debugging purposes. Toggling any of
+ these feature may result in disruptions in connectivity.
+ The audio and video codecs parameters to configure.
+
+
+
+
+
+
+
+ video
+ {JSON}
+
+ Optional
+
+
+
+
+ The video codecs parameters to configure.
+
+
+
+
+ video.h264
+ {JSON}
+
+ Optional
+
+
+
+
+ The H264 video codec parameters to configure.
+
+ Note that this parameter should only be used for debugging purposes only.
+ The H264 video codec base16 encoded string which indicates the H264 baseline, main, or the extended profiles.
+ When not provided, the default browser configuration is used.
+
+ Note that this is an experimental parameter which may result in connectivity issues when toggled.
+ The flag if streaming H264 sending video data should be encoded at a different level
+ from receiving video data from Peer encoding to User when Peer is the offerer.
+ If Peer is the offerer instead of the User, the Peer's peerInfo.config.priorityWeight will be
+ higher than User's peerInfo.config.priorityWeight.
+ When not provided, the default browser configuration is used.
+
+ Note that this is an experimental parameter which may result in connectivity issues when enabled. It is
+ advisable to turn off this feature off when receiving H264 decoders do not support the packetization mode,
+ which may result in a blank receiving video stream.
+ The flag to enable H264 video codec packetization mode, which splits video frames that are larger
+ for a RTP packet into RTP packet chunks.
+ When not provided, the default browser configuration is used.
+
+
+
+
+ video.vp8
+ {JSON}
+
+ Optional
+
+
+
+
+ The VP8 video codec parameters to configure.
+
+
+
+
+ video.vp8.maxFr
+ {Number}
+
+ Optional
+
+
+
+
+
+ Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
+ The maximum number of fps (frames per second) that the VP8 video codec decoder is capable of
+ decoding when receiving encoded video data packets.
+ When not provided, the default browser configuration is used.
+
+
+
+
+ video.vp8.maxFs
+ {Number}
+
+ Optional
+
+
+
+
+
+ Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
+ The maximum number of frame size macroblocks that the VP8 video codec decoder is capable of
+ decoding when receiving encoded video data packets.
+ The value has to have the width and height of the frame in macroblocks less than the value of
+ parseInt(Math.sqrt(maxFs * 8)). E.g. If the value is 1200, it is capable of
+ support 640x480 frame width and height, which heights up to 1552px
+ (97 macroblocks value.
+ When not provided, the default browser configuration is used.
+
+
+
+
+ video.vp9
+ {JSON}
+
+ Optional
+
+
+
+
+ The VP9 video codec parameters to configure.
+
+
+
+
+ video.vp9.maxFr
+ {Number}
+
+ Optional
+
+
+
+
+
+ Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
+ The maximum number of fps (frames per second) that the VP9 video codec decoder is capable of
+ decoding when receiving encoded video data packets.
+ When not provided, the default browser configuration is used.
+
+
+
+
+ video.vp9.maxFs
+ {Number}
+
+ Optional
+
+
+
+
+
+ Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
+ The maximum number of frame size macroblocks that the VP9 video codec decoder is capable of
+ decoding when receiving encoded video data packets.
+ The value has to have the width and height of the frame in macroblocks less than the value of
+ parseInt(Math.sqrt(maxFs * 8)). E.g. If the value is 1200, it is capable of
+ support 640x480 frame width and height, which heights up to 1552px
+ (97 macroblocks value.
+ When not provided, the default browser configuration is used.
+
+
+
+
+ audio
+ {JSON}
+
+ Optional
+
+
+
+
+ The audio codecs parameters to configure.
+
+
+
+
+ audio.opus
+ {JSON}
+
+ Optional
+
+
+
+
+
+ Note that this is only applicable to OPUS audio codecs with a sampling rate of 48000 Hz (hertz).
+
+
+ The flag if OPUS audio codec stereo band
+ should be configured for sending encoded audio data.
+ When not provided, the default browser configuration is used.
+
+ Note that this feature might not work depending on the browser support and implementation.
+ The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.
+ This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and
+ goes hand-in-hand with the options.voiceActivityDetection flag in
+ joinRoom() method.
+ When not provided, the default browser configuration is used.
+
+ Note that this parameter should only be used for debugging purposes only.
+ The flag if OPUS audio codec has the capability to take advantage of the in-band FEC
+ (Forward Error Correction) when sending encoded audio data.
+ This helps to reduce the harm of packet loss by encoding information about the previous packet loss.
+ When not provided, the default browser configuration is used.
+
+ Note that this parameter should only be used for debugging purposes only.
+ The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving
+ decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data
+ would not encode at a higher sampling rate specified by this.
+ This value must be between 8000 to 48000.
+ When not provided, the default browser configuration is used.
+
+
+
+
+ minptime
+ {Number}
+
+ Optional
+
+
+
+
+
+ Note that this parameter should only be used for debugging purposes only.
+ The OPUS audio codec receiving audio data decoder minimum length of time in milleseconds should be
+ encapsulated in a single received encoded audio data packet.
+ This value must be between 3 to 120
+ When not provided, the default browser configuration is used.
+
The flag if voice activity detection should be enabled.
+ This can only be toggled if User is and for the offerer, which is determined if User's
+ peerInfo.config.priorityWeight is higher than Peer's.
+
+ This works hand-in-hand with the options.disableComfortNoiseCodec flag in the
+ init() method and the options.audio.usedtx setting in
+ getUserMedia() method. VAD (voice activity detection)
+ detects if there is an active voice in the Stream, and if there is no active voice in the Stream, the
+ options.audio.usedtx (if enabled) would prevent sending these empty bits. To prevent huge differences
+ when there is a silence and an active voice later, the CN codec would produce an empty voice to
+ make it sound better.
+
+
+
+
@@ -16478,8 +18134,181 @@
Parameters:
- The parent Peer ID to match to when Peer is connected.
+
Deprecation Warning!
+ This property has been deprecated. Use options.parentId instead.
+
The parent Peer ID to match to when Peer is connected.
This is useful for identification for users connecting the Room twice simultaneously for multi-streaming.
+ If User Peer ID matches the parent Peer ID provided from Peer, User will not be connected to Peer.
+
+
+
+
+
+
+
+
+ parentId
+ {String}
+
+ Optional
+
+
+
+
+
The parent Peer ID to match to when Peer is connected.
+ Note that configuring this value overrides the options.publishOnly.parentId value.
+ This is useful for identification for users connecting the Room twice simultaneously for multi-streaming.
+ If User Peer ID matches the parent Peer ID provided from Peer, User will not be connected to Peer.
+
+
+
+
+
+
+
+ peerConnection
+ {JSON}
+
+ Optional
+
+
+
+
+
+ Note that this is mainly used for debugging purposes, so it may cause disruptions in connections or
+ connectivity issues when configured.
The Peer connection constraints settings.
+
+
+
+
+
+
+
+ bundlePolicy
+ {String}
+
+ Optional
+
+
+
+
+ The Peer connection media bundle policy.
+- When not provided, its value is BALANCED.
+ [Rel: Skylink.BUNDLE_POLICY]
+
+
+
+
+ rtcpMuxPolicy
+ {String}
+
+ Optional
+
+
+
+
+ The Peer connection RTP and RTCP ICE candidates mux policy.
+- When not provided, its value is REQUIRE.
+ [Rel: Skylink.RTCP_MUX_POLICY]
+
+ DEFAULT: 0
+ The number of ICE candidates to gather before
+ gathering it when setting local offer / answer session description.
+
+
+
+
+ certificate
+ {String}
+
+ Optional
+
+
+
+
+ The type of certificate that Peer connection should
+ generate and use when available.
+- When not provided, its value is AUTO.
+ [Rel: Skylink.PEER_CERTIFICATE]
+
+ Note that this is an experimental feature which may be removed or changed in the future releases.
+ This feature is also only available for non-MCU enabled Peer connections and Edge Peer connections.
+
The flag if Peer connections uploading and downloading bandwidth should be automatically adjusted
+ each time based on a specified interval.
+ Note this would cause peerRestart event to be triggered
+ for each specified interval.
+
+
+
+
+
+
+
+ interval
+ {Number}
+
+ Optional
+
+
+
+ DEFAULT: 10
+ The interval each time to adjust bandwidth
+ connections in seconds.
+ Note that the minimum value is 10.
+
+
+
+
+ limitAtPercentage
+ {Number}
+
+ Optional
+
+
+
+ DEFAULT: 100
+ The percentage of the average bandwidth to adjust to.
+ E.g. avgBandwidth * (limitPercentage / 100).
+
+
+
+
+ useUploadBwOnly
+ {Boolean}
+
+ Optional
+
+
+
+ DEFAULT: false
+ The flag if average bandwidth computation
+ should only consist of the upload bandwidth.
+ Note that Edge browser does not support renegotiation.
For MCU enabled Peer connections with options.mcuUseRenegoRestart set to false
in the init() method, the restart functionality may differ, you
may learn more about how to workaround it
@@ -17975,6 +19813,66 @@
Parameters:
+
+ options
+ {JSON}
+
+ Optional
+
+
+
+
+
+ Note that for MCU connections, the bandwidth or googleXBandwidth
+ settings will override for all Peers or the current Room connection session settings.
+ The custom Peer configuration settings.
+
+
+
+
+
+
+
+ bandwidth
+ {JSON}
+
+ Optional
+
+
+
+
+
The configuration to set the maximum streaming bandwidth to send to Peers.
+ Object signature follows joinRoom() method
+ options.bandwidth settings.
+
+
+
+
+
+
+
+ googleXBandwidth
+ {JSON}
+
+ Optional
+
+
+
+
+
The configuration to set the experimental google
+ video streaming bandwidth sent to Peers.
+ Object signature follows joinRoom() method
+ options.googleXBandwidth settings.
+
+
+
+
+
+
+
+
+
+
callback{Function}
@@ -18054,6 +19952,62 @@
Parameters:
+
+ refreshSettings
+ {JSON}
+
+
+
+
+
+
+ The list of Peer connection refresh settings.
+
+
+
+
+ refreshSettings.#peerId
+ {JSON}
+
+
+
+
+
+
+ The Peer connection refresh settings associated
+ with the Peer ID defined in #peerId property.
+
If there is any conflicting streamData()
+ method data streaming session: If sendChunksAsBinary is provided as true,
+ it cannot start if existing data streaming session is expected binary data chunks, and if provided as
+ false, or method invoked is sendURLData() method,
+ or Peer is using string data chunks fallback due to its support despite provided as true,
+ it cannot start if existing data streaming session is expected string data chunks.
+
The flag if stereo band should be configured
- when encoding audio codec is OPUS for sending audio data.
+
Deprecation Warning!
+ This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo
+ parameter in the init() method instead. If the
+ options.codecParams.audio.opus.stereo is configured, this overrides the
+ options.audio.stereo setting.
+ The flag if OPUS audio codec stereo band should be configured for sending encoded audio data.
+ When not provided, the default browser configuration is used.
@@ -20421,11 +22450,16 @@
Parameters:
-
- Note that this feature might not work depending on the browser support and implementation.
- The flag if DTX (Discontinuous Transmission) should be configured when encoding audio codec
- is OPUS for sending audio data.
- This might help to reduce bandwidth it reduces the bitrate during silence or background noise.
+
Deprecation Warning!
+ This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo
+ parameter in the init() method instead. If the
+ options.codecParams.audio.opus.stereo is configured, this overrides the
+ options.audio.stereo setting. Note that this feature might
+ not work depending on the browser support and implementation.
+ The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.
+ This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and
+ goes hand-in-hand with the options.voiceActivityDetection flag in
+ joinRoom() method.
When not provided, the default browser configuration is used.
@@ -20442,11 +22476,15 @@
Parameters:
-
- Note that this feature might not work depending on the browser support and implementation.
- The flag if capability to take advantage of in-band FEC (Forward Error Correction) should be
- configured when encoding audio codec is OPUS for sending audio data.
- This might help to reduce the harm of packet loss by encoding information about the previous packet.
+
Deprecation Warning!
+ This property has been deprecated. Configure this with the options.codecParams.audio.opus.useinbandfec
+ parameter in the init() method instead. If the
+ options.codecParams.audio.opus.useinbandfec is configured, this overrides the
+ options.audio.useinbandfec setting. Note that this parameter should only be used
+ for debugging purposes only.
+ The flag if OPUS audio codec has the capability to take advantage of the in-band FEC
+ (Forward Error Correction) when sending encoded audio data.
+ This helps to reduce the harm of packet loss by encoding information about the previous packet loss.
When not provided, the default browser configuration is used.
@@ -20463,10 +22501,16 @@
Parameters:
-
- Note that this feature might not work depending on the browser support and implementation.
- The maximum output sampling rate rendered in Hertz (Hz) when encoding audio codec is
- OPUS for sending audio data.
+
Deprecation Warning!
+ This property has been deprecated. Configure this with the options.codecParams.audio.opus.maxplaybackrate
+ parameter in the init() method instead. If the
+ options.codecParams.audio.opus.maxplaybackrate is configured, this overrides the
+ options.audio.maxplaybackrate setting. Note that this feature might
+ not work depending on the browser support and implementation.
+ Note that this parameter should only be used for debugging purposes only.
+ The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving
+ decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data
+ would not encode at a higher sampling rate specified by this.
This value must be between 8000 to 48000.
When not provided, the default browser configuration is used.
@@ -20483,8 +22527,11 @@
Parameters:
- DEFAULT: false
-
The flag to enable audio tracks echo cancellation.
+ DEFAULT: true
+
+ For Chrome/Opera/IE/Safari/Bowser, the echo cancellation functionality may not work and may produce a terrible
+ feedback. It is recommended to use headphones or other microphone devices rather than the device
+ in-built microphones.
The flag to enable echo cancellation for audio track.
If Peer connection messaging Datachannel has not been opened: This can be checked with
+ dataChannelState event triggering parameter
+ payload state as OPEN and channelType as
+ MESSAGING for Peer.
If MCU is enabled for the App Key provided in init()method and connected:
+
If MCU Peer connection messaging Datachannel has not been opened: This can be checked with
+ dataChannelState event triggering parameter
+ payload state as OPEN, peerId value as "MCU"
+ and channelType as MESSAGING for MCU Peer.
+
If Peer supports simultaneous data streaming, open new data Datachannel: If MCU is connected,
+ this opens a new data Datachannel with MCU Peer with all the Peers IDs information that supports
+ simultaneous data transfers targeted for the data streaming session instead of opening new data Datachannel
+ with all Peers targeted for the data streaming session.
+
dataChannelState event triggers parameter
+ payload state as CONNECTING and channelType as DATA.
+ Note that there is no timeout to wait for parameter payload state to be
+ OPEN.
+
If Datachannel has been created and opened successfully:
+
dataChannelState event triggers parameter payload
+ state as OPEN and channelType as DATA.
+
Else:
dataChannelState event
+ triggers parameter payload state as CREATE_ERROR and channelType as
+ DATA.
Else: If MCU is connected,
+ this uses the messaging Datachannel with MCU Peer with all the Peers IDs information that supports
+ simultaneous data transfers targeted for the data streaming session instead of using the messaging Datachannels
+ with all Peers targeted for the data streaming session.
If messaging Datachannel connection has a
+ data streaming in-progress:
If there is any conflicting streamData()
+ method data streaming session: If isStringStream is provided as true and
+ sendBlobData() method or
+ sendURLData() method has an existing binary string transfer, it cannot start string data
+ streaming session. Else if sendBlobData() method
+ has an existing binary data transfer, it cannot start binary data streaming session.
+
For User onlydataStreamState event
+ triggers parameter payload state as SENDING_STARTED.
+
For Peer onlydataStreamState event
+ triggers parameter payload state as RECEIVING_STARTED.
+
+
+
+
+
+
Parameters:
+
+
+
+
+ isStringStream
+ {Boolean}
+
+ Optional
+
+
+
+ DEFAULT: false
+
The flag if data streaming session sending data chunks
+ should be expected as string data chunks sent.
+ By default, data chunks are expected to be sent in Blob or ArrayBuffer, and ArrayBuffer
+ data chunks will be converted to Blob.
+Function that stops a data chunks streaming session from User to Peers.
+
+
+
+
+
+
Example:
+
+
skylinkDemo.stopStreamData(streamId);
+
+
+
+
+
+
+
+
+
+
Events Sequence:
+
+
Checks if Peer connection and Datachannel connection are in correct states.
+
If Peer connection (or MCU Peer connection if enabled)
+ data streaming Datachannel has not been opened: This can be checked with
+ dataChannelState event triggering parameter
+ payload state as OPEN and channelType as
+ MESSAGING for Peer.
Checks if Peer connection and Datachannel connection are in correct states.
+
If Peer connection (or MCU Peer connection if enabled)
+ data streaming Datachannel has not been opened: This can be checked with
+ dataChannelState event triggering parameter
+ payload state as OPEN and channelType as
+ MESSAGING for Peer.
The data chunk.
+ By default when it is not string data streaming, data chunks when is are expected to be
+ sent in Blob or ArrayBuffer, and ArrayBuffer data chunks will be converted to Blob.
+ For binary data chunks, the limit is 65456.
+ For string data chunks, the limit is 1212.
Stores the data chunk size for Blob transfers transferring from/to
- Firefox browsers due to limitation tested in the past in some PCs (linx predominatly).
+
Stores the data chunk size for binary Blob transfers.
Stores the construct API REST path to obtain Room credentials.
+
Stores the data chunk size for Blob transfers transferring from/to
+ Firefox browsers due to limitation tested in the past in some PCs (linx predominatly).
Stores the Room credentials information for joinRoom().
+
Stores the User connection priority weight.
+If Peer has a higher connection weight, it will do the offer from its Peer connection first.
@@ -26638,90 +29532,6 @@
_room
-
-
Keys:
-
-
-
-
- id
- {String}
-
-
-
-
-
-
The "rid" for joinRoom().
-
-
-
-
-
-
-
- token
- {String}
-
-
-
-
-
-
The "roomCred" for joinRoom().
-
-
-
-
-
-
-
- startDateTime
- {String}
-
-
-
-
-
-
The "start" for joinRoom().
-
-
-
-
-
-
-
- duration
- {String}
-
-
-
-
-
-
The "len" for joinRoom().
-
-
-
-
-
-
-
- connection
- {String}
-
-
-
-
-
-
The RTCPeerConnection constraints and configuration. This is not used in the SDK
- except for the "mediaConstraints" property that sets the default getUserMedia() settings.
Stores the preferred sending Peer connection streaming video codec.
+
Stores the Room credentials information for joinRoom().
+
+
+
+
-
Default value:
- "auto"
+
Keys:
+
+
+
+
+ id
+ {String}
+
+
+
+
+
+
The "rid" for joinRoom().
+
+
+
+
+
+
+
+ token
+ {String}
+
+
+
+
+
+
The "roomCred" for joinRoom().
+
+
+
+
+
+
+
+ startDateTime
+ {String}
+
+
+
+
+
+
The "start" for joinRoom().
+
+
+
+
+
+
+
+ duration
+ {String}
+
+
+
+
+
+
The "len" for joinRoom().
+
+
+
+
+
+
+
+ connection
+ {String}
+
+
+
+
+
+
The RTCPeerConnection constraints and configuration. This is not used in the SDK
+ except for the "mediaConstraints" property that sets the default getUserMedia() settings.
Stores the queued socket messages.
-This is to prevent too many sent over less than a second interval that might cause dropped messages
- or jams to the Signaling connection.
Stores the list of socket ports to use to connect to the Signaling.
-These ports are defined by default which is commonly used currently by the Signaling.
-Should re-evaluate this sometime.
+
Stores the current Room name that User is connected to.
Stores the queued socket messages.
+This is to prevent too many sent over less than a second interval that might cause dropped messages
+ or jams to the Signaling connection.
Stores the list of socket ports to use to connect to the Signaling.
+These ports are defined by default which is commonly used currently by the Signaling.
+Should re-evaluate this sometime.
- Note that if the audio codec is not supported, the SDK will not configure the local "offer" or
- "answer" session description to prefer the codec.
-
-The list of available audio codecs to set as the preferred audio codec to use to encode
-sending audio data when available encoded audio codec for Peer connections
-configured in the init() method.
+
Stores the timestamps data used for throttling.
@@ -29611,90 +32742,101 @@
AUDIO_CODEC
-
-
Keys:
-
-
-
- AUTO
- {String}
+
+
+
+
-
+
+
+
_TURNTransport
+ Attribute Type: {String}
-
-
Value "auto"
- The value of the option to not prefer any audio codec but rather use the created
- local "offer" / "answer" session description audio codec preference.
+
+
+
-
+
-
-
-
- OPUS
- {String}
+ required
+
-
-
+
-
-
Value "opus"
- The value of the option to prefer the OPUS audio codec.
+
+ private
+
-
+
-
-
-
- ISAC
- {String}
-
-
+
-
-
Value "ISAC"
- The value of the option to prefer the ISAC audio codec.
+
-
+
-
-
-
- G722
- {String}
-
-
+
-
-
Value "G722"
- The value of the option to prefer the G722 audio codec.
- Learn more about how ICE works in this
- article here.
-
-The list of Peer connection ICE gathering states.
+
Stores the flag that indicates if public STUN ICE servers should be used when constructing Peer connection.
-
+
+
Default value:
+ true
+
-
-
Keys:
-
-
-
-
- GATHERING
- {String}
-
-
-
-
-
-
Value "gathering"
- The value of the state when Peer connection is gathering ICE candidates.
- These ICE candidates are sent to Peer for its connection to check for a suitable matching
- pair of ICE candidates to establish an ICE connection for stream audio, video and data.
- See iceConnectionState event for ICE connection status.
- This state cannot happen until Peer connection remote "offer" / "answer"
- session description is set. See
- peerConnectionState event for session description exchanging status.
-
-
-
-
-
-
-
- COMPLETED
- {String}
-
-
-
-
-
-
Value "completed"
- The value of the state when Peer connection gathering of ICE candidates has completed.
- Learn more about how ICE works in this
- article here.
-
-The list of Peer connection remote ICE candidate processing states for trickle ICE connections.
+
Stores the Signaling user credentials from the API response required for connecting to the Signaling server.
@@ -29896,47 +32989,14 @@
Keys:
- RECEIVED
- {String}
-
-
-
-
-
-
Value "received"
- The value of the state when the remote ICE candidate was received.
-
-
-
-
-
-
-
- DROPPED
- {String}
-
-
-
-
-
-
Value "received"
- The value of the state when the remote ICE candidate is dropped.
-
-
-
-
-
-
-
- BUFFERED
+ uid{String}
-
Value "buffered"
- The value of the state when the remote ICE candidate is buffered.
+
The API result "username".
@@ -29944,15 +33004,14 @@
Keys:
- PROCESSING
+ token{String}
-
Value "processing"
- The value of the state when the remote ICE candidate is being processed.
+
The API result "userCred".
@@ -29960,17 +33019,14 @@
Keys:
- PROCESS_SUCCESS
+ timeStamp{String}
-
Value "processSuccess"
- The value of the state when the remote ICE candidate has been processed successfully.
- The ICE candidate that is processed will be used to check against the list of
- locally generated ICE candidate to start matching for the suitable pair for the best ICE connection.
+
The API result "timeStamp".
@@ -29978,15 +33034,14 @@
Keys:
- PROCESS_ERROR
+ sid{String}
-
Value "processError"
- The value of the state when the remote ICE candidate has failed to be processed.
The list of Datachannel sending message error types.
+
Stores the User custom data.
+By default, if no custom user data is set, it is an empty string "".
-
+
+
Default value:
+ ""
+
-
-
Keys:
-
-
-
-
- MESSAGE
- {String}
-
-
-
-
-
-
Value "message"
- The value of the Datachannel sending message error type when encountered during
- sending P2P message from sendP2PMessage() method.
-
-
-
-
-
-
-
- TRANSFER
- {String}
-
-
-
-
-
-
Value "transfer"
- The value of the Datachannel sending message error type when encountered during
- data transfers from sendURLData() method or
- sendBlobData() method.
+ Note that if the audio codec is not supported, the SDK will not configure the local "offer" or
+ "answer" session description to prefer the codec.
+
+The list of available audio codecs to set as the preferred audio codec to use to encode
+sending audio data when available encoded audio codec for Peer connections
+configured in the init() method.
+
+
+
+
+
+
+
+
+
+
Keys:
+
+
- CLOSED
+ AUTO{String}
-
Value "closed"
- The value of the state when Datachannel connection has closed.
+
Value "auto"
+ The value of the option to not prefer any audio codec but rather use the created
+ local "offer" / "answer" session description audio codec preference.
@@ -30261,15 +33319,15 @@
Keys:
- ERROR
+ OPUS{String}
-
Value "error"
- The value of the state when Datachannel has encountered an exception during connection.
+
Value "opus"
+ The value of the option to prefer the OPUS audio codec.
@@ -30277,15 +33335,15 @@
Keys:
- CREATE_ERROR
+ ISAC{String}
-
Value "createError"
- The value of the state when Datachannel has failed to establish a connection.
+
Value "ISAC"
+ The value of the option to prefer the ISAC audio codec.
@@ -30293,19 +33351,15 @@
Keys:
- BUFFERED_AMOUNT_LOW
+ ILBC{String}
-
Value "bufferedAmountLow"
- The value of the state when Datachannel when the amount of data buffered to be sent
- falls below the Datachannel threshold.
- This state should occur only during after
- sendBlobData() method or sendURLData() method or
- sendP2PMessage() method.
+
Value "ILBC"
+ The value of the option to prefer the iLBC audio codec.
Value "messaging"
- The value of the Datachannel type that is used only for messaging in
- sendP2PMessage() method.
- However for Peers that do not support simultaneous data transfers, this Datachannel
- type will be used to do data transfers (1 at a time).
- Each Peer connections will only have one of this Datachannel type and the
- connection will only close when the Peer connection is closed (happens when
- peerConnectionState event triggers parameter payload state as
- CLOSED for Peer).
+
Value "PCMA"
+ The value of the option to prefer the G711u audio codec.
@@ -30439,21 +33399,15 @@
Keys:
- DATA
+ PCMU{String}
-
Value "data"
- The value of the Datachannel type that is used only for a data transfer in
- sendURLData() method and
- sendBlobData() method.
- The connection will close after the data transfer has been completed or terminated (happens when
- dataTransferState event triggers parameter payload
- state as DOWNLOAD_COMPLETED, UPLOAD_COMPLETED,
- REJECTED, CANCEL or ERROR for Peer).
+
Value "PCMU"
+ The value of the option to prefer the G711a audio codec.
+ Learn more about how ICE works in this
+ article here.
+
+The list of available Peer connection bundle policies.
@@ -30545,18 +33503,16 @@
Keys:
- BINARY_STRING
+ MAX_COMPAT{String}
-
Value "binaryString"
- The value of data transfer data type when Blob binary data chunks encoded to Base64 encoded string are
- sent or received over the Datachannel connection for the data transfer session.
- Used only in sendBlobData() method when
- parameter sendChunksAsBinary value is false.
+
Value "max-compat"
+ The value of the bundle policy to generate ICE candidates for each media type
+ so each media type flows through different transports.
@@ -30564,18 +33520,16 @@
Keys:
- ARRAY_BUFFER
+ MAX_BUNDLE{String}
-
Value "arrayBuffer"
- The value of data transfer data type when ArrayBuffer binary data chunks are
- sent or received over the Datachannel connection for the data transfer session.
- Used only in sendBlobData() method when
- parameter sendChunksAsBinary value is true.
+
Value "max-bundle"
+ The value of the bundle policy to generate ICE candidates for one media type
+ so all media type flows through a single transport.
@@ -30583,18 +33537,16 @@
Keys:
- BLOB
+ BALANCED{String}
-
Value "blob"
- The value of data transfer data type when Blob binary data chunks are
- sent or received over the Datachannel connection for the data transfer session.
- Used only in sendBlobData() method when
- parameter sendChunksAsBinary value is true.
+
Value "balanced"
+ The value of the bundle policy to use MAX_BUNDLE if Peer supports it,
+ else fallback to MAX_COMPAT.
@@ -30602,17 +33554,16 @@
Keys:
- STRING
+ NONE{String}
-
Value "string"
- The value of data transfer data type when only string data chunks are
- sent or received over the Datachannel connection for the data transfer session.
- Used only in sendURLData() method.
+
Value "none"
+ The value of the bundle policy to not use any media bundle.
+ This removes the a=group:BUNDLE line from session descriptions.
+ Learn more about how ICE works in this
+ article here.
+
+The list of Peer connection ICE gathering states.
@@ -30704,16 +33659,21 @@
Keys:
- BLOB
+ GATHERING{String}
-
Value "blob"
- The value of the session type for
- sendURLData() method data transfer.
+
Value "gathering"
+ The value of the state when Peer connection is gathering ICE candidates.
+ These ICE candidates are sent to Peer for its connection to check for a suitable matching
+ pair of ICE candidates to establish an ICE connection for stream audio, video and data.
+ See iceConnectionState event for ICE connection status.
+ This state cannot happen until Peer connection remote "offer" / "answer"
+ session description is set. See
+ peerConnectionState event for session description exchanging status.
+ Learn more about how ICE works in this
+ article here.
+
+The list of Peer connection remote ICE candidate processing states for trickle ICE connections.
@@ -30822,121 +33785,15 @@
Keys:
- UPLOAD_REQUEST
- {String}
-
-
-
-
-
-
Value "request"
- The value of the state when receiving an upload data transfer request from Peer to User.
- At this stage, the upload data transfer request from Peer may be accepted or rejected with the
- acceptDataTransfer() method invoked by User.
-
-
-
-
-
-
-
- USER_UPLOAD_REQUEST
- {String}
-
-
-
-
-
-
Value "userRequest"
- The value of the state when User sent an upload data transfer request to Peer.
- At this stage, the upload data transfer request to Peer may be accepted or rejected with the
- acceptDataTransfer() method invoked by Peer.
-
-
-
-
-
-
-
- UPLOAD_STARTED
- {String}
-
-
-
-
-
-
Value "uploadStarted"
- The value of the state when the data transfer request has been accepted
- and data transfer will start uploading data to Peer.
- At this stage, the data transfer may be terminated with the
- cancelDataTransfer() method.
-
-
-
-
-
-
-
- DOWNLOAD_STARTED
- {String}
-
-
-
-
-
-
Value "downloadStarted"
- The value of the state when the data transfer request has been accepted
- and data transfer will start downloading data from Peer.
- At this stage, the data transfer may be terminated with the
- cancelDataTransfer() method.
-
-
-
-
-
-
-
- REJECTED
- {String}
-
-
-
-
-
-
Value "rejected"
- The value of the state when upload data transfer request to Peer has been rejected and terminated.
-
-
-
-
-
-
-
- USER_REJECTED
- {String}
-
-
-
-
-
-
Value "userRejected"
- The value of the state when User rejected and terminated upload data transfer request from Peer.
-
-
-
-
-
-
-
- UPLOADING
+ RECEIVED{String}
-
Value "uploading"
- The value of the state when data transfer is uploading data to Peer.
+
Value "received"
+ The value of the state when the remote ICE candidate was received.
@@ -30944,15 +33801,15 @@
Keys:
- DOWNLOADING
+ DROPPED{String}
-
Value "downloading"
- The value of the state when data transfer is downloading data from Peer.
+
Value "received"
+ The value of the state when the remote ICE candidate is dropped.
@@ -30960,15 +33817,15 @@
Keys:
- UPLOAD_COMPLETED
+ BUFFERED{String}
-
Value "uploadCompleted"
- The value of the state when data transfer has uploaded successfully to Peer.
+
Value "buffered"
+ The value of the state when the remote ICE candidate is buffered.
@@ -30976,15 +33833,15 @@
Keys:
- DOWNLOAD_COMPLETED
+ PROCESSING{String}
-
Value "downloadCompleted"
- The value of the state when data transfer has downloaded successfully from Peer.
+
Value "processing"
+ The value of the state when the remote ICE candidate is being processed.
@@ -30992,15 +33849,17 @@
Keys:
- CANCEL
+ PROCESS_SUCCESS{String}
-
Value "cancel"
- The value of the state when data transfer has been terminated from / to Peer.
+
Value "processSuccess"
+ The value of the state when the remote ICE candidate has been processed successfully.
+ The ICE candidate that is processed will be used to check against the list of
+ locally generated ICE candidate to start matching for the suitable pair for the best ICE connection.
@@ -31008,15 +33867,15 @@
Keys:
- ERROR
+ PROCESS_ERROR{String}
-
Value "error"
- The value of the state when data transfer has errors and has been terminated from / to Peer.
+
Value "processError"
+ The value of the state when the remote ICE candidate has failed to be processed.
The list of Datachannel sending message error types.
@@ -31108,15 +33967,16 @@
Keys:
- UPLOAD
+ MESSAGE{String}
-
Value "upload"
- The value of the data transfer direction when User is uploading data to Peer.
+
Value "message"
+ The value of the Datachannel sending message error type when encountered during
+ sending P2P message from sendP2PMessage() method.
@@ -31124,15 +33984,17 @@
Keys:
- DOWNLOAD
+ TRANSFER{String}
-
Value "download"
- The value of the data transfer direction when User is downloading data from Peer.
+
Value "transfer"
+ The value of the Datachannel sending message error type when encountered during
+ data transfers from sendURLData() method or
+ sendBlobData() method.
Value 1
- The value of the state when getConnectionStatus() has retrieved the Peer connection stats successfully.
+
Value "bufferedAmountLow"
+ The value of the state when Datachannel when the amount of data buffered to be sent
+ falls below the Datachannel threshold.
+ This state should occur only during after
+ sendBlobData() method or sendURLData() method or
+ sendP2PMessage() method.
- Note that this feature requires "isPrivileged" flag to be enabled for the App Key
- provided in the init() method, as only Users connecting using
- the App Key with this flag enabled (which we call privileged Users / Peers) can retrieve the list of
- Peer IDs from Rooms within the same App space.
-
- Read more about privileged App Key feature here.
-
Value "enquired"
- The value of the state when getPeers() is retrieving the list of Peer IDs
- from Rooms within the same App space from the Signaling server.
+
Value "messaging"
+ The value of the Datachannel type that is used only for messaging in
+ sendP2PMessage() method.
+ However for Peers that do not support simultaneous data transfers, this Datachannel
+ type will be used to do data transfers (1 at a time).
+ Each Peer connections will only have one of this Datachannel type and the
+ connection will only close when the Peer connection is closed (happens when
+ peerConnectionState event triggers parameter payload state as
+ CLOSED for Peer).
@@ -31462,16 +34328,21 @@
Keys:
- RECEIVED
+ DATA{String}
-
Value "received"
- The value of the state when getPeers() has retrieved the list of Peer IDs
- from Rooms within the same App space from the Signaling server successfully.
+
Value "data"
+ The value of the Datachannel type that is used only for a data transfer in
+ sendURLData() method and
+ sendBlobData() method.
+ The connection will close after the data transfer has been completed or terminated (happens when
+ dataTransferState event triggers parameter payload
+ state as DOWNLOAD_COMPLETED, UPLOAD_COMPLETED,
+ REJECTED, CANCEL or ERROR for Peer).
Value "enter"
- The value of the connection state when Peer has just entered the Room.
- At this stage, peerJoined event
- is triggered.
+
Value "sendStart"
+ The value of the state when data streaming session has started from User to Peer.
@@ -31581,17 +34450,15 @@
Keys:
- WELCOME
+ RECEIVING_STARTED{String}
-
Value "welcome"
- The value of the connection state when Peer is aware that User has entered the Room.
- At this stage, peerJoined event
- is triggered and Peer connection may commence.
+
Value "receiveStart"
+ The value of the state when data streaming session has started from Peer to Peer.
@@ -31599,16 +34466,15 @@
Keys:
- OFFER
+ RECEIVED{String}
-
Value "offer"
- The value of the connection state when Peer connection has set the local / remote "offer"
- session description to start streaming connection.
+
Value "received"
+ The value of the state when data streaming session data chunk has been received from Peer to User.
@@ -31616,16 +34482,47 @@
Keys:
- ANSWER
+ SENT{String}
-
Value "answer"
- The value of the connection state when Peer connection has set the local / remote "answer"
- session description to establish streaming connection.
+
Value "sent"
+ The value of the state when data streaming session data chunk has been sent from User to Peer.
+
+
+
+
+
+
+
+ SENDING_STOPPED
+ {String}
+
+
+
+
+
+
Value "sendStop"
+ The value of the state when data streaming session has stopped from User to Peer.
+
+
+
+
+
+
+
+ RECEIVING_STOPPED
+ {String}
+
+
+
+
+
+
Value "receivingStop"
+ The value of the state when data streaming session has stopped from Peer to User.
@@ -31641,9 +34538,25 @@
Keys:
Value "error"
- The value of the connection state when Peer connection has failed to establish streaming connection.
- This happens when there are errors that occurs in creating local "offer" /
- "answer", or when setting remote / local "offer" / "answer".
+ The value of the state when data streaming session has errors.
+ At this stage, the data streaming state is considered SENDING_STOPPED or
+ RECEIVING_STOPPED.
+
+
+
+
+
+
+
+ START_ERROR
+ {String}
+
+
+
+
+
+
Value "startError"
+ The value of the state when data streaming session failed to start from User to Peer.
- Learn more about how ICE works in this
- article here.
-
-The list of Peer connection ICE connection states.
+
The list of supported data transfer data types.
@@ -31739,73 +34648,18 @@
Keys:
- CHECKING
- {String}
-
-
-
-
-
-
Value "checking"
- The value of the state when Peer connection is checking for a suitable matching pair of
- ICE candidates to establish ICE connection.
- Exchanging of ICE candidates happens during
- candidateGenerationState event.
-
-
-
-
-
-
-
- CONNECTED
- {String}
-
-
-
-
-
-
Value "connected"
- The value of the state when Peer connection has found a suitable matching pair of
- ICE candidates to establish ICE connection but is still checking for a better
- suitable matching pair of ICE candidates for the best ICE connectivity.
- At this state, ICE connection is already established and audio, video and
- data streaming has already started.
-
-
-
-
-
-
-
- COMPLETED
- {String}
-
-
-
-
-
-
Value "completed"
- The value of the state when Peer connection has found the best suitable matching pair
- of ICE candidates to establish ICE connection and checking has stopped.
- At this state, ICE connection is already established and audio, video and
- data streaming has already started. This may happpen after CONNECTED.
-
-
-
-
-
-
-
- FAILED
+ BINARY_STRING{String}
-
Value "failed"
- The value of the state when Peer connection ICE connection has failed.
+
Value "binaryString"
+ The value of data transfer data type when Blob binary data chunks encoded to Base64 encoded string are
+ sent or received over the Datachannel connection for the data transfer session.
+ Used only in sendBlobData() method when
+ parameter sendChunksAsBinary value is false.
@@ -31813,17 +34667,18 @@
Keys:
- DISCONNECTED
+ ARRAY_BUFFER{String}
-
Value "disconnected"
- The value of the state when Peer connection ICE connection is disconnected.
- At this state, the Peer connection may attempt to revive the ICE connection.
- This may happen due to flaky network conditions.
+
Value "arrayBuffer"
+ The value of data transfer data type when ArrayBuffer binary data chunks are
+ sent or received over the Datachannel connection for the data transfer session.
+ Used only in sendBlobData() method when
+ parameter sendChunksAsBinary value is true.
@@ -31831,16 +34686,18 @@
Keys:
- CLOSED
+ BLOB{String}
-
Value "closed"
- The value of the state when Peer connection ICE connection has closed.
- This happens when Peer connection is closed and no streaming can occur at this stage.
+
Value "blob"
+ The value of data transfer data type when Blob binary data chunks are
+ sent or received over the Datachannel connection for the data transfer session.
+ Used only in sendBlobData() method when
+ parameter sendChunksAsBinary value is true.
@@ -31848,17 +34705,17 @@
Keys:
- TRICKLE_FAILED
+ STRING{String}
-
Value "trickeFailed"
- The value of the state when Peer connection ICE connection has failed during trickle ICE.
- Trickle ICE is enabled in init() method
- enableIceTrickle option.
+
Value "string"
+ The value of data transfer data type when only string data chunks are
+ sent or received over the Datachannel connection for the data transfer session.
+ Used only in sendURLData() method.
- Note that this feature requires "isPrivileged" flag to be enabled and
- "autoIntroduce" flag to be disabled for the App Key provided in the
- init() method, as only Users connecting using
- the App Key with this flag enabled (which we call privileged Users / Peers) can retrieve the list of
- Peer IDs from Rooms within the same App space.
-
- Read more about privileged App Key feature here.
-
Stores the flag that indicates if "isPrivileged" is enabled.
-If enabled, the User has Privileged features which has the ability to retrieve the list of
- Peers in the same App space with getPeers() method
- and introduce Peers to each other with introducePeer method.
Value "request"
+ The value of the state when receiving an upload data transfer request from Peer to User.
+ At this stage, the upload data transfer request from Peer may be accepted or rejected with the
+ acceptDataTransfer() method invoked by User.
Value "userRequest"
+ The value of the state when User sent an upload data transfer request to Peer.
+ At this stage, the upload data transfer request to Peer may be accepted or rejected with the
+ acceptDataTransfer() method invoked by Peer.
@@ -32192,14 +34961,18 @@
Keys:
- info
- {Function}
+ UPLOAD_STARTED
+ {String}
-
The function that handles the INFO level logs.
+
Value "uploadStarted"
+ The value of the state when the data transfer request has been accepted
+ and data transfer will start uploading data to Peer.
+ At this stage, the data transfer may be terminated with the
+ cancelDataTransfer() method.
@@ -32207,29 +34980,146 @@
Keys:
- warn
- {Function}
+ DOWNLOAD_STARTED
+ {String}
-
The function that handles the WARN level logs.
-
-
-
+
Value "downloadStarted"
+ The value of the state when the data transfer request has been accepted
+ and data transfer will start downloading data from Peer.
+ At this stage, the data transfer may be terminated with the
+ cancelDataTransfer() method.
+
+
+
- error
- {Function}
+ REJECTED
+ {String}
-
The function that handles the ERROR level logs.
+
Value "rejected"
+ The value of the state when upload data transfer request to Peer has been rejected and terminated.
+
+
+
+
+
+
+
+ USER_REJECTED
+ {String}
+
+
+
+
+
+
Value "userRejected"
+ The value of the state when User rejected and terminated upload data transfer request from Peer.
+
+
+
+
+
+
+
+ UPLOADING
+ {String}
+
+
+
+
+
+
Value "uploading"
+ The value of the state when data transfer is uploading data to Peer.
+
+
+
+
+
+
+
+ DOWNLOADING
+ {String}
+
+
+
+
+
+
Value "downloading"
+ The value of the state when data transfer is downloading data from Peer.
+
+
+
+
+
+
+
+ UPLOAD_COMPLETED
+ {String}
+
+
+
+
+
+
Value "uploadCompleted"
+ The value of the state when data transfer has uploaded successfully to Peer.
+
+
+
+
+
+
+
+ DOWNLOAD_COMPLETED
+ {String}
+
+
+
+
+
+
Value "downloadCompleted"
+ The value of the state when data transfer has downloaded successfully from Peer.
+
+
+
+
+
+
+
+ CANCEL
+ {String}
+
+
+
+
+
+
Value "cancel"
+ The value of the state when data transfer has been terminated from / to Peer.
+
+
+
+
+
+
+
+ ERROR
+ {String}
+
+
+
+
+
+
Value "error"
+ The value of the state when data transfer has errors and has been terminated from / to Peer.
Value 0
- The value of the state when getUserMedia() will retrieve audio track only
- when retrieving audio and video tracks failed.
- This can be configured by init() method
- audioFallback option.
+ The value of the state when getConnectionStatus() is retrieving the Peer connection stats.
Value 1
- The value of the state when getUserMedia() or shareScreen()
- retrieves camera / screensharing Stream successfully but with missing originally required audio or video tracks.
+ The value of the state when getConnectionStatus() has retrieved the Peer connection stats successfully.
@@ -32542,16 +35440,15 @@
Keys:
- ERROR
- {JSON}
+ RETRIEVE_ERROR
+ {Number}
Value -1
- The value of the state when getUserMedia() failed to retrieve audio track only
- after retrieving audio and video tracks failed.
+ The value of the state when getConnectionStatus() has failed retrieving the Peer connection stats.
- Learn more about how ICE works in this
- article here.
+ Note that this feature requires "isPrivileged" flag to be enabled for the App Key
+ provided in the init() method, as only Users connecting using
+ the App Key with this flag enabled (which we call privileged Users / Peers) can retrieve the list of
+ Peer IDs from Rooms within the same App space.
+
+ Read more about privileged App Key feature here.
-The list of Peer connection session description exchanging states.
+The list of getPeers() method retrieval states.
@@ -32647,55 +35548,16 @@
Keys:
- STABLE
- {String}
-
-
-
-
-
-
Value "stable"
- The value of the state when there is no session description being exchanged between Peer connection.
-
-
-
-
-
-
-
- HAVE_LOCAL_OFFER
- {String}
-
-
-
-
-
-
Value "have-local-offer"
- The value of the state when local "offer" session description is set.
- This should transition to STABLE state after remote "answer"
- session description is set.
- See handshakeProgress event for a more
- detailed exchanging of session description states.
-
-
-
-
-
-
-
- HAVE_REMOTE_OFFER
+ ENQUIRED{String}
-
Value "have-remote-offer"
- The value of the state when remote "offer" session description is set.
- This should transition to STABLE state after local "answer"
- session description is set.
- See handshakeProgress event for a more
- detailed exchanging of session description states.
+
Value "enquired"
+ The value of the state when getPeers() is retrieving the list of Peer IDs
+ from Rooms within the same App space from the Signaling server.
@@ -32703,15 +35565,16 @@
Keys:
- CLOSED
+ RECEIVED{String}
-
Value "closed"
- The value of the state when Peer connection is closed and no session description can be exchanged and set.
+
Value "received"
+ The value of the state when getPeers() has retrieved the list of Peer IDs
+ from Rooms within the same App space from the Signaling server successfully.
Value 0
- The value of the state when init() has just started.
+
Value "enter"
+ The value of the connection state when Peer has just entered the Room.
+ At this stage, peerJoined event
+ is triggered.
@@ -32819,16 +35684,17 @@
Keys:
- LOADING
- {Number}
+ WELCOME
+ {String}
-
Value 1
- The value of the state when init() is authenticating App Key provided
- (and with credentials if provided as well) with the Auth server.
+
Value "welcome"
+ The value of the connection state when Peer is aware that User has entered the Room.
+ At this stage, peerJoined event
+ is triggered and Peer connection may commence.
@@ -32836,18 +35702,33 @@
Keys:
- COMPLETED
- {Number}
+ OFFER
+ {String}
-
Value 2
- The value of the state when init() has successfully authenticated with the Auth server.
- Room session token is generated for joining the defaultRoom provided in init().
- Room session token has to be generated each time User switches to a different Room
- in joinRoom() method.
+
Value "offer"
+ The value of the connection state when Peer connection has set the local / remote "offer"
+ session description to start streaming connection.
+
+
+
+
+
+
+
+ ANSWER
+ {String}
+
+
+
+
+
+
Value "answer"
+ The value of the connection state when Peer connection has set the local / remote "answer"
+ session description to establish streaming connection.
@@ -32856,15 +35737,16 @@
Keys:
ERROR
- {Number}
+ {String}
-
Value -1
- The value of the state when init() has failed authenticating with the Auth server.
- [Rel: Skylink.READY_STATE_CHANGE_ERROR]
+
Value "error"
+ The value of the connection state when Peer connection has failed to establish streaming connection.
+ This happens when there are errors that occurs in creating local "offer" /
+ "answer", or when setting remote / local "offer" / "answer".
The list of init() method ready state failure codes.
+
+ Learn more about how ICE works in this
+ article here.
+
+The list of Peer connection ICE connection states.
@@ -32956,17 +35842,18 @@
Keys:
- API_INVALID
- {Number}
+ CHECKING
+ {String}
-
Value 4001
- The value of the failure code when provided App Key in init() does not exists.
- To resolve this, check that the provided App Key exists in
- the Temasys Console.
+
Value "checking"
+ The value of the state when Peer connection is checking for a suitable matching pair of
+ ICE candidates to establish ICE connection.
+ Exchanging of ICE candidates happens during
+ candidateGenerationState event.
Value 4002
- The value of the failure code when "domainName" property in the App Key does not
- match the accessing server IP address.
- To resolve this, contact our support portal.
+
Value "connected"
+ The value of the state when Peer connection has found a suitable matching pair of
+ ICE candidates to establish ICE connection but is still checking for a better
+ suitable matching pair of ICE candidates for the best ICE connectivity.
+ At this state, ICE connection is already established and audio, video and
+ data streaming has already started.
Value 4003
- The value of the failure code when "corsurl" property in the App Key does not match accessing CORS.
- To resolve this, configure the App Key CORS in
- the Temasys Console.
+
Value "completed"
+ The value of the state when Peer connection has found the best suitable matching pair
+ of ICE candidates to establish ICE connection and checking has stopped.
+ At this state, ICE connection is already established and audio, video and
+ data streaming has already started. This may happpen after CONNECTED.
Value 4004
- The value of the failure code when there is no CORS
- present in the HTTP headers during the request to the Auth server present nor
- options.credentials.credentials configuration provided in the init().
- To resolve this, ensure that CORS are present in the HTTP headers during the request to the Auth server.
+
Value "failed"
+ The value of the state when Peer connection ICE connection has failed.
@@ -33029,186 +35916,17 @@
Keys:
- API_CREDENTIALS_NOT_MATCH
- {Number}
-
-
-
-
-
-
Value 4005
- The value of the failure code when the options.credentials.credentials configuration provided in the
- init() does not match up with the options.credentials.startDateTime,
- options.credentials.duration or that the "secret" used to generate
- options.credentials.credentials does not match the App Key's "secret property provided.
- To resolve this, check that the options.credentials.credentials is generated correctly and
- that the "secret" used to generate it is from the App Key provided in the init().
-
-
-
-
-
-
-
- API_INVALID_PARENT_KEY
- {Number}
-
-
-
-
-
-
Value 4006
- The value of the failure code when the App Key provided does not belong to any existing App.
- To resolve this, check that the provided App Key exists in
- the Developer Console.
Value 4010
- The value of the failure code when provided options.credentials
- does not match any scheduled meetings available for the "Persistent Room" enabled App Key provided.
- See the Persistent Room article to learn more.
-
-
-
-
-
-
-
- API_OVER_SEAT_LIMIT
- {Number}
-
-
-
-
-
-
Value 4020
- The value of the failure code when App Key has reached its current concurrent users limit.
- To resolve this, use another App Key. To create App Keys dynamically, see the
- Application REST API
- docs for more information.
-
-
-
-
-
-
-
- API_RETRIEVAL_FAILED
- {Number}
-
-
-
-
-
-
Value 4021
- The value of the failure code when App Key retrieval of authentication token fails.
- If this happens frequently, contact our support portal.
-
-
-
-
-
-
-
- API_WRONG_ACCESS_DOMAIN
- {Number}
-
-
-
-
-
-
Value 5005
- The value of the failure code when App Key makes request to the incorrect Auth server.
- To resolve this, ensure that the roomServer is not configured. If this persists even without
- roomServer configuration, contact our support portal.
-
-
-
-
-
-
-
- XML_HTTP_REQUEST_ERROR
- {Number}
-
-
-
-
-
-
Value -1
- The value of the failure code when requesting to Auth server has timed out.
-
-
-
-
-
-
-
- NO_SOCKET_IO
- {Number}
-
-
-
-
-
-
Value 1
- The value of the failure code when dependency Socket.IO client is not loaded.
- To resolve this, ensure that the Socket.IO client dependency is loaded before the Skylink SDK.
- You may use the provided Socket.IO client CDN here.
-
-
-
-
-
-
-
- NO_XMLHTTPREQUEST_SUPPORT
- {Number}
-
-
-
-
-
-
Value 2
- The value of the failure code when
- XMLHttpRequest API required to make request to Auth server is not supported.
- To resolve this, display in the Web UI to ask clients to switch to the list of supported browser
- as listed in here.
Value 3
- The value of the failure code when
- RTCPeerConnection API required for Peer connections is not supported.
- To resolve this, display in the Web UI to ask clients to switch to the list of supported browser
- as listed in here.
- For plugin supported browsers, if the clients
- does not have the plugin installed, there will be an installation toolbar that will prompt for installation
- to support the RTCPeerConnection API.
+
Value "disconnected"
+ The value of the state when Peer connection ICE connection is disconnected.
+ At this state, the Peer connection may attempt to revive the ICE connection.
+ This may happen due to flaky network conditions.
@@ -33216,15 +35934,16 @@
Keys:
- NO_PATH
- {Number}
+ CLOSED
+ {String}
-
Value 4
- The value of the failure code when provided init() configuration has errors.
+
Value "closed"
+ The value of the state when Peer connection ICE connection has closed.
+ This happens when Peer connection is closed and no streaming can occur at this stage.
Value 7
- The value of the failure code when dependency AdapterJS
- is not loaded.
- To resolve this, ensure that the AdapterJS dependency is loaded before the Skylink dependency.
- You may use the provided AdapterJS CDN here.
+
Value "trickeFailed"
+ The value of the state when Peer connection ICE connection has failed during trickle ICE.
+ Trickle ICE is enabled in init() method
+ enableIceTrickle option.
+ Note that this feature requires "isPrivileged" flag to be enabled and
+ "autoIntroduce" flag to be disabled for the App Key provided in the
+ init() method, as only Users connecting using
+ the App Key with this flag enabled (which we call privileged Users / Peers) can retrieve the list of
+ Peer IDs from Rooms within the same App space.
+
+ Read more about privileged App Key feature here.
+
Value 0
- The value of the state when recording session has started.
-
-
-
-
-
-
-
- STOP
- {Number}
-
-
-
-
-
-
Value 1
- The value of the state when recording session has stopped.
- At this stage, the recorded videos will go through the mixin server to compile the videos.
-
-
-
-
-
-
-
- LINK
- {Number}
+ INTRODUCING
+ {String}
-
Value 2
- The value of the state when recording session mixin request has been completed.
+
Value "enquired"
+ The value of the state when introduction request for the selected pair of Peers has been made to the Signaling server.
@@ -33385,16 +36079,15 @@
Keys:
ERROR
- {Number}
+ {String}
-
Value -1
- The value of the state state when recording session has errors.
- This can happen during recording session or during mixin of recording videos,
- and at this stage, any current recording session or mixin is aborted.
+
Value "error"
+ The value of the state when introduction request made to the Signaling server
+ for the selected pair of Peers has failed.
Spoofs the REGIONAL_SERVER to prevent errors on deployed apps except the fact this no longer works.
-Automatic regional selection has already been implemented hence REGIONAL_SERVER is no longer useful.
+
Stores the flag that indicates if "isPrivileged" is enabled.
+If enabled, the User has Privileged features which has the ability to retrieve the list of
+ Peers in the same App space with getPeers() method
+ and introduce Peers to each other with introducePeer method.
Value 0
- The value of the failure state when joinRoom() socket connection failed to establish with
- the Signaling server at the first attempt.
+
Value 4
+ The value of the log level that displays consoledebug,
+ log, info, warn and error logs.
@@ -33764,16 +36441,16 @@
Keys:
- RECONNECTION_FAILED
+ LOG{Number}
-
Value -1
- The value of the failure state when joinRoom() socket connection failed to establish
- the Signaling server after the first attempt.
+
Value 3
+ The value of the log level that displays only consolelog,
+ info, warn and error logs.
@@ -33781,17 +36458,16 @@
Keys:
- CONNECTION_ABORTED
+ INFO{Number}
-
Value -2
- The value of the failure state when joinRoom() socket connection will not attempt
- to reconnect after the failure of the first attempt in CONNECTION_FAILED as there
- are no more ports or transports to attempt for reconnection.
+
Value 2
+ The value of the log level that displays only consoleinfo,
+ warn and error logs.
@@ -33799,17 +36475,16 @@
Keys:
- RECONNECTION_ABORTED
+ WARN{Number}
-
Value -3
- The value of the failure state when joinRoom() socket connection will not attempt
- to reconnect after the failure of several attempts in RECONNECTION_FAILED as there
- are no more ports or transports to attempt for reconnection.
+
Value 1
+ The value of the log level that displays only consolewarn
+ and error logs.
@@ -33817,17 +36492,31 @@
Keys:
- RECONNECTION_ATTEMPT
+ ERROR{Number}
-
Value -4
- The value of the failure state when joinRoom() socket connection is attempting
- to reconnect with a new port or transport after the failure of attempts in
- CONNECTION_FAILED or RECONNECTED_FAILED.
+
Value 0
+ The value of the log level that displays only consoleerror logs.
+
+
+
+
+
+
+
+ NONE
+ {Number}
+
+
+
+
+
+
Value -1
+ The value of the log level that displays no logs.
Value "nonfallback"
- The value of the reconnection state when joinRoom() socket connection is at its initial state
- without transitioning to any new socket port or transports yet.
-
-
-
-
-
-
-
- FALLBACK_PORT
- {String}
-
-
-
-
-
-
Value "fallbackPortNonSSL"
- The value of the reconnection state when joinRoom() socket connection is reconnecting with
- another new HTTP port using WebSocket transports to attempt to establish connection with Signaling server.
Value "fallbackPortSSL"
- The value of the reconnection state when joinRoom() socket connection is reconnecting with
- another new HTTPS port using WebSocket transports to attempt to establish connection with Signaling server.
+
Value 0
+ The value of the state when getUserMedia() will retrieve audio track only
+ when retrieving audio and video tracks failed.
+ This can be configured by init() method
+ audioFallback option.
@@ -33970,16 +36628,16 @@
Keys:
- LONG_POLLING
- {String}
+ FALLBACKED
+ {JSON}
-
Value "fallbackLongPollingNonSSL"
- The value of the reconnection state when joinRoom() socket connection is reconnecting with
- another new HTTP port using Polling transports to attempt to establish connection with Signaling server.
+
Value 1
+ The value of the state when getUserMedia() or shareScreen()
+ retrieves camera / screensharing Stream successfully but with missing originally required audio or video tracks.
@@ -33987,16 +36645,16 @@
Keys:
- LONG_POLLING
- {String}
+ ERROR
+ {JSON}
-
Value "fallbackLongPollingSSL"
- The value of the reconnection state when joinRoom() socket connection is reconnecting with
- another new HTTPS port using Polling transports to attempt to establish connection with Signaling server.
+
Value -1
+ The value of the state when getUserMedia() failed to retrieve audio track only
+ after retrieving audio and video tracks failed.
The list of Signaling server reaction states reason of action code during
-joinRoom() method.
+
+ Learn more about how ICE works in this
+ article here.
+
+The list of Peer connection session description exchanging states.
@@ -34205,151 +36886,15 @@
Keys:
- CREDENTIALS_EXPIRED
- {String}
-
-
-
-
-
-
Value "oldTimeStamp"
- The value of the reason code when Room session token has expired.
- Happens during joinRoom() method request.
- Results with: REJECT
-
-
-
-
-
-
-
- CREDENTIALS_ERROR
- {String}
-
-
-
-
-
-
Value "credentialError"
- The value of the reason code when Room session token provided is invalid.
- Happens during joinRoom() method request.
-
-
-
-
-
-
-
- DUPLICATED_LOGIN
- {String}
-
-
-
-
-
-
Value "duplicatedLogin"
- The value of the reason code when Room session token has been used already.
- Happens during joinRoom() method request.
- Results with: REJECT
-
-
-
-
-
-
-
- ROOM_NOT_STARTED
- {String}
-
-
-
-
-
-
Value "notStart"
- The value of the reason code when Room session has not started.
- Happens during joinRoom() method request.
- Results with: REJECT
-
-
-
-
-
-
-
- EXPIRED
- {String}
-
-
-
-
-
-
Value "expired"
- The value of the reason code when Room session has ended already.
- Happens during joinRoom() method request.
- Results with: REJECT
-
-
-
-
-
-
-
- ROOM_LOCKED
- {String}
-
-
-
-
-
-
Value "locked"
- The value of the reason code when Room is locked.
- Happens during joinRoom() method request.
- Results with: REJECT
Value "toClose"
- The value of the reason code when Room session is ending.
- Happens after Room session has started. This serves as a prerequisite warning before
- ROOM_CLOSED occurs.
- Results with: WARNING
+
Value "stable"
+ The value of the state when there is no session description being exchanged between Peer connection.
@@ -34357,17 +36902,19 @@
Keys:
- ROOM_CLOSED
+ HAVE_LOCAL_OFFER{String}
-
Value "roomclose"
- The value of the reason code when Room session has just ended.
- Happens after Room session has started.
- Results with: REJECT
+
Value "have-local-offer"
+ The value of the state when local "offer" session description is set.
+ This should transition to STABLE state after remote "answer"
+ session description is set.
+ See handshakeProgress event for a more
+ detailed exchanging of session description states.
@@ -34375,17 +36922,19 @@
Keys:
- SERVER_ERROR
+ HAVE_REMOTE_OFFER{String}
-
Value "serverError"
- The value of the reason code when Room session fails to start due to some technical errors.
- Happens during joinRoom() method request.
- Results with: REJECT
+
Value "have-remote-offer"
+ The value of the state when remote "offer" session description is set.
+ This should transition to STABLE state after local "answer"
+ session description is set.
+ See handshakeProgress event for a more
+ detailed exchanging of session description states.
@@ -34393,18 +36942,15 @@
Keys:
- KEY_ERROR
+ CLOSED{String}
-
Value "keyFailed"
- The value of the reason code when Room session fails to start due to some technical error pertaining to
- App Key initialization.
- Happens during joinRoom() method request.
- Results with: REJECT
+
Value "closed"
+ The value of the state when Peer connection is closed and no session description can be exchanged and set.
- Note that configuring the protocol may not necessarily result in the desired network transports protocol
- used in the actual TURN network traffic as it depends which protocol the browser selects and connects with.
- This simply configures the TURN ICE server urls query option when constructing
- the Peer connection. When all protocols are selected, the ICE servers urls are duplicated with all protocols.
-
-The list of TURN network transport protocols options when constructing Peer connections
-configured in the init() method.
-Example .urls inital input: ["turn:server.com?transport=tcp",
-"turn:server1.com:3478", "turn:server.com?transport=udp"]
+
The list of User's priority weight schemes for
+joinRoom() method connections.
@@ -34505,53 +37043,15 @@
Keys:
- TCP
- {String}
-
-
-
-
-
-
Value "tcp"
- The value of the option to configure using only TCP network transport protocol.
- Example .urls output: ["turn:server.com?transport=tcp",
- "turn:server1.com:3478?transport=tcp"]
-
-
-
-
-
-
-
- UDP
- {String}
-
-
-
-
-
-
Value "udp"
- The value of the option to configure using only UDP network transport protocol.
- Example .urls output: ["turn:server.com?transport=udp",
- "turn:server1.com:3478?transport=udp"]
-
-
-
-
-
-
-
- ANY
+ ENFORCE_OFFERER{String}
-
Value "any"
- The value of the option to configure using any network transport protocols configured from the Signaling server.
- Example .urls output: ["turn:server.com?transport=tcp",
- "turn:server1.com:3478", "turn:server.com?transport=udp"]
+
Value "enforceOfferer"
+ The value of the priority weight scheme to enforce User as the offerer.
@@ -34559,19 +37059,15 @@
Keys:
- NONE
+ ENFORCE_ANSWERER{String}
-
Value "none"
- The value of the option to not configure using any network transport protocols.
- Example .urls output: ["turn:server.com", "turn:server1.com:3478"]
- Configuring this does not mean that no protocols will be used, but
- rather removing ?transport=(protocol) query option in
- the TURN ICE server .urls when constructing the Peer connection.
+
Value "enforceAnswerer"
+ The value of the priority weight scheme to enforce User as the answerer.
@@ -34579,18 +37075,15 @@
Keys:
- ALL
+ AUTO{String}
-
Value "all"
- The value of the option to configure using both TCP and UDP network transport protocols.
- Example .urls output: ["turn:server.com?transport=tcp",
- "turn:server.com?transport=udp", "turn:server1.com:3478?transport=tcp",
- "turn:server1.com:3478?transport=udp"]
+
Value "auto"
+ The value of the priority weight scheme to let User be offerer or answerer based on Signaling server selection.
- Note that if the video codec is not supported, the SDK will not configure the local "offer" or
- "answer" session description to prefer the codec.
-
-The list of available video codecs to set as the preferred video codec to use to encode
-sending video data when available encoded video codec for Peer connections
-configured in the init() method.
+
Value "auto"
- The value of the option to not prefer any video codec but rather use the created
- local "offer" / "answer" session description video codec preference.
+
Value 0
+ The value of the state when init() has just started.
@@ -34781,15 +37191,16 @@
Keys:
- VP8
- {String}
+ LOADING
+ {Number}
-
Value "VP8"
- The value of the option to prefer the VP8 video codec.
+
Value 1
+ The value of the state when init() is authenticating App Key provided
+ (and with credentials if provided as well) with the Auth server.
@@ -34797,15 +37208,18 @@
Keys:
- VP9
- {String}
+ COMPLETED
+ {Number}
-
Value "VP9"
- The value of the option to prefer the VP9 video codec.
+
Value 2
+ The value of the state when init() has successfully authenticated with the Auth server.
+ Room session token is generated for joining the defaultRoom provided in init().
+ Room session token has to be generated each time User switches to a different Room
+ in joinRoom() method.
@@ -34813,15 +37227,16 @@
Keys:
- H264
- {String}
+ ERROR
+ {Number}
-
Value "H264"
- The value of the option to prefer the H264 video codec.
+
Value -1
+ The value of the state when init() has failed authenticating with the Auth server.
+ [Rel: Skylink.READY_STATE_CHANGE_ERROR]
The list of init() method ready state failure codes.
@@ -34918,17 +37328,17 @@
Keys:
- QQVGA
- {JSON}
+ API_INVALID
+ {Number}
-
Value { width: 160, height: 120 }
- The value of the option to configure QQVGA resolution.
- Aspect ratio: 4:3
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 4001
+ The value of the failure code when provided App Key in init() does not exists.
+ To resolve this, check that the provided App Key exists in
+ the Temasys Console.
Value { width: 240, height: 160 }
- The value of the option to configure HQVGA resolution.
- Aspect ratio: 3:2
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 4002
+ The value of the failure code when "domainName" property in the App Key does not
+ match the accessing server IP address.
+ To resolve this, contact our support portal.
Value { width: 320, height: 240 }
- The value of the option to configure QVGA resolution.
- Aspect ratio: 4:3
+
Value 4003
+ The value of the failure code when "corsurl" property in the App Key does not match accessing CORS.
+ To resolve this, configure the App Key CORS in
+ the Temasys Console.
Value { width: 384, height: 240 }
- The value of the option to configure WQVGA resolution.
- Aspect ratio: 16:10
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 4004
+ The value of the failure code when there is no CORS
+ present in the HTTP headers during the request to the Auth server present nor
+ options.credentials.credentials configuration provided in the init().
+ To resolve this, ensure that CORS are present in the HTTP headers during the request to the Auth server.
Value { width: 480, height: 320 }
- The value of the option to configure HVGA resolution.
- Aspect ratio: 3:2
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 4005
+ The value of the failure code when the options.credentials.credentials configuration provided in the
+ init() does not match up with the options.credentials.startDateTime,
+ options.credentials.duration or that the "secret" used to generate
+ options.credentials.credentials does not match the App Key's "secret property provided.
+ To resolve this, check that the options.credentials.credentials is generated correctly and
+ that the "secret" used to generate it is from the App Key provided in the init().
Value { width: 640, height: 480 }
- The value of the option to configure VGA resolution.
- Aspect ratio: 4:3
+
Value 4006
+ The value of the failure code when the App Key provided does not belong to any existing App.
+ To resolve this, check that the provided App Key exists in
+ the Developer Console.
Value { width: 768, height: 480 }
- The value of the option to configure WVGA resolution.
- Aspect ratio: 16:10
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 4010
+ The value of the failure code when provided options.credentials
+ does not match any scheduled meetings available for the "Persistent Room" enabled App Key provided.
+ See the Persistent Room article to learn more.
@@ -35042,17 +37459,18 @@
Keys:
- FWVGA
- {JSON}
+ API_OVER_SEAT_LIMIT
+ {Number}
-
Value { width: 854, height: 480 }
- The value of the option to configure FWVGA resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 4020
+ The value of the failure code when App Key has reached its current concurrent users limit.
+ To resolve this, use another App Key. To create App Keys dynamically, see the
+ Application REST API
+ docs for more information.
@@ -35060,17 +37478,16 @@
Keys:
- SVGA
- {JSON}
+ API_RETRIEVAL_FAILED
+ {Number}
-
Value { width: 800, height: 600 }
- The value of the option to configure SVGA resolution.
- Aspect ratio: 4:3
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 4021
+ The value of the failure code when App Key retrieval of authentication token fails.
+ If this happens frequently, contact our support portal.
Value { width: 960, height: 640 }
- The value of the option to configure DVGA resolution.
- Aspect ratio: 3:2
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 5005
+ The value of the failure code when App Key makes request to the incorrect Auth server.
+ To resolve this, ensure that the roomServer is not configured. If this persists even without
+ roomServer configuration, contact our support portal.
Value { width: 1024, height: 576 }
- The value of the option to configure WSVGA resolution.
- Aspect ratio: 16:9
+
Value -1
+ The value of the failure code when requesting to Auth server has timed out.
@@ -35113,17 +37529,17 @@
Keys:
- HD
- {JSON}
+ NO_SOCKET_IO
+ {Number}
-
Value { width: 1280, height: 720 }
- The value of the option to configure HD resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on device supports.
+
Value 1
+ The value of the failure code when dependency Socket.IO client is not loaded.
+ To resolve this, ensure that the Socket.IO client dependency is loaded before the Skylink SDK.
+ You may use the provided Socket.IO client CDN here.
Value { width: 1600, height: 900 }
- The value of the option to configure HDPLUS resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 2
+ The value of the failure code when
+ XMLHttpRequest API required to make request to Auth server is not supported.
+ To resolve this, display in the Web UI to ask clients to switch to the list of supported browser
+ as listed in here.
@@ -35149,17 +37566,21 @@
Keys:
- FHD
- {JSON}
+ NO_WEBRTC_SUPPORT
+ {Number}
-
Value { width: 1920, height: 1080 }
- The value of the option to configure FHD resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on device supports.
+
Value 3
+ The value of the failure code when
+ RTCPeerConnection API required for Peer connections is not supported.
+ To resolve this, display in the Web UI to ask clients to switch to the list of supported browser
+ as listed in here.
+ For plugin supported browsers, if the clients
+ does not have the plugin installed, there will be an installation toolbar that will prompt for installation
+ to support the RTCPeerConnection API.
@@ -35167,17 +37588,15 @@
Keys:
- QHD
- {JSON}
+ NO_PATH
+ {Number}
-
Value { width: 2560, height: 1440 }
- The value of the option to configure QHD resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 4
+ The value of the failure code when provided init() configuration has errors.
Value { width: 3200, height: 1800 }
- The value of the option to configure WQXGAPLUS resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 7
+ The value of the failure code when dependency AdapterJS
+ is not loaded.
+ To resolve this, ensure that the AdapterJS dependency is loaded before the Skylink dependency.
+ You may use the provided AdapterJS CDN here.
@@ -35203,17 +37623,115 @@
Keys:
- UHD
- {JSON}
+ PARSE_CODECS
+ {Number}
-
Value { width: 3840, height: 2160 }
- The value of the option to configure UHD resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 8
+ The value of the failure code when codecs support cannot be parsed and retrieved.
Value 0
+ The value of the state when recording session has started.
@@ -35221,17 +37739,16 @@
Keys:
- UHDPLUS
- {JSON}
+ STOP
+ {Number}
-
Value { width: 5120, height: 2880 }
- The value of the option to configure UHDPLUS resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 1
+ The value of the state when recording session has stopped.
+ At this stage, the recorded videos will go through the mixin server to compile the videos.
@@ -35239,17 +37756,15 @@
Keys:
- FUHD
- {JSON}
+ LINK
+ {Number}
-
Value { width: 7680, height: 4320 }
- The value of the option to configure FUHD resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value 2
+ The value of the state when recording session mixin request has been completed.
@@ -35257,17 +37772,17 @@
Keys:
- QUHD
- {JSON}
+ ERROR
+ {Number}
-
Value { width: 15360, height: 8640 }
- The value of the option to configure QUHD resolution.
- Aspect ratio: 16:9
- Note that configurating this resolution may not be supported depending on browser and device supports.
+
Value -1
+ The value of the state state when recording session has errors.
+ This can happen during recording session or during mixin of recording videos,
+ and at this stage, any current recording session or mixin is aborted.
Spoofs the REGIONAL_SERVER to prevent errors on deployed apps except the fact this no longer works.
+Automatic regional selection has already been implemented hence REGIONAL_SERVER is no longer useful.
- Learn more about how ICE works in this
- article here.
- Note that this event may not be triggered for MCU enabled Peer connections as ICE candidates
- may be received in the session description instead.
+ As there are more features getting implemented, there will be eventually more different types of
+ server Peers.
-Event triggered when remote ICE candidate processing state has changed when Peer is using trickle ICE.
+The list of available types of server Peer connections.
+
+
+
+
-
Event Payload:
+
Keys:
- state
+ MCU{String}
-
The ICE candidate processing state.
- [Rel: Skylink.CANDIDATE_PROCESSING_STATE]
+
Value "mcu"
+ The value of the server Peer type that is used for MCU connection.
-
- peerId
- {String}
+
+
+
+
+
+
+
+
-
+
+
+
SM_PROTOCOL_VERSION
+ Attribute Type: {String}
-
-
The Peer ID.
+
+
+
-
+
-
-
-
- candidateId
- {String}
-
-
+
-
-
The remote ICE candidate session ID.
- Note that this value is not related to WebRTC API but for identification of remote ICE candidate received.
-
-
-
-
-
-
-
- candidateType
- {String}
-
-
-
-
-
-
The remote ICE candidate type.
- Expected values are "host" (local network), "srflx" (STUN) and "relay" (TURN).
-
-
-
-
-
-
-
- candidate
- {JSON}
-
-
-
-
-
-
The remote ICE candidate.
-
-
-
-
-
-
-
- candidate
- {String}
-
-
-
-
-
-
The remote ICE candidate connection description.
-
-
-
-
-
-
-
- sdpMid
- {String}
-
-
-
-
-
-
The remote ICE candidate identifier based on the remote session description.
-
-
-
-
-
-
-
- sdpMLineIndex
- {Number}
-
-
-
-
-
-
The remote ICE candidate media description index
- (starting from 0) based on the remote session description.
-
-
-
-
-
-
-
-
-
-
-
- error
- {Error}
-
- Optional
-
-
-
-
The error object.
- Defined only when state is DROPPED or PROCESS_ERROR.
- This may be caused by Javascript errors in the event listener when subscribing to events.
- It may be resolved by checking for code errors in your Web App in the event subscribing listener.
- skylinkDemo.on("eventName", function () { // Errors here });
-
-Event triggered when socket connection encountered exception.
+
Value 0
+ The value of the failure state when joinRoom() socket connection failed to establish with
+ the Signaling server at the first attempt.
+
+
+
+
+
+
+
+ RECONNECTION_FAILED
+ {Number}
+
+
+
+
+
+
Value -1
+ The value of the failure state when joinRoom() socket connection failed to establish
+ the Signaling server after the first attempt.
+
+
+
+
+
+
+
+ CONNECTION_ABORTED
+ {Number}
+
+
+
+
+
+
Value -2
+ The value of the failure state when joinRoom() socket connection will not attempt
+ to reconnect after the failure of the first attempt in CONNECTION_FAILED as there
+ are no more ports or transports to attempt for reconnection.
+
+
+
+
+
+
+
+ RECONNECTION_ABORTED
+ {Number}
+
+
+
+
+
+
Value -3
+ The value of the failure state when joinRoom() socket connection will not attempt
+ to reconnect after the failure of several attempts in RECONNECTION_FAILED as there
+ are no more ports or transports to attempt for reconnection.
+
+
+
+
+
+
+
+ RECONNECTION_ATTEMPT
+ {Number}
+
+
+
+
+
+
Value -4
+ The value of the failure state when joinRoom() socket connection is attempting
+ to reconnect with a new port or transport after the failure of attempts in
+ CONNECTION_FAILED or RECONNECTED_FAILED.
- Note that this is used only for SDK developer purposes.
-
-Event triggered when receiving socket message from the Signaling server.
+
The list of joinRoom() method socket connection reconnection states.
+
+
+
+
-
Event Payload:
+
Keys:
- message
- {JSON}
+ NON_FALLBACK
+ {String}
-
The socket message object.
+
Value "nonfallback"
+ The value of the reconnection state when joinRoom() socket connection is at its initial state
+ without transitioning to any new socket port or transports yet.
-
-
-
-
-
+
+ FALLBACK_PORT
+ {String}
-
-
-
-
-
channelOpen
+
-
-
-
+
+
Value "fallbackPortNonSSL"
+ The value of the reconnection state when joinRoom() socket connection is reconnecting with
+ another new HTTP port using WebSocket transports to attempt to establish connection with Signaling server.
-
+
+
+
+
+ FALLBACK_PORT_SSL
+ {String}
-
+
+
-
+
+
Value "fallbackPortSSL"
+ The value of the reconnection state when joinRoom() socket connection is reconnecting with
+ another new HTTPS port using WebSocket transports to attempt to establish connection with Signaling server.
-
+
+
+
+
+ LONG_POLLING
+ {String}
-
+
+
-
-
+
+
Value "fallbackLongPollingNonSSL"
+ The value of the reconnection state when joinRoom() socket connection is reconnecting with
+ another new HTTP port using Polling transports to attempt to establish connection with Signaling server.
+ LONG_POLLING_SSL
+ {String}
-
- Available since 0.1.0
-
-
+
+
-
-
Event triggered when socket connection to Signaling server has opened.
+
+
Value "fallbackLongPollingSSL"
+ The value of the reconnection state when joinRoom() socket connection is reconnecting with
+ another new HTTPS port using Polling transports to attempt to establish connection with Signaling server.
Event triggered when a Datachannel connection state has changed.
+
The list of Signaling server reaction states reason of action code during
+joinRoom() method.
+
+
+
+
-
Event Payload:
+
Keys:
- state
+ CREDENTIALS_EXPIRED{String}
-
The current Datachannel connection state.
- [Rel: Skylink.DATA_CHANNEL_STATE]
+
Value "oldTimeStamp"
+ The value of the reason code when Room session token has expired.
+ Happens during joinRoom() method request.
+ Results with: REJECT
@@ -36062,14 +38731,16 @@
Event Payload:
- peerId
+ CREDENTIALS_ERROR{String}
-
The Peer ID.
+
Value "credentialError"
+ The value of the reason code when Room session token provided is invalid.
+ Happens during joinRoom() method request.
The error object.
- Defined only when state payload is ERROR or SEND_MESSAGE_ERROR.
+
Value "duplicatedLogin"
+ The value of the reason code when Room session token has been used already.
+ Happens during joinRoom() method request.
+ Results with: REJECT
@@ -36093,14 +38766,17 @@
Event Payload:
- channelName
+ ROOM_NOT_STARTED{String}
-
The Datachannel ID.
+
Value "notStart"
+ The value of the reason code when Room session has not started.
+ Happens during joinRoom() method request.
+ Results with: REJECT
@@ -36108,15 +38784,17 @@
Event Payload:
- channelType
+ EXPIRED{String}
-
The Datachannel type.
- [Rel: Skylink.DATA_CHANNEL_TYPE]
+
Value "expired"
+ The value of the reason code when Room session has ended already.
+ Happens during joinRoom() method request.
+ Results with: REJECT
@@ -36124,25 +38802,126 @@
Event Payload:
- messageType
+ ROOM_LOCKED{String}
-
The Datachannel sending Datachannel message error type.
- Defined only when state payload is SEND_MESSAGE_ERROR.
- [Rel: Skylink.DATA_CHANNEL_MESSAGE_ERROR]
+
Value "locked"
+ The value of the reason code when Room is locked.
+ Happens during joinRoom() method request.
+ Results with: REJECT
Value "toClose"
+ The value of the reason code when Room session is ending.
+ Happens after Room session has started. This serves as a prerequisite warning before
+ ROOM_CLOSED occurs.
+ Results with: WARNING
+
+
+
+
+
+
+
+ ROOM_CLOSED
+ {String}
+
+
+
+
+
+
Value "roomclose"
+ The value of the reason code when Room session has just ended.
+ Happens after Room session has started.
+ Results with: REJECT
+
+
+
+
+
+
+
+ SERVER_ERROR
+ {String}
+
+
+
+
+
+
Value "serverError"
+ The value of the reason code when Room session fails to start due to some technical errors.
+ Happens during joinRoom() method request.
+ Results with: REJECT
+
+
+
+
+
+
+
+ KEY_ERROR
+ {String}
+
+
+
+
+
+
Value "keyFailed"
+ The value of the reason code when Room session fails to start due to some technical error pertaining to
+ App Key initialization.
+ Happens during joinRoom() method request.
+ Results with: REJECT
Event triggered when a data transfer state has changed.
+
+ Note that configuring the protocol may not necessarily result in the desired network transports protocol
+ used in the actual TURN network traffic as it depends which protocol the browser selects and connects with.
+ This simply configures the TURN ICE server urls query option when constructing
+ the Peer connection. When all protocols are selected, the ICE servers urls are duplicated with all protocols.
+
+The list of TURN network transport protocols options when constructing Peer connections
+configured in the init() method.
+Example .urls inital input: ["turn:server.com?transport=tcp",
+"turn:server1.com:3478", "turn:server.com?transport=udp"]
+
+
+
+
-
Event Payload:
+
Keys:
- state
+ TCP{String}
-
The current data transfer state.
- [Rel: Skylink.DATA_TRANSFER_STATE]
+
Value "tcp"
+ The value of the option to configure using only TCP network transport protocol.
+ Example .urls output: ["turn:server.com?transport=tcp",
+ "turn:server1.com:3478?transport=tcp"]
@@ -36223,14 +39031,17 @@
Event Payload:
- transferId
+ UDP{String}
-
The data transfer ID.
+
Value "udp"
+ The value of the option to configure using only UDP network transport protocol.
+ Example .urls output: ["turn:server.com?transport=udp",
+ "turn:server1.com:3478?transport=udp"]
@@ -36238,14 +39049,17 @@
Event Payload:
- peerId
+ ANY{String}
-
The Peer ID.
+
Value "any"
+ The value of the option to configure using any network transport protocols configured from the Signaling server.
+ Example .urls output: ["turn:server.com?transport=tcp",
+ "turn:server1.com:3478", "turn:server.com?transport=udp"]
@@ -36253,261 +39067,122 @@
Event Payload:
- transferInfo
- {JSON}
+ NONE
+ {String}
-
The data transfer information.
+
Value "none"
+ The value of the option to not configure using any network transport protocols.
+ Example .urls output: ["turn:server.com", "turn:server1.com:3478"]
+ Configuring this does not mean that no protocols will be used, but
+ rather removing ?transport=(protocol) query option in
+ the TURN ICE server .urls when constructing the Peer connection.
-
-
-
- data
- {Blob | String}
-
- Optional
-
-
-
-
The data object.
- Defined only when state payload is UPLOAD_STARTED or
- DOWNLOAD_COMPLETED.
-
-
-
-
-
-
-
- name
- {String}
-
-
-
-
-
-
The data transfer name.
-
-
-
-
-
-
-
- size
- {Number}
-
-
-
-
-
-
The data transfer data object size.
-
-
-
-
-
-
-
- dataType
- {String}
-
-
-
-
-
-
The data transfer session type.
- [Rel: Skylink.DATA_TRANSFER_SESSION_TYPE]
-
-
-
-
-
-
-
- chunkType
- {String}
-
-
-
-
-
-
The data transfer type of data chunk being used to send to Peer for transfers.
- For sendBlobData() method data transfers, the
- initial data chunks value may change depending on the currently received data chunk type or the
- agent supported sending type of data chunks.
- For sendURLData() method data transfers, it is
- STRING always.
- [Rel: Skylink.DATA_TRANSFER_DATA_TYPE]
-
-
-
-
-
-
-
- mimeType
- {String}
-
- Optional
-
-
-
-
The data transfer data object MIME type.
- Defined only when sendBlobData() method
- data object sent MIME type information is defined.
-
-
-
-
-
-
-
- chunkSize
- {Number}
-
-
-
-
-
-
The data transfer data chunk size.
-
-
-
-
-
-
-
- percentage
- {Number}
+
+
+
+ ALL
+ {String}
-
-
+
+
-
-
The data transfer percentage of completion progress.
+
+
Value "all"
+ The value of the option to configure using both TCP and UDP network transport protocols.
+ Example .urls output: ["turn:server.com?transport=tcp",
+ "turn:server.com?transport=udp", "turn:server1.com:3478?transport=tcp",
+ "turn:server1.com:3478?transport=udp"]
+ Note that if the video codec is not supported, the SDK will not configure the local "offer" or
+ "answer" session description to prefer the codec.
+
+The list of available video codecs to set as the preferred video codec to use to encode
+sending video data when available encoded video codec for Peer connections
+configured in the init() method.
+
+
+
+
-
Event Payload:
+
Keys:
- state
- {Number}
+ AUTO
+ {String}
-
The current getConnectionStatus() retrieval state.
- [Rel: Skylink.GET_CONNECTION_STATUS_STATE]
+
Value "auto"
+ The value of the option to not prefer any video codec but rather use the created
+ local "offer" / "answer" session description video codec preference.
@@ -36590,14 +39289,15 @@
Event Payload:
- peerId
+ VP8{String}
-
The Peer ID.
+
Value "VP8"
+ The value of the option to prefer the VP8 video codec.
@@ -36605,45 +39305,3048 @@
Event Payload:
- stats
- {JSON}
+ VP9
+ {String}
- Optional
+
-
The Peer connection current stats.
- Defined only when state payload is RETRIEVE_SUCCESS.
+
Value "VP9"
+ The value of the option to prefer the VP9 video codec.
+
+
+
+
+
+
+
+ H264
+ {String}
+
+
+
+
+
+
Value "H264"
+ The value of the option to prefer the H264 video codec.
Value { width: 160, height: 120 }
+ The value of the option to configure QQVGA resolution.
+ Aspect ratio: 4:3
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ HQVGA
+ {JSON}
+
+
+
+
+
+
Value { width: 240, height: 160 }
+ The value of the option to configure HQVGA resolution.
+ Aspect ratio: 3:2
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ QVGA
+ {JSON}
+
+
+
+
+
+
Value { width: 320, height: 240 }
+ The value of the option to configure QVGA resolution.
+ Aspect ratio: 4:3
+
+
+
+
+
+
+
+ WQVGA
+ {JSON}
+
+
+
+
+
+
Value { width: 384, height: 240 }
+ The value of the option to configure WQVGA resolution.
+ Aspect ratio: 16:10
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ HVGA
+ {JSON}
+
+
+
+
+
+
Value { width: 480, height: 320 }
+ The value of the option to configure HVGA resolution.
+ Aspect ratio: 3:2
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ VGA
+ {JSON}
+
+
+
+
+
+
Value { width: 640, height: 480 }
+ The value of the option to configure VGA resolution.
+ Aspect ratio: 4:3
+
+
+
+
+
+
+
+ WVGA
+ {JSON}
+
+
+
+
+
+
Value { width: 768, height: 480 }
+ The value of the option to configure WVGA resolution.
+ Aspect ratio: 16:10
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ FWVGA
+ {JSON}
+
+
+
+
+
+
Value { width: 854, height: 480 }
+ The value of the option to configure FWVGA resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ SVGA
+ {JSON}
+
+
+
+
+
+
Value { width: 800, height: 600 }
+ The value of the option to configure SVGA resolution.
+ Aspect ratio: 4:3
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ DVGA
+ {JSON}
+
+
+
+
+
+
Value { width: 960, height: 640 }
+ The value of the option to configure DVGA resolution.
+ Aspect ratio: 3:2
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ WSVGA
+ {JSON}
+
+
+
+
+
+
Value { width: 1024, height: 576 }
+ The value of the option to configure WSVGA resolution.
+ Aspect ratio: 16:9
+
+
+
+
+
+
+
+ HD
+ {JSON}
+
+
+
+
+
+
Value { width: 1280, height: 720 }
+ The value of the option to configure HD resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on device supports.
+
+
+
+
+
+
+
+ HDPLUS
+ {JSON}
+
+
+
+
+
+
Value { width: 1600, height: 900 }
+ The value of the option to configure HDPLUS resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ FHD
+ {JSON}
+
+
+
+
+
+
Value { width: 1920, height: 1080 }
+ The value of the option to configure FHD resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on device supports.
+
+
+
+
+
+
+
+ QHD
+ {JSON}
+
+
+
+
+
+
Value { width: 2560, height: 1440 }
+ The value of the option to configure QHD resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ WQXGAPLUS
+ {JSON}
+
+
+
+
+
+
Value { width: 3200, height: 1800 }
+ The value of the option to configure WQXGAPLUS resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ UHD
+ {JSON}
+
+
+
+
+
+
Value { width: 3840, height: 2160 }
+ The value of the option to configure UHD resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ UHDPLUS
+ {JSON}
+
+
+
+
+
+
Value { width: 5120, height: 2880 }
+ The value of the option to configure UHDPLUS resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ FUHD
+ {JSON}
+
+
+
+
+
+
Value { width: 7680, height: 4320 }
+ The value of the option to configure FUHD resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+
+
+
+
+
+
+
+ QUHD
+ {JSON}
+
+
+
+
+
+
Value { width: 15360, height: 8640 }
+ The value of the option to configure QUHD resolution.
+ Aspect ratio: 16:9
+ Note that configurating this resolution may not be supported depending on browser and device supports.
+ Learn more about how ICE works in this
+ article here.
+ Note that this event may not be triggered for MCU enabled Peer connections as ICE candidates
+ may be received in the session description instead.
+
+Event triggered when remote ICE candidate processing state has changed when Peer is using trickle ICE.
+
+
+
+
+
+
Event Payload:
+
+
+
+
+ state
+ {String}
+
+
+
+
+
+
The ICE candidate processing state.
+ [Rel: Skylink.CANDIDATE_PROCESSING_STATE]
+
+
+
+
+
+
+
+ peerId
+ {String}
+
+
+
+
+
+
The Peer ID.
+
+
+
+
+
+
+
+ candidateId
+ {String}
+
+
+
+
+
+
The remote ICE candidate session ID.
+ Note that this value is not related to WebRTC API but for identification of remote ICE candidate received.
+
+
+
+
+
+
+
+ candidateType
+ {String}
+
+
+
+
+
+
The remote ICE candidate type.
+ Expected values are "host" (local network), "srflx" (STUN) and "relay" (TURN).
+
+
+
+
+
+
+
+ candidate
+ {JSON}
+
+
+
+
+
+
The remote ICE candidate.
+
+
+
+
+
+
+
+ candidate
+ {String}
+
+
+
+
+
+
The remote ICE candidate connection description.
+
+
+
+
+
+
+
+ sdpMid
+ {String}
+
+
+
+
+
+
The remote ICE candidate identifier based on the remote session description.
+
+
+
+
+
+
+
+ sdpMLineIndex
+ {Number}
+
+
+
+
+
+
The remote ICE candidate media description index
+ (starting from 0) based on the remote session description.
+
+
+
+
+
+
+
+
+
+
+
+ error
+ {Error}
+
+ Optional
+
+
+
+
The error object.
+ Defined only when state is DROPPED or PROCESS_ERROR.
+ Learn more about how ICE works in this
+ article here.
+ Note that this event may not be triggered for MCU enabled Peer connections as ICE candidates
+ may be received in the session description instead.
+
+Event triggered when all remote ICE candidates gathering has completed and been processed.
+
+
+
+
+
+
Event Payload:
+
+
+
+
+ peerId
+ {String}
+
+
+
+
+
+
The Peer ID.
+
+
+
+
+
+
+
+ length
+ {JSON}
+
+
+
+
+
+
The remote ICE candidates length.
+
+
+
+
+
+
+
+ expected
+ {Number}
+
+
+
+
+
+
The expected total number of remote ICE candidates to be received.
+
+
+
+
+
+
+
+ received
+ {Number}
+
+
+
+
+
+
The actual total number of remote ICE candidates received.
+
+
+
+
+
+
+
+ processed
+ {Number}
+
+
+
+
+
+
The total number of remote ICE candidates processed.
+ This may be caused by Javascript errors in the event listener when subscribing to events.
+ It may be resolved by checking for code errors in your Web App in the event subscribing listener.
+ skylinkDemo.on("eventName", function () { // Errors here });
+
+Event triggered when socket connection encountered exception.
+
+
+
+
+
+
Event Payload:
+
+
+
+
+ error
+ {Error | String}
+
+
+
+
+
+
The error object.
+
+
+
+
+
+
+
+ session
+ {JSON}
+
+
+
+
+
+
The socket connection session information.
+ Object signature matches the session parameter payload received in the
+ channelOpen event.
Event triggered when a Datachannel connection state has changed.
+
+
+
+
+
+
Event Payload:
+
+
+
+
+ state
+ {String}
+
+
+
+
+
+
The current Datachannel connection state.
+ [Rel: Skylink.DATA_CHANNEL_STATE]
+
+
+
+
+
+
+
+ peerId
+ {String}
+
+
+
+
+
+
The Peer ID.
+
+
+
+
+
+
+
+ error
+ {Error}
+
+ Optional
+
+
+
+
The error object.
+ Defined only when state payload is ERROR or SEND_MESSAGE_ERROR.
+
+
+
+
+
+
+
+ channelName
+ {String}
+
+
+
+
+
+
The Datachannel ID.
+
+
+
+
+
+
+
+ channelType
+ {String}
+
+
+
+
+
+
The Datachannel type.
+ [Rel: Skylink.DATA_CHANNEL_TYPE]
+
+
+
+
+
+
+
+ messageType
+ {String}
+
+
+
+
+
+
The Datachannel sending Datachannel message error type.
+ Defined only when state payload is SEND_MESSAGE_ERROR.
+ [Rel: Skylink.DATA_CHANNEL_MESSAGE_ERROR]
+
+
+
+
+
+
+
+ bufferAmount
+ {JSON}
+
+
+
+
+
+
The Datachannel buffered amount information.
+
+
+
+
+
+
+
+ bufferedAmountLow
+ {Number}
+
+
+
+
+
+
The size of currently queued data to send on the Datachannel connection.
+
+
+
+
+
+
+
+ bufferedAmountLowThreshold
+ {Number}
+
+
+
+
+
+
The current buffered amount low threshold configured.
Event triggered when a data streaming state has changed.
+
+
+
+
+
+
Event Payload:
+
+
+
+
+ state
+ {String}
+
+
+
+
+
+
The current data streaming state.
+ [Rel: Skylink.DATA_STREAM_STATE]
+
+
+
+
+
+
+
+ streamId
+ {String}
+
+
+
+
+
+
The data streaming session ID.
+ Note that this is defined as null when state payload is START_ERROR.
+
+
+
+
+
+
+
+ peerId
+ {String}
+
+
+
+
+
+
The Peer ID.
+ Note that this could be defined as null when state payload is
+ START_ERROR and there is no Peers to start data streaming with.
+
+
+
+
+
+
+
+ streamInfo
+ {JSON}
+
+
+
+
+
+
The data streaming information.
+
+
+
+
+
+
+
+ chunk
+ {Blob | String}
+
+ Optional
+
+
+
+
The data chunk received.
+ Defined only when state payload is RECEIVED or SENT.
+
+
+
+
+
+
+
+ chunkSize
+ {Number}
+
+
+
+
+
+
The data streaming data chunk size received.
+
+
+
+
+
+
+
+ chunkType
+ {String}
+
+
+
+
+
+
The data streaming data chunk type received.
+ The initial data chunks value may change depending on the currently received data chunk type or the
+ agent supported sending type of data chunks.
+ [Rel: Skylink.DATA_TRANSFER_DATA_TYPE]
+
+
+
+
+
+
+
+ isStringStream
+ {String}
+
+
+
+
+
+
The flag if data streaming data chunks are strings.
+
+
+
+
+
+
+
+ isPrivate
+ {Boolean}
+
+
+
+
+
+
The flag if data streaming is targeted or not, basing
+ off the targetPeerId parameter being defined in
+ startStreamingData() method.
+
+
+
+
+
+
+
+ senderPeerId
+ {String}
+
+
+
+
+
+
The sender Peer ID.
+
+
+
+
+
+
+
+
+
+
+
+ error
+ {Error}
+
+ Optional
+
+
+
+
The error object.
+ Defined only when state payload is ERROR or START_ERROR,.
Event triggered when a data transfer state has changed.
+
+
+
+
+
+
Event Payload:
+
+
+
+
+ state
+ {String}
+
+
+
+
+
+
The current data transfer state.
+ [Rel: Skylink.DATA_TRANSFER_STATE]
+
+
+
+
+
+
+
+ transferId
+ {String}
+
+
+
+
+
+
The data transfer ID.
+ Note that this is defined as null when state payload is START_ERROR.
+
+
+
+
+
+
+
+ peerId
+ {String}
+
+
+
+
+
+
The Peer ID.
+ Note that this could be defined as null when state payload is
+ START_ERROR and there is no Peers to start data transfer with.
+
+
+
+
+
+
+
+ transferInfo
+ {JSON}
+
+
+
+
+
+
The data transfer information.
+
+
+
+
+
+
+
+ data
+ {Blob | String}
+
+ Optional
+
+
+
+
The data object.
+ Defined only when state payload is UPLOAD_STARTED or
+ DOWNLOAD_COMPLETED.
+
+
+
+
+
+
+
+ name
+ {String}
+
+
+
+
+
+
The data transfer name.
+
+
+
+
+
+
+
+ size
+ {Number}
+
+
+
+
+
+
The data transfer data object size.
+
+
+
+
+
+
+
+ dataType
+ {String}
+
+
+
+
+
+
The data transfer session type.
+ [Rel: Skylink.DATA_TRANSFER_SESSION_TYPE]
+
+
+
+
+
+
+
+ chunkType
+ {String}
+
+
+
+
+
+
The data transfer type of data chunk being used to send to Peer for transfers.
+ For sendBlobData() method data transfers, the
+ initial data chunks value may change depending on the currently received data chunk type or the
+ agent supported sending type of data chunks.
+ For sendURLData() method data transfers, it is
+ STRING always.
+ [Rel: Skylink.DATA_TRANSFER_DATA_TYPE]
+
+
+
+
+
+
+
+ mimeType
+ {String}
+
+ Optional
+
+
+
+
The data transfer data object MIME type.
+ Defined only when sendBlobData() method
+ data object sent MIME type information is defined.
+
+
+
+
+
+
+
+ chunkSize
+ {Number}
+
+
+
+
+
+
The data transfer data chunk size.
+
+
+
+
+
+
+
+ percentage
+ {Number}
+
+
+
+
+
+
The data transfer percentage of completion progress.
The current getConnectionStatus() retrieval state.
+ [Rel: Skylink.GET_CONNECTION_STATUS_STATE]
+
+
+
+
+
+
+
+ peerId
+ {String}
+
+
+
+
+
+
The Peer ID.
+
+
+
+
+
+
+
+ stats
+ {JSON}
+
+ Optional
+
+
+
+
The Peer connection current stats.
+ Defined only when state payload is RETRIEVE_SUCCESS.
+
+
+
+
+
+
+
+ raw
+ {JSON}
+
+
+
+
+
+
The Peer connection raw stats before parsing.
+
+
+
+
+
+
+
+ audio
+ {JSON}
+
+
+
+
+
+
The Peer connection audio streaming stats.
+
+
+
+
+
+
+
+ sending
+ {JSON}
+
+
+
+
+
+ The Peer connection sending audio streaming stats.
+
+
+
+
+ sending.bytes
+ {Number}
+
+
+
+
+
+ The Peer connection current sending audio streaming bytes.
+ Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+
+
+
+
+ sending.totalBytes
+ {Number}
+
+
+
+
+
+ The Peer connection total sending audio streaming bytes.
+ Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+
+
+
+
+ sending.packets
+ {Number}
+
+
+
+
+
+ The Peer connection current sending audio streaming packets.
+
+
+
+
+ sending.totalPackets
+ {Number}
+
+
+
+
+
+ The Peer connection total sending audio streaming packets.
+
+
+
+
+ sending.packetsLost
+ {Number}
+
+
+
+
+
+
+ This property has been deprecated and would be removed in future releases
+ as it should not be in sending property.
+
The Peer connection current sending audio streaming packets lost.
+
+
+
+
+ sending.totalPacketsLost
+ {Number}
+
+
+
+
+
+
+ This property has been deprecated and would be removed in future releases
+ as it should not be in sending property.
+
The Peer connection total sending audio streaming packets lost.
+
+ This property has been deprecated and would be removed in future releases
+ as it should not be in sending property.
+
The Peer connection sending audio streaming
+ RTP packets jitter buffer in miliseconds.
+ Defined as null if it's not available in original raw stats before parsing.
+
+
+
+
+ sending.codec
+ {JSON}
+
+ Optional
+
+
+
+ The Peer connection sending audio streaming selected codec information.
+ Defined as null if local session description is not available before parsing.
+
+ The Peer connection sending audio streaming selected codec implementation.
+ Defined as null if it's not available in original raw stats before parsing.
+
+ The Peer connection sending audio streaming selected codec channels (2 for stereo).
+ Defined as null if it's not available in original raw stats before parsing,
+ and this is usually present in stats.audio property.
+
+ The Peer connection sending audio streaming selected codec media sampling rate.
+ Defined as null if it's not available in original raw stats before parsing.
+
+ The Peer connection sending audio streaming selected codec parameters.
+ Defined as null if it's not available in original raw stats before parsing.
+
+ The Peer connection sending audio streaming echo return loss in db (decibels).
+ Defined as null if it's not available in original raw stats before parsing.
+
+ The Peer connection sending audio streaming
+ echo return loss enhancement db (decibels).
+ Defined as null if it's not available in original raw stats before parsing.
+
+
+
+
+ receiving
+ {JSON}
+
+
+
+
+
+ The Peer connection receiving audio streaming stats.
+
+
+
+
+ receiving.bytes
+ {Number}
+
+
+
+
+
+ The Peer connection current sending audio streaming bytes.
+ Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+
+
+
+
+ receiving.totalBytes
+ {Number}
+
+
+
+
+
+ The Peer connection total sending audio streaming bytes.
+ Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+
+
+
+
+ receiving.packets
+ {Number}
+
+
+
+
+
+ The Peer connection current receiving audio streaming packets.
+
+
+
+
+ receiving.totalPackets
+ {Number}
+
+
+
+
+
+ The Peer connection total receiving audio streaming packets.
+
+
+
+
+ receiving.packetsLost
+ {Number}
+
+
+
+
+
+ The Peer connection current receiving audio streaming packets lost.
+
+
+
+
+ receiving.fractionLost
+ {Number}
+
+
+
+
+
+ The Peer connection current receiving audio streaming fraction packets lost.
+
+
+
+
+ receiving.packetsDiscarded
+ {Number}
+
+
+
+
+
+ The Peer connection current receiving audio streaming packets discarded.
+
+
+
+
+ receiving.totalPacketsLost
+ {Number}
+
+
+
+
+
+ The Peer connection total receiving audio streaming packets lost.
+
+ The Peer connection receiving audio streaming RTP packets jitter in seconds.
+ Defined as 0 if it's not present in original raw stats before parsing.
+
+ The Peer connection receiving audio streaming
+ RTP packets jitter buffer in miliseconds.
+ Defined as null if it's not available in original raw stats before parsing.
+
+
+
+
+ receiving.codec
+ {JSON}
+
+ Optional
+
+
+
+ The Peer connection receiving audio streaming selected codec information.
+ Defined as null if remote session description is not available before parsing.
+ Note that if the value is polyfilled, the value may not be accurate since the remote Peer can override the selected codec.
+ The value is derived from the remote session description.
+
+ The Peer connection receiving audio streaming selected codec implementation.
+ Defined as null if it's not available in original raw stats before parsing.
+
+ The Peer connection receiving audio streaming selected codec channels (2 for stereo).
+ Defined as null if it's not available in original raw stats before parsing,
+ and this is usually present in stats.audio property.
+
+
+
+
+ receiving.codec.clockRate
+ {Number}
-
+ Optional
+
-
-
-
-
- raw
- {JSON}
+
+ The Peer connection receiving audio streaming selected codec media sampling rate.
+ Defined as null if it's not available in original raw stats before parsing.
+
+ The Peer connection receiving audio streaming selected codec parameters.
+ Defined as null if it's not available in original raw stats before parsing.
+
+
+
+
+ receiving.outputLevel
+ {Number}
-
+ Optional
+
+
+ The Peer connection receiving audio streaming output level.
+ Defined as null if it's not available in original raw stats before parsing.
+
+
+
+
- audio
+ video{JSON}
-
The Peer connection audio streaming stats.
+
The Peer connection video streaming stats.
@@ -36658,7 +42361,7 @@
Event Payload:
- The Peer connection sending audio streaming stats.
+ The Peer connection sending video streaming stats.
@@ -36670,7 +42373,7 @@
Event Payload:
- The Peer connection current sending audio streaming bytes.
+ The Peer connection current sending video streaming bytes.
Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
@@ -36683,7 +42386,7 @@
Event Payload:
- The Peer connection total sending audio streaming bytes.
+ The Peer connection total sending video streaming bytes.
Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
@@ -36696,7 +42399,7 @@
Event Payload:
- The Peer connection current sending audio streaming packets.
+ The Peer connection current sending video streaming packets.
@@ -36708,7 +42411,7 @@
Event Payload:
- The Peer connection total sending audio streaming packets.
+ The Peer connection total sending video streaming packets.
@@ -36720,7 +42423,10 @@
Event Payload:
- The Peer connection current sending audio streaming packets lost.
+
+ This property has been deprecated and would be removed in future releases
+ as it should not be in sending property.
+
The Peer connection current sending video streaming packets lost.
@@ -36732,7 +42438,10 @@
Event Payload:
- The Peer connection total sending audio streaming packets lost.
+
+ This property has been deprecated and would be removed in future releases
+ as it should not be in sending property.
+
The Peer connection total sending video streaming packets lost.
@@ -36744,7 +42453,7 @@
Event Payload:
- The Peer connection sending audio streaming RTP packets SSRC.
+ The Peer connection sending video streaming RTP packets SSRC.
@@ -36756,7 +42465,7 @@
Event Payload:
- The Peer connection sending audio streaming RTT (Round-trip delay time).
+ The Peer connection sending video streaming RTT (Round-trip delay time).
Defined as 0 if it's not present in original raw stats before parsing.
@@ -36769,7 +42478,10 @@
Event Payload:
- The Peer connection sending audio streaming RTP packets jitter in seconds.
+
+ This property has been deprecated and would be removed in future releases
+ as it should not be in sending property.
+
The Peer connection sending video streaming RTP packets jitter in seconds.
Defined as 0 if it's not present in original raw stats before parsing.
@@ -36782,8 +42494,23 @@
Event Payload:
- The Peer connection sending audio streaming
- RTP packets jitter buffer in miliseconds.
+
+ This property has been deprecated and would be removed in future releases
+ as it should not be in sending property.
+
The Peer connection sending video streaming RTP packets jitter buffer in miliseconds.
+ Defined as null if it's not available in original raw stats before parsing.
+
+
+
+
+ sending.qpSum
+ {Number}
+
+ Optional
+
+
+
+ The Peer connection sending video streaming sum of the QP values of frames passed.
Defined as null if it's not available in original raw stats before parsing.
@@ -36796,7 +42523,7 @@
Event Payload:
- The Peer connection sending audio streaming selected codec information.
+ The Peer connection sending video streaming selected codec information.
Defined as null if local session description is not available before parsing.
@@ -36809,7 +42536,7 @@
Event Payload:
- The Peer connection sending audio streaming selected codec name.
+ The Peer connection sending video streaming selected codec name.
@@ -36821,7 +42548,7 @@
Event Payload:
- The Peer connection sending audio streaming selected codec payload type.
+ The Peer connection sending video streaming selected codec payload type.
@@ -36833,7 +42560,7 @@
Event Payload:
- The Peer connection sending audio streaming selected codec implementation.
+ The Peer connection sending video streaming selected codec implementation.
Defined as null if it's not available in original raw stats before parsing.
@@ -36846,7 +42573,7 @@
Event Payload:
- The Peer connection sending audio streaming selected codec channels (2 for stereo).
+ The Peer connection sending video streaming selected codec channels (2 for stereo).
Defined as null if it's not available in original raw stats before parsing,
and this is usually present in stats.audio property.
@@ -36860,7 +42587,7 @@
Event Payload:
- The Peer connection sending audio streaming selected codec media sampling rate.
+ The Peer connection sending video streaming selected codec media sampling rate.
Defined as null if it's not available in original raw stats before parsing.
@@ -36873,1043 +42600,1201 @@
Event Payload:
- The Peer connection sending audio streaming selected codec parameters.
+ The Peer connection sending video streaming selected codec parameters.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection sending audio streaming input level.
+ The Peer connection sending video streaming frames.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection sending audio streaming echo return loss in db (decibels).
+ The Peer connection sending video streaming fps input.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection sending audio streaming
- echo return loss enhancement db (decibels).
+ The Peer connection sending video streaming fps input.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming stats.
+ The Peer connection sending video streaming frames dropped.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection current sending audio streaming bytes.
- Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+ The Peer connection sending video streaming fps mean.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection total sending audio streaming bytes.
- Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+ The Peer connection sending video streaming fps standard deviation.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection current receiving audio streaming packets.
+ The Peer connection sending video streaming fps.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection total receiving audio streaming packets.
+ The Peer connection sending video streaming frames decoded.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection current receiving audio streaming packets lost.
+ The Peer connection sending video streaming frames corrupted.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection total receiving audio streaming packets lost.
+ The Peer connection total sending video streaming frames.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming RTP packets SSRC.
+ The Peer connection current sending video streaming nacks.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming RTP packets jitter in seconds.
- Defined as 0 if it's not present in original raw stats before parsing.
+ The Peer connection total sending video streaming nacks.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming
- RTP packets jitter buffer in miliseconds.
+ The Peer connection current sending video streaming plis.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming selected codec information.
- Defined as null if remote session description is not available before parsing.
- Note that if the value is polyfilled, the value may not be accurate since the remote Peer can override the selected codec.
- The value is derived from the remote session description.
+ The Peer connection total sending video streaming plis.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming selected codec name.
+ The Peer connection current sending video streaming firs.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming selected codec payload type.
+ The Peer connection total sending video streaming firs.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming selected codec implementation.
+ The Peer connection current sending video streaming slis.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming selected codec channels (2 for stereo).
- Defined as null if it's not available in original raw stats before parsing,
- and this is usually present in stats.audio property.
+ The Peer connection total sending video streaming slis.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving audio streaming selected codec media sampling rate.
- Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection receiving video streaming stats.
- The Peer connection receiving audio streaming selected codec parameters.
- Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection current receiving video streaming bytes.
+ Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
- The Peer connection receiving audio streaming output level.
- Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection total receiving video streaming bytes.
+ Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
-
-
-
-
-
- video
- {JSON}
-
-
-
-
-
-
The Peer connection video streaming stats.
-
-
-
-
-
-
- sending
- {JSON}
+ receiving.packets
+ {Number}
- The Peer connection sending video streaming stats.
+ The Peer connection current receiving video streaming packets.
- sending.bytes
+ receiving.totalPackets{Number}
- The Peer connection current sending video streaming bytes.
- Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+ The Peer connection total receiving video streaming packets.
- The Peer connection total sending video streaming bytes.
- Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+ The Peer connection current receiving video streaming packets lost.
- The Peer connection sending video streaming RTT (Round-trip delay time).
- Defined as 0 if it's not present in original raw stats before parsing.
+ The Peer connection receiving video streaming e2e delay.
+ Defined as null if it's not present in original raw stats before parsing, and that
+ it finds any existing audio, video or object (plugin) DOM elements that has set with the
+ Peer remote stream object to parse current time. Note that document.getElementsByTagName function
+ and DOM .currentTime has to be supported inorder for data to be parsed correctly.
- sending.jitter
+ receiving.jitter{Number}
- The Peer connection sending video streaming RTP packets jitter in seconds.
+ The Peer connection receiving video streaming RTP packets jitter in seconds.
Defined as 0 if it's not present in original raw stats before parsing.
- The Peer connection sending video streaming
+ The Peer connection receiving video streaming
RTP packets jitter buffer in miliseconds.
Defined as null if it's not available in original raw stats before parsing.
- sending.codec
+ receiving.codec{JSON}Optional
- The Peer connection sending video streaming selected codec information.
- Defined as null if local session description is not available before parsing.
+ The Peer connection receiving video streaming selected codec information.
+ Defined as null if remote session description is not available before parsing.
+ Note that if the value is polyfilled, the value may not be accurate since the remote Peer can override the selected codec.
+ The value is derived from the remote session description.
- The Peer connection sending video streaming selected codec implementation.
+ The Peer connection receiving video streaming selected codec implementation.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection sending video streaming selected codec channels (2 for stereo).
+ The Peer connection receiving video streaming selected codec channels (2 for stereo).
Defined as null if it's not available in original raw stats before parsing,
and this is usually present in stats.audio property.
- The Peer connection sending video streaming selected codec media sampling rate.
+ The Peer connection receiving video streaming selected codec media sampling rate.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection sending video streaming selected codec parameters.
+ The Peer connection receiving video streaming selected codec parameters.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection sending video streaming frames.
+ The Peer connection receiving video streaming frames.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection sending video streaming frames input.
+ The Peer connection receiving video streaming fps output.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection sending video streaming frames dropped.
+ The Peer connection receiving video streaming frames decoded.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection sending video streaming fps mean.
+ The Peer connection receiving video streaming fps mean.
Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection receiving video streaming fps standard deviation.
+ Defined as null if it's not available in original raw stats before parsing.
+
- The Peer connection current sending video streaming nacks.
- Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection selected local ICE candidate.
- The Peer connection total sending video streaming nacks.
- Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection selected
+ local ICE candidate IP address.
- The Peer connection current sending video streaming plis.
- Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection selected
+ local ICE candidate port number.
- The Peer connection total sending video streaming plis.
- Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection selected
+ local ICE candidate IP transport type.
- The Peer connection current sending video streaming firs.
- Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection selected
+ local ICE candidate type.
- The Peer connection total sending video streaming firs.
- Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection possible
+ transport used when relaying local media to TURN server.
+ Types are "UDP" (UDP connections), "TCP" (TCP connections) and
+ "TCP/TLS" (TCP over TLS connections).
- receiving
+ remote{JSON}
- The Peer connection receiving video streaming stats.
+ The Peer connection selected remote ICE candidate.
- The Peer connection current receiving video streaming bytes.
- Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+ The Peer connection selected
+ remote ICE candidate IP address.
- The Peer connection total receiving video streaming bytes.
- Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
+ The Peer connection selected
+ remote ICE candidate port number.
- The Peer connection current receiving video streaming packets lost.
+ The flag if Peer has gotten ACK to an ICE request.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection total receiving video streaming packets lost.
+ The flag if Peer has gotten a valid incoming ICE request.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming RTP packets SSRC.
+ The current STUN connectivity checks RTT (Round-trip delay time).
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming e2e delay.
- Defined as null if it's not present in original raw stats before parsing, and that
- it finds any existing audio, video or object (plugin) DOM elements that has set with the
- Peer remote stream object to parse current time. Note that document.getElementsByTagName function
- and DOM .currentTime has to be supported inorder for data to be parsed correctly.
+ The total STUN connectivity checks RTT (Round-trip delay time).
+ Defined as null if it's not available in original raw stats before parsing.
- receiving.jitter
- {Number}
+ requests
+ {JSON}
- The Peer connection receiving video streaming RTP packets jitter in seconds.
- Defined as 0 if it's not present in original raw stats before parsing.
+ The ICE connectivity check requests.
- The Peer connection receiving video streaming
- RTP packets jitter buffer in miliseconds.
+ The current ICE connectivity check requests received.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming selected codec information.
- Defined as null if remote session description is not available before parsing.
- Note that if the value is polyfilled, the value may not be accurate since the remote Peer can override the selected codec.
- The value is derived from the remote session description.
+ The current ICE connectivity check requests sent.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming selected codec name.
+ The total ICE connectivity check requests received.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming selected codec payload type.
+ The total ICE connectivity check requests sent.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming selected codec implementation.
- Defined as null if it's not available in original raw stats before parsing.
+ The ICE connectivity check responses.
- The Peer connection receiving video streaming selected codec channels (2 for stereo).
- Defined as null if it's not available in original raw stats before parsing,
- and this is usually present in stats.audio property.
+ The current ICE connectivity check responses received.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming selected codec media sampling rate.
+ The current ICE connectivity check responses sent.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming selected codec parameters.
+ The total ICE connectivity check responses received.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming frames.
+ The total ICE connectivity check responses sent.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming frames output.
- Defined as null if it's not available in original raw stats before parsing.
+ The current ICE consent requests.
- The Peer connection receiving video streaming frames decoded.
+ The current ICE consent requests received.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming fps mean.
+ The current ICE consent requests sent.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection receiving video streaming fps standard deviation.
+ The total ICE consent requests received.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection current receiving video streaming nacks.
+ The total ICE consent requests sent.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection total receiving video streaming nacks.
- Defined as null if it's not available in original raw stats before parsing.
+ The current ICE consent responses.
- The Peer connection current receiving video streaming plis.
+ The current ICE consent responses received.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection totally receiving video streaming plis.
+ The current ICE consent responses sent.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection current receiving video streaming firs.
+ The total ICE consent responses received.
Defined as null if it's not available in original raw stats before parsing.
- The Peer connection total receiving video streaming firs.
+ The total ICE consent responses sent.
Defined as null if it's not available in original raw stats before parsing.
@@ -37919,14 +43804,14 @@
Event Payload:
- selectedCandidate
+ certificate{JSON}
-
The Peer connection selected ICE candidate pair stats.
+
The Peer connection DTLS/SRTP exchanged certificates information.
@@ -37941,123 +43826,127 @@
Event Payload:
- The Peer connection selected local ICE candidate.
+ The Peer connection local certificate information.
- The Peer connection selected
- local ICE candidate IP address.
+ The Peer connection local certificate fingerprint.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection selected
- local ICE candidate port number.
+ The Peer connection local
+ certificate fingerprint algorithm.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection selected
- local ICE candidate IP transport type.
+ The Peer connection local
+ base64 certificate in binary DER format encoded in base64.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection selected remote ICE candidate.
+ The Peer connection remote certificate fingerprint.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection selected
- remote ICE candidate IP address.
+ The Peer connection remote
+ certificate fingerprint algorithm.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection selected
- remote ICE candidate port number.
+ The Peer connection remote
+ base64 certificate in binary DER format encoded in base64.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection selected
- remote ICE candidate IP transport type.
+ The certificates SRTP cipher.
+ Defined as null if it's not available in original raw stats before parsing.
- The Peer connection selected
- remote ICE candidate type.
+ The certificates DTLS cipher.
+ Defined as null if it's not available in original raw stats before parsing.
+ The Peer connection
+ Datachannel connection current data streaming session ID.
+ Defined as null when there is currently no data streaming session on the Datachannel connection.
+
The error object.
- Defined only when state is ERROR.
+
The data transfer information.
+ Object signature matches the transferInfo parameter payload received in the
+ dataTransferState event
+ except without the data property.
- Learn more about how ICE works in this
- article here.
-
-Event triggered when a Peer connection ICE connection state has changed.
+
Event triggered when receiving upload data transfer from Peer.
@@ -39039,15 +45183,14 @@
Event Payload:
- state
+ transferId{String}
-
The current Peer connection ICE connection state.
- [Rel: Skylink.ICE_CONNECTION_STATE]
+
The transfer ID.
@@ -39069,6 +45212,39 @@
Event Payload:
+
+ transferInfo
+ {String}
+
+
+
+
+
+
The data transfer information.
+ Object signature matches the transferInfo parameter payload received in the
+ dataTransferState event
+ except without the data property.
Event triggered when receiving completed data transfer from Peer.
+
Event triggered when data streaming session has been stopped from Peer to User.
@@ -39136,14 +45314,14 @@
Event Payload:
- data
+ chunk{Blob | String}
-
The data.
+
The data chunk received.
@@ -39151,14 +45329,14 @@
Event Payload:
- transferId
+ streamId{String}
-
The data transfer ID.
+
The data streaming session ID.
@@ -39181,16 +45359,17 @@
Event Payload:
- transferInfo
+ streamInfo{JSON}
-
The data transfer information.
- Object signature matches the transferInfo parameter payload received in the
- dataTransferState event.
+
The data streaming session information.
+ Object signature matches the streamInfo parameter payload received in the
+ dataStreamState event
+ except without the chunk property.
Event triggered when receiving upload data transfer from Peer.
+
Event triggered when data streaming session has been started from Peer to User.
@@ -39279,14 +45460,14 @@
Event Payload:
- transferId
+ streamId{String}
-
The transfer ID.
+
The data streaming session ID.
@@ -39309,16 +45490,148 @@
Event Payload:
- transferInfo
+ streamInfo
+ {JSON}
+
+
+
+
+
+
The data streaming session information.
+ Object signature matches the streamInfo parameter payload received in the
+ dataStreamState event
+ except without the chunk property.
Event triggered when data streaming session has been stopped from Peer to User.
+
+
+
+
+
+
Event Payload:
+
+
+
+
+ streamId{String}
-
The data transfer information.
- Object signature matches the transferInfo parameter payload received in the
- dataTransferState event.
+
The data streaming session ID.
+
+
+
+
+
+
+
+ peerId
+ {String}
+
+
+
+
+
+
The Peer ID.
+
+
+
+
+
+
+
+ streamInfo
+ {JSON}
+
+
+
+
+
+
The data streaming session information.
+ Object signature matches the streamInfo parameter payload received in the
+ dataStreamState event
+ except without the chunk property.
+ The flag if Peer has any Datachannel connections enabled.
+ If isSelf value is true, this determines if User allows
+ Datachannel connections, else if value is false, this determines if Peer has any active
+ Datachannel connections (where dataChannelState event
+ triggers state as OPEN and channelType as
+ MESSAGING for Peer) with Peer.
+
+
+
audio{Boolean | JSON}
@@ -41377,6 +47707,30 @@
Event Payload:
+
+ DTProtocolVersion
+ {String}
+
+
+
+
+
+ The Peer data transfer (DT) protocol version.
+
+
+
+
+ SMProtocolVersion
+ {String}
+
+
+
+
+
+ The Peer signaling message (SM) protocol version.
+
- Defined in: source/skylink-events.js:551
+ Defined in: source/skylink-events.js:668
diff --git a/doc/data.json b/doc/data.json
index 5d2ae33a7..047d8e79a 100644
--- a/doc/data.json
+++ b/doc/data.json
@@ -2,7 +2,7 @@
"project": {
"name": "skylinkjs",
"description": "Temasys SkylinkJS 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.",
- "version": "0.6.17",
+ "version": "0.6.18",
"url": "https://temasys.github.io/"
},
"files": {
@@ -182,7 +182,7 @@
"plugin_for": [],
"extension_for": [],
"file": "source/template/header.js",
- "line": 132,
+ "line": 49,
"description": "
Prerequisites on using Skylink
\nBefore using any Skylink functionalities, you will need to authenticate your App Key using\n the `init()` method.\n\nTo manage or create App Keys, you may access the [Skylink Developer Portal here](https://console.temasys.io).\n\nTo view the list of supported browsers, visit [the list here](\nhttps://github.com/Temasys/SkylinkJS#supported-browsers).\n\nHere are some articles to help you get started:\n- [How to setup a simple video call](https://temasys.com.sg/getting-started-with-webrtc-and-skylinkjs/)\n- [How to setup screensharing](https://temasys.com.sg/screensharing-with-skylinkjs/)\n- [How to create a chatroom like feature](https://temasys.com.sg/building-a-simple-peer-to-peer-webrtc-chat/)\n\nHere are some demos you may use to aid your development:\n- Getaroom.io [[Demo](https://getaroom.io) / [Source code](https://github.com/Temasys/getaroom)]\n- Creating a component [[Link](https://github.com/Temasys/skylink-call-button)]\n\nYou may see the example below in the Constructor tab to have a general idea how event subscription\n and the ordering of init() and\n joinRoom() methods should be called.\n\nIf you have any issues, you may find answers to your questions in the FAQ section on [our support portal](\nhttp://support.temasys.io), asks questions, request features or raise bug tickets as well.\n\nIf you would like to contribute to our Temasys SkylinkJS codebase, see [the contributing README](\nhttps://github.com/Temasys/SkylinkJS/blob/master/CONTRIBUTING.md).\n\n[See License (Apache 2.0)](https://github.com/Temasys/SkylinkJS/blob/master/LICENSE)",
"is_constructor": 1,
"example": [
@@ -194,31 +194,13 @@
"classitems": [
{
"file": "source/template/header.js",
- "line": 5,
- "description": "Polyfill for Object.keys() from Mozilla\nFrom https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys",
- "class": "Skylink"
- },
- {
- "file": "source/template/header.js",
- "line": 45,
- "description": "Polyfill for Date.getISOString() from Mozilla\nFrom https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString",
- "class": "Skylink"
- },
- {
- "file": "source/template/header.js",
- "line": 69,
- "description": "Polyfill for addEventListener() from Eirik Backer @eirikbacker (github.com).\nFrom https://gist.github.com/eirikbacker/2864711\nMIT Licensed",
- "class": "Skylink"
- },
- {
- "file": "source/template/header.js",
- "line": 103,
+ "line": 20,
"description": "Global function that clones an object.",
"class": "Skylink"
},
{
"file": "source/template/header.js",
- "line": 208,
+ "line": 125,
"description": "Stores the flag if Peers should have any Datachannel connections.",
"itemtype": "attribute",
"name": "_enableDataChannel",
@@ -231,7 +213,7 @@
},
{
"file": "source/template/header.js",
- "line": 219,
+ "line": 136,
"description": "Stores the list of Peer Datachannel connections.",
"itemtype": "attribute",
"name": "_dataChannels",
@@ -257,7 +239,7 @@
},
{
"file": "source/template/header.js",
- "line": 232,
+ "line": 149,
"description": "Stores the list of data transfers from / to Peers.",
"itemtype": "attribute",
"name": "_dataTransfers",
@@ -276,7 +258,26 @@
},
{
"file": "source/template/header.js",
- "line": 243,
+ "line": 160,
+ "description": "Stores the list of sending data streaming sessions to Peers.",
+ "itemtype": "attribute",
+ "name": "_dataStreams",
+ "params": [
+ {
+ "name": "#streamId",
+ "description": "The data stream session.",
+ "type": "JSON"
+ }
+ ],
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 171,
"description": "Stores the list of buffered ICE candidates that is received before\n remote session description is received and set.",
"itemtype": "attribute",
"name": "_peerCandidatesQueue",
@@ -289,7 +290,7 @@
{
"name": "<#index>",
"description": "The Peer connection buffered ICE candidate received.",
- "type": "Object"
+ "type": "RTCIceCandidate"
}
]
}
@@ -302,7 +303,7 @@
},
{
"file": "source/template/header.js",
- "line": 256,
+ "line": 184,
"description": "Stores the list of ICE candidates received before signaling end.",
"itemtype": "attribute",
"name": "_peerEndOfCandidatesCounter",
@@ -314,7 +315,7 @@
},
{
"file": "source/template/header.js",
- "line": 266,
+ "line": 194,
"description": "Stores the list of Peer connection ICE candidates.",
"itemtype": "attribute",
"name": "_gatheredCandidates",
@@ -345,7 +346,7 @@
},
{
"file": "source/template/header.js",
- "line": 279,
+ "line": 207,
"description": "Stores the flags for ICE candidate filtering.",
"itemtype": "attribute",
"name": "_filterCandidatesType",
@@ -357,7 +358,7 @@
},
{
"file": "source/template/header.js",
- "line": 293,
+ "line": 221,
"description": "Stores the flag that indicates if Peer connections should trickle ICE.",
"itemtype": "attribute",
"name": "_enableIceTrickle",
@@ -370,7 +371,7 @@
},
{
"file": "source/template/header.js",
- "line": 304,
+ "line": 232,
"description": "Stores the flag that indicates if STUN ICE servers should be used when constructing Peer connection.",
"itemtype": "attribute",
"name": "_enableSTUN",
@@ -383,7 +384,7 @@
},
{
"file": "source/template/header.js",
- "line": 315,
+ "line": 243,
"description": "Stores the flag that indicates if TURN ICE servers should be used when constructing Peer connection.",
"itemtype": "attribute",
"name": "_enableTURN",
@@ -396,7 +397,7 @@
},
{
"file": "source/template/header.js",
- "line": 326,
+ "line": 254,
"description": "Stores the flag that indicates if public STUN ICE servers should be used when constructing Peer connection.",
"itemtype": "attribute",
"name": "_usePublicSTUN",
@@ -409,7 +410,7 @@
},
{
"file": "source/template/header.js",
- "line": 337,
+ "line": 265,
"description": "Stores the global number of Peer connection retries that would increase the wait-for-response timeout\n for the Peer connection health timer.",
"itemtype": "attribute",
"name": "_retryCounters",
@@ -421,7 +422,7 @@
},
{
"file": "source/template/header.js",
- "line": 348,
+ "line": 276,
"description": "Stores the list of the Peer connections.",
"itemtype": "attribute",
"name": "_peerConnections",
@@ -429,7 +430,7 @@
{
"name": "<#peerId>",
"description": "The Peer connection.",
- "type": "Object"
+ "type": "RTCPeerConnection"
}
],
"type": "JSON",
@@ -440,7 +441,7 @@
},
{
"file": "source/template/header.js",
- "line": 359,
+ "line": 287,
"description": "Stores the list of the Peer connections stats.",
"itemtype": "attribute",
"name": "_peerStats",
@@ -448,7 +449,7 @@
{
"name": "<#peerId>",
"description": "The Peer connection stats.",
- "type": "Object"
+ "type": "JSON"
}
],
"type": "JSON",
@@ -459,7 +460,38 @@
},
{
"file": "source/template/header.js",
- "line": 370,
+ "line": 298,
+ "description": "Stores the list of the Peer connections stats.",
+ "itemtype": "attribute",
+ "name": "_peerBandwidth",
+ "params": [
+ {
+ "name": "<#peerId>",
+ "description": "The Peer connection stats.",
+ "type": "JSON"
+ }
+ ],
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.16",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 309,
+ "description": "Stores the list of the Peer custom configs.",
+ "itemtype": "attribute",
+ "name": "_peerCustomConfigs",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 319,
"description": "The flag if User is using plugin.",
"itemtype": "attribute",
"name": "_isUsingPlugin",
@@ -471,7 +503,7 @@
},
{
"file": "source/template/header.js",
- "line": 380,
+ "line": 329,
"description": "Stores the option for the TURN protocols to use.\nThis should configure the TURN ICE servers urls ?transport=protocol flag.",
"itemtype": "attribute",
"name": "_TURNTransport",
@@ -485,7 +517,7 @@
},
{
"file": "source/template/header.js",
- "line": 393,
+ "line": 342,
"description": "Stores the list of Peers session information.",
"itemtype": "attribute",
"name": "_peerInformations",
@@ -526,7 +558,7 @@
},
{
"file": "source/template/header.js",
- "line": 408,
+ "line": 357,
"description": "Stores the Signaling user credentials from the API response required for connecting to the Signaling server.",
"itemtype": "attribute",
"name": "_user",
@@ -560,7 +592,7 @@
},
{
"file": "source/template/header.js",
- "line": 422,
+ "line": 371,
"description": "Stores the User custom data.\nBy default, if no custom user data is set, it is an empty string \"\".",
"itemtype": "attribute",
"name": "_userData",
@@ -573,7 +605,7 @@
},
{
"file": "source/template/header.js",
- "line": 434,
+ "line": 383,
"description": "Stores the User connection priority weight.\nIf Peer has a higher connection weight, it will do the offer from its Peer connection first.",
"itemtype": "attribute",
"name": "_peerPriorityWeight",
@@ -585,7 +617,7 @@
},
{
"file": "source/template/header.js",
- "line": 445,
+ "line": 394,
"description": "Stores the flag that indicates if \"autoIntroduce\" is enabled.\nIf enabled, the Peers connecting the same Room will receive each others \"enter\" message ping.",
"itemtype": "attribute",
"name": "_autoIntroduce",
@@ -598,7 +630,7 @@
},
{
"file": "source/template/header.js",
- "line": 457,
+ "line": 406,
"description": "Stores the flag that indicates if \"isPrivileged\" is enabled.\nIf enabled, the User has Privileged features which has the ability to retrieve the list of\n Peers in the same App space with getPeers() method\n and introduce Peers to each other with introducePeer method.",
"itemtype": "attribute",
"name": "isPrivileged",
@@ -611,7 +643,7 @@
},
{
"file": "source/template/header.js",
- "line": 471,
+ "line": 420,
"description": "Stores the list of Peers retrieved from the Signaling from getPeers() method.",
"itemtype": "attribute",
"name": "_peerList",
@@ -623,7 +655,7 @@
},
{
"file": "source/template/header.js",
- "line": 481,
+ "line": 430,
"description": "Stores the current Room name that User is connected to.",
"itemtype": "attribute",
"name": "_selectedRoom",
@@ -635,7 +667,7 @@
},
{
"file": "source/template/header.js",
- "line": 491,
+ "line": 440,
"description": "Stores the flag that indicates if Room is locked.",
"itemtype": "attribute",
"name": "_roomLocked",
@@ -647,7 +679,7 @@
},
{
"file": "source/template/header.js",
- "line": 501,
+ "line": 450,
"description": "Stores the flag that indicates if User is connected to the Room.",
"itemtype": "attribute",
"name": "_inRoom",
@@ -659,7 +691,7 @@
},
{
"file": "source/template/header.js",
- "line": 511,
+ "line": 460,
"description": "Stores the list of on() event handlers.",
"itemtype": "attribute",
"name": "_EVENTS",
@@ -685,7 +717,7 @@
},
{
"file": "source/template/header.js",
- "line": 523,
+ "line": 472,
"description": "Stores the list of once() event handlers.\nThese events are only triggered once.",
"itemtype": "attribute",
"name": "_onceEvents",
@@ -711,7 +743,7 @@
},
{
"file": "source/template/header.js",
- "line": 536,
+ "line": 485,
"description": "Stores the timestamps data used for throttling.",
"itemtype": "attribute",
"name": "_timestamp",
@@ -723,7 +755,7 @@
},
{
"file": "source/template/header.js",
- "line": 552,
+ "line": 501,
"description": "Stores the throttling interval timeout.",
"itemtype": "attribute",
"name": "_throttlingTimeouts",
@@ -735,7 +767,7 @@
},
{
"file": "source/template/header.js",
- "line": 566,
+ "line": 515,
"description": "Stores the flag if throttling should throw when called less than the interval timeout.",
"itemtype": "attribute",
"name": "_throttlingShouldThrowError",
@@ -747,7 +779,7 @@
},
{
"file": "source/template/header.js",
- "line": 576,
+ "line": 525,
"description": "Stores the current socket connection information.",
"itemtype": "attribute",
"name": "_socketSession",
@@ -759,7 +791,7 @@
},
{
"file": "source/template/header.js",
- "line": 586,
+ "line": 535,
"description": "Stores the queued socket messages.\nThis is to prevent too many sent over less than a second interval that might cause dropped messages\n or jams to the Signaling connection.",
"itemtype": "attribute",
"name": "_socketMessageQueue",
@@ -771,7 +803,7 @@
},
{
"file": "source/template/header.js",
- "line": 598,
+ "line": 547,
"description": "Stores the setTimeout to sent queued socket messages.",
"itemtype": "attribute",
"name": "_socketMessageTimeout",
@@ -783,7 +815,7 @@
},
{
"file": "source/template/header.js",
- "line": 608,
+ "line": 557,
"description": "Stores the list of socket ports to use to connect to the Signaling.\nThese ports are defined by default which is commonly used currently by the Signaling.\nShould re-evaluate this sometime.",
"itemtype": "attribute",
"name": "_socketPorts",
@@ -807,7 +839,7 @@
},
{
"file": "source/template/header.js",
- "line": 625,
+ "line": 574,
"description": "Stores the flag that indicates if socket connection to the Signaling has opened.",
"itemtype": "attribute",
"name": "_channelOpen",
@@ -819,7 +851,7 @@
},
{
"file": "source/template/header.js",
- "line": 635,
+ "line": 584,
"description": "Stores the Signaling server url.",
"itemtype": "attribute",
"name": "_signalingServer",
@@ -831,7 +863,7 @@
},
{
"file": "source/template/header.js",
- "line": 645,
+ "line": 594,
"description": "Stores the Signaling server protocol.",
"itemtype": "attribute",
"name": "_signalingServerProtocol",
@@ -843,7 +875,7 @@
},
{
"file": "source/template/header.js",
- "line": 655,
+ "line": 604,
"description": "Stores the Signaling server port.",
"itemtype": "attribute",
"name": "_signalingServerPort",
@@ -855,7 +887,7 @@
},
{
"file": "source/template/header.js",
- "line": 665,
+ "line": 614,
"description": "Stores the Signaling socket connection object.",
"itemtype": "attribute",
"name": "_socket",
@@ -867,7 +899,7 @@
},
{
"file": "source/template/header.js",
- "line": 675,
+ "line": 624,
"description": "Stores the socket connection timeout when establishing connection to the Signaling.",
"itemtype": "attribute",
"name": "_socketTimeout",
@@ -879,7 +911,7 @@
},
{
"file": "source/template/header.js",
- "line": 685,
+ "line": 634,
"description": "Stores the flag that indicates if XDomainRequest is used for IE 8/9.",
"itemtype": "attribute",
"name": "_socketUseXDR",
@@ -891,7 +923,7 @@
},
{
"file": "source/template/header.js",
- "line": 695,
+ "line": 644,
"description": "Stores the value if ICE restart is supported.",
"itemtype": "attribute",
"name": "_enableIceRestart",
@@ -903,7 +935,7 @@
},
{
"file": "source/template/header.js",
- "line": 706,
+ "line": 655,
"description": "Stores the flag if MCU environment is enabled.",
"itemtype": "attribute",
"name": "_hasMCU",
@@ -915,7 +947,7 @@
},
{
"file": "source/template/header.js",
- "line": 716,
+ "line": 665,
"description": "Stores the flag if HTTPS connections should be enforced when connecting to\n the API or Signaling server if App is accessing from HTTP domain.\nHTTPS connections are enforced if App is accessing from HTTPS domains.",
"itemtype": "attribute",
"name": "_forceSSL",
@@ -928,7 +960,7 @@
},
{
"file": "source/template/header.js",
- "line": 729,
+ "line": 678,
"description": "Stores the flag if TURNS connections should be enforced when connecting to\n the TURN server if App is accessing from HTTP domain.\nTURNS connections are enforced if App is accessing from HTTPS domains.",
"itemtype": "attribute",
"name": "_forceTURNSSL",
@@ -941,7 +973,7 @@
},
{
"file": "source/template/header.js",
- "line": 742,
+ "line": 691,
"description": "Stores the flag if TURN connections should be enforced when connecting to Peers.\nThis filters all non \"relay\" ICE candidates to enforce connections via the TURN server.",
"itemtype": "attribute",
"name": "_forceTURN",
@@ -954,7 +986,7 @@
},
{
"file": "source/template/header.js",
- "line": 754,
+ "line": 703,
"description": "Stores the construct API REST path to obtain Room credentials.",
"itemtype": "attribute",
"name": "_path",
@@ -966,7 +998,7 @@
},
{
"file": "source/template/header.js",
- "line": 764,
+ "line": 713,
"description": "Stores the API server url.",
"itemtype": "attribute",
"name": "_roomServer",
@@ -978,7 +1010,7 @@
},
{
"file": "source/template/header.js",
- "line": 774,
+ "line": 723,
"description": "Stores the App Key configured in init().",
"itemtype": "attribute",
"name": "_appKey",
@@ -990,7 +1022,7 @@
},
{
"file": "source/template/header.js",
- "line": 784,
+ "line": 733,
"description": "Stores the default Room name to connect to when joinRoom() does not provide a Room name.",
"itemtype": "attribute",
"name": "_defaultRoom",
@@ -1002,7 +1034,7 @@
},
{
"file": "source/template/header.js",
- "line": 794,
+ "line": 743,
"description": "Stores the init() credentials starting DateTime stamp in ISO 8601.",
"itemtype": "attribute",
"name": "_roomStart",
@@ -1014,7 +1046,7 @@
},
{
"file": "source/template/header.js",
- "line": 804,
+ "line": 753,
"description": "Stores the init() credentials duration counted in hours.",
"itemtype": "attribute",
"name": "_roomDuration",
@@ -1026,7 +1058,7 @@
},
{
"file": "source/template/header.js",
- "line": 814,
+ "line": 763,
"description": "Stores the init() generated credentials string.",
"itemtype": "attribute",
"name": "_roomCredentials",
@@ -1038,7 +1070,7 @@
},
{
"file": "source/template/header.js",
- "line": 824,
+ "line": 773,
"description": "Stores the current init() readyState.",
"itemtype": "attribute",
"name": "_readyState",
@@ -1050,7 +1082,7 @@
},
{
"file": "source/template/header.js",
- "line": 834,
+ "line": 783,
"description": "Stores the \"cid\" used for joinRoom().",
"itemtype": "attribute",
"name": "_key",
@@ -1062,7 +1094,7 @@
},
{
"file": "source/template/header.js",
- "line": 844,
+ "line": 793,
"description": "Stores the \"apiOwner\" used for joinRoom().",
"itemtype": "attribute",
"name": "_appKeyOwner",
@@ -1074,7 +1106,7 @@
},
{
"file": "source/template/header.js",
- "line": 854,
+ "line": 803,
"description": "Stores the Room credentials information for joinRoom().",
"itemtype": "attribute",
"name": "_room",
@@ -1113,7 +1145,7 @@
},
{
"file": "source/template/header.js",
- "line": 870,
+ "line": 819,
"description": "Stores the list of Peer messages timestamp.",
"itemtype": "attribute",
"name": "_peerMessagesStamps",
@@ -1125,7 +1157,7 @@
},
{
"file": "source/template/header.js",
- "line": 880,
+ "line": 829,
"description": "Stores the flag that indicates if getUserMedia() should fallback to retrieve\n audio only Stream after retrieval of audio and video Stream had failed.",
"itemtype": "attribute",
"name": "_audioFallback",
@@ -1138,7 +1170,7 @@
},
{
"file": "source/template/header.js",
- "line": 892,
+ "line": 841,
"description": "Stores the Streams.",
"itemtype": "attribute",
"name": "_streams",
@@ -1150,7 +1182,7 @@
},
{
"file": "source/template/header.js",
- "line": 905,
+ "line": 854,
"description": "Stores the default camera Stream settings.",
"itemtype": "attribute",
"name": "_streamsDefaultSettings",
@@ -1162,7 +1194,7 @@
},
{
"file": "source/template/header.js",
- "line": 931,
+ "line": 880,
"description": "Stores all the Stream required muted settings.",
"itemtype": "attribute",
"name": "_streamsMutedSettings",
@@ -1174,7 +1206,7 @@
},
{
"file": "source/template/header.js",
- "line": 944,
+ "line": 893,
"description": "Stores all the Stream sending maximum bandwidth settings.",
"itemtype": "attribute",
"name": "_streamsBandwidthSettings",
@@ -1186,7 +1218,7 @@
},
{
"file": "source/template/header.js",
- "line": 957,
+ "line": 906,
"description": "Stores all the Stream stopped callbacks.",
"itemtype": "attribute",
"name": "_streamsStoppedCbs",
@@ -1198,7 +1230,7 @@
},
{
"file": "source/template/header.js",
- "line": 967,
+ "line": 916,
"description": "Stores all the Stream sessions.\nDefined as false when Stream has already ended.",
"itemtype": "attribute",
"name": "_streamsSession",
@@ -1210,7 +1242,7 @@
},
{
"file": "source/template/header.js",
- "line": 978,
+ "line": 927,
"description": "Stores the preferred sending Peer connection streaming audio codec.",
"itemtype": "attribute",
"name": "_selectedAudioCodec",
@@ -1223,7 +1255,7 @@
},
{
"file": "source/template/header.js",
- "line": 989,
+ "line": 938,
"description": "Stores the preferred sending Peer connection streaming video codec.",
"itemtype": "attribute",
"name": "_selectedVideoCodec",
@@ -1236,7 +1268,7 @@
},
{
"file": "source/template/header.js",
- "line": 1000,
+ "line": 949,
"description": "Stores the flag if ulpfec and red codecs should be removed.",
"itemtype": "attribute",
"name": "_disableVideoFecCodecs",
@@ -1249,7 +1281,7 @@
},
{
"file": "source/template/header.js",
- "line": 1011,
+ "line": 960,
"description": "Stores the flag if CN (Comfort Noise) codec should be removed.",
"itemtype": "attribute",
"name": "_disableComfortNoiseCodec",
@@ -1262,7 +1294,7 @@
},
{
"file": "source/template/header.js",
- "line": 1022,
+ "line": 971,
"description": "Stores the flag if REMB feedback packets should be removed.",
"itemtype": "attribute",
"name": "_disableREMB",
@@ -1275,7 +1307,7 @@
},
{
"file": "source/template/header.js",
- "line": 1033,
+ "line": 982,
"description": "Stores the session description settings.",
"itemtype": "attribute",
"name": "_sdpSettings",
@@ -1287,11 +1319,11 @@
},
{
"file": "source/template/header.js",
- "line": 1053,
+ "line": 1002,
"description": "Stores the publish only settings.",
"itemtype": "attribute",
"name": "_publishOnly",
- "type": "JSON|Boolean",
+ "type": "Boolean",
"access": "private",
"tagname": "",
"since": "0.6.16",
@@ -1299,7 +1331,19 @@
},
{
"file": "source/template/header.js",
- "line": 1063,
+ "line": 1012,
+ "description": "Stores the parent ID.",
+ "itemtype": "attribute",
+ "name": "_parentId",
+ "type": "String",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1022,
"description": "Stores the list of recordings.",
"itemtype": "attribute",
"name": "_recordings",
@@ -1312,7 +1356,7 @@
},
{
"file": "source/template/header.js",
- "line": 1074,
+ "line": 1033,
"description": "Stores the current active recording session ID.\nThere can only be 1 recording session at a time in a Room",
"itemtype": "attribute",
"name": "_currentRecordingId",
@@ -1325,7 +1369,7 @@
},
{
"file": "source/template/header.js",
- "line": 1086,
+ "line": 1045,
"description": "Stores the recording session timeout to ensure 4 seconds has been recorded.",
"itemtype": "attribute",
"name": "_recordingStartInterval",
@@ -1338,7 +1382,7 @@
},
{
"file": "source/template/header.js",
- "line": 1097,
+ "line": 1056,
"description": "Stores the flag if MCU should use renegotiation.",
"itemtype": "attribute",
"name": "_mcuUseRenegoRestart",
@@ -1348,6 +1392,127 @@
"since": "0.6.16",
"class": "Skylink"
},
+ {
+ "file": "source/template/header.js",
+ "line": 1066,
+ "description": "Stores the debugging TURN/STUN ICE server.",
+ "itemtype": "attribute",
+ "name": "_iceServer",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1076,
+ "description": "Stores the debugging Signaling server.",
+ "itemtype": "attribute",
+ "name": "_socketServer",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1086,
+ "description": "Stores the currently supported codecs.",
+ "itemtype": "attribute",
+ "name": "_currentCodecSupport",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1096,
+ "description": "Stores the session description orders and info.",
+ "itemtype": "attribute",
+ "name": "_sdpSessions",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1106,
+ "description": "Stores the flag if voice activity detection should be enabled.",
+ "itemtype": "attribute",
+ "name": "_voiceActivityDetection",
+ "type": "Boolean",
+ "default": "true",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1117,
+ "description": "Stores the datachannel binary data chunk type.",
+ "itemtype": "attribute",
+ "name": "_binaryChunkType",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1128,
+ "description": "Stores the RTCPeerConnection configuration.",
+ "itemtype": "attribute",
+ "name": "_peerConnectionConfig",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1138,
+ "description": "Stores the RTCPeerConnection configuration.",
+ "itemtype": "attribute",
+ "name": "_peerConnectionConfig",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1148,
+ "description": "Stores the User's priority weight scheme to determine if User is offerer or answerer.",
+ "itemtype": "attribute",
+ "name": "_priorityWeightScheme",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/template/header.js",
+ "line": 1158,
+ "description": "Stores the auto bandwidth settings.",
+ "itemtype": "attribute",
+ "name": "_bandwidthAdjuster",
+ "type": "JSON",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
{
"file": "source/data-channel.js",
"line": 1,
@@ -1460,13 +1625,28 @@
},
{
"file": "source/data-channel.js",
- "line": 149,
+ "line": 153,
"description": "Subscribe to events",
"class": "Skylink"
},
{
"file": "source/data-channel.js",
- "line": 254,
+ "line": 275,
+ "description": "Function that returns the Datachannel buffer threshold and amount.",
+ "itemtype": "method",
+ "name": "_getDataChannelBuffer",
+ "return": {
+ "description": "The buffered amount information.",
+ "type": "JSON"
+ },
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/data-channel.js",
+ "line": 309,
"description": "Function that sends data over the Datachannel connection.",
"itemtype": "method",
"name": "_sendMessageToDataChannel",
@@ -1477,7 +1657,7 @@
},
{
"file": "source/data-channel.js",
- "line": 327,
+ "line": 384,
"description": "Function that stops the Datachannel connection and removes object references.",
"itemtype": "method",
"name": "_closeDataChannel",
@@ -1771,7 +1951,60 @@
},
{
"file": "source/data-transfer.js",
- "line": 108,
+ "line": 109,
+ "description": "The list of data streaming states.",
+ "itemtype": "attribute",
+ "name": "DATA_STREAM_STATE",
+ "params": [
+ {
+ "name": "SENDING_STARTED",
+ "description": "Value \"sendStart\"\n The value of the state when data streaming session has started from User to Peer.",
+ "type": "String"
+ },
+ {
+ "name": "RECEIVING_STARTED",
+ "description": "Value \"receiveStart\"\n The value of the state when data streaming session has started from Peer to Peer.",
+ "type": "String"
+ },
+ {
+ "name": "RECEIVED",
+ "description": "Value \"received\"\n The value of the state when data streaming session data chunk has been received from Peer to User.",
+ "type": "String"
+ },
+ {
+ "name": "SENT",
+ "description": "Value \"sent\"\n The value of the state when data streaming session data chunk has been sent from User to Peer.",
+ "type": "String"
+ },
+ {
+ "name": "SENDING_STOPPED",
+ "description": "Value \"sendStop\"\n The value of the state when data streaming session has stopped from User to Peer.",
+ "type": "String"
+ },
+ {
+ "name": "RECEIVING_STOPPED",
+ "description": "Value \"receivingStop\"\n The value of the state when data streaming session has stopped from Peer to User.",
+ "type": "String"
+ },
+ {
+ "name": "ERROR",
+ "description": "Value \"error\"\n The value of the state when data streaming session has errors.\n At this stage, the data streaming state is considered SENDING_STOPPED or\n RECEIVING_STOPPED.",
+ "type": "String"
+ },
+ {
+ "name": "START_ERROR",
+ "description": "Value \"startError\"\n The value of the state when data streaming session failed to start from User to Peer.",
+ "type": "String"
+ }
+ ],
+ "type": "JSON",
+ "readonly": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/data-transfer.js",
+ "line": 146,
"description": "Stores the list of data transfer protocols.",
"itemtype": "attribute",
"name": "_DC_PROTOCOL_TYPE",
@@ -1811,21 +2044,8 @@
},
{
"file": "source/data-transfer.js",
- "line": 132,
- "description": "Stores the list of agent names supported by the Web for Web only functionalities.",
- "itemtype": "attribute",
- "name": "_SUPPORTED_WEB_AGENTS",
- "type": "Array",
- "readonly": "",
- "access": "private",
- "tagname": "",
- "since": "0.6.16",
- "class": "Skylink"
- },
- {
- "file": "source/data-transfer.js",
- "line": 143,
- "description": "
\n Note that Android, iOS and C++ SDKs do not support simultaneous data transfers.\n
\nFunction that starts an uploading data transfer from User to Peers.",
+ "line": 170,
+ "description": "Function that starts an uploading data transfer from User to Peers.",
"itemtype": "method",
"name": "sendBlobData",
"params": [
@@ -1917,7 +2137,7 @@
]
}
],
- "trigger": "\n
Checks if Peer connection and Datachannel connection are in correct states. \n
If Peer connection is not stable: The stable state can be checked with \n peerConnectionState event triggering parameter payload state as STABLE\n for Peer.
If Peer connection messaging Datachannel has not been opened: This can be checked with\n dataChannelState event triggering parameter\n payload state as OPEN and channelType as\n MESSAGING for Peer.
If MCU is enabled for the App Key provided in init()method and connected: \n
If MCU Peer connection is not stable: The stable state can be checked with \n peerConnectionState event triggering parameter payload state as STABLE\n and peerId value as \"MCU\" for MCU Peer.\n
If MCU Peer connection messaging Datachannel has not been opened: This can be checked with\n dataChannelState event triggering parameter\n payload state as OPEN, peerId value as \"MCU\"\n and channelType as MESSAGING for MCU Peer.\n
If Peer supports simultaneous data transfer, open new data Datachannel: If MCU is connected,\n this opens a new data Datachannel with MCU Peer with all the Peers IDs information that supports\n simultaneous data transfers targeted for the data transfer session instead of opening new data Datachannel\n with all Peers targeted for the data transfer session. \n
dataChannelState event triggers parameter\n payload state as CONNECTING and channelType as DATA.\n Note that there is no timeout to wait for parameter payload state to be\n OPEN.
\n
If Datachannel has been created and opened successfully: \n
dataChannelState event triggers parameter payload\n state as OPEN and channelType as DATA.
\n
Else:
dataChannelState event\n triggers parameter payload state as CREATE_ERROR and channelType as\n DATA.
Else: If MCU is connected,\n this uses the messaging Datachannel with MCU Peer with all the Peers IDs information that supports\n simultaneous data transfers targeted for the data transfer session instead of using the messaging Datachannels\n with all Peers targeted for the data transfer session.
If messaging Datachannel connection has a\n data transfer in-progress:
Checks for Peer connection and Datachannel connection during data transfer: \n
If MCU is enabled for the App Key provided in init()\n method and connected: \n
If MCU Datachannel has closed abruptly during data transfer: \n This can be checked with dataChannelState event\n triggering parameter payload state as CLOSED, peerId value as\n \"MCU\" and channelType as DATA for targeted Peers that supports simultaneous\n data transfer or MESSAGING for targeted Peers that do not support it. \n
If MCU Peer connection has changed from not being stable: \n This can be checked with peerConnection event\n triggering parameter payload state as not STABLE, peerId value as\n \"MCU\".
If Peer connection has changed from not being stable: \n This can be checked with peerConnection event\n triggering parameter payload state as not STABLE. \n
If Datachannel has closed abruptly during data transfer:\n This can be checked with dataChannelState event\n triggering parameter payload state as CLOSED and channelType\n as DATA for Peer that supports simultaneous data transfer or MESSAGING\n for Peer that do not support it. \n
If Peer connection is not stable: The stable state can be checked with \n peerConnectionState event triggering parameter payload state as STABLE\n for Peer.
If Peer connection messaging Datachannel has not been opened: This can be checked with\n dataChannelState event triggering parameter\n payload state as OPEN and channelType as\n MESSAGING for Peer.
If MCU is enabled for the App Key provided in init()method and connected: \n
If MCU Peer connection is not stable: The stable state can be checked with \n peerConnectionState event triggering parameter payload state as STABLE\n and peerId value as \"MCU\" for MCU Peer.\n
If MCU Peer connection messaging Datachannel has not been opened: This can be checked with\n dataChannelState event triggering parameter\n payload state as OPEN, peerId value as \"MCU\"\n and channelType as MESSAGING for MCU Peer.\n
If Peer supports simultaneous data transfer, open new data Datachannel: If MCU is connected,\n this opens a new data Datachannel with MCU Peer with all the Peers IDs information that supports\n simultaneous data transfers targeted for the data transfer session instead of opening new data Datachannel\n with all Peers targeted for the data transfer session. \n
dataChannelState event triggers parameter\n payload state as CONNECTING and channelType as DATA.\n Note that there is no timeout to wait for parameter payload state to be\n OPEN.
\n
If Datachannel has been created and opened successfully: \n
dataChannelState event triggers parameter payload\n state as OPEN and channelType as DATA.
\n
Else:
dataChannelState event\n triggers parameter payload state as CREATE_ERROR and channelType as\n DATA.
Else: If MCU is connected,\n this uses the messaging Datachannel with MCU Peer with all the Peers IDs information that supports\n simultaneous data transfers targeted for the data transfer session instead of using the messaging Datachannels\n with all Peers targeted for the data transfer session.
If messaging Datachannel connection has a\n data transfer in-progress:
If there is any conflicting streamData()\n method data streaming session: If sendChunksAsBinary is provided as true,\n it cannot start if existing data streaming session is expected binary data chunks, and if provided as\n false, or method invoked is sendURLData() method,\n or Peer is using string data chunks fallback due to its support despite provided as true,\n it cannot start if existing data streaming session is expected string data chunks.\n
Checks for Peer connection and Datachannel connection during data transfer: \n
If MCU is enabled for the App Key provided in init()\n method and connected: \n
If MCU Datachannel has closed abruptly during data transfer: \n This can be checked with dataChannelState event\n triggering parameter payload state as CLOSED, peerId value as\n \"MCU\" and channelType as DATA for targeted Peers that supports simultaneous\n data transfer or MESSAGING for targeted Peers that do not support it. \n
If MCU Peer connection has changed from not being stable: \n This can be checked with peerConnection event\n triggering parameter payload state as not STABLE, peerId value as\n \"MCU\".
If Peer connection has changed from not being stable: \n This can be checked with peerConnection event\n triggering parameter payload state as not STABLE. \n
If Datachannel has closed abruptly during data transfer:\n This can be checked with dataChannelState event\n triggering parameter payload state as CLOSED and channelType\n as DATA for Peer that supports simultaneous data transfer or MESSAGING\n for Peer that do not support it. \n
",
"example": [
"\n<body>\n <input type=\"radio\" name=\"timeout\" onchange=\"setTransferTimeout(0)\"> 1s timeout (Default)\n <input type=\"radio\" name=\"timeout\" onchange=\"setTransferTimeout(120)\"> 2s timeout\n <input type=\"radio\" name=\"timeout\" onchange=\"setTransferTimeout(300)\"> 5s timeout\n <hr>\n <input type=\"file\" onchange=\"uploadFile(this.files[0], this.getAttribute('data'))\" data=\"peerId\">\n <input type=\"file\" onchange=\"uploadFileGroup(this.files[0], this.getAttribute('data').split(',')))\" data=\"peerIdA,peerIdB\">\n <input type=\"file\" onchange=\"uploadFileAll(this.files[0])\" data=\"\">\n <script>\n var transferTimeout = 0;\n\n function setTransferTimeout (timeout) {\n transferTimeout = timeout;\n }\n\n // Example 1: Upload data to a Peer\n function uploadFile (file, peerId) {\n var cb = function (error, success) {\n if (error) return;\n console.info(\"File has been transferred to '\" + peerId + \"' successfully\");\n };\n if (transferTimeout > 0) {\n skylinkDemo.sendBlobData(file, peerId, transferTimeout, cb);\n } else {\n skylinkDemo.sendBlobData(file, peerId, cb);\n }\n }\n\n // Example 2: Upload data to a list of Peers\n function uploadFileGroup (file, peerIds) {\n var cb = function (error, success) {\n var listOfPeers = error ? error.listOfPeers : success.listOfPeers;\n var listOfPeersErrors = error ? error.transferErrors : {};\n for (var i = 0; i < listOfPeers.length; i++) {\n if (listOfPeersErrors[listOfPeers[i]]) {\n console.error(\"Failed file transfer to '\" + listOfPeers[i] + \"'\");\n } else {\n console.info(\"File has been transferred to '\" + listOfPeers[i] + \"' successfully\");\n }\n }\n };\n if (transferTimeout > 0) {\n skylinkDemo.sendBlobData(file, peerIds, transferTimeout, cb);\n } else {\n skylinkDemo.sendBlobData(file, peerIds, cb);\n }\n }\n\n // Example 2: Upload data to a list of Peers\n function uploadFileAll (file) {\n var cb = function (error, success) {\n var listOfPeers = error ? error.listOfPeers : success.listOfPeers;\n var listOfPeersErrors = error ? error.transferErrors : {};\n for (var i = 0; i < listOfPeers.length; i++) {\n if (listOfPeersErrors[listOfPeers[i]]) {\n console.error(\"Failed file transfer to '\" + listOfPeers[i] + \"'\");\n } else {\n console.info(\"File has been transferred to '\" + listOfPeers[i] + \"' successfully\");\n }\n }\n };\n if (transferTimeout > 0) {\n skylinkDemo.sendBlobData(file, transferTimeout, cb);\n } else {\n skylinkDemo.sendBlobData(file, cb);\n }\n }\n</script>\n</body>"
],
@@ -1926,8 +2146,8 @@
},
{
"file": "source/data-transfer.js",
- "line": 515,
- "description": "
\n Currently, the Android, iOS and C++ SDKs do not support this type of data transfer session.\n
\nFunction that starts an uploading string data transfer from User to Peers.",
+ "line": 422,
+ "description": "Function that starts an uploading string data transfer from User to Peers.",
"itemtype": "method",
"name": "sendURLData",
"params": [
@@ -2021,7 +2241,7 @@
},
{
"file": "source/data-transfer.js",
- "line": 744,
+ "line": 557,
"description": "Function that accepts or rejects an upload data transfer request from Peer to User.",
"itemtype": "method",
"name": "acceptDataTransfer",
@@ -2053,7 +2273,7 @@
},
{
"file": "source/data-transfer.js",
- "line": 880,
+ "line": 693,
"description": "
\n For MCU enabled Peer connections, the cancel data transfer functionality may differ, as it\n will result in all Peers related to the data transfer ID to be terminated.\n
\nFunction that terminates a currently uploading / downloading data transfer from / to Peer.",
"itemtype": "method",
"name": "cancelDataTransfer",
@@ -2078,13 +2298,13 @@
},
{
"file": "source/data-transfer.js",
- "line": 935,
+ "line": 748,
"description": "Emit data state event function.",
"class": "Skylink"
},
{
"file": "source/data-transfer.js",
- "line": 1008,
+ "line": 821,
"description": "Function that sends a message to Peers via the Datachannel connection.\nConsider using sendURLData() method if you are\nsending large strings to Peers.",
"itemtype": "method",
"name": "sendP2PMessage",
@@ -2110,24 +2330,100 @@
},
{
"file": "source/data-transfer.js",
- "line": 1143,
- "description": "Function that starts the data transfer to Peers.",
+ "line": 956,
+ "description": "
\nFunction that starts a data chunks streaming session from User to Peers.",
"itemtype": "method",
- "name": "_startDataTransfer",
- "access": "private",
- "tagname": "",
- "since": "0.6.1",
- "class": "Skylink"
- },
- {
- "file": "source/data-transfer.js",
- "line": 1196,
- "description": "Complete Peer function.",
- "class": "Skylink"
- },
- {
+ "name": "startStreamingData",
+ "params": [
+ {
+ "name": "isStringStream",
+ "description": "The flag if data streaming session sending data chunks\n should be expected as string data chunks sent.\n By default, data chunks are expected to be sent in Blob or ArrayBuffer, and ArrayBuffer\n data chunks will be converted to Blob.",
+ "type": "Boolean",
+ "optional": true,
+ "optdefault": "false"
+ },
+ {
+ "name": "targetPeerId",
+ "description": "The target Peer ID to send message to.\n- When provided as an Array, it will start streaming session to only Peers which IDs are in the list.\n- When not provided, it will start the streaming session to all connected Peers with Datachannel connection in the Room.",
+ "type": "String|Array",
+ "optional": true
+ }
+ ],
+ "trigger": "\n
If Peer connection messaging Datachannel has not been opened: This can be checked with\n dataChannelState event triggering parameter\n payload state as OPEN and channelType as\n MESSAGING for Peer.
If MCU is enabled for the App Key provided in init()method and connected: \n
If MCU Peer connection messaging Datachannel has not been opened: This can be checked with\n dataChannelState event triggering parameter\n payload state as OPEN, peerId value as \"MCU\"\n and channelType as MESSAGING for MCU Peer.\n
If Peer supports simultaneous data streaming, open new data Datachannel: If MCU is connected,\n this opens a new data Datachannel with MCU Peer with all the Peers IDs information that supports\n simultaneous data transfers targeted for the data streaming session instead of opening new data Datachannel\n with all Peers targeted for the data streaming session. \n
dataChannelState event triggers parameter\n payload state as CONNECTING and channelType as DATA.\n Note that there is no timeout to wait for parameter payload state to be\n OPEN.
\n
If Datachannel has been created and opened successfully: \n
dataChannelState event triggers parameter payload\n state as OPEN and channelType as DATA.
\n
Else:
dataChannelState event\n triggers parameter payload state as CREATE_ERROR and channelType as\n DATA.
Else: If MCU is connected,\n this uses the messaging Datachannel with MCU Peer with all the Peers IDs information that supports\n simultaneous data transfers targeted for the data streaming session instead of using the messaging Datachannels\n with all Peers targeted for the data streaming session.
If messaging Datachannel connection has a\n data streaming in-progress:
If there is any conflicting streamData()\n method data streaming session: If isStringStream is provided as true and\n sendBlobData() method or \n sendURLData() method has an existing binary string transfer, it cannot start string data\n streaming session. Else if sendBlobData() method\n has an existing binary data transfer, it cannot start binary data streaming session.\n
\nFunction that sends a data chunk from User to Peers for an existing active data streaming session.",
+ "itemtype": "method",
+ "name": "streamData",
+ "params": [
+ {
+ "name": "streamId",
+ "description": "The data streaming session ID.",
+ "type": "String"
+ },
+ {
+ "name": "chunk",
+ "description": "The data chunk.\n By default when it is not string data streaming, data chunks when is are expected to be\n sent in Blob or ArrayBuffer, and ArrayBuffer data chunks will be converted to Blob.\n For binary data chunks, the limit is 65456.\n For string data chunks, the limit is 1212.",
+ "type": "String|Blob|ArrayBuffer"
+ }
+ ],
+ "trigger": "\n
Checks if Peer connection and Datachannel connection are in correct states. \n
If Peer connection (or MCU Peer connection if enabled)\n data streaming Datachannel has not been opened: This can be checked with\n dataChannelState event triggering parameter\n payload state as OPEN and channelType as\n MESSAGING for Peer.
\nFunction that stops a data chunks streaming session from User to Peers.",
+ "itemtype": "method",
+ "name": "stopStreamingData",
+ "params": [
+ {
+ "name": "streamId",
+ "description": "The data streaming session ID.",
+ "type": "String"
+ }
+ ],
+ "trigger": "\n
Checks if Peer connection and Datachannel connection are in correct states. \n
If Peer connection (or MCU Peer connection if enabled)\n data streaming Datachannel has not been opened: This can be checked with\n dataChannelState event triggering parameter\n payload state as OPEN and channelType as\n MESSAGING for Peer.
For User onlydataStreamState event\n triggers parameter payload state as SENDING_STOPPED.
\n
For Peer onlydataStreamState event\n triggers parameter payload state as RECEIVING_STOPPED.
",
+ "example": [
+ "\n skylinkDemo.stopStreamData(streamId);"
+ ],
+ "beta": 1,
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/data-transfer.js",
+ "line": 1669,
+ "description": "Function that starts the data transfer to Peers.",
+ "itemtype": "method",
+ "name": "_startDataTransfer",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.1",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/data-transfer.js",
+ "line": 1866,
+ "description": "Complete Peer function.",
+ "class": "Skylink"
+ },
+ {
"file": "source/data-transfer.js",
- "line": 1260,
+ "line": 1930,
"description": "Function that starts or listens the data transfer status to Peer.\nThis reacts differently during MCU environment.",
"itemtype": "method",
"name": "_startDataTransferToPeer",
@@ -2142,25 +2438,25 @@
},
{
"file": "source/data-transfer.js",
- "line": 1275,
+ "line": 1945,
"description": "Emit event for Peers function.",
"class": "Skylink"
},
{
"file": "source/data-transfer.js",
- "line": 1285,
+ "line": 1955,
"description": "Return error and trigger them if failed before or during data transfers function.",
"class": "Skylink"
},
{
"file": "source/data-transfer.js",
- "line": 1301,
+ "line": 1971,
"description": "Send WRQ protocol to start data transfers.",
"class": "Skylink"
},
{
"file": "source/data-transfer.js",
- "line": 1521,
+ "line": 2209,
"description": "Function that returns the data transfer session.",
"itemtype": "method",
"name": "_getTransferInfo",
@@ -2171,7 +2467,7 @@
},
{
"file": "source/data-transfer.js",
- "line": 1603,
+ "line": 2291,
"description": "Function that returns the compiled data transfer data.",
"itemtype": "method",
"name": "_getTransferData",
@@ -2182,7 +2478,7 @@
},
{
"file": "source/data-transfer.js",
- "line": 1630,
+ "line": 2318,
"description": "Function that handles the data transfers sessions timeouts.",
"itemtype": "method",
"name": "_handleDataTransferTimeoutForPeer",
@@ -2193,13 +2489,13 @@
},
{
"file": "source/data-transfer.js",
- "line": 1674,
+ "line": 2362,
"description": "Emit event for Peers function.",
"class": "Skylink"
},
{
"file": "source/data-transfer.js",
- "line": 1721,
+ "line": 2409,
"description": "Function that handles the data received from Datachannel and\nroutes to the relevant data transfer protocol handler.",
"itemtype": "method",
"name": "_processDataChannelData",
@@ -2210,7 +2506,7 @@
},
{
"file": "source/data-transfer.js",
- "line": 1858,
+ "line": 2585,
"description": "Function that handles the \"WRQ\" data transfer protocol.",
"itemtype": "method",
"name": "_WRQProtocolHandler",
@@ -2221,7 +2517,7 @@
},
{
"file": "source/data-transfer.js",
- "line": 1900,
+ "line": 2728,
"description": "Function that handles the \"ACK\" data transfer protocol.",
"itemtype": "method",
"name": "_ACKProtocolHandler",
@@ -2232,13 +2528,13 @@
},
{
"file": "source/data-transfer.js",
- "line": 1919,
+ "line": 2747,
"description": "Emit event for Peers function.",
"class": "Skylink"
},
{
"file": "source/data-transfer.js",
- "line": 2002,
+ "line": 2830,
"description": "Function that handles the \"MESSAGE\" data transfer protocol.",
"itemtype": "method",
"name": "_MESSAGEProtocolHandler",
@@ -2249,7 +2545,7 @@
},
{
"file": "source/data-transfer.js",
- "line": 2023,
+ "line": 2851,
"description": "Function that handles the \"ERROR\" data transfer protocol.",
"itemtype": "method",
"name": "_ERRORProtocolHandler",
@@ -2260,13 +2556,13 @@
},
{
"file": "source/data-transfer.js",
- "line": 2042,
+ "line": 2870,
"description": "Emit event for Peers function.",
"class": "Skylink"
},
{
"file": "source/data-transfer.js",
- "line": 2074,
+ "line": 2902,
"description": "Function that handles the \"CANCEL\" data transfer protocol.",
"itemtype": "method",
"name": "_CANCELProtocolHandler",
@@ -2277,13 +2573,13 @@
},
{
"file": "source/data-transfer.js",
- "line": 2091,
+ "line": 2919,
"description": "Emit event for Peers function.",
"class": "Skylink"
},
{
"file": "source/data-transfer.js",
- "line": 2123,
+ "line": 2951,
"description": "Function that handles the data transfer chunk received.",
"itemtype": "method",
"name": "_DATAProtocolHandler",
@@ -2371,7 +2667,7 @@
},
{
"file": "source/ice-candidate.js",
- "line": 185,
+ "line": 191,
"description": "Function that buffers the Peer connection ICE candidate when received\n before remote session description is received and set.",
"itemtype": "method",
"name": "_addIceCandidateToQueue",
@@ -2382,7 +2678,7 @@
},
{
"file": "source/ice-candidate.js",
- "line": 209,
+ "line": 215,
"description": "Function that adds all the Peer connection buffered ICE candidates received.\nThis should be called only after the remote session description is received and set.",
"itemtype": "method",
"name": "_addIceCandidateFromQueue",
@@ -2393,7 +2689,7 @@
},
{
"file": "source/ice-candidate.js",
- "line": 241,
+ "line": 248,
"description": "Function that adds the ICE candidate to Peer connection.",
"itemtype": "method",
"name": "_addIceCandidate",
@@ -2581,7 +2877,91 @@
{
"file": "source/peer-connection.js",
"line": 76,
- "description": "
\n For MCU enabled Peer connections with options.mcuUseRenegoRestart set to false\n in the init() method, the restart functionality may differ, you\n may learn more about how to workaround it\n in this article here.\n For restarts with Peers connecting from Android, iOS or C++ SDKs, restarts might not work as written in\n in this article here.\n Note that this functionality should be used when Peer connection stream freezes during a connection.\n For a better user experience for only MCU enabled Peer connections, the functionality is throttled when invoked many\n times in less than the milliseconds interval configured in the init() method.\n
\nFunction that refreshes Peer connections to update with the current streaming.",
+ "description": "
\n Learn more about how ICE works in this\n article here.\n
\nThe list of available Peer connection bundle policies.",
+ "itemtype": "attribute",
+ "name": "BUNDLE_POLICY",
+ "params": [
+ {
+ "name": "MAX_COMPAT",
+ "description": "Value \"max-compat\"\n The value of the bundle policy to generate ICE candidates for each media type\n so each media type flows through different transports.",
+ "type": "String"
+ },
+ {
+ "name": "MAX_BUNDLE",
+ "description": "Value \"max-bundle\"\n The value of the bundle policy to generate ICE candidates for one media type\n so all media type flows through a single transport.",
+ "type": "String"
+ },
+ {
+ "name": "BALANCED",
+ "description": "Value \"balanced\"\n The value of the bundle policy to use MAX_BUNDLE if Peer supports it,\n else fallback to MAX_COMPAT.",
+ "type": "String"
+ },
+ {
+ "name": "NONE",
+ "description": "Value \"none\"\n The value of the bundle policy to not use any media bundle.\n This removes the a=group:BUNDLE line from session descriptions.",
+ "type": "String"
+ }
+ ],
+ "type": "JSON",
+ "readonly": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/peer-connection.js",
+ "line": 107,
+ "description": "
\n Learn more about how ICE works in this\n article here.\n
\nThe list of available Peer connection RTCP mux policies.",
+ "itemtype": "attribute",
+ "name": "RTCP_MUX_POLICY",
+ "params": [
+ {
+ "name": "REQUIRE",
+ "description": "Value \"require\"\n The value of the RTCP mux policy to generate ICE candidates for RTP only and RTCP shares the same ICE candidates.",
+ "type": "String"
+ },
+ {
+ "name": "NEGOTIATE",
+ "description": "Value \"negotiate\"\n The value of the RTCP mux policy to generate ICE candidates for both RTP and RTCP each.",
+ "type": "String"
+ }
+ ],
+ "type": "JSON",
+ "readonly": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/peer-connection.js",
+ "line": 128,
+ "description": "
\n Learn more about how ICE works in this\n article here.\n
\nThe list of available Peer connection certificates cryptographic algorithm to use.",
+ "itemtype": "attribute",
+ "name": "PEER_CERTIFICATE",
+ "params": [
+ {
+ "name": "RSA",
+ "description": "Value \"RSA\"\n The value of the Peer connection certificate algorithm to use RSA-1024.",
+ "type": "String"
+ },
+ {
+ "name": "ECDSA",
+ "description": "Value \"ECDSA\"\n The value of the Peer connection certificate algorithm to use ECDSA.",
+ "type": "String"
+ },
+ {
+ "name": "AUTO",
+ "description": "Value \"AUTO\"\n The value of the Peer connection to use the default certificate generated.",
+ "type": "String"
+ }
+ ],
+ "type": "JSON",
+ "readonly": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/peer-connection.js",
+ "line": 152,
+ "description": "
\n Note that Edge browser does not support renegotiation.\n For MCU enabled Peer connections with options.mcuUseRenegoRestart set to false\n in the init() method, the restart functionality may differ, you\n may learn more about how to workaround it\n in this article here.\n For restarts with Peers connecting from Android, iOS or C++ SDKs, restarts might not work as written in\n in this article here.\n Note that this functionality should be used when Peer connection stream freezes during a connection.\n For a better user experience for only MCU enabled Peer connections, the functionality is throttled when invoked many\n times in less than the milliseconds interval configured in the init() method.\n
\nFunction that refreshes Peer connections to update with the current streaming.",
"itemtype": "method",
"name": "refreshConnection",
"params": [
@@ -2598,6 +2978,26 @@
"optional": true,
"optdefault": "false"
},
+ {
+ "name": "options",
+ "description": "
\n Note that for MCU connections, the bandwidth or googleXBandwidth\n settings will override for all Peers or the current Room connection session settings.
\n The custom Peer configuration settings.",
+ "type": "JSON",
+ "optional": true,
+ "props": [
+ {
+ "name": "bandwidth",
+ "description": "The configuration to set the maximum streaming bandwidth to send to Peers.\n Object signature follows joinRoom() method\n options.bandwidth settings.",
+ "type": "JSON",
+ "optional": true
+ },
+ {
+ "name": "googleXBandwidth",
+ "description": "The configuration to set the experimental google\n video streaming bandwidth sent to Peers.\n Object signature follows joinRoom() method\n options.googleXBandwidth settings.",
+ "type": "JSON",
+ "optional": true
+ }
+ ]
+ },
{
"name": "callback",
"description": "The callback function fired when request has completed.\n Function parameters signature is function (error, success)\n Function request completion is determined by the \n peerRestart event triggering isSelfInitiateRestart parameter payload\n value as true for all Peers targeted for request success.",
@@ -2623,6 +3023,26 @@
"name": "refreshErrors.#peerId",
"description": "The Peer connection refresh error associated\n with the Peer ID defined in #peerId property.\n If #peerId value is \"self\", it means that it is the error when there\n is no Peer connections to refresh with.",
"type": "Error|String"
+ },
+ {
+ "name": "refreshSettings",
+ "description": "The list of Peer connection refresh settings.",
+ "type": "JSON"
+ },
+ {
+ "name": "refreshSettings.#peerId",
+ "description": "The Peer connection refresh settings associated\n with the Peer ID defined in #peerId property.",
+ "type": "JSON"
+ },
+ {
+ "name": "refreshSettings.#peerId.iceRestart",
+ "description": "The flag if ICE restart is enabled for\n this Peer connection refresh session.",
+ "type": "Boolean"
+ },
+ {
+ "name": "refreshSettings.#peerId.customSettings",
+ "description": "The Peer connection custom settings.\n Object signature follows getPeersCustomSettings\n method returned per #peerId object.",
+ "type": "JSON"
}
]
},
@@ -2635,6 +3055,26 @@
"name": "listOfPeers",
"description": "The list of Peer IDs targeted.",
"type": "Array"
+ },
+ {
+ "name": "refreshSettings",
+ "description": "The list of Peer connection refresh settings.",
+ "type": "JSON"
+ },
+ {
+ "name": "refreshSettings.#peerId",
+ "description": "The Peer connection refresh settings associated\n with the Peer ID defined in #peerId property.",
+ "type": "JSON"
+ },
+ {
+ "name": "refreshSettings.#peerId.iceRestart",
+ "description": "The flag if ICE restart is enabled for\n this Peer connection refresh session.",
+ "type": "Boolean"
+ },
+ {
+ "name": "refreshSettings.#peerId.customSettings",
+ "description": "The Peer connection custom settings.\n Object signature follows getPeersCustomSettings\n method returned per #peerId object.",
+ "type": "JSON"
}
]
}
@@ -2650,7 +3090,7 @@
},
{
"file": "source/peer-connection.js",
- "line": 258,
+ "line": 378,
"description": "Function that refresh connections.",
"itemtype": "method",
"name": "_refreshPeerConnection",
@@ -2661,8 +3101,8 @@
},
{
"file": "source/peer-connection.js",
- "line": 335,
- "description": "Function that retrieves Peer connection bandwidth and ICE connection stats.",
+ "line": 464,
+ "description": "
\nNote that this is not well supported in the Edge browser.\n
\nFunction that retrieves Peer connection bandwidth and ICE connection stats.",
"itemtype": "method",
"name": "getConnectionStatus",
"params": [
@@ -2744,7 +3184,18 @@
},
{
"file": "source/peer-connection.js",
- "line": 988,
+ "line": 735,
+ "description": "Function that retrieves Peer connection stats.",
+ "itemtype": "method",
+ "name": "_retrieveStats",
+ "access": "private",
+ "tagname": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/peer-connection.js",
+ "line": 1499,
"description": "Function that starts the Peer connection session.\nRemember to remove previous method of reconnection (re-creating the Peer connection - destroy and create connection).",
"itemtype": "method",
"name": "_addPeer",
@@ -2755,7 +3206,7 @@
},
{
"file": "source/peer-connection.js",
- "line": 1023,
+ "line": 1534,
"description": "Function that re-negotiates a Peer connection.\nRemember to remove previous method of reconnection (re-creating the Peer connection - destroy and create connection).",
"itemtype": "method",
"name": "_restartPeerConnection",
@@ -2766,7 +3217,7 @@
},
{
"file": "source/peer-connection.js",
- "line": 1145,
+ "line": 1685,
"description": "Function that ends the Peer connection session.",
"itemtype": "method",
"name": "_removePeer",
@@ -2777,7 +3228,7 @@
},
{
"file": "source/peer-connection.js",
- "line": 1215,
+ "line": 1785,
"description": "Function that creates the Peer connection.",
"itemtype": "method",
"name": "_createPeerConnection",
@@ -2788,7 +3239,7 @@
},
{
"file": "source/peer-connection.js",
- "line": 1366,
+ "line": 2031,
"description": "Function that handles the _restartPeerConnection scenario\n for MCU enabled Peer connections.\nThis is implemented currently by making the user leave and join the Room again.\nThe Peer ID will not stay the same though.",
"itemtype": "method",
"name": "_restartMCUConnection",
@@ -2799,7 +3250,7 @@
},
{
"file": "source/peer-connection.js",
- "line": 1483,
+ "line": 2179,
"description": "Function that handles the stats tabulation.",
"itemtype": "method",
"name": "_parseConnectionStats",
@@ -2810,7 +3261,7 @@
},
{
"file": "source/peer-connection.js",
- "line": 1503,
+ "line": 2199,
"description": "Function that signals the end-of-candidates flag.",
"itemtype": "method",
"name": "_signalingEndOfCandidates",
@@ -2889,7 +3340,7 @@
},
{
"file": "source/peer-data.js",
- "line": 233,
+ "line": 292,
"description": "Function that gets the list of connected Peers in the Room.",
"itemtype": "method",
"name": "getPeersInRoom",
@@ -2905,7 +3356,7 @@
},
{
"file": "source/peer-data.js",
- "line": 264,
+ "line": 323,
"description": "Function that gets the list of connected Peers Streams in the Room.",
"itemtype": "method",
"name": "getPeersStream",
@@ -2914,14 +3365,78 @@
"type": "JSON"
},
"example": [
- "\n // Example 1: Get the list of currently connected Peers in the same Room\n var streams = skylinkDemo.getPeersStream();"
+ "\n // Example 1: Get the list of current Peers Streams in the same Room\n var streams = skylinkDemo.getPeersStream();"
],
"since": "0.6.16",
"class": "Skylink"
},
{
"file": "source/peer-data.js",
- "line": 327,
+ "line": 386,
+ "description": "Function that gets the current list of connected Peers Datachannel connections in the Room.",
+ "itemtype": "method",
+ "name": "getPeersDatachannels",
+ "return": {
+ "description": "The list of Peers Stream.
\n
#peerId{JSON}
The Peer Datachannels information.
\n
#channelName{JSON}
The Datachannel information.
\n
channelName{String}
The Datachannel ID..
\n
channelType{String}
The Datachannel type.\n [Rel: Skylink.DATA_CHANNEL_TYPE]
\n
channelProp{String}
The Datachannel property.
\n
currentTransferId{String}
The Datachannel connection\n current progressing transfer session. Defined as null when there is\n currently no transfer session progressing on the Datachannel connection.
\n
currentStreamId{String}
The Datachannel connection\n current data streaming session ID. Defined as null when there is currently\n no data streaming session on the Datachannel connection.
\n
readyState{String}
The Datachannel connection readyState.\n [Rel: Skylink.DATA_CHANNEL_STATE]
\n
bufferedAmountLow{Number}
The Datachannel buffered amount.
\n
bufferedAmountLowThreshold{Number}
The Datachannel\n buffered amount threshold.
\n
",
+ "type": "JSON"
+ },
+ "example": [
+ "\n // Example 1: Get the list of current Peers Datachannels in the same Room\n var channels = skylinkDemo.getPeersDatachannels();"
+ ],
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/peer-data.js",
+ "line": 442,
+ "description": "Function that gets the list of current data transfers.",
+ "itemtype": "method",
+ "name": "getCurrentDataTransfers",
+ "return": {
+ "description": "The list of Peers Stream.
\n
#transferId{JSON}
The data transfer session.
\n
transferInfo{JSON}
The data transfer information.\n Object signature matches the transferInfo parameter payload received in the\n dataTransferState event\n except without the data property.
\n
peerId{String}
The sender Peer ID.
\n
isSelf{Boolean}
The flag if Peer is User.
\n
",
+ "type": "JSON"
+ },
+ "example": [
+ "\n // Example 1: Get the list of current data transfers in the same Room\n var currentTransfers = skylinkDemo.getCurrentDataTransfers();"
+ ],
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/peer-data.js",
+ "line": 480,
+ "description": "Function that gets the list of current data streaming sessions.",
+ "itemtype": "method",
+ "name": "getCurrentDataStreamsSession",
+ "return": {
+ "description": "The list of Peers Stream.
\n
#streamId{JSON}
The data streaming session.
\n
streamInfo{JSON}
The data streaming information.\n Object signature matches the streamInfo parameter payload received in the\n dataStreamState event\n except without the chunk amd chunkSize property.
\n
peerId{String}
The sender Peer ID.
\n
isSelf{Boolean}
The flag if Peer is User.
\n
",
+ "type": "JSON"
+ },
+ "example": [
+ "\n // Example 1: Get the list of current data streaming sessions in the same Room\n var currentDataStreams = skylinkDemo.getCurrentDataStreamsSession();"
+ ],
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/peer-data.js",
+ "line": 524,
+ "description": "Function that gets the list of current custom Peer settings sent and set.",
+ "itemtype": "method",
+ "name": "getPeerCustomSettings",
+ "return": {
+ "description": "The list of Peers custom settings sent and set.
\n
#peerId{JSON}
The Peer settings sent and set.
\n
settings{JSON}
The custom Peer settings.\n Object signature matches the peerInfo.settings parameter payload received in the\n peerJoined event.
\n
mediaStatus{JSON}
The custom Peer Stream muted settings.\n Object signature matches the peerInfo.mediaStatus parameter payload received in the\n peerJoined event.
",
+ "type": "JSON"
+ },
+ "example": [
+ "\n // Example 1: Get the list of current Peer custom settings\n var currentPeerSettings = skylinkDemo.getPeersCustomSettings();"
+ ],
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/peer-data.js",
+ "line": 646,
"description": "Function that returns the User session information to be sent to Peers.",
"itemtype": "method",
"name": "_getUserInfo",
@@ -2981,7 +3496,7 @@
},
{
"file": "source/peer-handshake.js",
- "line": 138,
+ "line": 126,
"description": "Function that creates the Peer connection answer session description.\nThis comes after receiving and setting the offer session description.",
"itemtype": "method",
"name": "_doAnswer",
@@ -2992,7 +3507,7 @@
},
{
"file": "source/peer-handshake.js",
- "line": 183,
+ "line": 182,
"description": "Function that sets the local session description and sends to Peer.\nIf trickle ICE is disabled, the local session description will be sent after\n ICE gathering has been completed.",
"itemtype": "method",
"name": "_setLocalAndSendMessage",
@@ -3245,6 +3760,13 @@
"type": "Boolean|JSON",
"optional": true
},
+ {
+ "name": "voiceActivityDetection",
+ "description": "The flag if voice activity detection should be enabled.\n This can only be toggled if User is and for the offerer, which is determined if User's\n peerInfo.config.priorityWeight is higher than Peer's.\n
\n This works hand-in-hand with the options.disableComfortNoiseCodec flag in the\n init() method and the options.audio.usedtx setting in\n getUserMedia() method. VAD (voice activity detection)\n detects if there is an active voice in the Stream, and if there is no active voice in the Stream, the\n options.audio.usedtx (if enabled) would prevent sending these empty bits. To prevent huge differences\n when there is a silence and an active voice later, the CN codec would produce an empty voice to\n make it sound better.
Note that this is currently not supported\n with Firefox browsers versions 48 and below as noted in an existing\n bugzilla ticket here.
\n The configuration to set the maximum streaming bandwidth to send to Peers.",
@@ -3386,11 +3908,80 @@
"props": [
{
"name": "parentId",
- "description": "The parent Peer ID to match to when Peer is connected.\n This is useful for identification for users connecting the Room twice simultaneously for multi-streaming.",
+ "description": "
Deprecation Warning!\n This property has been deprecated. Use options.parentId instead.\n
The parent Peer ID to match to when Peer is connected.\n This is useful for identification for users connecting the Room twice simultaneously for multi-streaming.\n If User Peer ID matches the parent Peer ID provided from Peer, User will not be connected to Peer.",
+ "type": "String",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "parentId",
+ "description": "The parent Peer ID to match to when Peer is connected.\n Note that configuring this value overrides the options.publishOnly.parentId value.\n This is useful for identification for users connecting the Room twice simultaneously for multi-streaming.\n If User Peer ID matches the parent Peer ID provided from Peer, User will not be connected to Peer.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "peerConnection",
+ "description": "
\n Note that this is mainly used for debugging purposes, so it may cause disruptions in connections or\n connectivity issues when configured.
The Peer connection constraints settings.",
+ "type": "JSON",
+ "optional": true,
+ "props": [
+ {
+ "name": "bundlePolicy",
+ "description": "The Peer connection media bundle policy.\n- When not provided, its value is BALANCED.\n [Rel: Skylink.BUNDLE_POLICY]",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "rtcpMuxPolicy",
+ "description": "The Peer connection RTP and RTCP ICE candidates mux policy.\n- When not provided, its value is REQUIRE.\n [Rel: Skylink.RTCP_MUX_POLICY]",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "iceCandidatePoolSize",
+ "description": "The number of ICE candidates to gather before\n gathering it when setting local offer / answer session description.",
+ "type": "Number",
+ "optional": true,
+ "optdefault": "0"
+ },
+ {
+ "name": "certificate",
+ "description": "The type of certificate that Peer connection should\n generate and use when available.\n- When not provided, its value is AUTO.\n [Rel: Skylink.PEER_CERTIFICATE]",
"type": "String",
"optional": true
}
]
+ },
+ {
+ "name": "autoBandwidthAdjustment",
+ "description": "
\n Note that this is an experimental feature which may be removed or changed in the future releases.\n This feature is also only available for non-MCU enabled Peer connections and Edge Peer connections.\n
The flag if Peer connections uploading and downloading bandwidth should be automatically adjusted\n each time based on a specified interval.\n Note this would cause peerRestart event to be triggered\n for each specified interval.",
+ "type": "Boolean|JSON",
+ "optional": true,
+ "optdefault": "false",
+ "props": [
+ {
+ "name": "interval",
+ "description": "The interval each time to adjust bandwidth\n connections in seconds.\n Note that the minimum value is 10.",
+ "type": "Number",
+ "optional": true,
+ "optdefault": "10"
+ },
+ {
+ "name": "limitAtPercentage",
+ "description": "The percentage of the average bandwidth to adjust to.\n E.g. avgBandwidth * (limitPercentage / 100).",
+ "type": "Number",
+ "optional": true,
+ "optdefault": "100"
+ },
+ {
+ "name": "useUploadBwOnly",
+ "description": "The flag if average bandwidth computation\n should only consist of the upload bandwidth.",
+ "type": "Boolean",
+ "optional": true,
+ "optdefault": "false"
+ }
+ ]
}
]
},
@@ -3457,7 +4048,7 @@
},
{
"file": "source/room-connection.js",
- "line": 430,
+ "line": 477,
"description": "
\n Note that this method will close any existing socket channel connection despite not being in the Room.\n
\nFunction that locks the current Room when in session to prevent other Peers from joining the Room.",
"itemtype": "method",
"name": "lockRoom",
@@ -3532,7 +4123,7 @@
},
{
"file": "source/room-connection.js",
- "line": 576,
+ "line": 627,
"description": "
\nFunction that unlocks the current Room when in session to allow other Peers to join the Room.",
"itemtype": "method",
"name": "unlockRoom",
@@ -3542,7 +4133,7 @@
},
{
"file": "source/room-connection.js",
- "line": 605,
+ "line": 661,
"description": "Function that waits for Socket connection to Signaling to be opened.",
"itemtype": "method",
"name": "_waitForOpenChannel",
@@ -3681,6 +4272,11 @@
"name": "ADAPTER_NO_LOADED",
"description": "Value 7\n The value of the failure code when dependency AdapterJS\n is not loaded.\n To resolve this, ensure that the AdapterJS dependency is loaded before the Skylink dependency.\n You may use the provided AdapterJS CDN here.",
"type": "Number"
+ },
+ {
+ "name": "PARSE_CODECS",
+ "description": "Value 8\n The value of the failure code when codecs support cannot be parsed and retrieved.",
+ "type": "Number"
}
],
"type": "JSON",
@@ -3690,7 +4286,7 @@
},
{
"file": "source/room-init.js",
- "line": 137,
+ "line": 140,
"description": "Spoofs the REGIONAL_SERVER to prevent errors on deployed apps except the fact this no longer works.\nAutomatic regional selection has already been implemented hence REGIONAL_SERVER is no longer useful.",
"itemtype": "attribute",
"name": "REGIONAL_SERVER",
@@ -3703,7 +4299,35 @@
},
{
"file": "source/room-init.js",
- "line": 152,
+ "line": 155,
+ "description": "The list of User's priority weight schemes for \njoinRoom() method connections.",
+ "itemtype": "attribute",
+ "name": "PRIORITY_WEIGHT_SCHEME",
+ "params": [
+ {
+ "name": "ENFORCE_OFFERER",
+ "description": "Value \"enforceOfferer\"\n The value of the priority weight scheme to enforce User as the offerer.",
+ "type": "String"
+ },
+ {
+ "name": "ENFORCE_ANSWERER",
+ "description": "Value \"enforceAnswerer\"\n The value of the priority weight scheme to enforce User as the answerer.",
+ "type": "String"
+ },
+ {
+ "name": "AUTO",
+ "description": "Value \"auto\"\n The value of the priority weight scheme to let User be offerer or answerer based on Signaling server selection.",
+ "type": "String"
+ }
+ ],
+ "type": "JSON",
+ "readonly": "",
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/room-init.js",
+ "line": 176,
"description": "Function that generates an UUID (Unique ID).",
"itemtype": "method",
"name": "generateUUID",
@@ -3716,7 +4340,7 @@
},
{
"file": "source/room-init.js",
- "line": 171,
+ "line": 195,
"description": "Function that authenticates and initialises App Key used for Room connections.",
"itemtype": "method",
"name": "init",
@@ -3739,7 +4363,7 @@
},
{
"name": "roomServer",
- "description": "The Auth server.\nNote that this is a debugging feature and is only used when instructed for debugging purposes.",
+ "description": "The Auth server for debugging purposes to use.\n Note that this is a debugging feature and is only used when instructed for debugging purposes.",
"type": "String",
"optional": true
},
@@ -3766,7 +4390,7 @@
},
{
"name": "enableSTUNServer",
- "description": "
\n Note that for Edge browsers, this value is overriden as false due to its supports.\n
The flag if STUN ICE servers should\n be used when constructing Peer connections to allow TURN connections when required.",
+ "description": "The flag if STUN ICE servers should\n be used when constructing Peer connections to allow TURN connections when required.",
"type": "Boolean",
"optional": true,
"optdefault": "true"
@@ -3852,18 +4476,50 @@
{
"name": "audioCodec",
"description": "
\n Note that if the audio codec is not supported, the SDK will not configure the local \"offer\" or\n \"answer\" session description to prefer the codec. \n Note that for Edge browsers, this value is set as OPUS due to its supports.
\n The option to configure the preferred audio codec to use to encode sending audio data when available for Peer connection.\n- When not provided, its value is AUTO.\n [Rel: Skylink.AUDIO_CODEC]",
- "type": "String",
- "optional": true
+ "type": "String|JSON",
+ "optional": true,
+ "props": [
+ {
+ "name": "codec",
+ "description": "The audio codec to prefer to encode sending audio data when available.\n The value must not be AUTO.\n [Rel: Skylink.AUDIO_CODEC]",
+ "type": "String"
+ },
+ {
+ "name": "samplingRate",
+ "description": "The audio codec sampling to prefer to encode sending audio data when available.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "channels",
+ "description": "The audio codec channels to prefer to encode sending audio data when available.",
+ "type": "Number",
+ "optional": true
+ }
+ ]
},
{
"name": "videoCodec",
"description": "
\n Note that if the video codec is not supported, the SDK will not configure the local \"offer\" or\n \"answer\" session description to prefer the codec. \n Note that for Edge browsers, this value is set as H264 due to its supports.
\n The option to configure the preferred video codec to use to encode sending video data when available for Peer connection.\n- When not provided, its value is AUTO.\n [Rel: Skylink.VIDEO_CODEC]",
- "type": "String",
- "optional": true
+ "type": "String|JSON",
+ "optional": true,
+ "props": [
+ {
+ "name": "codec",
+ "description": "The video codec to prefer to encode sending audio data when available.\n The value must not be AUTO.\n [Rel: Skylink.VIDEO_CODEC]",
+ "type": "String"
+ },
+ {
+ "name": "samplingRate",
+ "description": "The video codec sampling to prefer to encode sending video data when available.",
+ "type": "Number",
+ "optional": true
+ }
+ ]
},
{
"name": "socketTimeout",
- "description": "The timeout for each attempts for socket connection\n with the Signaling server to indicate that connection has timed out and has failed to establish.\n Note that the mininum timeout value is 5000. If less, this value will be 5000.",
+ "description": "The timeout for each attempts for socket connection\n with the Signaling server to indicate that connection has timed out and has failed to establish.\n Note that the mininum timeout value is 5000. If less, this value will be 5000.\n Note that it is recommended to use 12000 as the lowest timeout value if Peers are connecting\n using Polling transports to prevent connection errors.",
"type": "Number",
"optional": true,
"optdefault": "20000"
@@ -3946,6 +4602,172 @@
"type": "Boolean",
"optional": true,
"optdefault": "false"
+ },
+ {
+ "name": "iceServer",
+ "description": "The ICE servers for debugging purposes to use.\n - When defined as string, the value is considered as [options.iceServer].\n Note that this is a debugging feature and is only used when instructed for debugging purposes.",
+ "type": "String|Array",
+ "optional": true,
+ "props": [
+ {
+ "name": "#index",
+ "description": "The ICE server url for debugging purposes to use.",
+ "type": "String",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "socketServer",
+ "description": "The Signaling server for debugging purposes to use.\n - When defined as string, the value is considered as { url: options.socketServer }.\n Note that this is a debugging feature and is only used when instructed for debugging purposes.",
+ "type": "String|JSON",
+ "optional": true,
+ "props": [
+ {
+ "name": "url",
+ "description": "The Signaling server URL for debugging purposes to use.",
+ "type": "String"
+ },
+ {
+ "name": "ports",
+ "description": "The list of Signaling server ports for debugging purposes to use.\n If not defined, it will use the default list of ports specified.",
+ "type": "Array",
+ "optional": true
+ },
+ {
+ "name": "ports.#index",
+ "description": "The Signaling server port to fallback and use for debugging purposes.",
+ "type": "Number"
+ },
+ {
+ "name": "protocol",
+ "description": "The Signaling server protocol for debugging purposes to use.\n If not defined, it will use the default protocol specified.",
+ "type": "String",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "codecParams",
+ "description": "
\n Note that some of these parameters are mainly used for experimental or debugging purposes. Toggling any of\n these feature may result in disruptions in connectivity.
\n The audio and video codecs parameters to configure.",
+ "type": "JSON",
+ "optional": true,
+ "props": [
+ {
+ "name": "video",
+ "description": "The video codecs parameters to configure.",
+ "type": "JSON",
+ "optional": true
+ },
+ {
+ "name": "video.h264",
+ "description": "The H264 video codec parameters to configure.",
+ "type": "JSON",
+ "optional": true
+ },
+ {
+ "name": "video.h264.profileLevelId",
+ "description": "
\n Note that this parameter should only be used for debugging purposes only.
\n The H264 video codec base16 encoded string which indicates the H264 baseline, main, or the extended profiles.\n When not provided, the default browser configuration is used.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "video.h264.levelAsymmetryAllowed",
+ "description": "
\n Note that this is an experimental parameter which may result in connectivity issues when toggled.
\n The flag if streaming H264 sending video data should be encoded at a different level\n from receiving video data from Peer encoding to User when Peer is the offerer.\n If Peer is the offerer instead of the User, the Peer's peerInfo.config.priorityWeight will be\n higher than User's peerInfo.config.priorityWeight.\n When not provided, the default browser configuration is used.",
+ "type": "Boolean",
+ "optional": true
+ },
+ {
+ "name": "video.h264.packetizationMode",
+ "description": "
\n Note that this is an experimental parameter which may result in connectivity issues when enabled. It is\n advisable to turn off this feature off when receiving H264 decoders do not support the packetization mode,\n which may result in a blank receiving video stream.
\n The flag to enable H264 video codec packetization mode, which splits video frames that are larger\n for a RTP packet into RTP packet chunks.\n When not provided, the default browser configuration is used.",
+ "type": "Boolean",
+ "optional": true
+ },
+ {
+ "name": "video.vp8",
+ "description": "The VP8 video codec parameters to configure.",
+ "type": "JSON",
+ "optional": true
+ },
+ {
+ "name": "video.vp8.maxFr",
+ "description": "
\n Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
\n The maximum number of fps (frames per second) that the VP8 video codec decoder is capable of\n decoding when receiving encoded video data packets.\n When not provided, the default browser configuration is used.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "video.vp8.maxFs",
+ "description": "
\n Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
\n The maximum number of frame size macroblocks that the VP8 video codec decoder is capable of\n decoding when receiving encoded video data packets.\n The value has to have the width and height of the frame in macroblocks less than the value of\n parseInt(Math.sqrt(maxFs * 8)). E.g. If the value is 1200, it is capable of\n support 640x480 frame width and height, which heights up to 1552px\n (97 macroblocks value.\n When not provided, the default browser configuration is used.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "video.vp9",
+ "description": "The VP9 video codec parameters to configure.",
+ "type": "JSON",
+ "optional": true
+ },
+ {
+ "name": "video.vp9.maxFr",
+ "description": "
\n Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
\n The maximum number of fps (frames per second) that the VP9 video codec decoder is capable of\n decoding when receiving encoded video data packets.\n When not provided, the default browser configuration is used.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "video.vp9.maxFs",
+ "description": "
\n Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
\n The maximum number of frame size macroblocks that the VP9 video codec decoder is capable of\n decoding when receiving encoded video data packets.\n The value has to have the width and height of the frame in macroblocks less than the value of\n parseInt(Math.sqrt(maxFs * 8)). E.g. If the value is 1200, it is capable of\n support 640x480 frame width and height, which heights up to 1552px\n (97 macroblocks value.\n When not provided, the default browser configuration is used.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "audio",
+ "description": "The audio codecs parameters to configure.",
+ "type": "JSON",
+ "optional": true
+ },
+ {
+ "name": "audio.opus",
+ "description": "
\n Note that this is only applicable to OPUS audio codecs with a sampling rate of 48000 Hz (hertz).\n
The OPUS audio codec parameters to configure.",
+ "type": "JSON",
+ "optional": true
+ },
+ {
+ "name": "audio.opus.stereo",
+ "description": "The flag if OPUS audio codec stereo band\n should be configured for sending encoded audio data.\n When not provided, the default browser configuration is used.",
+ "type": "Boolean",
+ "optional": true
+ },
+ {
+ "name": "audio.opus.usedtx",
+ "description": "
\n Note that this feature might not work depending on the browser support and implementation.
\n The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.\n This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and\n goes hand-in-hand with the options.voiceActivityDetection flag in \n joinRoom() method.\n When not provided, the default browser configuration is used.",
+ "type": "Boolean",
+ "optional": true
+ },
+ {
+ "name": "audio.opus.useinbandfec",
+ "description": "
\n Note that this parameter should only be used for debugging purposes only.
\n The flag if OPUS audio codec has the capability to take advantage of the in-band FEC\n (Forward Error Correction) when sending encoded audio data.\n This helps to reduce the harm of packet loss by encoding information about the previous packet loss.\n When not provided, the default browser configuration is used.",
+ "type": "Boolean",
+ "optional": true
+ },
+ {
+ "name": "audio.opus.maxplaybackrate",
+ "description": "
\n Note that this parameter should only be used for debugging purposes only.
\n The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving\n decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data\n would not encode at a higher sampling rate specified by this.\n This value must be between 8000 to 48000.\n When not provided, the default browser configuration is used.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "minptime",
+ "description": "
\n Note that this parameter should only be used for debugging purposes only.
\n The OPUS audio codec receiving audio data decoder minimum length of time in milleseconds should be\n encapsulated in a single received encoded audio data packet.\n This value must be between 3 to 120\n When not provided, the default browser configuration is used.",
+ "type": "Number",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "priorityWeightScheme",
+ "description": "
\n Note that this parameter should only be used for debugging purposes only and may not work when\n internals change.
The User's priority weight to enforce User as offerer or answerer.\n- When not provided, its value is AUTO.\n [Rel: Skylink.PRIORITY_WEIGHT_SCHEME]",
+ "type": "String",
+ "optional": true
}
]
},
@@ -3968,7 +4790,7 @@
{
"name": "error",
"description": "The readyStateChange\n eventerror.content parameter payload value.",
- "type": "Object"
+ "type": "Error|String"
},
{
"name": "status",
@@ -3990,7 +4812,7 @@
{
"name": "readyState",
"description": "The current ready state.\n [Rel: Skylink.READY_STATE_CHANGE]",
- "type": "String"
+ "type": "Number"
},
{
"name": "selectedRoom",
@@ -4050,12 +4872,12 @@
{
"name": "audioCodec",
"description": "The configured value of the options.audioCodec.",
- "type": "String"
+ "type": "String|JSON"
},
{
"name": "videoCodec",
"description": "The configured value of the options.videoCodec.",
- "type": "String"
+ "type": "String|JSON"
},
{
"name": "socketTimeout",
@@ -4100,17 +4922,27 @@
{
"name": "throttleIntervals",
"description": "The configured value of the options.throttleIntervals.",
- "type": "Number"
+ "type": "JSON"
},
{
"name": "throttleShouldThrowError",
"description": "The configured value of the options.throttleShouldThrowError.",
- "type": "Number"
+ "type": "Boolean"
},
{
"name": "mcuUseRenegoRestart",
"description": "The configured value of the options.mcuUseRenegoRestart.",
- "type": "Number"
+ "type": "JSON"
+ },
+ {
+ "name": "iceServer",
+ "description": "The configured value of the options.iceServer.\n See the .urls property in this object for configured value if defined.",
+ "type": "JSON"
+ },
+ {
+ "name": "socketServer",
+ "description": "The configured value of the options.socketServer.",
+ "type": "JSON|String"
}
]
}
@@ -4126,7 +4958,7 @@
},
{
"file": "source/room-init.js",
- "line": 751,
+ "line": 1055,
"description": "Starts retrieving Room credentials information from API server.",
"itemtype": "method",
"name": "_requestServerInfo",
@@ -4137,7 +4969,7 @@
},
{
"file": "source/room-init.js",
- "line": 825,
+ "line": 1129,
"description": "Parses the Room credentials information retrieved from API server.",
"itemtype": "method",
"name": "_parseInfo",
@@ -4148,7 +4980,7 @@
},
{
"file": "source/room-init.js",
- "line": 898,
+ "line": 1199,
"description": "Loads and checks the dependencies if they are loaded correctly.",
"itemtype": "method",
"name": "_loadInfo",
@@ -4159,7 +4991,7 @@
},
{
"file": "source/room-init.js",
- "line": 991,
+ "line": 1330,
"description": "Starts initialising for Room credentials for room name provided in joinRoom() method.",
"itemtype": "method",
"name": "_initSelectedRoom",
@@ -4526,21 +5358,62 @@
"description": "Event triggered when socket connection to Signaling server has opened.",
"itemtype": "event",
"name": "channelOpen",
+ "params": [
+ {
+ "name": "session",
+ "description": "The socket connection session information.",
+ "type": "JSON",
+ "props": [
+ {
+ "name": "serverUrl",
+ "description": "The socket connection Signaling url used.",
+ "type": "String"
+ },
+ {
+ "name": "transportType",
+ "description": "The socket connection transport type used.",
+ "type": "String"
+ },
+ {
+ "name": "socketOptions",
+ "description": "The socket connection options.",
+ "type": "JSON"
+ },
+ {
+ "name": "attempts",
+ "description": "The socket connection current reconnection attempts.",
+ "type": "Number"
+ },
+ {
+ "name": "finalAttempts",
+ "description": "The socket connection current last attempts\n for the last available transports and port.",
+ "type": "Number"
+ }
+ ]
+ }
+ ],
"since": "0.1.0",
"class": "Skylink"
},
{
"file": "source/skylink-events.js",
- "line": 10,
+ "line": 17,
"description": "Event triggered when socket connection to Signaling server has closed.",
"itemtype": "event",
"name": "channelClose",
+ "params": [
+ {
+ "name": "session",
+ "description": "The socket connection session information.\n Object signature matches the session parameter payload received in the\n channelOpen event.",
+ "type": "JSON"
+ }
+ ],
"since": "0.1.0",
"class": "Skylink"
},
{
"file": "source/skylink-events.js",
- "line": 18,
+ "line": 28,
"description": "
\n Note that this is used only for SDK developer purposes.\n
\nEvent triggered when receiving socket message from the Signaling server.",
"itemtype": "event",
"name": "channelMessage",
@@ -4549,6 +5422,11 @@
"name": "message",
"description": "The socket message object.",
"type": "JSON"
+ },
+ {
+ "name": "session",
+ "description": "The socket connection session information.\n Object signature matches the session parameter payload received in the\n channelOpen event.",
+ "type": "JSON"
}
],
"since": "0.1.0",
@@ -4556,7 +5434,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 30,
+ "line": 43,
"description": "
\n This may be caused by Javascript errors in the event listener when subscribing to events. \n It may be resolved by checking for code errors in your Web App in the event subscribing listener. \n skylinkDemo.on(\"eventName\", function () { // Errors here });\n
\nEvent triggered when socket connection encountered exception.",
"itemtype": "event",
"name": "channelError",
@@ -4565,6 +5443,11 @@
"name": "error",
"description": "The error object.",
"type": "Error|String"
+ },
+ {
+ "name": "session",
+ "description": "The socket connection session information.\n Object signature matches the session parameter payload received in the\n channelOpen event.",
+ "type": "JSON"
}
],
"since": "0.1.0",
@@ -4572,7 +5455,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 44,
+ "line": 60,
"description": "Event triggered when attempting to establish socket connection to Signaling server when failed.",
"itemtype": "event",
"name": "channelRetry",
@@ -4584,8 +5467,13 @@
},
{
"name": "currentAttempt",
- "description": "The current reconnection attempt.",
+ "description": "The current socket reconnection attempt.",
"type": "Number"
+ },
+ {
+ "name": "session",
+ "description": "The socket connection session information.\n Object signature matches the session parameter payload received in the\n channelOpen event.",
+ "type": "JSON"
}
],
"since": "0.5.6",
@@ -4593,7 +5481,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 55,
+ "line": 74,
"description": "Event triggered when attempt to establish socket connection to Signaling server has failed.",
"itemtype": "event",
"name": "socketError",
@@ -4612,6 +5500,11 @@
"name": "type",
"description": "The fallback state of the socket connection attempt.\n [Rel: Skylink.SOCKET_FALLBACK]",
"type": "String"
+ },
+ {
+ "name": "session",
+ "description": "The socket connection session information.\n Object signature matches the session parameter payload received in the\n channelOpen event.",
+ "type": "JSON"
}
],
"since": "0.5.5",
@@ -4619,7 +5512,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 68,
+ "line": 90,
"description": "Event triggered when init() method ready state changes.",
"itemtype": "event",
"name": "readyStateChange",
@@ -4663,7 +5556,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 85,
+ "line": 107,
"description": "Event triggered when a Peer connection establishment state has changed.",
"itemtype": "event",
"name": "handshakeProgress",
@@ -4690,7 +5583,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 98,
+ "line": 120,
"description": "
\n Learn more about how ICE works in this\n article here.\n
\nEvent triggered when a Peer connection ICE gathering state has changed.",
"itemtype": "event",
"name": "candidateGenerationState",
@@ -4711,7 +5604,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 113,
+ "line": 135,
"description": "
\n Learn more about how ICE works in this\n article here.\n
\nEvent triggered when a Peer connection session description exchanging state has changed.",
"itemtype": "event",
"name": "peerConnectionState",
@@ -4732,7 +5625,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 128,
+ "line": 150,
"description": "
\n Learn more about how ICE works in this\n article here.\n
\nEvent triggered when a Peer connection ICE connection state has changed.",
"itemtype": "event",
"name": "iceConnectionState",
@@ -4753,7 +5646,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 143,
+ "line": 165,
"description": "Event triggered when retrieval of Stream failed.",
"itemtype": "event",
"name": "mediaAccessError",
@@ -4779,7 +5672,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 158,
+ "line": 180,
"description": "Event triggered when Stream retrieval fallback state has changed.",
"itemtype": "event",
"name": "mediaAccessFallback",
@@ -4861,7 +5754,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 186,
+ "line": 208,
"description": "Event triggered when retrieval of Stream is successful.",
"itemtype": "event",
"name": "mediaAccessSuccess",
@@ -4892,7 +5785,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 203,
+ "line": 225,
"description": "Event triggered when retrieval of Stream is required to complete \njoinRoom() method request.",
"itemtype": "event",
"name": "mediaAccessRequired",
@@ -4901,7 +5794,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 212,
+ "line": 234,
"description": "Event triggered when Stream has stopped streaming.",
"itemtype": "event",
"name": "mediaAccessStopped",
@@ -4927,7 +5820,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 227,
+ "line": 249,
"description": "Event triggered when a Peer joins the room.",
"itemtype": "event",
"name": "peerJoined",
@@ -4952,6 +5845,11 @@
"description": "The Peer sending Stream settings.",
"type": "JSON",
"props": [
+ {
+ "name": "data",
+ "description": "The flag if Peer has any Datachannel connections enabled.\n If isSelf value is true, this determines if User allows\n Datachannel connections, else if value is false, this determines if Peer has any active\n Datachannel connections (where dataChannelState event\n triggers state as OPEN and channelType as\n MESSAGING for Peer) with Peer.",
+ "type": "Boolean|JSON"
+ },
{
"name": "audio",
"description": "The Peer Stream audio settings.\n When defined as false, it means there is no audio being sent from Peer.\n When defined as true, the peerInfo.settings.audio.stereo value is\n considered as false and the peerInfo.settings.audio.exactConstraints\n value is considered as false.",
@@ -5142,6 +6040,16 @@
"description": "The Peer Temasys Plugin version.\n Defined only when Peer is using the Temasys Plugin (IE / Safari).",
"type": "String",
"optional": true
+ },
+ {
+ "name": "DTProtocolVersion",
+ "description": "The Peer data transfer (DT) protocol version.",
+ "type": "String"
+ },
+ {
+ "name": "SMProtocolVersion",
+ "description": "The Peer signaling message (SM) protocol version.",
+ "type": "String"
}
]
},
@@ -5206,7 +6114,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 340,
+ "line": 370,
"description": "Event triggered when a Peer connection has been refreshed.",
"itemtype": "event",
"name": "peerRestart",
@@ -5237,7 +6145,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 354,
+ "line": 384,
"description": "Event triggered when a Peer session information has been updated.",
"itemtype": "event",
"name": "peerUpdated",
@@ -5263,7 +6171,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 367,
+ "line": 397,
"description": "Event triggered when a Peer leaves the room.",
"itemtype": "event",
"name": "peerLeft",
@@ -5289,7 +6197,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 380,
+ "line": 410,
"description": "Event triggered when Room session has ended abruptly due to network disconnections.",
"itemtype": "event",
"name": "sessionDisconnect",
@@ -5310,7 +6218,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 392,
+ "line": 422,
"description": "Event triggered when receiving Peer Stream.",
"itemtype": "event",
"name": "incomingStream",
@@ -5351,7 +6259,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 409,
+ "line": 439,
"description": "Event triggered when receiving message from Peer.",
"itemtype": "event",
"name": "incomingMessage",
@@ -5416,7 +6324,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 440,
+ "line": 470,
"description": "Event triggered when receiving completed data transfer from Peer.",
"itemtype": "event",
"name": "incomingData",
@@ -5438,7 +6346,7 @@
},
{
"name": "transferInfo",
- "description": "The data transfer information.\n Object signature matches the transferInfo parameter payload received in the\n dataTransferState event.",
+ "description": "The data transfer information.\n Object signature matches the transferInfo parameter payload received in the\n dataTransferState event\n except without the data property.",
"type": "JSON"
},
{
@@ -5452,7 +6360,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 456,
+ "line": 486,
"description": "Event triggered when receiving upload data transfer from Peer.",
"itemtype": "event",
"name": "incomingDataRequest",
@@ -5469,7 +6377,7 @@
},
{
"name": "transferInfo",
- "description": "The data transfer information.\n Object signature matches the transferInfo parameter payload received in the\n dataTransferState event.",
+ "description": "The data transfer information.\n Object signature matches the transferInfo parameter payload received in the\n dataTransferState event\n except without the data property.",
"type": "String"
},
{
@@ -5483,7 +6391,108 @@
},
{
"file": "source/skylink-events.js",
- "line": 470,
+ "line": 501,
+ "description": "Event triggered when data streaming session has been started from Peer to User.",
+ "itemtype": "event",
+ "name": "incomingDataStreamStarted",
+ "params": [
+ {
+ "name": "streamId",
+ "description": "The data streaming session ID.",
+ "type": "String"
+ },
+ {
+ "name": "peerId",
+ "description": "The Peer ID.",
+ "type": "String"
+ },
+ {
+ "name": "streamInfo",
+ "description": "The data streaming session information.\n Object signature matches the streamInfo parameter payload received in the\n dataStreamState event\n except without the chunk property.",
+ "type": "JSON"
+ },
+ {
+ "name": "isSelf",
+ "description": "The flag if Peer is User.",
+ "type": "Boolean"
+ }
+ ],
+ "beta": 1,
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/skylink-events.js",
+ "line": 517,
+ "description": "Event triggered when data streaming session has been stopped from Peer to User.",
+ "itemtype": "event",
+ "name": "incomingDataStreamStopped",
+ "params": [
+ {
+ "name": "streamId",
+ "description": "The data streaming session ID.",
+ "type": "String"
+ },
+ {
+ "name": "peerId",
+ "description": "The Peer ID.",
+ "type": "String"
+ },
+ {
+ "name": "streamInfo",
+ "description": "The data streaming session information.\n Object signature matches the streamInfo parameter payload received in the\n dataStreamState event\n except without the chunk property.",
+ "type": "JSON"
+ },
+ {
+ "name": "isSelf",
+ "description": "The flag if Peer is User.",
+ "type": "Boolean"
+ }
+ ],
+ "beta": 1,
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/skylink-events.js",
+ "line": 533,
+ "description": "Event triggered when data streaming session has been stopped from Peer to User.",
+ "itemtype": "event",
+ "name": "incomingDataStream",
+ "params": [
+ {
+ "name": "chunk",
+ "description": "The data chunk received.",
+ "type": "Blob|String"
+ },
+ {
+ "name": "streamId",
+ "description": "The data streaming session ID.",
+ "type": "String"
+ },
+ {
+ "name": "peerId",
+ "description": "The Peer ID.",
+ "type": "String"
+ },
+ {
+ "name": "streamInfo",
+ "description": "The data streaming session information.\n Object signature matches the streamInfo parameter payload received in the\n dataStreamState event\n except without the chunk property.",
+ "type": "JSON"
+ },
+ {
+ "name": "isSelf",
+ "description": "The flag if Peer is User.",
+ "type": "Boolean"
+ }
+ ],
+ "beta": 1,
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/skylink-events.js",
+ "line": 550,
"description": "Event triggered when Room locked status has changed.",
"itemtype": "event",
"name": "roomLock",
@@ -5514,7 +6523,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 484,
+ "line": 564,
"description": "Event triggered when a Datachannel connection state has changed.",
"itemtype": "event",
"name": "dataChannelState",
@@ -5549,6 +6558,23 @@
"name": "messageType",
"description": "The Datachannel sending Datachannel message error type.\n Defined only when state payload is SEND_MESSAGE_ERROR.\n [Rel: Skylink.DATA_CHANNEL_MESSAGE_ERROR]",
"type": "String"
+ },
+ {
+ "name": "bufferAmount",
+ "description": "The Datachannel buffered amount information.",
+ "type": "JSON",
+ "props": [
+ {
+ "name": "bufferedAmountLow",
+ "description": "The size of currently queued data to send on the Datachannel connection.",
+ "type": "Number"
+ },
+ {
+ "name": "bufferedAmountLowThreshold",
+ "description": "The current buffered amount low threshold configured.",
+ "type": "Number"
+ }
+ ]
}
],
"since": "0.1.0",
@@ -5556,7 +6582,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 503,
+ "line": 586,
"description": "Event triggered when a data transfer state has changed.",
"itemtype": "event",
"name": "dataTransferState",
@@ -5568,12 +6594,12 @@
},
{
"name": "transferId",
- "description": "The data transfer ID.",
+ "description": "The data transfer ID.\n Note that this is defined as null when state payload is START_ERROR.",
"type": "String"
},
{
"name": "peerId",
- "description": "The Peer ID.",
+ "description": "The Peer ID.\n Note that this could be defined as null when state payload is\n START_ERROR and there is no Peers to start data transfer with.",
"type": "String"
},
{
@@ -5625,7 +6651,7 @@
},
{
"name": "timeout",
- "description": "The flag if message is targeted or not, basing\n off the targetPeerId parameter being defined in\n sendURLData() method or\n sendBlobData() method.",
+ "description": "The flag if data transfer is targeted or not, basing\n off the targetPeerId parameter being defined in\n sendURLData() method or\n sendBlobData() method.",
"type": "Number"
},
{
@@ -5642,7 +6668,7 @@
},
{
"name": "error",
- "description": "The error result.\n Defined only when state payload is ERROR, CANCEL,\n REJECTED or USER_REJECTED.",
+ "description": "The error result.\n Defined only when state payload is ERROR, CANCEL,\n REJECTED, START_ERROR or USER_REJECTED.",
"type": "JSON",
"optional": true,
"props": [
@@ -5664,7 +6690,78 @@
},
{
"file": "source/skylink-events.js",
- "line": 551,
+ "line": 637,
+ "description": "Event triggered when a data streaming state has changed.",
+ "itemtype": "event",
+ "name": "dataStreamState",
+ "params": [
+ {
+ "name": "state",
+ "description": "The current data streaming state.\n [Rel: Skylink.DATA_STREAM_STATE]",
+ "type": "String"
+ },
+ {
+ "name": "streamId",
+ "description": "The data streaming session ID.\n Note that this is defined as null when state payload is START_ERROR.",
+ "type": "String"
+ },
+ {
+ "name": "peerId",
+ "description": "The Peer ID.\n Note that this could be defined as null when state payload is\n START_ERROR and there is no Peers to start data streaming with.",
+ "type": "String"
+ },
+ {
+ "name": "streamInfo",
+ "description": "The data streaming information.",
+ "type": "JSON",
+ "props": [
+ {
+ "name": "chunk",
+ "description": "The data chunk received.\n Defined only when state payload is RECEIVED or SENT.",
+ "type": "Blob|String",
+ "optional": true
+ },
+ {
+ "name": "chunkSize",
+ "description": "The data streaming data chunk size received.",
+ "type": "Number"
+ },
+ {
+ "name": "chunkType",
+ "description": "The data streaming data chunk type received.\n The initial data chunks value may change depending on the currently received data chunk type or the\n agent supported sending type of data chunks.\n [Rel: Skylink.DATA_TRANSFER_DATA_TYPE]",
+ "type": "String"
+ },
+ {
+ "name": "isStringStream",
+ "description": "The flag if data streaming data chunks are strings.",
+ "type": "String"
+ },
+ {
+ "name": "isPrivate",
+ "description": "The flag if data streaming is targeted or not, basing\n off the targetPeerId parameter being defined in\n startStreamingData() method.",
+ "type": "Boolean"
+ },
+ {
+ "name": "senderPeerId",
+ "description": "The sender Peer ID.",
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "error",
+ "description": "The error object.\n Defined only when state payload is ERROR or START_ERROR,.",
+ "type": "Error",
+ "optional": true
+ }
+ ],
+ "beta": 1,
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/skylink-events.js",
+ "line": 668,
"description": "Event triggered when Signaling server reaction state has changed.",
"itemtype": "event",
"name": "systemAction",
@@ -5690,7 +6787,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 564,
+ "line": 681,
"description": "Event triggered when a server Peer joins the room.",
"itemtype": "event",
"name": "serverPeerJoined",
@@ -5711,7 +6808,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 575,
+ "line": 692,
"description": "Event triggered when a server Peer leaves the room.",
"itemtype": "event",
"name": "serverPeerLeft",
@@ -5732,7 +6829,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 586,
+ "line": 703,
"description": "Event triggered when a server Peer connection has been refreshed.",
"itemtype": "event",
"name": "serverPeerRestart",
@@ -5753,7 +6850,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 597,
+ "line": 714,
"description": "Event triggered when a Peer Stream streaming has stopped.\nNote that it may not be the currently sent Stream to User, and it also triggers\nwhen User leaves the Room for any currently sent Stream to User from Peer.",
"itemtype": "event",
"name": "streamEnded",
@@ -5789,7 +6886,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 614,
+ "line": 731,
"description": "Event triggered when Peer Stream audio or video tracks has been muted / unmuted.",
"itemtype": "event",
"name": "streamMuted",
@@ -5820,7 +6917,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 628,
+ "line": 745,
"description": "Event triggered when getPeers() method retrieval state changes.",
"itemtype": "event",
"name": "getPeersStateChange",
@@ -5853,7 +6950,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 641,
+ "line": 758,
"description": "Event triggered when introducePeer() method\nintroduction request state changes.",
"itemtype": "event",
"name": "introduceStateChange",
@@ -5890,7 +6987,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 657,
+ "line": 774,
"description": "Event triggered when recording session state has changed.",
"itemtype": "event",
"name": "recordingState",
@@ -5929,7 +7026,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 678,
+ "line": 795,
"description": "Event triggered when getConnectionStatus() method\nretrieval state changes.",
"itemtype": "event",
"name": "getConnectionStatusStateChange",
@@ -5987,12 +7084,12 @@
},
{
"name": "sending.packetsLost",
- "description": "The Peer connection current sending audio streaming packets lost.",
+ "description": "
\n This property has been deprecated and would be removed in future releases\n as it should not be in sending property.\n
The Peer connection current sending audio streaming packets lost.",
"type": "Number"
},
{
"name": "sending.totalPacketsLost",
- "description": "The Peer connection total sending audio streaming packets lost.",
+ "description": "
\n This property has been deprecated and would be removed in future releases\n as it should not be in sending property.\n
The Peer connection total sending audio streaming packets lost.",
"type": "Number"
},
{
@@ -6007,12 +7104,12 @@
},
{
"name": "sending.jitter",
- "description": "The Peer connection sending audio streaming RTP packets jitter in seconds.\n Defined as 0 if it's not present in original raw stats before parsing.",
+ "description": "
\n This property has been deprecated and would be removed in future releases\n as it should not be in sending property.\n
The Peer connection sending audio streaming RTP packets jitter in seconds.\n Defined as 0 if it's not present in original raw stats before parsing.",
"type": "Number"
},
{
"name": "sending.jitterBufferMs",
- "description": "The Peer connection sending audio streaming\n RTP packets jitter buffer in miliseconds.\n Defined as null if it's not available in original raw stats before parsing.",
+ "description": "
\n This property has been deprecated and would be removed in future releases\n as it should not be in sending property.\n
The Peer connection sending audio streaming\n RTP packets jitter buffer in miliseconds.\n Defined as null if it's not available in original raw stats before parsing.",
"type": "Number",
"optional": true
},
@@ -6104,11 +7201,26 @@
"description": "The Peer connection current receiving audio streaming packets lost.",
"type": "Number"
},
+ {
+ "name": "receiving.fractionLost",
+ "description": "The Peer connection current receiving audio streaming fraction packets lost.",
+ "type": "Number"
+ },
+ {
+ "name": "receiving.packetsDiscarded",
+ "description": "The Peer connection current receiving audio streaming packets discarded.",
+ "type": "Number"
+ },
{
"name": "receiving.totalPacketsLost",
"description": "The Peer connection total receiving audio streaming packets lost.",
"type": "Number"
},
+ {
+ "name": "receiving.totalPacketsDiscarded",
+ "description": "The Peer connection total receiving audio streaming packets discarded.",
+ "type": "Number"
+ },
{
"name": "receiving.ssrc",
"description": "The Peer connection receiving audio streaming RTP packets SSRC.",
@@ -6205,12 +7317,12 @@
},
{
"name": "sending.packetsLost",
- "description": "The Peer connection current sending video streaming packets lost.",
+ "description": "
\n This property has been deprecated and would be removed in future releases\n as it should not be in sending property.\n
The Peer connection current sending video streaming packets lost.",
"type": "Number"
},
{
"name": "sending.totalPacketsLost",
- "description": "The Peer connection total sending video streaming packets lost.",
+ "description": "
\n This property has been deprecated and would be removed in future releases\n as it should not be in sending property.\n
The Peer connection total sending video streaming packets lost.",
"type": "Number"
},
{
@@ -6225,12 +7337,18 @@
},
{
"name": "sending.jitter",
- "description": "The Peer connection sending video streaming RTP packets jitter in seconds.\n Defined as 0 if it's not present in original raw stats before parsing.",
+ "description": "
\n This property has been deprecated and would be removed in future releases\n as it should not be in sending property.\n
The Peer connection sending video streaming RTP packets jitter in seconds.\n Defined as 0 if it's not present in original raw stats before parsing.",
"type": "Number"
},
{
"name": "sending.jitterBufferMs",
- "description": "The Peer connection sending video streaming\n RTP packets jitter buffer in miliseconds.\n Defined as null if it's not available in original raw stats before parsing.",
+ "description": "
\n This property has been deprecated and would be removed in future releases\n as it should not be in sending property.\n
The Peer connection sending video streaming RTP packets jitter buffer in miliseconds.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "sending.qpSum",
+ "description": "The Peer connection sending video streaming sum of the QP values of frames passed.\n Defined as null if it's not available in original raw stats before parsing.",
"type": "Number",
"optional": true
},
@@ -6281,8 +7399,14 @@
"optional": true
},
{
- "name": "sending.framesInput",
- "description": "The Peer connection sending video streaming frames input.\n Defined as null if it's not available in original raw stats before parsing.",
+ "name": "sending.frameRateInput",
+ "description": "The Peer connection sending video streaming fps input.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "sending.frameRateInput",
+ "description": "The Peer connection sending video streaming fps input.\n Defined as null if it's not available in original raw stats before parsing.",
"type": "Number",
"optional": true
},
@@ -6304,6 +7428,30 @@
"type": "Number",
"optional": true
},
+ {
+ "name": "sending.framesPerSecond",
+ "description": "The Peer connection sending video streaming fps.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "sending.framesDecoded",
+ "description": "The Peer connection sending video streaming frames decoded.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "sending.framesCorrupted",
+ "description": "The Peer connection sending video streaming frames corrupted.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "sending.totalFrames",
+ "description": "The Peer connection total sending video streaming frames.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
{
"name": "sending.nacks",
"description": "The Peer connection current sending video streaming nacks.\n Defined as null if it's not available in original raw stats before parsing.",
@@ -6340,6 +7488,18 @@
"type": "Number",
"optional": true
},
+ {
+ "name": "sending.slis",
+ "description": "The Peer connection current sending video streaming slis.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "sending.totalSlis",
+ "description": "The Peer connection total sending video streaming slis.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
{
"name": "receiving",
"description": "The Peer connection receiving video streaming stats.",
@@ -6370,11 +7530,26 @@
"description": "The Peer connection current receiving video streaming packets lost.",
"type": "Number"
},
+ {
+ "name": "receiving.fractionLost",
+ "description": "The Peer connection current receiving video streaming fraction packets lost.",
+ "type": "Number"
+ },
+ {
+ "name": "receiving.packetsDiscarded",
+ "description": "The Peer connection current receiving video streaming packets discarded.",
+ "type": "Number"
+ },
{
"name": "receiving.totalPacketsLost",
"description": "The Peer connection total receiving video streaming packets lost.",
"type": "Number"
},
+ {
+ "name": "receiving.totalPacketsDiscarded",
+ "description": "The Peer connection total receiving video streaming packets discarded.",
+ "type": "Number"
+ },
{
"name": "receiving.ssrc",
"description": "The Peer connection receiving video streaming RTP packets SSRC.",
@@ -6383,7 +7558,8 @@
{
"name": "receiving.e2eDelay",
"description": "The Peer connection receiving video streaming e2e delay.\n Defined as null if it's not present in original raw stats before parsing, and that\n it finds any existing audio, video or object (plugin) DOM elements that has set with the\n Peer remote stream object to parse current time. Note that document.getElementsByTagName function\n and DOM .currentTime has to be supported inorder for data to be parsed correctly.",
- "type": "Number"
+ "type": "Number",
+ "optional": true
},
{
"name": "receiving.jitter",
@@ -6443,8 +7619,32 @@
"optional": true
},
{
- "name": "receiving.framesOutput",
- "description": "The Peer connection receiving video streaming frames output.\n Defined as null if it's not available in original raw stats before parsing.",
+ "name": "receiving.framesOutput",
+ "description": "The Peer connection receiving video streaming fps output.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "receiving.framesDecoded",
+ "description": "The Peer connection receiving video streaming frames decoded.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "receiving.frameRateMean",
+ "description": "The Peer connection receiving video streaming fps mean.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "receiving.frameRateStdDev",
+ "description": "The Peer connection receiving video streaming fps standard deviation.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "receiving.framesPerSecond",
+ "description": "The Peer connection receiving video streaming fps.\n Defined as null if it's not available in original raw stats before parsing.",
"type": "Number",
"optional": true
},
@@ -6455,14 +7655,14 @@
"optional": true
},
{
- "name": "receiving.frameRateMean",
- "description": "The Peer connection receiving video streaming fps mean.\n Defined as null if it's not available in original raw stats before parsing.",
+ "name": "receiving.framesCorrupted",
+ "description": "The Peer connection receiving video streaming frames corrupted.\n Defined as null if it's not available in original raw stats before parsing.",
"type": "Number",
"optional": true
},
{
- "name": "receiving.frameRateStdDev",
- "description": "The Peer connection receiving video streaming fps standard deviation.\n Defined as null if it's not available in original raw stats before parsing.",
+ "name": "receiving.totalFrames",
+ "description": "The Peer connection total receiving video streaming frames.\n Defined as null if it's not available in original raw stats before parsing.",
"type": "Number",
"optional": true
},
@@ -6486,7 +7686,7 @@
},
{
"name": "receiving.totalPlis",
- "description": "The Peer connection totally receiving video streaming plis.\n Defined as null if it's not available in original raw stats before parsing.",
+ "description": "The Peer connection total receiving video streaming plis.\n Defined as null if it's not available in original raw stats before parsing.",
"type": "Number",
"optional": true
},
@@ -6501,6 +7701,18 @@
"description": "The Peer connection total receiving video streaming firs.\n Defined as null if it's not available in original raw stats before parsing.",
"type": "Number",
"optional": true
+ },
+ {
+ "name": "receiving.slis",
+ "description": "The Peer connection current receiving video streaming slis.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
+ },
+ {
+ "name": "receiving.totalPlis",
+ "description": "The Peer connection total receiving video streaming slis.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Number",
+ "optional": true
}
]
},
@@ -6534,6 +7746,12 @@
"description": "The Peer connection selected\n local ICE candidate type.",
"type": "String"
},
+ {
+ "name": "local.turnMediaTransport",
+ "description": "The Peer connection possible\n transport used when relaying local media to TURN server.\n Types are \"UDP\" (UDP connections), \"TCP\" (TCP connections) and\n \"TCP/TLS\" (TCP over TLS connections).",
+ "type": "String",
+ "optional": true
+ },
{
"name": "remote",
"description": "The Peer connection selected remote ICE candidate.",
@@ -6558,6 +7776,211 @@
"name": "remote.candidateType",
"description": "The Peer connection selected\n remote ICE candidate type.",
"type": "String"
+ },
+ {
+ "name": "writable",
+ "description": "The flag if Peer has gotten ACK to an ICE request.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Boolean",
+ "optional": true
+ },
+ {
+ "name": "readable",
+ "description": "The flag if Peer has gotten a valid incoming ICE request.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "Boolean",
+ "optional": true
+ },
+ {
+ "name": "rtt",
+ "description": "The current STUN connectivity checks RTT (Round-trip delay time).\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "totalRtt",
+ "description": "The total STUN connectivity checks RTT (Round-trip delay time).\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "requests",
+ "description": "The ICE connectivity check requests.",
+ "type": "JSON"
+ },
+ {
+ "name": "requests.received",
+ "description": "The current ICE connectivity check requests received.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "requests.sent",
+ "description": "The current ICE connectivity check requests sent.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "requests.totalReceived",
+ "description": "The total ICE connectivity check requests received.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "requests.totalSent",
+ "description": "The total ICE connectivity check requests sent.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "responses",
+ "description": "The ICE connectivity check responses.",
+ "type": "JSON"
+ },
+ {
+ "name": "responses.received",
+ "description": "The current ICE connectivity check responses received.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "responses.sent",
+ "description": "The current ICE connectivity check responses sent.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "responses.totalReceived",
+ "description": "The total ICE connectivity check responses received.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "responses.totalSent",
+ "description": "The total ICE connectivity check responses sent.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "consentRequests",
+ "description": "The current ICE consent requests.",
+ "type": "JSON"
+ },
+ {
+ "name": "consentRequests.received",
+ "description": "The current ICE consent requests received.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "consentRequests.sent",
+ "description": "The current ICE consent requests sent.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "consentRequests.totalReceived",
+ "description": "The total ICE consent requests received.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "consentRequests.totalSent",
+ "description": "The total ICE consent requests sent.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "consentResponses",
+ "description": "The current ICE consent responses.",
+ "type": "JSON"
+ },
+ {
+ "name": "consentResponses.received",
+ "description": "The current ICE consent responses received.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "consentResponses.sent",
+ "description": "The current ICE consent responses sent.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "consentResponses.totalReceived",
+ "description": "The total ICE consent responses received.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "consentResponses.totalSent",
+ "description": "The total ICE consent responses sent.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ }
+ ]
+ },
+ {
+ "name": "certificate",
+ "description": "The Peer connection DTLS/SRTP exchanged certificates information.",
+ "type": "JSON",
+ "props": [
+ {
+ "name": "local",
+ "description": "The Peer connection local certificate information.",
+ "type": "JSON"
+ },
+ {
+ "name": "local.fingerprint",
+ "description": "The Peer connection local certificate fingerprint.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "local.fingerprintAlgorithm",
+ "description": "The Peer connection local\n certificate fingerprint algorithm.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "local.derBase64",
+ "description": "The Peer connection local\n base64 certificate in binary DER format encoded in base64.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "remote",
+ "description": "The Peer connection remote certificate information.",
+ "type": "JSON"
+ },
+ {
+ "name": "remote.fingerprint",
+ "description": "The Peer connection remote certificate fingerprint.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "remote.fingerprintAlgorithm",
+ "description": "The Peer connection remote\n certificate fingerprint algorithm.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "remote.derBase64",
+ "description": "The Peer connection remote\n base64 certificate in binary DER format encoded in base64.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "srtpCipher",
+ "description": "The certificates SRTP cipher.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
+ },
+ {
+ "name": "dtlsCipher",
+ "description": "The certificates DTLS cipher.\n Defined as null if it's not available in original raw stats before parsing.",
+ "type": "String",
+ "optional": true
}
]
},
@@ -6805,6 +8228,11 @@
"name": "dataChannels.#channelName.currentTransferId",
"description": "The Peer connection\n Datachannel connection current progressing transfer session ID.\n Defined as null when there is currently no transfer session progressing on the Datachannel connection.",
"type": "String"
+ },
+ {
+ "name": "dataChannels.#channelName.currentStreamId",
+ "description": "The Peer connection\n Datachannel connection current data streaming session ID.\n Defined as null when there is currently no data streaming session on the Datachannel connection.",
+ "type": "String"
}
]
}
@@ -6821,7 +8249,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 987,
+ "line": 1235,
"description": "Event triggered when muteStream() method changes\nUser Streams audio and video tracks muted status.",
"itemtype": "event",
"name": "localMediaMuted",
@@ -6849,7 +8277,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 1004,
+ "line": 1252,
"description": "
\n Learn more about how ICE works in this\n article here. \n Note that this event may not be triggered for MCU enabled Peer connections as ICE candidates\n may be received in the session description instead.\n
\nEvent triggered when remote ICE candidate processing state has changed when Peer is using trickle ICE.",
"itemtype": "event",
"name": "candidateProcessingState",
@@ -6908,7 +8336,45 @@
},
{
"file": "source/skylink-events.js",
- "line": 1033,
+ "line": 1280,
+ "description": "
\n Learn more about how ICE works in this\n article here. \n Note that this event may not be triggered for MCU enabled Peer connections as ICE candidates\n may be received in the session description instead.\n
\nEvent triggered when all remote ICE candidates gathering has completed and been processed.",
+ "itemtype": "event",
+ "name": "candidatesGathered",
+ "params": [
+ {
+ "name": "peerId",
+ "description": "The Peer ID.",
+ "type": "String"
+ },
+ {
+ "name": "length",
+ "description": "The remote ICE candidates length.",
+ "type": "JSON",
+ "props": [
+ {
+ "name": "expected",
+ "description": "The expected total number of remote ICE candidates to be received.",
+ "type": "Number"
+ },
+ {
+ "name": "received",
+ "description": "The actual total number of remote ICE candidates received.",
+ "type": "Number"
+ },
+ {
+ "name": "processed",
+ "description": "The total number of remote ICE candidates processed.",
+ "type": "Number"
+ }
+ ]
+ }
+ ],
+ "since": "0.6.18",
+ "class": "Skylink"
+ },
+ {
+ "file": "source/skylink-events.js",
+ "line": 1300,
"description": "Function that subscribes a listener to an event.",
"itemtype": "method",
"name": "on",
@@ -6932,7 +8398,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 1057,
+ "line": 1324,
"description": "Function that subscribes a listener to an event once.",
"itemtype": "method",
"name": "once",
@@ -6969,15 +8435,16 @@
},
{
"file": "source/skylink-events.js",
- "line": 1115,
+ "line": 1379,
"description": "Function that unsubscribes listeners from an event.",
"itemtype": "method",
"name": "off",
"params": [
{
"name": "eventName",
- "description": "The event.",
- "type": "String"
+ "description": "The event.\n- When not provided, all listeners to all events will be unsubscribed.",
+ "type": "String",
+ "optional": true
},
{
"name": "callback",
@@ -6994,7 +8461,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 1164,
+ "line": 1434,
"description": "Function that triggers an event.\nThe rest of the parameters after the eventName parameter is considered as the event parameter payloads.",
"itemtype": "method",
"name": "_trigger",
@@ -7005,7 +8472,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 1218,
+ "line": 1487,
"description": "Function that checks if the current state condition is met before subscribing\n event handler to wait for condition to be fulfilled.",
"itemtype": "method",
"name": "_condition",
@@ -7016,7 +8483,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 1244,
+ "line": 1513,
"description": "Function that starts an interval check to wait for a condition to be resolved.",
"itemtype": "method",
"name": "_wait",
@@ -7027,7 +8494,7 @@
},
{
"file": "source/skylink-events.js",
- "line": 1282,
+ "line": 1551,
"description": "Function that throttles a method function to prevent multiple invokes over a specified amount of time.\nReturns a function to be invoked ._throttle(fn, 1000)() to make throttling functionality work.",
"itemtype": "method",
"name": "_throttle",
@@ -7102,7 +8569,7 @@
"type": "String"
},
{
- "name": "LONG_POLLING",
+ "name": "LONG_POLLING_SSL",
"description": "Value \"fallbackLongPollingSSL\"\n The value of the reconnection state when joinRoom() socket connection is reconnecting with\n another new HTTPS port using Polling transports to attempt to establish connection with Signaling server.",
"type": "String"
}
@@ -7125,7 +8592,7 @@
},
{
"file": "source/socket-channel.js",
- "line": 261,
+ "line": 269,
"description": "Function that creates and opens a socket connection to the Signaling.",
"itemtype": "method",
"name": "_createSocket",
@@ -7136,7 +8603,7 @@
},
{
"file": "source/socket-channel.js",
- "line": 425,
+ "line": 444,
"description": "Function that starts the socket connection to the Signaling.\nThis starts creating the socket connection and called at first not when requiring to fallback.",
"itemtype": "method",
"name": "_openChannel",
@@ -7147,7 +8614,7 @@
},
{
"file": "source/socket-channel.js",
- "line": 467,
+ "line": 488,
"description": "Function that stops the socket connection to the Signaling.",
"itemtype": "method",
"name": "_closeChannel",
@@ -7324,20 +8791,9 @@
{
"file": "source/socket-message.js",
"line": 433,
- "description": "Function that process and parses the socket message string received from the Signaling.",
- "itemtype": "method",
- "name": "_processSigMessage",
- "access": "private",
- "tagname": "",
- "since": "0.1.0",
- "class": "Skylink"
- },
- {
- "file": "source/socket-message.js",
- "line": 452,
"description": "Function that handles and processes the socket message received.",
"itemtype": "method",
- "name": "_processingSingleMessage",
+ "name": "_processSigMessage",
"access": "private",
"tagname": "",
"since": "0.1.0",
@@ -7345,7 +8801,7 @@
},
{
"file": "source/socket-message.js",
- "line": 544,
+ "line": 524,
"description": "Function that handles the \"peerList\" socket message received.\nSee confluence docs for the \"peerList\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_peerListEventHandler",
@@ -7356,7 +8812,7 @@
},
{
"file": "source/socket-message.js",
- "line": 560,
+ "line": 540,
"description": "Function that handles the \"endOfCandidates\" socket message received.\nSee confluence docs for the \"endOfCandidates\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_endOfCandidatesHandler",
@@ -7367,7 +8823,7 @@
},
{
"file": "source/socket-message.js",
- "line": 582,
+ "line": 562,
"description": "Function that handles the \"introduceError\" socket message received.\nSee confluence docs for the \"introduceError\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_introduceErrorEventHandler",
@@ -7378,7 +8834,7 @@
},
{
"file": "source/socket-message.js",
- "line": 598,
+ "line": 578,
"description": "Function that handles the \"approach\" socket message received.\nSee confluence docs for the \"approach\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_approachEventHandler",
@@ -7389,7 +8845,7 @@
},
{
"file": "source/socket-message.js",
- "line": 645,
+ "line": 626,
"description": "Function that handles the \"redirect\" socket message received.\nSee confluence docs for the \"redirect\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_redirectHandler",
@@ -7400,7 +8856,7 @@
},
{
"file": "source/socket-message.js",
- "line": 677,
+ "line": 658,
"description": "Function that handles the \"updateUserEvent\" socket message received.\nSee confluence docs for the \"updateUserEvent\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_updateUserEventHandler",
@@ -7411,7 +8867,7 @@
},
{
"file": "source/socket-message.js",
- "line": 704,
+ "line": 685,
"description": "Function that handles the \"roomLockEvent\" socket message received.\nSee confluence docs for the \"roomLockEvent\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_roomLockEventHandler",
@@ -7422,7 +8878,7 @@
},
{
"file": "source/socket-message.js",
- "line": 719,
+ "line": 700,
"description": "Function that handles the \"muteAudioEvent\" socket message received.\nSee confluence docs for the \"muteAudioEvent\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_muteAudioEventHandler",
@@ -7433,7 +8889,7 @@
},
{
"file": "source/socket-message.js",
- "line": 749,
+ "line": 730,
"description": "Function that handles the \"muteVideoEvent\" socket message received.\nSee confluence docs for the \"muteVideoEvent\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_muteVideoEventHandler",
@@ -7444,7 +8900,7 @@
},
{
"file": "source/socket-message.js",
- "line": 779,
+ "line": 760,
"description": "Function that handles the \"stream\" socket message received.\nSee confluence docs for the \"stream\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_streamEventHandler",
@@ -7455,7 +8911,7 @@
},
{
"file": "source/socket-message.js",
- "line": 811,
+ "line": 792,
"description": "Function that handles the \"bye\" socket message received.\nSee confluence docs for the \"bye\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_byeHandler",
@@ -7466,7 +8922,7 @@
},
{
"file": "source/socket-message.js",
- "line": 832,
+ "line": 813,
"description": "Function that handles the \"private\" socket message received.\nSee confluence docs for the \"private\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_privateMessageHandler",
@@ -7477,7 +8933,7 @@
},
{
"file": "source/socket-message.js",
- "line": 854,
+ "line": 835,
"description": "Function that handles the \"public\" socket message received.\nSee confluence docs for the \"public\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_publicMessageHandler",
@@ -7488,7 +8944,7 @@
},
{
"file": "source/socket-message.js",
- "line": 876,
+ "line": 857,
"description": "Handles the RECORDING Protocol message event received from the platform signaling.",
"itemtype": "method",
"name": "_recordingEventHandler",
@@ -7524,7 +8980,7 @@
},
{
"file": "source/socket-message.js",
- "line": 979,
+ "line": 960,
"description": "Function that handles the \"inRoom\" socket message received.\nSee confluence docs for the \"inRoom\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_inRoomHandler",
@@ -7535,7 +8991,7 @@
},
{
"file": "source/socket-message.js",
- "line": 1044,
+ "line": 1027,
"description": "Function that handles the \"enter\" socket message received.\nSee confluence docs for the \"enter\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_enterHandler",
@@ -7546,7 +9002,7 @@
},
{
"file": "source/socket-message.js",
- "line": 1172,
+ "line": 1182,
"description": "Function that handles the \"restart\" socket message received.\nSee confluence docs for the \"restart\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_restartHandler",
@@ -7557,7 +9013,7 @@
},
{
"file": "source/socket-message.js",
- "line": 1301,
+ "line": 1317,
"description": "Function that handles the \"welcome\" socket message received.\nSee confluence docs for the \"welcome\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_welcomeHandler",
@@ -7568,7 +9024,7 @@
},
{
"file": "source/socket-message.js",
- "line": 1446,
+ "line": 1489,
"description": "Function that handles the \"offer\" socket message received.\nSee confluence docs for the \"offer\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_offerHandler",
@@ -7579,7 +9035,7 @@
},
{
"file": "source/socket-message.js",
- "line": 1537,
+ "line": 1590,
"description": "Function that handles the \"candidate\" socket message received.\nSee confluence docs for the \"candidate\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_candidateHandler",
@@ -7590,7 +9046,7 @@
},
{
"file": "source/socket-message.js",
- "line": 1632,
+ "line": 1685,
"description": "Function that handles the \"answer\" socket message received.\nSee confluence docs for the \"answer\" expected properties to be received\n based on the current SM_PROTOCOL_VERSION.",
"itemtype": "method",
"name": "_answerHandler",
@@ -7601,7 +9057,7 @@
},
{
"file": "source/socket-message.js",
- "line": 1738,
+ "line": 1799,
"description": "Function that compares the SM / DT protocol versions to see if it in the version.",
"itemtype": "method",
"name": "_isLowerThanVersion",
@@ -7665,10 +9121,25 @@
"description": "Value \"ISAC\"\n The value of the option to prefer the ISAC audio codec.",
"type": "String"
},
+ {
+ "name": "ILBC",
+ "description": "Value \"ILBC\"\n The value of the option to prefer the iLBC audio codec.",
+ "type": "String"
+ },
{
"name": "G722",
"description": "Value \"G722\"\n The value of the option to prefer the G722 audio codec.",
"type": "String"
+ },
+ {
+ "name": "PCMA",
+ "description": "Value \"PCMA\"\n The value of the option to prefer the G711u audio codec.",
+ "type": "String"
+ },
+ {
+ "name": "PCMU",
+ "description": "Value \"PCMU\"\n The value of the option to prefer the G711a audio codec.",
+ "type": "String"
}
],
"type": "JSON",
@@ -7678,7 +9149,7 @@
},
{
"file": "source/stream-media.js",
- "line": 65,
+ "line": 72,
"description": "
\n Note that currently getUserMedia() method only configures\n the maximum resolution of the Stream due to browser interopability and support.\n
\nThe list of \nvideo resolutions sets configured in the getUserMedia() method.",
"itemtype": "attribute",
"name": "VIDEO_RESOLUTION",
@@ -7791,7 +9262,7 @@
},
{
"file": "source/stream-media.js",
- "line": 178,
+ "line": 185,
"description": "The list of getUserMedia() method or\nshareScreen() method Stream fallback states.",
"itemtype": "attribute",
"name": "MEDIA_ACCESS_FALLBACK_STATE",
@@ -7818,7 +9289,7 @@
},
{
"file": "source/stream-media.js",
- "line": 203,
+ "line": 210,
"description": "The list of recording states.",
"itemtype": "attribute",
"name": "RECORDING_STATE",
@@ -7851,7 +9322,7 @@
},
{
"file": "source/stream-media.js",
- "line": 229,
+ "line": 236,
"description": "
\n For a better user experience, the functionality is throttled when invoked many times in less\n than the milliseconds interval configured in the init() method.\n
\nFunction that retrieves camera Stream.",
"itemtype": "method",
"name": "getUserMedia",
@@ -7878,26 +9349,26 @@
"props": [
{
"name": "stereo",
- "description": "The flag if stereo band should be configured\n when encoding audio codec is OPUS for sending / receiving audio data.\n Note that Peers may override the \"receiving\" stereo config depending on the Peers configuration.",
+ "description": "
Deprecation Warning!\n This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo\n parameter in the init() method instead. If the\n options.codecParams.audio.opus.stereo is configured, this overrides the\n options.audio.stereo setting.
\n The flag if OPUS audio codec stereo band should be configured for sending encoded audio data.\n When not provided, the default browser configuration is used.",
"type": "Boolean",
"optional": true,
"optdefault": "false"
},
{
"name": "usedtx",
- "description": "
\n Note that this feature might not work depending on the browser support and implementation.
\n The flag if DTX (Discontinuous Transmission) should be configured when encoding audio codec\n is OPUS for sending / receiving audio data.\n This might help to reduce bandwidth it reduces the bitrate during silence or background noise.\n When not provided, the default browser configuration is used.\n Note that Peers may override the \"receiving\" usedtx config depending on the Peers configuration.",
+ "description": "
Deprecation Warning!\n This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo\n parameter in the init() method instead. If the\n options.codecParams.audio.opus.stereo is configured, this overrides the\n options.audio.stereo setting. Note that this feature might\n not work depending on the browser support and implementation.
\n The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.\n This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and\n goes hand-in-hand with the options.voiceActivityDetection flag in \n joinRoom() method.\n When not provided, the default browser configuration is used.",
"type": "Boolean",
"optional": true
},
{
"name": "useinbandfec",
- "description": "
\n Note that this feature might not work depending on the browser support and implementation.
\n The flag if capability to take advantage of in-band FEC (Forward Error Correction) should be\n configured when encoding audio codec is OPUS for sending / receiving audio data.\n This might help to reduce the harm of packet loss by encoding information about the previous packet.\n When not provided, the default browser configuration is used.\n Note that Peers may override the \"receiving\" useinbandfec config depending on the Peers configuration.",
+ "description": "
Deprecation Warning!\n This property has been deprecated. Configure this with the options.codecParams.audio.opus.useinbandfec\n parameter in the init() method instead. If the\n options.codecParams.audio.opus.useinbandfec is configured, this overrides the\n options.audio.useinbandfec setting. Note that this parameter should only be used\n for debugging purposes only.
\n The flag if OPUS audio codec has the capability to take advantage of the in-band FEC\n (Forward Error Correction) when sending encoded audio data.\n This helps to reduce the harm of packet loss by encoding information about the previous packet loss.\n When not provided, the default browser configuration is used.",
"type": "Boolean",
"optional": true
},
{
"name": "maxplaybackrate",
- "description": "
\n Note that this feature might not work depending on the browser support and implementation.
\n The maximum output sampling rate rendered in Hertz (Hz) when encoding audio codec is\n OPUS for sending / receiving audio data.\n This value must be between 8000 to 48000.\n When not provided, the default browser configuration is used.\n Note that Peers may override the \"receiving\" maxplaybackrate config depending on the Peers configuration.",
+ "description": "
Deprecation Warning!\n This property has been deprecated. Configure this with the options.codecParams.audio.opus.maxplaybackrate\n parameter in the init() method instead. If the\n options.codecParams.audio.opus.maxplaybackrate is configured, this overrides the\n options.audio.maxplaybackrate setting. Note that this feature might\n not work depending on the browser support and implementation.\n Note that this parameter should only be used for debugging purposes only.
\n The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving\n decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data\n would not encode at a higher sampling rate specified by this.\n This value must be between 8000 to 48000.\n When not provided, the default browser configuration is used.",
"type": "Number",
"optional": true
},
@@ -7922,10 +9393,10 @@
},
{
"name": "echoCancellation",
- "description": "The flag to enable audio tracks echo cancellation.",
+ "description": "
\n For Chrome/Opera/IE/Safari/Bowser, the echo cancellation functionality may not work and may produce a terrible\n feedback. It is recommended to use headphones or other microphone devices rather than the device\n in-built microphones.
The flag to enable echo cancellation for audio track.",
"type": "Boolean",
"optional": true,
- "optdefault": "false"
+ "optdefault": "true"
}
]
},
@@ -8017,7 +9488,7 @@
},
{
"file": "source/stream-media.js",
- "line": 582,
+ "line": 608,
"description": "
Deprecation Warning!\n This method has been deprecated. Use muteStream() method instead.\n
\nFunction that mutes both getUserMedia() Stream and\nshareScreen() Stream audio tracks.",
"itemtype": "method",
"name": "disableAudio",
@@ -8134,7 +9605,7 @@
},
{
"file": "source/stream-media.js",
- "line": 1025,
+ "line": 1060,
"description": "
Deprecation Warning!\n This method has been deprecated. Use muteStream() method instead.\n
\nFunction that unmutes both getUserMedia() Stream and\nshareScreen() Stream video tracks.",
"itemtype": "method",
"name": "enableVideo",
@@ -8149,7 +9620,7 @@
},
{
"file": "source/stream-media.js",
- "line": 1052,
+ "line": 1087,
"description": "
Deprecation Warning!\n This method has been deprecated. Use muteStream() method instead.\n
\nFunction that mutes both getUserMedia() Stream and\nshareScreen() Stream video tracks.",
"itemtype": "method",
"name": "disableVideo",
@@ -8164,7 +9635,7 @@
},
{
"file": "source/stream-media.js",
- "line": 1079,
+ "line": 1114,
"description": "
\n For a better user experience, the functionality is throttled when invoked many times in less\n than the milliseconds interval configured in the init() method.\n Note that the Opera and Edge browser does not support screensharing, and as for IE / Safari browsers using\n the Temasys Plugin screensharing support, check out the \n commercial licensing for more options.\n
\nFunction that retrieves screensharing Stream.",
"itemtype": "method",
"name": "shareScreen",
@@ -8178,35 +9649,35 @@
"props": [
{
"name": "stereo",
- "description": "The flag if stereo band should be configured\n when encoding audio codec is OPUS for sending audio data.",
+ "description": "
Deprecation Warning!\n This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo\n parameter in the init() method instead. If the\n options.codecParams.audio.opus.stereo is configured, this overrides the\n options.audio.stereo setting.
\n The flag if OPUS audio codec stereo band should be configured for sending encoded audio data.\n When not provided, the default browser configuration is used.",
"type": "Boolean",
"optional": true,
"optdefault": "false"
},
{
"name": "usedtx",
- "description": "
\n Note that this feature might not work depending on the browser support and implementation.
\n The flag if DTX (Discontinuous Transmission) should be configured when encoding audio codec\n is OPUS for sending audio data.\n This might help to reduce bandwidth it reduces the bitrate during silence or background noise.\n When not provided, the default browser configuration is used.",
+ "description": "
Deprecation Warning!\n This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo\n parameter in the init() method instead. If the\n options.codecParams.audio.opus.stereo is configured, this overrides the\n options.audio.stereo setting. Note that this feature might\n not work depending on the browser support and implementation.
\n The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.\n This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and\n goes hand-in-hand with the options.voiceActivityDetection flag in \n joinRoom() method.\n When not provided, the default browser configuration is used.",
"type": "Boolean",
"optional": true
},
{
"name": "useinbandfec",
- "description": "
\n Note that this feature might not work depending on the browser support and implementation.
\n The flag if capability to take advantage of in-band FEC (Forward Error Correction) should be\n configured when encoding audio codec is OPUS for sending audio data.\n This might help to reduce the harm of packet loss by encoding information about the previous packet.\n When not provided, the default browser configuration is used.",
+ "description": "
Deprecation Warning!\n This property has been deprecated. Configure this with the options.codecParams.audio.opus.useinbandfec\n parameter in the init() method instead. If the\n options.codecParams.audio.opus.useinbandfec is configured, this overrides the\n options.audio.useinbandfec setting. Note that this parameter should only be used\n for debugging purposes only.
\n The flag if OPUS audio codec has the capability to take advantage of the in-band FEC\n (Forward Error Correction) when sending encoded audio data.\n This helps to reduce the harm of packet loss by encoding information about the previous packet loss.\n When not provided, the default browser configuration is used.",
"type": "Boolean",
"optional": true
},
{
"name": "maxplaybackrate",
- "description": "
\n Note that this feature might not work depending on the browser support and implementation.
\n The maximum output sampling rate rendered in Hertz (Hz) when encoding audio codec is\n OPUS for sending audio data.\n This value must be between 8000 to 48000.\n When not provided, the default browser configuration is used.",
+ "description": "
Deprecation Warning!\n This property has been deprecated. Configure this with the options.codecParams.audio.opus.maxplaybackrate\n parameter in the init() method instead. If the\n options.codecParams.audio.opus.maxplaybackrate is configured, this overrides the\n options.audio.maxplaybackrate setting. Note that this feature might\n not work depending on the browser support and implementation.\n Note that this parameter should only be used for debugging purposes only.
\n The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving\n decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data\n would not encode at a higher sampling rate specified by this.\n This value must be between 8000 to 48000.\n When not provided, the default browser configuration is used.",
"type": "Number",
"optional": true
},
{
"name": "echoCancellation",
- "description": "The flag to enable audio tracks echo cancellation.",
+ "description": "
\n For Chrome/Opera/IE/Safari/Bowser, the echo cancellation functionality may not work and may produce a terrible\n feedback. It is recommended to use headphones or other microphone devices rather than the device\n in-built microphones.
The flag to enable echo cancellation for audio track.",
"type": "Boolean",
"optional": true,
- "optdefault": "false"
+ "optdefault": "true"
}
]
},
@@ -8238,7 +9709,7 @@
},
{
"file": "source/stream-media.js",
- "line": 1323,
+ "line": 1380,
"description": "
/**
* The list of Datachannel sending message error types.
* @attribute DATA_CHANNEL_MESSAGE_ERROR
- * @param {String} MESSAGE <small>Value <code>"message"</code></small>
+ * @param {String} MESSAGE <small>Value <code>"message"</code></small>
* The value of the Datachannel sending message error type when encountered during
* sending P2P message from <a href="#method_sendP2PMessage"><code>sendP2PMessage()</code> method</a>.
* @param {String} TRANSFER <small>Value <code>"transfer"</code></small>
@@ -188,24 +188,25 @@
File: source/data-channel.js
* @for Skylink
* @since 0.5.5
*/
-Skylink.prototype._createDataChannel = function(peerId, dataChannel, createAsMessagingChannel) {
+Skylink.prototype._createDataChannel = function(peerId, dataChannel, bufferThreshold, createAsMessagingChannel) {
var self = this;
+ var channelName = (self._user && self._user.sid ? self._user.sid : '-') + '_' + peerId;
+ var channelType = createAsMessagingChannel ? self.DATA_CHANNEL_TYPE.MESSAGING : self.DATA_CHANNEL_TYPE.DATA;
+ var channelProp = channelType === self.DATA_CHANNEL_TYPE.MESSAGING ? 'main' : channelName;
if (!self._user) {
- log.error([peerId, 'RTCDataChannel', null,
+ log.error([peerId, 'RTCDataChannel', channelProp,
'Aborting of creating or initializing Datachannel as User does not have Room session']);
return;
}
if (!(self._peerConnections[peerId] &&
self._peerConnections[peerId].signalingState !== self.PEER_CONNECTION_STATE.CLOSED)) {
- log.error([peerId, 'RTCDataChannel', null,
+ log.error([peerId, 'RTCDataChannel', channelProp,
'Aborting of creating or initializing Datachannel as Peer connection does not exists']);
return;
}
- var channelName = self._user.sid + '_' + peerId;
- var channelType = createAsMessagingChannel ? self.DATA_CHANNEL_TYPE.MESSAGING : self.DATA_CHANNEL_TYPE.DATA;
if (dataChannel && typeof dataChannel === 'object') {
channelName = dataChannel.label;
@@ -217,23 +218,26 @@
dataChannel.onerror = function (evt) {
var channelError = evt.error || evt;
- log.error([peerId, 'RTCDataChannel', channelName, 'Datachannel has an exception ->'], channelError);
+ log.error([peerId, 'RTCDataChannel', channelProp, 'Datachannel has an exception ->'], channelError);
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.ERROR, peerId, channelError, channelName, channelType, null);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.ERROR, peerId, channelError, channelName,
+ channelType, null, self._getDataChannelBuffer(dataChannel));
};
+ // State where we can start calling .send() to queue more buffered data to be sent
+ // RTCDataChannel has an internal mechanism to queue data to be sent over
+ // This event might not be even triggered at all
dataChannel.onbufferedamountlow = function () {
- log.debug([peerId, 'RTCDataChannel', channelName, 'Datachannel buffering data transfer low']);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Datachannel buffering data transfer low']);
- // TODO: Should we add an event here
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.BUFFERED_AMOUNT_LOW, peerId, null, channelName, channelType, null);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.BUFFERED_AMOUNT_LOW, peerId, null, channelName,
+ channelType, null, self._getDataChannelBuffer(dataChannel));
};
dataChannel.onmessage = function(event) {
@@ -260,33 +268,44 @@
// TODO: What happens when we want to send binary data over or ArrayBuffers?
if (!(typeof data === 'object' && data) && !(data && typeof data === 'string')) {
- log.warn([peerId, 'RTCDataChannel', 'prop:' + channelProp, 'Dropping invalid data ->'], data);
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Dropping invalid data ->'], data);
return;
}
if (!(self._peerConnections[peerId] &&
self._peerConnections[peerId].signalingState !== self.PEER_CONNECTION_STATE.CLOSED)) {
- log.warn([peerId, 'RTCDataChannel', 'prop:' + channelProp,
+ log.warn([peerId, 'RTCDataChannel', channelProp,
'Dropping for sending message as Peer connection does not exists or is closed ->'], data);
return;
}
if (!(self._dataChannels[peerId] && self._dataChannels[peerId][channelProp])) {
- log.warn([peerId, 'RTCDataChannel', 'prop:' + channelProp,
+ log.warn([peerId, 'RTCDataChannel', channelProp,
'Dropping for sending message as Datachannel connection does not exists ->'], data);
return;
}
@@ -386,30 +441,32 @@
* @for Skylink
* @since 0.5.10
*/
-Skylink.prototype.DT_PROTOCOL_VERSION = '0.1.0';
+Skylink.prototype.DT_PROTOCOL_VERSION = '0.1.3';
/**
* The list of data transfers directions.
@@ -193,7 +193,45 @@
File: source/data-transfer.js
UPLOAD_COMPLETED: 'uploadCompleted',
DOWNLOAD_COMPLETED: 'downloadCompleted',
USER_REJECTED: 'userRejected',
- USER_UPLOAD_REQUEST: 'userRequest'
+ USER_UPLOAD_REQUEST: 'userRequest',
+ START_ERROR: 'startError'
+};
+
+/**
+ * The list of data streaming states.
+ * @attribute DATA_STREAM_STATE
+ * @param {String} SENDING_STARTED <small>Value <code>"sendStart"</code></small>
+ * The value of the state when data streaming session has started from User to Peer.
+ * @param {String} RECEIVING_STARTED <small>Value <code>"receiveStart"</code></small>
+ * The value of the state when data streaming session has started from Peer to Peer.
+ * @param {String} RECEIVED <small>Value <code>"received"</code></small>
+ * The value of the state when data streaming session data chunk has been received from Peer to User.
+ * @param {String} SENT <small>Value <code>"sent"</code></small>
+ * The value of the state when data streaming session data chunk has been sent from User to Peer.
+ * @param {String} SENDING_STOPPED <small>Value <code>"sendStop"</code></small>
+ * The value of the state when data streaming session has stopped from User to Peer.
+ * @param {String} RECEIVING_STOPPED <small>Value <code>"receivingStop"</code></small>
+ * The value of the state when data streaming session has stopped from Peer to User.
+ * @param {String} ERROR <small>Value <code>"error"</code></small>
+ * The value of the state when data streaming session has errors.
+ * <small>At this stage, the data streaming state is considered <code>SENDING_STOPPED</code> or
+ * <code>RECEIVING_STOPPED</code>.</small>
+ * @param {String} START_ERROR <small>Value <code>"startError"</code></small>
+ * The value of the state when data streaming session failed to start from User to Peer.
+ * @type JSON
+ * @readOnly
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.DATA_STREAM_STATE = {
+ SENDING_STARTED: 'sendStart',
+ SENDING_STOPPED: 'sendStop',
+ RECEIVING_STARTED: 'receiveStart',
+ RECEIVING_STOPPED: 'receiveStop',
+ RECEIVED: 'received',
+ SENT: 'sent',
+ ERROR: 'error',
+ START_ERROR: 'startError'
};
/**
@@ -221,20 +259,6 @@
File: source/data-transfer.js
};
/**
- * Stores the list of agent names supported by the Web for Web only functionalities.
- * @attribute _SUPPORTED_WEB_AGENTS
- * @type Array
- * @readOnly
- * @private
- * @for Skylink
- * @since 0.6.16
- */
-Skylink.prototype._SUPPORTED_WEB_AGENTS = ['chrome', 'firefox', 'safari', 'IE', 'edge' ,'opera', 'bowser', 'blink'];
-
-/**
- * <blockquote class="info">
- * Note that Android, iOS and C++ SDKs do not support simultaneous data transfers.
- * </blockquote>
* Function that starts an uploading data transfer from User to Peers.
* @method sendBlobData
* @param {Blob} data The Blob object.
@@ -276,6 +300,18 @@
File: source/data-transfer.js
* <a href="#event_dataTransferState"><code>dataTransferState</code> event</a> except without the
* <code>percentage</code> property and <code>data</code>.</small>
* @trigger <ol class="desc-seq">
+ * <li>Checks if User is in Room. <ol>
+ * <li>If User is not in Room: <ol><li><a href="#event_dataTransferState">
+ * <code>dataTransferState</code> event</a> triggers parameter payload <code>state</code>
+ * as <code>START_ERROR</code>.</li><li><b>ABORT</b> step and return error.</li></ol></li></ol></li>
+ * <li>Checks if there is any available Datachannel connections. <ol>
+ * <li>If User is not in Room: <ol><li><a href="#event_dataTransferState">
+ * <code>dataTransferState</code> event</a> triggers parameter payload <code>state</code>
+ * as <code>START_ERROR</code>.</li><li><b>ABORT</b> step and return error.</li></ol></li></ol></li>
+ * <li>Checks if provided <code>data</code> parameter is valid. <ol>
+ * <li>If it is invalid: <ol><li><a href="#event_dataTransferState">
+ * <code>dataTransferState</code> event</a> triggers parameter payload <code>state</code>
+ * as <code>START_ERROR</code>.</li><li><b>ABORT</b> step and return error.</li></ol></li></ol></li>
* <li>Checks if Peer connection and Datachannel connection are in correct states. <ol>
* <li>If Peer connection or session does not exists: <ol><li><a href="#event_dataTransferState">
* <code>dataTransferState</code> event</a> triggers parameter payload <code>state</code>
@@ -325,6 +361,14 @@
File: source/data-transfer.js
* with all Peers targeted for the data transfer session.</small> <ol><li>If messaging Datachannel connection has a
* data transfer in-progress: <ol><li><a href="#event_dataTransferState"><code>dataTransferState</code> event</a>
* triggers parameter payload <code>state</code> as <code>ERROR</code>.</li><li><b>ABORT</b> step and
+ * return error.</li></ol></li><li>If there is any conflicting <a href="#method_streamData"><code>streamData()</code>
+ * method</a> data streaming session: <small>If <code>sendChunksAsBinary</code> is provided as <code>true</code>,
+ * it cannot start if existing data streaming session is expected binary data chunks, and if provided as
+ * <code>false</code>, or method invoked is <a href="#method_sendURLData"><code>sendURLData()</code> method</a>,
+ * or Peer is using string data chunks fallback due to its support despite provided as <code>true</code>,
+ * it cannot start if existing data streaming session is expected string data chunks.</small><ol>
+ * <li><a href="#event_dataTransferState"><code>dataTransferState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>ERROR</code>.</li><li><b>ABORT</b> step and
* return error.</li></ol></li></li></ol></ol></li></ol></li>
* <li>Starts the data transfer to Peer. <ol>
* <li><a href="#event_incomingDataRequest"><code>incomingDataRequest</code> event</a> triggers.</li>
@@ -463,150 +507,10 @@
File: source/data-transfer.js
* @since 0.5.5
*/
Skylink.prototype.sendBlobData = function(data, timeout, targetPeerId, sendChunksAsBinary, callback) {
- var self = this;
- var listOfPeers = Object.keys(self._peerConnections);
- var transferInfo = {
- name: null,
- size: null,
- chunkSize: self._CHUNK_FILE_SIZE,
- chunkType: self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING,
- dataType: self.DATA_TRANSFER_SESSION_TYPE.BLOB,
- mimeType: null,
- direction: self.DATA_TRANSFER_TYPE.UPLOAD,
- timeout: 60,
- isPrivate: false,
- percentage: 0
- };
-
- // Function that returns the error emitted before data transfer has started
- var emitErrorBeforeDataTransferFn = function (error) {
- log.error(error);
-
- if (typeof callback === 'function') {
- var transferErrors = {};
-
- if (listOfPeers.length === 0) {
- transferErrors.self = new Error(error);
- } else {
- for (var i = 0; i < listOfPeers.length; i++) {
- transferErrors[listOfPeers[i]] = new Error(error);
- }
- }
-
- callback({
- transferId: null,
- transferInfo: transferInfo,
- listOfPeers: listOfPeers,
- transferErrors: transferErrors
- }, null);
- }
- };
-
- // Remove MCU Peer as list of Peers
- if (listOfPeers.indexOf('MCU') > -1) {
- listOfPeers.splice(listOfPeers.indexOf('MCU'), 1);
- }
-
- // sendBlobData(.., timeout)
- if (typeof timeout === 'number') {
- transferInfo.timeout = timeout;
- } else if (Array.isArray(timeout)) {
- listOfPeers = timeout;
- } else if (timeout && typeof timeout === 'string') {
- listOfPeers = [timeout];
- } else if (timeout && typeof timeout === 'boolean') {
- transferInfo.chunkType = self.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER;
- transferInfo.chunkSize = self._BINARY_FILE_SIZE;
- } else if (typeof timeout === 'function') {
- callback = timeout;
- }
-
- // sendBlobData(.., .., targetPeerId)
- if (Array.isArray(targetPeerId)) {
- listOfPeers = targetPeerId;
- } else if (targetPeerId && typeof targetPeerId === 'string') {
- listOfPeers = [targetPeerId];
- } else if (targetPeerId && typeof targetPeerId === 'boolean') {
- transferInfo.chunkType = self.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER;
- transferInfo.chunkSize = self._BINARY_FILE_SIZE;
- } else if (typeof targetPeerId === 'function') {
- callback = targetPeerId;
- }
-
- // sendBlobData(.., .., .., sendChunksAsBinary)
- if (sendChunksAsBinary && typeof sendChunksAsBinary === 'boolean') {
- transferInfo.chunkType = self.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER;
- transferInfo.chunkSize = self._BINARY_FILE_SIZE;
- } else if (typeof sendChunksAsBinary === 'function') {
- callback = sendChunksAsBinary;
- }
-
- if (window.webrtcDetectedBrowser === 'firefox' &&
- transferInfo.chunkType === self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING) {
- transferInfo.chunkSize = self._MOZ_CHUNK_FILE_SIZE;
- }
-
- if (self._hasMCU && transferInfo.chunkType === self.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER) {
- log.warn('Binary data chunks transfer is not yet supported with MCU environment. ' +
- 'Fallbacking to binary string data chunks transfer.');
- transferInfo.chunkType = self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING;
- transferInfo.chunkSize = self._CHUNK_FILE_SIZE;
- }
-
- // Use BLOB for Firefox
- if (transferInfo.chunkType === self.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER &&
- window.webrtcDetectedBrowser === 'firefox') {
- transferInfo.chunkType = self.DATA_TRANSFER_DATA_TYPE.BLOB;
- transferInfo.chunkSize = self._MOZ_BINARY_FILE_SIZE;
- }
-
- // Start checking if data transfer can start
- if (!(data && typeof data === 'object' && data instanceof Blob)) {
- emitErrorBeforeDataTransferFn('Provided data is not a Blob data');
- return;
- }
-
- transferInfo.name = data.name || null;
- transferInfo.mimeType = data.type || null;
-
- if (data.size < 1) {
- emitErrorBeforeDataTransferFn('Provided data is not a valid Blob data.');
- return;
- }
-
- transferInfo.size = data.size;
-
- if (!self._user) {
- emitErrorBeforeDataTransferFn('Unable to send any blob data. User is not in Room.');
- return;
- }
-
- if (listOfPeers.length === 0) {
- emitErrorBeforeDataTransferFn('Unable to send any blob data. There are no Peers to start data transfer with');
- return;
- }
-
- if (!self._enableDataChannel) {
- emitErrorBeforeDataTransferFn('Unable to send any blob data. Datachannel is disabled');
- return;
- }
-
- var chunks = self._chunkBlobData(data, transferInfo.chunkSize);
-
- transferInfo.originalSize = transferInfo.size;
-
- if (transferInfo.chunkType === self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING) {
- transferInfo.size = 4 * Math.ceil(transferInfo.size / 3);
- transferInfo.chunkSize = 4 * Math.ceil(transferInfo.chunkSize / 3);
- }
-
- self._startDataTransfer(chunks, transferInfo, listOfPeers, callback);
+ this._startDataTransfer(data, timeout, targetPeerId, sendChunksAsBinary, callback, 'blob');
};
/**
- * <blockquote class="info">
- * Currently, the Android, iOS and C++ SDKs do not support this type of data transfer session.
- * </blockquote>
* Function that starts an uploading string data transfer from User to Peers.
* @method sendURLData
* @param {String} data The data string to transfer to Peer.
@@ -738,98 +642,7 @@
File: source/data-transfer.js
* @since 0.6.1
*/
Skylink.prototype.sendURLData = function(data, timeout, targetPeerId, callback) {
- var self = this;
- var listOfPeers = Object.keys(self._peerConnections);
- var transferInfo = {
- name: null,
- size: null,
- chunkSize: self._CHUNK_FILE_SIZE,
- chunkType: self.DATA_TRANSFER_DATA_TYPE.STRING,
- dataType: self.DATA_TRANSFER_SESSION_TYPE.DATA_URL,
- mimeType: null,
- direction: self.DATA_TRANSFER_TYPE.UPLOAD,
- timeout: 60,
- isPrivate: false,
- percentage: 0
- };
-
- // Function that returns the error emitted before data transfer has started
- var emitErrorBeforeDataTransferFn = function (error) {
- log.error(error);
-
- if (typeof callback === 'function') {
- var transferErrors = {};
-
- if (listOfPeers.length === 0) {
- transferErrors.self = new Error(error);
- } else {
- for (var i = 0; i < listOfPeers.length; i++) {
- transferErrors[listOfPeers[i]] = new Error(error);
- }
- }
-
- callback({
- transferId: null,
- transferInfo: transferInfo,
- listOfPeers: listOfPeers,
- transferErrors: transferErrors
- }, null);
- }
- };
-
- // Remove MCU Peer as list of Peers
- if (listOfPeers.indexOf('MCU') > -1) {
- listOfPeers.splice(listOfPeers.indexOf('MCU'), 1);
- }
-
- // sendURLData(.., timeout)
- if (typeof timeout === 'number') {
- transferInfo.timeout = timeout;
- } else if (Array.isArray(timeout)) {
- listOfPeers = timeout;
- } else if (timeout && typeof timeout === 'string') {
- listOfPeers = [timeout];
- } else if (typeof timeout === 'function') {
- callback = timeout;
- }
-
- // sendURLData(.., .., targetPeerId)
- if (Array.isArray(targetPeerId)) {
- listOfPeers = targetPeerId;
- } else if (targetPeerId && typeof targetPeerId === 'string') {
- listOfPeers = [targetPeerId];
- } else if (typeof targetPeerId === 'function') {
- callback = targetPeerId;
- }
-
- // Start checking if data transfer can start
- if (!(data && typeof data === 'string')) {
- emitErrorBeforeDataTransferFn('Provided data is not a dataURL');
- return;
- }
-
- transferInfo.size = data.length || data.size;
-
- if (!self._user) {
- emitErrorBeforeDataTransferFn('Unable to send any dataURL. User is not in Room.');
- return;
- }
-
- if (listOfPeers.length === 0) {
- emitErrorBeforeDataTransferFn('Unable to send any dataURL. There are no Peers to start data transfer with');
- return;
- }
-
- if (!self._enableDataChannel) {
- emitErrorBeforeDataTransferFn('Unable to send any dataURL. Datachannel is disabled');
- return;
- }
-
- var chunks = self._chunkDataURL(data, transferInfo.chunkSize);
-
- transferInfo.originalSize = transferInfo.size;
-
- self._startDataTransfer(chunks, transferInfo, listOfPeers, callback);
+ this._startDataTransfer(data, timeout, targetPeerId, callback, null, 'data');
};
/**
@@ -1153,84 +966,797 @@
File: source/data-transfer.js
* skylinkDemo.sendP2PMessage(message, readyToSend);
* }
* @for Skylink
- * @since 0.5.5
+ * @since 0.5.5
+ */
+Skylink.prototype.sendP2PMessage = function(message, targetPeerId) {
+ var listOfPeers = Object.keys(this._dataChannels);
+ var isPrivate = false;
+
+ if (Array.isArray(targetPeerId)) {
+ listOfPeers = targetPeerId;
+ isPrivate = true;
+ } else if (targetPeerId && typeof targetPeerId === 'string') {
+ listOfPeers = [targetPeerId];
+ isPrivate = true;
+ }
+
+ if (!this._inRoom || !(this._user && this._user.sid)) {
+ log.error('Unable to send message as User is not in Room. ->', message);
+ return;
+ }
+
+ if (!this._enableDataChannel) {
+ log.error('Unable to send message as User does not have Datachannel enabled. ->', message);
+ return;
+ }
+
+ // Loop out unwanted Peers
+ for (var i = 0; i < listOfPeers.length; i++) {
+ var peerId = listOfPeers[i];
+
+ if (!this._dataChannels[peerId]) {
+ log.error([peerId, 'RTCDataChannel', null, 'Dropping of sending message to Peer as ' +
+ 'Datachannel connection does not exists']);
+ listOfPeers.splice(i, 1);
+ i--;
+ } else if (peerId === 'MCU') {
+ listOfPeers.splice(i, 1);
+ i--;
+ } else if (!this._hasMCU) {
+ log.debug([peerId, 'RTCDataChannel', null, 'Sending ' + (isPrivate ? 'private' : '') +
+ ' P2P message to Peer']);
+
+ this._sendMessageToDataChannel(peerId, {
+ type: this._DC_PROTOCOL_TYPE.MESSAGE,
+ isPrivate: isPrivate,
+ sender: this._user.sid,
+ target: peerId,
+ data: message
+ }, 'main');
+ }
+ }
+
+ if (listOfPeers.length === 0) {
+ log.warn('Currently there are no Peers to send P2P message to (unless the message is queued ' +
+ 'and there are Peer connected by then).');
+ }
+
+ if (this._hasMCU) {
+ log.debug(['MCU', 'RTCDataChannel', null, 'Broadcasting ' + (isPrivate ? 'private' : '') +
+ ' P2P message to Peers']);
+
+ this._sendMessageToDataChannel('MCU', {
+ type: this._DC_PROTOCOL_TYPE.MESSAGE,
+ isPrivate: isPrivate,
+ sender: this._user.sid,
+ target: listOfPeers,
+ data: message
+ }, 'main');
+ }
+
+ this._trigger('incomingMessage', {
+ content: message,
+ isPrivate: isPrivate,
+ targetPeerId: targetPeerId || null,
+ listOfPeers: listOfPeers,
+ isDataChannel: true,
+ senderPeerId: this._user.sid
+ }, this._user.sid, this.getPeerInfo(), true);
+};
+
+/**
+ * <blockquote class="info">
+ * To start streaming data, see the <a href="#method_streamData"><code>streamData()</code>
+ * method</a>. To stop data streaming session, see the <a href="#method_stopStreamingData"><code>stopStreamingData()</code> method</a>
+ * </blockquote>
+ * Function that starts a data chunks streaming session from User to Peers.
+ * @method startStreamingData
+ * @param {Boolean} [isStringStream=false] The flag if data streaming session sending data chunks
+ * should be expected as string data chunks sent.
+ * <small>By default, data chunks are expected to be sent in Blob or ArrayBuffer, and ArrayBuffer
+ * data chunks will be converted to Blob.</small>
+ * @param {String|Array} [targetPeerId] The target Peer ID to send message to.
+ * - When provided as an Array, it will start streaming session to only Peers which IDs are in the list.
+ * - When not provided, it will start the streaming session to all connected Peers with Datachannel connection in the Room.
+ * @trigger <ol class="desc-seq">
+ * @trigger <ol class="desc-seq">
+ * <li>Checks if User is in Room. <ol>
+ * <li>If User is not in Room: <ol><li><a href="#event_dataStreamState">
+ * <code>dataStreamState</code> event</a> triggers parameter payload <code>state</code>
+ * as <code>START_ERROR</code>.</li><li><b>ABORT</b> step and return error.</li></ol></li></ol></li>
+ * <li>Checks if there is any available Datachannel connections. <ol>
+ * <li>If User is not in Room: <ol><li><a href="#event_dataStreamState">
+ * <code>dataStreamState</code> event</a> triggers parameter payload <code>state</code>
+ * as <code>START_ERROR</code>.</li><li><b>ABORT</b> step and return error.</li></ol></li></ol></li>
+ * <li>Checks if Peer connection and Datachannel connection are in correct states. <ol>
+ * <li>If Peer connection or session does not exists: <ol><li><a href="#event_dataStreamState">
+ * <code>dataStreamState</code> event</a> triggers parameter payload <code>state</code>
+ * as <code>START_ERROR</code>.</li><li><b>ABORT</b> step and return error.</li></ol></li>
+ * <li>If Peer connection messaging Datachannel has not been opened: <small>This can be checked with
+ * <a href="#event_dataChannelState"><code>dataChannelState</code> event</a> triggering parameter
+ * payload <code>state</code> as <code>OPEN</code> and <code>channelType</code> as
+ * <code>MESSAGING</code> for Peer.</small> <ol><li><a href="#event_dataStreamState">
+ * <code>dataStreamState</code> event</a> triggers parameter payload <code>state</code> as <code>START_ERROR</code>.</li>
+ * <li><b>ABORT</b> step and return error.</li></ol></li>
+ * <li>If MCU is enabled for the App Key provided in <a href="#method_init"><code>init()</code>method</a> and connected: <ol>
+ * <li>If MCU Peer connection messaging Datachannel has not been opened: <small>This can be checked with
+ * <a href="#event_dataChannelState"><code>dataChannelState</code> event</a> triggering parameter
+ * payload <code>state</code> as <code>OPEN</code>, <code>peerId</code> value as <code>"MCU"</code>
+ * and <code>channelType</code> as <code>MESSAGING</code> for MCU Peer.</small>
+ * <ol><li><a href="#event_dataStreamState"><code>dataStreamState</code> event</a> triggers
+ * parameter payload <code>state</code> as <code>START_ERROR</code>.</li>
+ * <li><b>ABORT</b> step and return error.</li></ol></li></ol></li>
+ * <li>Checks if should open a new data Datachannel.<ol>
+ * <li>If Peer supports simultaneous data streaming, open new data Datachannel: <small>If MCU is connected,
+ * this opens a new data Datachannel with MCU Peer with all the Peers IDs information that supports
+ * simultaneous data transfers targeted for the data streaming session instead of opening new data Datachannel
+ * with all Peers targeted for the data streaming session.</small> <ol>
+ * <li><a href="#event_dataChannelState"><code>dataChannelState</code> event</a> triggers parameter
+ * payload <code>state</code> as <code>CONNECTING</code> and <code>channelType</code> as <code>DATA</code>.
+ * <small>Note that there is no timeout to wait for parameter payload <code>state</code> to be
+ * <code>OPEN</code>.</small></li>
+ * <li>If Datachannel has been created and opened successfully: <ol>
+ * <li><a href="#event_dataChannelState"><code>dataChannelState</code> event</a> triggers parameter payload
+ * <code>state</code> as <code>OPEN</code> and <code>channelType</code> as <code>DATA</code>.</li></ol></li>
+ * <li>Else: <ol><li><a href="#event_dataChannelState"><code>dataChannelState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>CREATE_ERROR</code> and <code>channelType</code> as
+ * <code>DATA</code>.</li><li><a href="#event_dataStreamState"><code>dataStreamState</code> event</a> triggers
+ * parameter payload <code>state</code> as <code>START_ERROR</code>.</li><li><b>ABORT</b> step and
+ * return error.</li></ol></li></ol></li><li>Else: <small>If MCU is connected,
+ * this uses the messaging Datachannel with MCU Peer with all the Peers IDs information that supports
+ * simultaneous data transfers targeted for the data streaming session instead of using the messaging Datachannels
+ * with all Peers targeted for the data streaming session.</small> <ol><li>If messaging Datachannel connection has a
+ * data streaming in-progress: <ol><li><a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>START_ERROR</code>.</li><li><b>ABORT</b> step and
+ * return error.</li></ol></li><li>If there is any conflicting <a href="#method_streamData"><code>streamData()</code>
+ * method</a> data streaming session: <small>If <code>isStringStream</code> is provided as <code>true</code> and
+ * <a href="#method_sendBlobData"><code>sendBlobData()</code> method</a> or <a href="#method_sendURLData">
+ * <code>sendURLData()</code> method</a> has an existing binary string transfer, it cannot start string data
+ * streaming session. Else if <a href="#method_sendBlobData"><code>sendBlobData()</code> method</a>
+ * has an existing binary data transfer, it cannot start binary data streaming session.</small><ol>
+ * <li><a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>START_ERROR</code>.</li><li><b>ABORT</b> step and
+ * return error.</li></ol></li></li></ol></ol></li></ol></li>
+ * <li>Starts the data streaming session with Peer. <ol>
+ * <li><a href="#event_incomingDataStreamStarted"><code>incomingDataStreamStarted</code> event</a> triggers.</li>
+ * <li><em>For User only</em> <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>SENDING_STARTED</code>.</li>
+ * <li><em>For Peer only</em> <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>RECEIVING_STARTED</code>.</li></ol></li></ol>
+ * @example
+ * // Example 1: Start streaming to all Peers
+ * skylinkDemo.on("dataChannelState", function (state, peerId, error, channelName, channelType) {
+ * if (state === skylinkDemo.DATA_CHANNEL_STATE.OPEN &&
+ * channelType === skylinkDemo.DATA_CHANNEL_TYPE.MESSAGING) {
+ * skylinkDemo.startStreamingData(false);
+ * }
+ * });
+ *
+ * // Example 2: Start streaming to specific Peers
+ * var peersInExclusiveParty = [];
+ *
+ * skylinkDemo.on("peerJoined", function (peerId, peerInfo, isSelf) {
+ * if (isSelf) return;
+ * if (peerInfo.userData.exclusive) {
+ * peersInExclusiveParty[peerId] = false;
+ * }
+ * });
+ *
+ * skylinkDemo.on("dataChannelState", function (state, peerId, error, channelName, channelType) {
+ * if (state === skylinkDemo.DATA_CHANNEL_STATE.OPEN &&
+ * channelType === skylinkDemo.DATA_CHANNEL_TYPE.MESSAGING) {
+ * peersInExclusiveParty[peerId] = true;
+ * }
+ * });
+ *
+ * function updateExclusivePartyStatus (message) {
+ * var readyToSend = [];
+ * for (var p in peersInExclusiveParty) {
+ * if (peersInExclusiveParty.hasOwnProperty(p)) {
+ * readyToSend.push(p);
+ * }
+ * }
+ * skylinkDemo.startStreamingData(message, readyToSend);
+ * }
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.startStreamingData = function(isStringStream, targetPeerId) {
+ var self = this;
+ var listOfPeers = Object.keys(self._dataChannels);
+ var isPrivate = false;
+ var sessionChunkType = 'binary';
+
+ if (Array.isArray(targetPeerId)) {
+ listOfPeers = targetPeerId;
+ isPrivate = true;
+ } else if (targetPeerId && typeof targetPeerId === 'string') {
+ listOfPeers = [targetPeerId];
+ isPrivate = true;
+ }
+
+ if (Array.isArray(isStringStream)) {
+ listOfPeers = isStringStream;
+ targetPeerId = isStringStream;
+ isPrivate = true;
+ } else if (isStringStream && typeof isStringStream === 'string') {
+ listOfPeers = [isStringStream];
+ targetPeerId = isStringStream;
+ isPrivate = true;
+ } else if (isStringStream && typeof isStringStream === 'boolean') {
+ sessionChunkType = 'string';
+ }
+
+ var sessionInfo = {
+ chunk: null,
+ chunkSize: 0,
+ chunkType: sessionChunkType === 'string' ? self.DATA_TRANSFER_DATA_TYPE.STRING : self._binaryChunkType,
+ isPrivate: isPrivate,
+ isStringStream: sessionChunkType === 'string',
+ senderPeerId: self._user && self._user.sid ? self._user.sid : null
+ };
+
+ // Remove MCU from list
+ if (listOfPeers.indexOf('MCU') > -1) {
+ listOfPeers.splice(listOfPeers.indexOf('MCU'), 1);
+ }
+
+ var emitErrorBeforeStreamingFn = function (error) {
+ log.error(error);
+
+ /*if (listOfPeers.length > 0) {
+ for (var i = 0; i < listOfPeers.length; i++) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.START_ERROR, null,
+ listOfPeers[i], sessionInfo, new Error(error));
+ }
+ } else {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.START_ERROR, null,
+ null, sessionInfo, new Error(error));
+ }*/
+ };
+
+ if (!this._inRoom || !(this._user && this._user.sid)) {
+ return emitErrorBeforeStreamingFn('Unable to start data streaming as User is not in Room.');
+ }
+
+ if (!this._enableDataChannel) {
+ return emitErrorBeforeStreamingFn('Unable to start data streaming as User does not have Datachannel enabled.');
+ }
+
+ if (listOfPeers.length === 0) {
+ return emitErrorBeforeStreamingFn('Unable to start data streaming as there are no Peers to start session with.');
+ }
+
+ var transferId = 'stream_' + (self._user && self._user.sid ? self._user.sid : '-') + '_' + (new Date()).getTime();
+ var peersInterop = [];
+ var peersNonInterop = [];
+ var sessions = {};
+ var listenToPeerFn = function (peerId, channelProp) {
+ var hasStarted = false;
+ sessions[peerId] = channelProp;
+
+ self.once('dataStreamState', function () {}, function (state, evtTransferId, evtPeerId, evtSessionInfo) {
+ if (!(evtTransferId === transferId && evtPeerId === peerId)) {
+ return;
+ }
+
+ var dataChunk = evtSessionInfo.chunk;
+ var updatedSessionInfo = clone(evtSessionInfo);
+ delete updatedSessionInfo.chunk;
+
+ if (state === self.DATA_STREAM_STATE.SENDING_STARTED) {
+ hasStarted = true;
+ return;
+ }
+
+ if (hasStarted && [self.DATA_STREAM_STATE.ERROR, self.DATA_STREAM_STATE.SENDING_STOPPED].indexOf(state) > -1) {
+ if (channelProp === transferId) {
+ self._closeDataChannel(peerId, transferId);
+ }
+
+ if (self._dataStreams[transferId] && self._dataStreams[transferId].sessions[peerId]) {
+ delete self._dataStreams[transferId].sessions[peerId];
+
+ if (Object.keys(self._dataStreams[transferId].sessions).length === 0) {
+ delete self._dataStreams[transferId];
+ }
+ }
+ return true;
+ }
+ });
+ };
+
+ // Loop out unwanted Peers
+ for (var i = 0; i < listOfPeers.length; i++) {
+ var peerId = listOfPeers[i];
+ var error = null;
+ var dtProtocolVersion = ((self._peerInformations[peerId] || {}).agent || {}).DTProtocolVersion || '';
+ var channelProp = self._isLowerThanVersion(dtProtocolVersion, '0.1.2') ? 'main' : transferId;
+
+ if (!(self._dataChannels[peerId] && self._dataChannels[peerId].main)) {
+ error = 'Datachannel connection does not exists';
+ } else if (self._hasMCU && !(self._dataChannels.MCU && self._dataChannels.MCU.main)) {
+ error = 'MCU Datachannel connection does not exists';
+ } else if (self._isLowerThanVersion(dtProtocolVersion, '0.1.3')) {
+ error = 'Peer DTProtocolVersion does not support data streaming. (received: "' + dtProtocolVersion + '", expected: "0.1.3")';
+ } else {
+ if (channelProp === 'main') {
+ var dataTransferId = self._hasMCU ? self._dataChannels.MCU.main.transferId : self._dataChannels[peerId].main.transferId;
+
+ if (self._dataChannels[peerId].main.streamId) {
+ error = 'Peer Datachannel currently has an active data transfer session.';
+ } else if (self._hasMCU && self._dataChannels.MCU.main.streamId) {
+ error = 'MCU Peer Datachannel currently has an active data transfer session.';
+ } else if (self._dataTransfers[dataTransferId] && self._dataTransfers[dataTransferId].sessionChunkType === sessionChunkType) {
+ error = (self._hasMCU ? 'MCU ' : '') + 'Peer Datachannel currently has an active ' + sessionChunkType + ' data transfer.';
+ } else {
+ peersInterop.push(peerId);
+ }
+ } else {
+ peersNonInterop.push(peerId);
+ }
+ }
+
+ if (error) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.START_ERROR, transferId, peerId, sessionInfo, new Error(error));
+ listOfPeers.splice(i, 1);
+ i--;
+ } else {
+ listenToPeerFn(peerId, channelProp);
+ }
+ }
+
+ if (listOfPeers.length === 0) {
+ log.warn('There are no Peers to start data session with.');
+ return;
+ }
+
+ self._dataStreams[transferId] = {
+ sessions: sessions,
+ chunkType: sessionChunkType === 'string' ? self.DATA_TRANSFER_DATA_TYPE.STRING : self._binaryChunkType,
+ sessionChunkType: sessionChunkType,
+ isPrivate: isPrivate,
+ isStringStream: sessionChunkType === 'string',
+ senderPeerId: self._user && self._user.sid ? self._user.sid : null,
+ isUpload: true
+ };
+
+ var startDataSessionFn = function (peerId, channelProp, targetPeers) {
+ self.once('dataChannelState', function () {}, function (state, evtPeerId, channelName, channelType, error) {
+ if (!self._dataStreams[transferId]) {
+ return true;
+ }
+
+ if (!(evtPeerId === peerId && (channelProp === 'main' ? channelType === self.DATA_CHANNEL_TYPE.MESSAGING :
+ channelName === transferId && channelType === self.DATA_CHANNEL_TYPE.DATA))) {
+ return;
+ }
+
+ if ([self.DATA_CHANNEL_STATE.ERROR, self.DATA_CHANNEL_STATE.CLOSED].indexOf(state) > -1) {
+ var updatedError = new Error(error && error.message ? error.message :
+ 'Failed data transfer as datachannel state is "' + state + '".');
+
+ if (peerId === 'MCU') {
+ for (var mp = 0; mp < targetPeers.length; mp++) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.ERROR, transferId, targetPeers[mp], sessionInfo, updatedError);
+ }
+ } else {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.ERROR, transferId, peerId, sessionInfo, updatedError);
+ }
+ return true;
+ }
+ });
+
+ if (!(self._dataChannels[peerId][channelProp] &&
+ self._dataChannels[peerId][channelProp].channel.readyState === self.DATA_CHANNEL_STATE.OPEN)) {
+ var notOpenError = new Error('Failed starting data streaming session as channel is not opened.');
+ if (peerId === 'MCU') {
+ for (i = 0; i < targetPeers.length; i++) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.START_ERROR, transferId, targetPeers[i], sessionInfo, notOpenError);
+ }
+ } else {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.START_ERROR, transferId, peerId, sessionInfo, notOpenError);
+ }
+ }
+
+ self._sendMessageToDataChannel(peerId, {
+ type: self._DC_PROTOCOL_TYPE.WRQ,
+ transferId: transferId,
+ name: transferId,
+ size: 0,
+ originalSize: 0,
+ dataType: 'fastBinaryStart',
+ mimeType: null,
+ chunkType: sessionChunkType,
+ chunkSize: 0,
+ timeout: 0,
+ isPrivate: isPrivate,
+ sender: self._user.sid,
+ agent: window.webrtcDetectedBrowser,
+ version: window.webrtcDetectedVersion,
+ target: peerId === 'MCU' ? targetPeers : peerId
+ }, channelProp);
+ self._dataChannels[peerId][channelProp].streamId = transferId;
+
+ var updatedSessionInfo = clone(sessionInfo);
+ delete updatedSessionInfo.chunk;
+
+ if (peerId === 'MCU') {
+ for (var tp = 0; tp < targetPeers.length; tp++) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.SENDING_STARTED, transferId, targetPeers[tp], sessionInfo, null);
+ self._trigger('incomingDataStreamStarted', transferId, targetPeers[tp], updatedSessionInfo, true);
+ }
+ } else {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.SENDING_STARTED, transferId, peerId, sessionInfo, null);
+ self._trigger('incomingDataStreamStarted', transferId, peerId, updatedSessionInfo, true);
+ }
+ };
+
+ var waitForChannelOpenFn = function (peerId, targetPeers) {
+ self.once('dataChannelState', function (state, evtPeerId, error) {
+ if (state === self.DATA_CHANNEL_STATE.CREATE_ERROR) {
+ if (peerId === 'MCU') {
+ for (var mp = 0; mp < targetPeers.length; mp++) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.START_ERROR, transferId, targetPeers[mp], sessionInfo, error);
+ }
+ } else {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.START_ERROR, transferId, peerId, sessionInfo, error);
+ }
+ return;
+ }
+ startDataSessionFn(peerId, transferId, targetPeers);
+ }, function (state, evtPeerId, error, channelName, channelType) {
+ if (evtPeerId === peerId && channelName === transferId && channelType === self.DATA_CHANNEL_TYPE.DATA) {
+ return [self.DATA_CHANNEL_STATE.CREATE_ERROR, self.DATA_CHANNEL_STATE.OPEN].indexOf(state) > -1;
+ }
+ });
+ self._createDataChannel(peerId, transferId, sessionChunkType === 'string' ? self._CHUNK_DATAURL_SIZE :
+ (window.webrtcDetectedBrowser === 'firefox' ? self._MOZ_BINARY_FILE_SIZE : self._BINARY_FILE_SIZE));
+ };
+
+ if (peersNonInterop.length > 0) {
+ if (self._hasMCU) {
+ waitForChannelOpenFn('MCU', peersNonInterop);
+ } else {
+ for (var pni = 0; pni < peersNonInterop.length; pni++) {
+ waitForChannelOpenFn(peersNonInterop[pni], null);
+ }
+ }
+ }
+
+ if (peersInterop.length > 0) {
+ if (self._hasMCU) {
+ startDataSessionFn('MCU', 'main', peersInterop);
+ } else {
+ for (var pi = 0; pi < peersInterop.length; pi++) {
+ startDataSessionFn(peersInterop[pi], 'main', null);
+ }
+ }
+ }
+};
+
+/**
+ * <blockquote class="info">
+ * To start data streaming session, see the <a href="#method_startStreamingData"><code>startStreamingData()</code>
+ * method</a>. To stop data streaming session, see the <a href="#method_stopStreamingData"><code>stopStreamingData()</code> method</a>
+ * </blockquote>
+ * Function that sends a data chunk from User to Peers for an existing active data streaming session.
+ * @method streamData
+ * @param {String} streamId The data streaming session ID.
+ * @param {String|Blob|ArrayBuffer} chunk The data chunk.
+ * <small>By default when it is not string data streaming, data chunks when is are expected to be
+ * sent in Blob or ArrayBuffer, and ArrayBuffer data chunks will be converted to Blob.</small>
+ * <small>For binary data chunks, the limit is <code>65456</code>.</small>
+ * <small>For string data chunks, the limit is <code>1212</code>.</small>
+ * @trigger <ol class="desc-seq">
+ * <li>Checks if Peer connection and Datachannel connection are in correct states. <ol>
+ * <li>If Peer connection (or MCU Peer connection if enabled)
+ * data streaming Datachannel has not been opened: <small>This can be checked with
+ * <a href="#event_dataChannelState"><code>dataChannelState</code> event</a> triggering parameter
+ * payload <code>state</code> as <code>OPEN</code> and <code>channelType</code> as
+ * <code>MESSAGING</code> for Peer.</small> <ol><li><a href="#event_dataStreamState">
+ * <code>dataStreamState</code> event</a> triggers parameter payload <code>state</code> as <code>ERROR</code>.</li>
+ * <li><b>ABORT</b> step and return error.</li></ol></li></ol></li>
+ * <li>Starts sending the data chunk to Peer. <ol>
+ * <li><a href="#event_incomingDataStream"><code>incomingDataStream</code> event</a> triggers.</li>
+ * <li><em>For User only</em> <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>SENT</code>.</li>
+ * <li><em>For Peer only</em> <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>RECEIVED</code>.</li></ol></li></ol>
+ * @example
+ * // Example 1: Start streaming
+ * var currentStreamId = null
+ * if (file.size > chunkLimit) {
+ * while ((file.size - 1) > endCount) {
+ * endCount = startCount + chunkLimit;
+ * chunks.push(file.slice(startCount, endCount));
+ * startCount += chunkLimit;
+ * }
+ * if ((file.size - (startCount + 1)) > 0) {
+ * chunks.push(file.slice(startCount, file.size - 1));
+ * }
+ * } else {
+ * chunks.push(file);
+ * }
+ * var processNextFn = function () {
+ * if (chunks.length > 0) {
+ * skylinkDemo.once("incomingDataStream", function () {
+ * setTimeout(processNextFn, 1);
+ * }, function (data, evtStreamId, evtPeerId, streamInfo, isSelf) {
+ * return isSelf && evtStreamId === currentStreamId;
+ * });
+ * var chunk = chunks[0];
+ * chunks.splice(0, 1);
+ * skylinkDemo.streamData(currentStreamId, chunk);
+ * } else {
+ * skylinkDemo.stopStreamingData(currentStreamId);
+ * }
+ * };
+ * skylinkDemo.once("incomingDataStreamStarted", processNextFn, function (streamId, peerId, streamInfo, isSelf) {
+ * currentStreamId = streamId;
+ * return isSelf;
+ * });
+ * skylinkDemo.once("incomingDataStreamStopped", function () {
+ * // Render file
+ * }, function (streamId, peerId, streamInfo, isSelf) {
+ * return currentStreamId === streamId && isSelf;
+ * });
+ * skylinkDemo.startStreamingData(false);
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.streamData = function(transferId, dataChunk) {
+ var self = this;
+
+ if (!(transferId && typeof transferId === 'string')) {
+ log.error('Failed streaming data chunk as stream session ID is not provided.');
+ return;
+ }
+
+ if (!(dataChunk && typeof dataChunk === 'object' && (dataChunk instanceof Blob || dataChunk instanceof ArrayBuffer))) {
+ log.error('Failed streaming data chunk as it is not provided.');
+ return;
+ }
+
+ if (!(self._inRoom && self._user && self._user.sid)) {
+ log.error('Failed streaming data chunk as User is not in the Room.');
+ return;
+ }
+
+ if (!self._dataStreams[transferId]) {
+ log.error('Failed streaming data chunk as session does not exists.');
+ return;
+ }
+
+ if (!self._dataStreams[transferId].isUpload) {
+ log.error('Failed streaming data chunk as session is not sending.');
+ return;
+ }
+
+ if (self._dataStreams[transferId].sessionChunkType === 'string' ? typeof dataChunk !== 'string' :
+ typeof dataChunk !== 'object') {
+ log.error('Failed streaming data chunk as data chunk does not match expected data type.');
+ return;
+ }
+
+ var updatedDataChunk = dataChunk instanceof ArrayBuffer ? new Blob(dataChunk) : dataChunk;
+
+ if (self._dataStreams[transferId].sessionChunkType === 'string' ? updatedDataChunk.length > self._CHUNK_DATAURL_SIZE :
+ updatedDataChunk.length > self._BINARY_FILE_SIZE) {
+ log.error('Failed streaming data chunk as data chunk exceeds maximum chunk limit.');
+ return;
+ }
+
+ var sessionInfo = {
+ chunk: updatedDataChunk,
+ chunkSize: updatedDataChunk.size || updatedDataChunk.length || updatedDataChunk.byteLength,
+ chunkType: self._dataStreams[transferId].sessionChunkType === 'string' ?
+ self.DATA_TRANSFER_DATA_TYPE.STRING : self._binaryChunkType,
+ isPrivate: self._dataStreams[transferId].sessionChunkType.isPrivate,
+ isStringStream: self._dataStreams[transferId].sessionChunkType === 'string',
+ senderPeerId: self._user && self._user.sid ? self._user.sid : null
+ };
+
+ var peersInterop = [];
+ var peersNonInterop = [];
+ var sendDataFn = function (peerId, channelProp, targetPeers) {
+ // When ready to be sent
+ var onSendDataFn = function (buffer) {
+ self._sendMessageToDataChannel(peerId, buffer, channelProp, true);
+
+ if (targetPeers) {
+ for (var i = 0; i < targetPeers.length; i++) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.SENT, transferId, targetPeers[i], sessionInfo, null);
+ self._trigger('incomingDataStream', dataChunk, transferId, targetPeers[i], updatedSessionInfo, true);
+ }
+ } else {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.SENT, transferId, peerId, sessionInfo, null);
+ self._trigger('incomingDataStream', dataChunk, transferId, peerId, updatedSessionInfo, true);
+ }
+ };
+
+ if (dataChunk instanceof Blob && sessionInfo.chunkType === self.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER) {
+ self._blobToArrayBuffer(dataChunk, onSendDataFn);
+ } else if (!(dataChunk instanceof Blob) && sessionInfo.chunkType === self.DATA_TRANSFER_DATA_TYPE.BLOB) {
+ onSendDataFn(new Blob([dataChunk]));
+ } else if (['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1 && typeof dataChunk !== 'string') {
+ onSendDataFn(new Int8Array(dataChunk));
+ } else {
+ onSendDataFn(dataChunk);
+ }
+ };
+
+ for (var peerId in self._dataStreams[transferId].sessions) {
+ if (self._dataStreams[transferId].sessions.hasOwnProperty(peerId) && self._dataStreams[transferId].sessions[peerId]) {
+ var channelProp = self._dataStreams[transferId].sessions[peerId];
+
+ if (!(self._dataChannels[self._hasMCU ? 'MCU' : peerId] && self._dataChannels[self._hasMCU ? 'MCU' : peerId][channelProp] &&
+ self._dataChannels[self._hasMCU ? 'MCU' : peerId][channelProp].channel.readyState === self.DATA_CHANNEL_STATE.OPEN &&
+ self._dataChannels[self._hasMCU ? 'MCU' : peerId][channelProp].streamId === transferId)) {
+ log.error([peerId, 'RTCDataChannel', transferId, 'Failed streaming data as it has not started or is ready.']);
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.ERROR, transferId, peerId, sessionInfo,
+ new Error('Streaming as it has not started or Datachannel connection is not open.'));
+ return;
+ }
+
+ if (self._hasMCU) {
+ if (channelProp === 'main') {
+ peersInterop.push(peerId);
+ } else {
+ peersNonInterop.push(peerId);
+ }
+ } else {
+ sendDataFn(peerId, channelProp);
+ }
+ }
+ }
+
+ if (self._hasMCU) {
+ if (peersInterop.length > 0) {
+ sendDataFn(peerId, 'main', peersInterop);
+ }
+ if (peersNonInterop.length > 0) {
+ sendDataFn(peerId, transferId, peersNonInterop);
+ }
+ }
+};
+
+/**
+ * <blockquote class="info">
+ * To start data streaming session, see the <a href="#method_startStreamingData"><code>startStreamingData()</code>
+ * method</a> To start streaming data, see the <a href="#method_streamData"><code>streamData()</code>
+ * method</a>.
+ * </blockquote>
+ * Function that stops a data chunks streaming session from User to Peers.
+ * @method stopStreamingData
+ * @param {String} streamId The data streaming session ID.
+ * @trigger <ol class="desc-seq">
+ * <li>Checks if Peer connection and Datachannel connection are in correct states. <ol>
+ * <li>If Peer connection (or MCU Peer connection if enabled)
+ * data streaming Datachannel has not been opened: <small>This can be checked with
+ * <a href="#event_dataChannelState"><code>dataChannelState</code> event</a> triggering parameter
+ * payload <code>state</code> as <code>OPEN</code> and <code>channelType</code> as
+ * <code>MESSAGING</code> for Peer.</small> <ol><li><a href="#event_dataStreamState">
+ * <code>dataStreamState</code> event</a> triggers parameter payload <code>state</code> as <code>ERROR</code>.</li>
+ * <li><b>ABORT</b> step and return error.</li></ol></li></ol></li>
+ * <li>Stops the data streaming session to Peer. <ol>
+ * <li><a href="#event_incomingDataStreamStopped"><code>incomingDataStreamStopped</code> event</a> triggers.</li>
+ * <li><em>For User only</em> <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>SENDING_STOPPED</code>.</li>
+ * <li><em>For Peer only</em> <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * triggers parameter payload <code>state</code> as <code>RECEIVING_STOPPED</code>.</li></ol></li></ol>
+ * @example
+ * skylinkDemo.stopStreamData(streamId);
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
*/
-Skylink.prototype.sendP2PMessage = function(message, targetPeerId) {
- var listOfPeers = Object.keys(this._dataChannels);
- var isPrivate = false;
+Skylink.prototype.stopStreamingData = function(transferId) {
+ var self = this;
- if (Array.isArray(targetPeerId)) {
- listOfPeers = targetPeerId;
- isPrivate = true;
- } else if (targetPeerId && typeof targetPeerId === 'string') {
- listOfPeers = [targetPeerId];
- isPrivate = true;
+ if (!(transferId && typeof transferId === 'string')) {
+ log.error('Failed streaming data chunk as stream session ID is not provided.');
+ return;
}
- if (!this._inRoom || !this._user) {
- log.error('Unable to send message as User is not in Room. ->', message);
+ if (!(self._inRoom && self._user && self._user.sid)) {
+ log.error('Failed streaming data chunk as User is not in the Room.');
return;
}
- if (!this._enableDataChannel) {
- log.error('Unable to send message as User does not have Datachannel enabled. ->', message);
+ if (!self._dataStreams[transferId]) {
+ log.error('Failed stopping data streaming session as it does not exists.');
return;
}
- // Loop out unwanted Peers
- for (var i = 0; i < listOfPeers.length; i++) {
- var peerId = listOfPeers[i];
+ if (!self._dataStreams[transferId].isUpload) {
+ log.error('Failed stopping data streaming session as it is not sending.');
+ return;
+ }
- if (!this._dataChannels[peerId]) {
- log.error([peerId, 'RTCDataChannel', null, 'Dropping of sending message to Peer as ' +
- 'Datachannel connection does not exists']);
- listOfPeers.splice(i, 1);
- i--;
- } else if (peerId === 'MCU') {
- listOfPeers.splice(i, 1);
- i--;
- } else if (!this._hasMCU) {
- log.debug([peerId, 'RTCDataChannel', null, 'Sending ' + (isPrivate ? 'private' : '') +
- ' P2P message to Peer']);
+ var sessionInfo = {
+ chunk: null,
+ chunkSize: 0,
+ chunkType: self._dataStreams[transferId].sessionChunkType === 'string' ?
+ self.DATA_TRANSFER_DATA_TYPE.STRING : self._binaryChunkType,
+ isPrivate: self._dataStreams[transferId].sessionChunkType.isPrivate,
+ isStringStream: self._dataStreams[transferId].sessionChunkType === 'string',
+ senderPeerId: self._user && self._user.sid ? self._user.sid : null
+ };
- this._sendMessageToDataChannel(peerId, {
- type: this._DC_PROTOCOL_TYPE.MESSAGE,
- isPrivate: isPrivate,
- sender: this._user.sid,
- target: peerId,
- data: message
- }, 'main');
+ var peersInterop = [];
+ var peersNonInterop = [];
+ var sendDataFn = function (peerId, channelProp, targetPeers) {
+ self._sendMessageToDataChannel(peerId, {
+ type: self._DC_PROTOCOL_TYPE.WRQ,
+ transferId: transferId,
+ name: transferId,
+ size: 0,
+ originalSize: 0,
+ dataType: 'fastBinaryStop',
+ mimeType: null,
+ chunkType: self._dataStreams[transferId].sessionChunkType,
+ chunkSize: 0,
+ timeout: 0,
+ isPrivate: self._dataStreams[transferId].isPrivate,
+ sender: self._user.sid,
+ agent: window.webrtcDetectedBrowser,
+ version: window.webrtcDetectedVersion,
+ target: targetPeers ? targetPeers : peerId
+ }, channelProp);
+
+ var updatedSessionInfo = clone(sessionInfo);
+ delete updatedSessionInfo.chunk;
+
+ if (targetPeers) {
+ for (var i = 0; i < targetPeers.length; i++) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.SENDING_STOPPED, transferId, targetPeers[i], sessionInfo, null);
+ self._trigger('incomingDataStreamStopped', transferId, targetPeers[i], updatedSessionInfo, true);
+ }
+ } else {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.SENDING_STOPPED, transferId, peerId, sessionInfo, null);
+ self._trigger('incomingDataStreamStopped', transferId, peerId, updatedSessionInfo, true);
}
- }
+ };
- if (listOfPeers.length === 0) {
- log.warn('Currently there are no Peers to send P2P message to (unless the message is queued ' +
- 'and there are Peer connected by then).');
- }
+ for (var peerId in self._dataStreams[transferId].sessions) {
+ if (self._dataStreams[transferId].sessions.hasOwnProperty(peerId) && self._dataStreams[transferId].sessions[peerId]) {
+ var channelProp = self._dataStreams[transferId].sessions[peerId];
- if (this._hasMCU) {
- log.debug(['MCU', 'RTCDataChannel', null, 'Broadcasting ' + (isPrivate ? 'private' : '') +
- ' P2P message to Peers']);
+ if (!(self._dataChannels[self._hasMCU ? 'MCU' : peerId] && self._dataChannels[self._hasMCU ? 'MCU' : peerId][channelProp] &&
+ self._dataChannels[self._hasMCU ? 'MCU' : peerId][channelProp].channel.readyState === self.DATA_CHANNEL_STATE.OPEN &&
+ self._dataChannels[self._hasMCU ? 'MCU' : peerId][channelProp].streamId === transferId)) {
+ log.error([peerId, 'RTCDataChannel', transferId, 'Failed stopping data streaming session as channel is closed.']);
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.ERROR, transferId, peerId, sessionInfo,
+ new Error('Failed stopping data streaming session as Datachannel connection is not open or is active.'));
+ return;
+ }
- this._sendMessageToDataChannel('MCU', {
- type: this._DC_PROTOCOL_TYPE.MESSAGE,
- isPrivate: isPrivate,
- sender: this._user.sid,
- target: listOfPeers,
- data: message
- }, 'main');
+ if (self._hasMCU) {
+ if (self._dataStreams[transferId].sessions[peerId] === 'main') {
+ peersInterop.push(peerId);
+ } else {
+ peersNonInterop.push(peerId);
+ }
+ } else {
+ sendDataFn(peerId, channelProp);
+ }
+ }
}
- this._trigger('incomingMessage', {
- content: message,
- isPrivate: isPrivate,
- targetPeerId: targetPeerId || null,
- listOfPeers: listOfPeers,
- isDataChannel: true,
- senderPeerId: this._user.sid
- }, this._user.sid, this.getPeerInfo(), true);
+ if (self._hasMCU) {
+ if (peersInterop.length > 0) {
+ sendDataFn(peerId, 'main', peersInterop);
+ }
+ if (peersNonInterop.length > 0) {
+ sendDataFn(peerId, transferId, peersNonInterop);
+ }
+ }
};
+
/**
* Function that starts the data transfer to Peers.
* @method _startDataTransfer
@@ -1238,16 +1764,158 @@
File: source/data-transfer.js
* @for Skylink
* @since 0.6.1
*/
-Skylink.prototype._startDataTransfer = function(chunks, transferInfo, listOfPeers, callback) {
+Skylink.prototype._startDataTransfer = function(data, timeout, targetPeerId, sendChunksAsBinary, callback, sessionType) {
var self = this;
- var transferId = self._user.sid + '_' + (new Date()).getTime();
+ var transferId = (self._user ? self._user.sid : '') + '_' + (new Date()).getTime();
var transferErrors = {};
var transferCompleted = [];
+ var chunks = [];
+ var listOfPeers = Object.keys(self._peerConnections);
+ var sessionChunkType = 'string';
+ var transferInfo = {
+ name: null,
+ size: null,
+ chunkSize: null,
+ chunkType: null,
+ dataType: null,
+ mimeType: null,
+ direction: self.DATA_TRANSFER_TYPE.UPLOAD,
+ timeout: 60,
+ isPrivate: false,
+ percentage: 0
+ };
+
+ // sendBlobData(.., timeout)
+ if (typeof timeout === 'number') {
+ transferInfo.timeout = timeout;
+ } else if (Array.isArray(timeout)) {
+ listOfPeers = timeout;
+ } else if (timeout && typeof timeout === 'string') {
+ listOfPeers = [timeout];
+ } else if (timeout && typeof timeout === 'boolean') {
+ sessionChunkType = 'binary';
+ } else if (typeof timeout === 'function') {
+ callback = timeout;
+ }
+
+ // sendBlobData(.., .., targetPeerId)
+ if (Array.isArray(targetPeerId)) {
+ listOfPeers = targetPeerId;
+ } else if (targetPeerId && typeof targetPeerId === 'string') {
+ listOfPeers = [targetPeerId];
+ } else if (targetPeerId && typeof targetPeerId === 'boolean') {
+ sessionChunkType = 'binary';
+ } else if (typeof targetPeerId === 'function') {
+ callback = targetPeerId;
+ }
+
+ // sendBlobData(.., .., .., sendChunksAsBinary)
+ if (sendChunksAsBinary && typeof sendChunksAsBinary === 'boolean') {
+ sessionChunkType = 'binary';
+ } else if (typeof sendChunksAsBinary === 'function') {
+ callback = sendChunksAsBinary;
+ }
+
+ // Remove MCU Peer as list of Peers
+ if (listOfPeers.indexOf('MCU') > -1) {
+ listOfPeers.splice(listOfPeers.indexOf('MCU'), 1);
+ }
+
+ // Function that returns the error emitted before data transfer has started
+ var emitErrorBeforeDataTransferFn = function (error) {
+ log.error(error);
+
+ if (typeof callback === 'function') {
+ var transferErrors = {};
+
+ if (listOfPeers.length === 0) {
+ transferErrors.self = new Error(error);
+ /*self._trigger('dataTransferState', self.DATA_TRANSFER_STATE.START_ERROR, null, null, transferInfo, {
+ transferType: self.DATA_TRANSFER_TYPE.DOWNLOAD,
+ message: new Error(error)
+ });*/
+ } else {
+ for (var i = 0; i < listOfPeers.length; i++) {
+ transferErrors[listOfPeers[i]] = new Error(error);
+ /*self._trigger('dataTransferState', self.DATA_TRANSFER_STATE.START_ERROR, null, listOfPeers[i], transferInfo, {
+ transferType: self.DATA_TRANSFER_TYPE.DOWNLOAD,
+ message: new Error(error)
+ });*/
+ }
+ }
+
+ callback({
+ transferId: null,
+ transferInfo: transferInfo,
+ listOfPeers: listOfPeers,
+ transferErrors: transferErrors
+ }, null);
+ }
+ };
+
+ if (sessionType === 'blob') {
+ if (self._hasMCU && sessionChunkType === 'binary') {
+ log.warn('Binary data chunks transfer is not yet supported with MCU environment. ' +
+ 'Fallbacking to binary string data chunks transfer.');
+ sessionChunkType = 'string';
+ }
+
+ var chunkSize = sessionChunkType === 'string' ? (window.webrtcDetectedBrowser === 'firefox' ?
+ self._MOZ_CHUNK_FILE_SIZE : self._CHUNK_FILE_SIZE) : (window.webrtcDetectedBrowser === 'firefox' ?
+ self._MOZ_BINARY_FILE_SIZE : self._BINARY_FILE_SIZE);
+
+ transferInfo.dataType = self.DATA_TRANSFER_SESSION_TYPE.BLOB;
+ transferInfo.chunkSize = sessionChunkType === 'string' ? 4 * Math.ceil(chunkSize / 3) : chunkSize;
+ transferInfo.chunkType = sessionChunkType === 'binary' ? self._binaryChunkType : self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING;
+
+ // Start checking if data transfer can start
+ if (!(data && typeof data === 'object' && data instanceof Blob)) {
+ emitErrorBeforeDataTransferFn('Provided data is not a Blob data');
+ return;
+ }
+
+ transferInfo.name = data.name || transferId;
+ transferInfo.mimeType = data.type || null;
+
+ if (data.size < 1) {
+ emitErrorBeforeDataTransferFn('Provided data is not a valid Blob data.');
+ return;
+ }
+
+ transferInfo.originalSize = data.size;
+ transferInfo.size = sessionChunkType === 'string' ? 4 * Math.ceil(data.size / 3) : data.size;
+ chunks = self._chunkBlobData(data, chunkSize);
+ } else {
+ transferInfo.dataType = self.DATA_TRANSFER_SESSION_TYPE.DATA_URL;
+ transferInfo.chunkSize = self._CHUNK_DATAURL_SIZE;
+ transferInfo.chunkType = self.DATA_TRANSFER_DATA_TYPE.STRING;
+
+ // Start checking if data transfer can start
+ if (!(data && typeof data === 'string')) {
+ emitErrorBeforeDataTransferFn('Provided data is not a dataURL');
+ return;
+ }
+
+ transferInfo.originalSize = transferInfo.size = data.length || data.size;
+ chunks = self._chunkDataURL(data, transferInfo.chunkSize);
+ }
+
+ if (!(self._user && self._user.sid)) {
+ emitErrorBeforeDataTransferFn('Unable to send any ' +
+ sessionType.replace('data', 'dataURL') + ' data. User is not in Room.');
+ return;
+ }
+
+ if (!self._enableDataChannel) {
+ emitErrorBeforeDataTransferFn('Unable to send any ' +
+ sessionType.replace('data', 'dataURL') + ' data. Datachannel is disabled');
+ return;
+ }
- // Polyfill data name to prevent empty fields in WRQ
- // TODO: What happens if transfer requires extension?
- if (!transferInfo.name) {
- transferInfo.name = transferId;
+ if (listOfPeers.length === 0) {
+ emitErrorBeforeDataTransferFn('Unable to send any ' +
+ sessionType.replace('data', 'dataURL') + ' data. There are no Peers to start data transfer with');
+ return;
}
self._dataTransfers[transferId] = clone(transferInfo);
@@ -1258,15 +1926,17 @@
File: source/data-transfer.js
self._dataTransfers[transferId].chunks = chunks;
self._dataTransfers[transferId].enforceBSPeers = [];
self._dataTransfers[transferId].enforcedBSInfo = {};
+ self._dataTransfers[transferId].sessionType = sessionType;
+ self._dataTransfers[transferId].sessionChunkType = sessionChunkType;
+ self._dataTransfers[transferId].senderPeerId = self._user.sid;
// Check if fallback chunks is required
- if ([self.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER, self.DATA_TRANSFER_DATA_TYPE.BLOB].indexOf(
- transferInfo.chunkType) > -1) {
+ if (sessionType === 'blob' && sessionChunkType === 'binary') {
for (var p = 0; p < listOfPeers.length; p++) {
- var agentName = (((self._peerInformations[listOfPeers[p]]) || {}).agent || {}).name || '';
+ var protocolVer = (((self._peerInformations[listOfPeers[p]]) || {}).agent || {}).DTProtocolVersion || '0.1.0';
// C++ SDK does not support binary file transfer for now
- if (self._SUPPORTED_WEB_AGENTS.indexOf(agentName) === -1) {
+ if (self._isLowerThanVersion(protocolVer, '0.1.3')) {
self._dataTransfers[transferId].enforceBSPeers.push(listOfPeers[p]);
}
}
@@ -1395,7 +2065,7 @@
File: source/data-transfer.js
var sendWRQFn = function () {
var size = self._dataTransfers[transferId].size;
var chunkSize = self._dataTransfers[transferId].chunkSize;
- var chunkType = self._dataTransfers[transferId].chunkType;
+ var chunkType = self._dataTransfers[transferId].sessionChunkType;
if (self._dataTransfers[transferId].enforceBSPeers.indexOf(peerId) > -1) {
log.warn([peerId, 'RTCDataChannel', transferId,
@@ -1404,7 +2074,7 @@
return;
}
- if (!self._user) {
+ if (!(self._user && self._user.sid)) {
log.debug([peerId, 'RTCDataChannel', transferId, 'User is not in Room. Ignoring expired timeout.']);
return;
}
@@ -1821,16 +2509,23 @@
File: source/data-transfer.js
var self = this;
var channelProp = channelType === self.DATA_CHANNEL_TYPE.MESSAGING ? 'main' : channelName;
- var transferId = channelProp === 'main' ? self._dataChannels[peerId].main.transferId : channelName;
+ var transferId = self._dataChannels[peerId][channelProp].transferId || null;
+ var streamId = self._dataChannels[peerId][channelProp].streamId || null;
+ var isStreamChunk = false;
+
+ if (streamId && self._dataStreams[streamId]) {
+ isStreamChunk = self._dataStreams[streamId].sessionChunkType === 'string' ? typeof rawData === 'string' :
+ typeof rawData === 'object';
+ }
if (!self._peerConnections[peerId]) {
- log.warn([peerId, 'RTCDataChannel', channelName, 'Dropping data received from Peer ' +
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Dropping data received from Peer ' +
'as connection is not present ->'], rawData);
return;
}
if (!(self._dataChannels[peerId] && self._dataChannels[peerId][channelProp])) {
- log.warn([peerId, 'RTCDataChannel', channelName, 'Dropping data received from Peer ' +
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Dropping data received from Peer ' +
'as Datachannel connection is not present ->'], rawData);
return;
}
@@ -1839,8 +2534,9 @@
File: source/data-transfer.js
if (typeof rawData === 'string') {
try {
var protocolData = JSON.parse(rawData);
+ isStreamChunk = false;
- log.debug([peerId, 'RTCDataChannel', channelProp, 'Received protocol message ->'], protocolData);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Received protocol "' + protocolData.type + '" message ->'], protocolData);
// Ignore ACK, ERROR and CANCEL if there is no data transfer session in-progress
if ([self._DC_PROTOCOL_TYPE.ACK, self._DC_PROTOCOL_TYPE.ERROR, self._DC_PROTOCOL_TYPE.CANCEL].indexOf(protocolData.type) > -1 &&
@@ -1855,7 +2551,7 @@
File: source/data-transfer.js
// Discard iOS bidirectional upload when Datachannel is in-progress for data transfers
if (transferId && self._dataTransfers[transferId] && self._dataTransfers[transferId].sessions[peerId]) {
log.warn([peerId, 'RTCDataChannel', channelProp, 'Rejecting bidirectional data transfer request as ' +
- 'it is currently not supported in the SDK']);
+ 'it is currently not supported in the SDK ->'], protocolData);
self._sendMessageToDataChannel(peerId, {
type: self._DC_PROTOCOL_TYPE.ACK,
@@ -1879,33 +2575,39 @@
File: source/data-transfer.js
self._MESSAGEProtocolHandler(peerId, protocolData, channelProp);
break;
default:
- log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded unknown protocol message ->'], protocolData);
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded unknown "' + protocolData.type + '" message ->'], protocolData);
}
} catch (error) {
if (rawData.indexOf('{') > -1 && rawData.indexOf('}') > 0) {
- log.error([peerId, 'RTCDataChannel', channelProp, 'Received error ->'], error);
+ log.error([peerId, 'RTCDataChannel', channelProp, 'Failed parsing protocol step data error ->'], {
+ data: rawData,
+ error: error
+ });
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.ERROR, peerId, error, channelName, channelType, null);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.ERROR, peerId, error, channelName,
+ channelType, null, self._getDataChannelBuffer(peerId, channelProp));
throw error;
}
- if (!(transferId && self._dataTransfers[transferId] && self._dataTransfers[transferId].sessions[peerId])) {
- log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded data chunk as data transfer session ' +
- 'is not present ->'], rawData);
+ if (!isStreamChunk && !(transferId && self._dataTransfers[transferId] && self._dataTransfers[transferId].sessions[peerId])) {
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded data chunk without session ->'], rawData);
return;
}
- if (self._dataTransfers[transferId].chunks[self._dataTransfers[transferId].sessions[peerId].ackN]) {
- log.warn([peerId, 'RTCDataChannel', transferId, 'Dropping data chunk as it has already been added ->'], rawData);
- return;
+ if (!isStreamChunk && transferId) {
+ if (self._dataTransfers[transferId].chunks[self._dataTransfers[transferId].sessions[peerId].ackN]) {
+ log.warn([peerId, 'RTCDataChannel', transferId, 'Dropping data chunk ' + (!isStreamChunk ? '@' +
+ self._dataTransfers[transferId].sessions[peerId].ackN : '') + ' as it has already been added ->'], rawData);
+ return;
+ }
}
var chunkType = self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING;
- if (self._dataTransfers[transferId].dataType === self.DATA_TRANSFER_SESSION_TYPE.DATA_URL) {
- log.debug([peerId, 'RTCDataChannel', channelProp, 'Received string data chunk @' +
- self._dataTransfers[transferId].sessions[peerId].ackN + ' with size ->'], rawData.length || rawData.size);
+ if (!isStreamChunk ? self._dataTransfers[transferId].dataType === self.DATA_TRANSFER_SESSION_TYPE.DATA_URL : true) {
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Received string data chunk ' + (!isStreamChunk ? '@' +
+ self._dataTransfers[transferId].sessions[peerId].ackN : '') + ' with size ->'], rawData.length || rawData.size);
self._DATAProtocolHandler(peerId, rawData, self.DATA_TRANSFER_DATA_TYPE.STRING,
rawData.length || rawData.size || 0, channelProp);
@@ -1922,24 +2624,49 @@
File: source/data-transfer.js
}
}
} else {
+ if (!isStreamChunk && !(transferId && self._dataTransfers[transferId] && self._dataTransfers[transferId].sessions[peerId])) {
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded data chunk without session ->'], rawData);
+ return;
+ }
+
+ if (!isStreamChunk && transferId) {
+ if (self._dataTransfers[transferId].chunks[self._dataTransfers[transferId].sessions[peerId].ackN]) {
+ log.warn([peerId, 'RTCDataChannel', transferId, 'Dropping data chunk ' + (!isStreamChunk ? '@' +
+ self._dataTransfers[transferId].sessions[peerId].ackN : '') + ' as it has already been added ->'], rawData);
+ return;
+ }
+ }
+
if (rawData instanceof Blob) {
- log.debug([peerId, 'RTCDataChannel', channelProp, 'Received blob data chunk @' +
- self._dataTransfers[transferId].sessions[peerId].ackN + ' with size ->'], rawData.size);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Received blob data chunk ' + (isStreamChunk ? '' :
+ '@' + self._dataTransfers[transferId].sessions[peerId].ackN) + ' with size ->'], rawData.size);
self._DATAProtocolHandler(peerId, rawData, self.DATA_TRANSFER_DATA_TYPE.BLOB, rawData.size, channelProp);
} else {
var byteArray = rawData;
+ var blob = null;
+ // Plugin binary handling
if (rawData.constructor && rawData.constructor.name === 'Array') {
// Need to re-parse on some browsers
byteArray = new Int8Array(rawData);
}
- var blob = new Blob([byteArray]);
+ // Fallback for older IE versions
+ if (window.webrtcDetectedBrowser === 'IE') {
+ if (window.BlobBuilder) {
+ var bb = new BlobBuilder();
+ bb.append(rawData.constructor && rawData.constructor.name === 'ArrayBuffer' ?
+ byteArray : (new Uint8Array(byteArray)).buffer);
+ blob = bb.getBlob();
+ }
+ } else {
+ blob = new Blob([byteArray]);
+ }
- log.debug([peerId, 'RTCDataChannel', channelProp, 'Received arraybuffer data chunk @' +
- self._dataTransfers[transferId].sessions[peerId].ackN + ' with size ->'], blob.size);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Received arraybuffer data chunk ' + (isStreamChunk ? '' :
+ '@' + self._dataTransfers[transferId].sessions[peerId].ackN) + ' with size ->'], blob.size);
self._DATAProtocolHandler(peerId, blob, self.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER, blob.size, channelProp);
}
@@ -1955,37 +2682,138 @@
* @since 0.5.4
*/
Skylink.prototype._setIceServers = function(givenConfig) {
+ var self = this;
var givenIceServers = clone(givenConfig.iceServers);
var iceServersList = {};
var newIceServers = [];
@@ -208,7 +209,7 @@
File: source/ice-connection.js
- if (this._forceTURNSSL) {
+ if (self._forceTURNSSL) {
if (window.webrtcDetectedBrowser === 'chrome' ||
window.webrtcDetectedBrowser === 'safari' ||
window.webrtcDetectedBrowser === 'IE') {
@@ -252,18 +253,18 @@
File: source/ice-connection.js
}
if (server.url.indexOf('stun') === 0) {
- if (!this._enableSTUN) {
+ if (!self._enableSTUN) {
log.warn('Ignoring STUN server provided at index ' + i, clone(server));
continue;
}
- if (!this._usePublicSTUN && server.url.indexOf('temasys') === -1) {
+ if (!self._usePublicSTUN && server.url.indexOf('temasys') === -1) {
log.warn('Ignoring public STUN server provided at index ' + i, clone(server));
continue;
}
} else if (server.url.indexOf('turn') === 0) {
- if (!this._enableTURN) {
+ if (!self._enableTURN) {
log.warn('Ignoring TURN server provided at index ' + i, clone(server));
continue;
}
@@ -300,7 +301,7 @@
File: source/ice-connection.js
var credential = typeof server.credential === 'string' ? server.credential : 'none';
if (server.url.indexOf('turn') === 0) {
- if (this._TURNTransport === this.TURN_TRANSPORT.ANY) {
+ if (self._TURNTransport === self.TURN_TRANSPORT.ANY) {
pushIceServer(username, credential, server.url);
} else {
@@ -310,17 +311,17 @@
File: source/ice-connection.js
rawUrl = rawUrl.split('?transport=')[0];
}
- if (this._TURNTransport === this.TURN_TRANSPORT.NONE) {
+ if (self._TURNTransport === self.TURN_TRANSPORT.NONE) {
pushIceServer(username, credential, rawUrl);
- } else if (this._TURNTransport === this.TURN_TRANSPORT.UDP) {
+ } else if (self._TURNTransport === self.TURN_TRANSPORT.UDP) {
pushIceServer(username, credential, rawUrl + '?transport=udp');
- } else if (this._TURNTransport === this.TURN_TRANSPORT.TCP) {
+ } else if (self._TURNTransport === self.TURN_TRANSPORT.TCP) {
pushIceServer(username, credential, rawUrl + '?transport=tcp');
- } else if (this._TURNTransport === this.TURN_TRANSPORT.ALL) {
+ } else if (self._TURNTransport === self.TURN_TRANSPORT.ALL) {
pushIceServer(username, credential, rawUrl + '?transport=tcp');
pushIceServer(username, credential, rawUrl + '?transport=udp');
} else {
- log.warn('Invalid TURN transport option "' + this._TURNTransport +
+ log.warn('Invalid TURN transport option "' + self._TURNTransport +
'". Ignoring TURN server at index' + i, clone(server));
continue;
}
@@ -331,7 +332,7 @@
File: source/ice-connection.js
}
// add mozilla STUN for firefox
- if (this._enableSTUN && this._usePublicSTUN && window.webrtcDetectedBrowser === 'firefox') {
+ if (self._enableSTUN && self._usePublicSTUN && window.webrtcDetectedBrowser === 'firefox') {
pushIceServer('none', 'none', 'stun:stun.services.mozilla.com', 0);
}
@@ -403,6 +404,23 @@
/**
* <blockquote class="info">
+ * Learn more about how ICE works in this
+ * <a href="https://temasys.com.sg/ice-what-is-this-sorcery/">article here</a>.
+ * </blockquote>
+ * The list of available Peer connection bundle policies.
+ * @attribute BUNDLE_POLICY
+ * @param {String} MAX_COMPAT <small>Value <code>"max-compat"</code></small>
+ * The value of the bundle policy to generate ICE candidates for each media type
+ * so each media type flows through different transports.
+ * @param {String} MAX_BUNDLE <small>Value <code>"max-bundle"</code></small>
+ * The value of the bundle policy to generate ICE candidates for one media type
+ * so all media type flows through a single transport.
+ * @param {String} BALANCED <small>Value <code>"balanced"</code></small>
+ * The value of the bundle policy to use <code>MAX_BUNDLE</code> if Peer supports it,
+ * else fallback to <code>MAX_COMPAT</code>.
+ * @param {String} NONE <small>Value <code>"none"</code></small>
+ * The value of the bundle policy to not use any media bundle.
+ * <small>This removes the <code>a=group:BUNDLE</code> line from session descriptions.</small>
+ * @type JSON
+ * @readOnly
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.BUNDLE_POLICY = {
+ MAX_COMPAT: 'max-compat',
+ BALANCED: 'balanced',
+ MAX_BUNDLE: 'max-bundle',
+ NONE: 'none'
+};
+
+/**
+ * <blockquote class="info">
+ * Learn more about how ICE works in this
+ * <a href="https://temasys.com.sg/ice-what-is-this-sorcery/">article here</a>.
+ * </blockquote>
+ * The list of available Peer connection RTCP mux policies.
+ * @attribute RTCP_MUX_POLICY
+ * @param {String} REQUIRE <small>Value <code>"require"</code></small>
+ * The value of the RTCP mux policy to generate ICE candidates for RTP only and RTCP shares the same ICE candidates.
+ * @param {String} NEGOTIATE <small>Value <code>"negotiate"</code></small>
+ * The value of the RTCP mux policy to generate ICE candidates for both RTP and RTCP each.
+ * @type JSON
+ * @readOnly
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.RTCP_MUX_POLICY = {
+ REQUIRE: 'require',
+ NEGOTIATE: 'negotiate'
+};
+
+/**
+ * <blockquote class="info">
+ * Learn more about how ICE works in this
+ * <a href="https://temasys.com.sg/ice-what-is-this-sorcery/">article here</a>.
+ * </blockquote>
+ * The list of available Peer connection certificates cryptographic algorithm to use.
+ * @attribute PEER_CERTIFICATE
+ * @param {String} RSA <small>Value <code>"RSA"</code></small>
+ * The value of the Peer connection certificate algorithm to use RSA-1024.
+ * @param {String} ECDSA <small>Value <code>"ECDSA"</code></small>
+ * The value of the Peer connection certificate algorithm to use ECDSA.
+ * @param {String} AUTO <small>Value <code>"AUTO"</code></small>
+ * The value of the Peer connection to use the default certificate generated.
+ * @type JSON
+ * @readOnly
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.PEER_CERTIFICATE = {
+ RSA: 'RSA',
+ ECDSA: 'ECDSA',
+ AUTO: 'AUTO'
+};
+
+/**
+ * <blockquote class="info">
+ * Note that Edge browser does not support renegotiation.
* For MCU enabled Peer connections with <code>options.mcuUseRenegoRestart</code> set to <code>false</code>
* in the <a href="#method_init"><code>init()</code> method</a>, the restart functionality may differ, you
* may learn more about how to workaround it
@@ -193,6 +270,17 @@
File: source/peer-connection.js
* The flag if ICE connections should restart when refreshing Peer connections.
* <small>This is used when ICE connection state is <code>FAILED</code> or <code>DISCONNECTED</code>, which state
* can be retrieved with the <a href="#event_iceConnectionState"><code>iceConnectionState</code> event</a>.</small>
+ * @param {JSON} [options] <blockquote class="info">
+ * Note that for MCU connections, the <code>bandwidth</code> or <code>googleXBandwidth</code>
+ * settings will override for all Peers or the current Room connection session settings.</blockquote>
+ * The custom Peer configuration settings.
+ * @param {JSON} [options.bandwidth] The configuration to set the maximum streaming bandwidth to send to Peers.
+ * <small>Object signature follows <a href="#method_joinRoom"><code>joinRoom()</code> method</a>
+ * <code>options.bandwidth</code> settings.</small>
+ * @param {JSON} [options.googleXBandwidth] The configuration to set the experimental google
+ * video streaming bandwidth sent to Peers.
+ * <small>Object signature follows <a href="#method_joinRoom"><code>joinRoom()</code> method</a>
+ * <code>options.googleXBandwidth</code> settings.</small>
* @param {Function} [callback] The callback function fired when request has completed.
* <small>Function parameters signature is <code>function (error, success)</code></small>
* <small>Function request completion is determined by the <a href="#event_peerRestart">
@@ -206,9 +294,25 @@
File: source/peer-connection.js
* with the Peer ID defined in <code>#peerId</code> property.
* <small>If <code>#peerId</code> value is <code>"self"</code>, it means that it is the error when there
* is no Peer connections to refresh with.</small>
+ * @param {JSON} callback.error.refreshSettings The list of Peer connection refresh settings.
+ * @param {JSON} callback.error.refreshSettings.#peerId The Peer connection refresh settings associated
+ * with the Peer ID defined in <code>#peerId</code> property.
+ * @param {Boolean} callback.error.refreshSettings.#peerId.iceRestart The flag if ICE restart is enabled for
+ * this Peer connection refresh session.
+ * @param {JSON} callback.error.refreshSettings.#peerId.customSettings The Peer connection custom settings.
+ * <small>Object signature follows <a href="#method_getPeersCustomSettings"><code>getPeersCustomSettings</code>
+ * method</a> returned per <code>#peerId</code> object.</small>
* @param {JSON} callback.success The success result in request.
* <small>Defined as <code>null</code> when there are errors in request</small>
* @param {Array} callback.success.listOfPeers The list of Peer IDs targeted.
+ * @param {JSON} callback.success.refreshSettings The list of Peer connection refresh settings.
+ * @param {JSON} callback.success.refreshSettings.#peerId The Peer connection refresh settings associated
+ * with the Peer ID defined in <code>#peerId</code> property.
+ * @param {Boolean} callback.success.refreshSettings.#peerId.iceRestart The flag if ICE restart is enabled for
+ * this Peer connection refresh session.
+ * @param {JSON} callback.success.refreshSettings.#peerId.customSettings The Peer connection custom settings.
+ * <small>Object signature follows <a href="#method_getPeersCustomSettings"><code>getPeersCustomSettings</code>
+ * method</a> returned per <code>#peerId</code> object.</small>
* @trigger <ol class="desc-seq">
* <li>Checks if MCU is enabled for App Key provided in <a href="#method_init"><code>init()</code> method</a><ol>
* <li>If MCU is enabled: <ol><li>If there are connected Peers in the Room: <ol>
@@ -286,11 +390,12 @@
}
};
- if (listOfPeers.length === 0) {
+ if (listOfPeers.length === 0 && !(self._hasMCU && !self._mcuUseRenegoRestart)) {
emitErrorForPeersFn('There is currently no peer connections to restart');
return;
}
+ if (window.webrtcDetectedBrowser === 'edge') {
+ emitErrorForPeersFn('Edge browser currently does not support renegotiation.');
+ return;
+ }
+
self._throttle(function (runFn) {
if (!runFn && self._hasMCU && !self._mcuUseRenegoRestart) {
if (self._throttlingShouldThrowError) {
@@ -341,7 +461,7 @@
log.log([peerId, 'PeerConnection', null, 'Restarting peer connection']);
// do a hard reset on variable object
- self._restartPeerConnection(peerId, doIceRestart, peerCallback);
+ self._restartPeerConnection(peerId, doIceRestart, bwOptions, peerCallback);
};
if(!self._hasMCU) {
@@ -419,11 +548,14 @@
File: source/peer-connection.js
}
}
} else {
- self._restartMCUConnection(callback, doIceRestart);
+ self._restartMCUConnection(callback, doIceRestart, bwOptions);
}
};
/**
+ * <blockquote class="info">
+ * Note that this is not well supported in the Edge browser.
+ * </blockquote>
* Function that retrieves Peer connection bandwidth and ICE connection stats.
* @method getConnectionStatus
* @param {String|Array} [targetPeerId] The target Peer ID to retrieve connection stats from.
@@ -597,6 +729,10 @@
File: source/peer-connection.js
return;
}
+ if (window.webrtcDetectedBrowser === 'edge') {
+ log.warn('Edge browser does not have well support for stats.');
+ }
+
var completedTaskCounter = [];
var checkCompletedFn = function (peerId) {
@@ -624,456 +760,831 @@
* <li><code>isSelf</code><var><b>{</b>Boolean<b>}</b></var><p>The flag if Peer is User.</p></li>
* </p></li></ul></li></ul>
* @example
- * // Example 1: Get the list of currently connected Peers in the same Room
+ * // Example 1: Get the list of current Peers Streams in the same Room
* var streams = skylinkDemo.getPeersStream();
* @for Skylink
* @since 0.6.16
@@ -415,6 +474,266 @@
File: source/peer-data.js
return listOfPeersStreams;
};
+/**
+ * Function that gets the current list of connected Peers Datachannel connections in the Room.
+ * @method getPeersDatachannels
+ * @return {JSON} The list of Peers Stream. <ul>
+ * <li><code>#peerId</code><var><b>{</b>JSON<b>}</b></var><p>The Peer Datachannels information.</p><ul>
+ * <li><code>#channelName</code><var><b>{</b>JSON<b>}</b></var><p>The Datachannel information.</p><ul>
+ * <li><code>channelName</code><var><b>{</b>String<b>}</b></var><p>The Datachannel ID..</p><ul>
+ * <li><code>channelType</code><var><b>{</b>String<b>}</b></var><p>The Datachannel type.
+ * [Rel: Skylink.DATA_CHANNEL_TYPE]</p></li>
+ * <li><code>channelProp</code><var><b>{</b>String<b>}</b></var><p>The Datachannel property.</p></li>
+ * <li><code>currentTransferId</code><var><b>{</b>String<b>}</b></var><p>The Datachannel connection
+ * current progressing transfer session. <small>Defined as <code>null</code> when there is
+ * currently no transfer session progressing on the Datachannel connection.</small></p></li>
+ * <li><code>currentStreamId</code><var><b>{</b>String<b>}</b></var><p>The Datachannel connection
+ * current data streaming session ID. <small>Defined as <code>null</code> when there is currently
+ * no data streaming session on the Datachannel connection.</small></p></li>
+ * <li><code>readyState</code><var><b>{</b>String<b>}</b></var><p>The Datachannel connection readyState.
+ * [Rel: Skylink.DATA_CHANNEL_STATE]</p></li>
+ * <li><code>bufferedAmountLow</code><var><b>{</b>Number<b>}</b></var><p>The Datachannel buffered amount.</p></li>
+ * <li><code>bufferedAmountLowThreshold</code><var><b>{</b>Number<b>}</b></var><p>The Datachannel
+ * buffered amount threshold.</p></li>
+ * </p></li></p></li></ul></li></ul></li></ul>
+ * @example
+ * // Example 1: Get the list of current Peers Datachannels in the same Room
+ * var channels = skylinkDemo.getPeersDatachannels();
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.getPeersDatachannels = function() {
+ var listOfPeersDatachannels = {};
+ var listOfPeers = Object.keys(this._peerConnections);
+
+ for (var i = 0; i < listOfPeers.length; i++) {
+ listOfPeersDatachannels[listOfPeers[i]] = {};
+
+ if (this._dataChannels[listOfPeers[i]]) {
+ for (var channelProp in this._dataChannels[listOfPeers[i]]) {
+ if (this._dataChannels[listOfPeers[i]].hasOwnProperty(channelProp) &&
+ this._dataChannels[listOfPeers[i]][channelProp]) {
+ var channel = this._dataChannels[listOfPeers[i]][channelProp];
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName] = this._getDataChannelBuffer(listOfPeers[i], channelProp);
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].channelName = channel.channelName;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].channelType = channel.channelType;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].channelProp = channelProp;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].currentTransferId = channel.transferId;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].currentStreamId = channel.streamId;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].readyState = channel.channel ?
+ channel.channel.readyState : self.DATA_CHANNEL_STATE.CREATE_ERROR;
+ }
+ }
+ }
+ }
+
+ return listOfPeersDatachannels;
+};
+
+/**
+ * Function that gets the list of current data transfers.
+ * @method getCurrentDataTransfers
+ * @return {JSON} The list of Peers Stream. <ul>
+ * <li><code>#transferId</code><var><b>{</b>JSON<b>}</b></var><p>The data transfer session.</p><ul>
+ * <li><code>transferInfo</code><var><b>{</b>JSON<b>}</b></var><p>The data transfer information.
+ * <small>Object signature matches the <code>transferInfo</code> parameter payload received in the
+ * <a href="#event_dataTransferState"><code>dataTransferState</code> event</a>
+ * except without the <code>data</code> property.</small></p></li>
+ * <li><code>peerId</code><var><b>{</b>String<b>}</b></var><p>The sender Peer ID.</p></li>
+ * <li><code>isSelf</code><var><b>{</b>Boolean<b>}</b></var><p>The flag if Peer is User.</p></li>
+ * </p></li></ul></li></ul>
+ * @example
+ * // Example 1: Get the list of current data transfers in the same Room
+ * var currentTransfers = skylinkDemo.getCurrentDataTransfers();
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.getCurrentDataTransfers = function() {
+ var listOfDataTransfers = {};
+
+ if (!(this._user && this._user.sid)) {
+ return {};
+ }
+
+ for (var prop in this._dataTransfers) {
+ if (this._dataTransfers.hasOwnProperty(prop) && this._dataTransfers[prop]) {
+ listOfDataTransfers[prop] = {
+ transferInfo: this._getTransferInfo(prop, this._user.sid, true, true, true),
+ isSelf: this._dataTransfers[prop].senderPeerId === this._user.sid,
+ peerId: this._dataTransfers[prop].senderPeerId || this._user.sid
+ };
+ }
+ }
+
+ return listOfDataTransfers;
+};
+
+/**
+ * Function that gets the list of current data streaming sessions.
+ * @method getCurrentDataStreamsSession
+ * @return {JSON} The list of Peers Stream. <ul>
+ * <li><code>#streamId</code><var><b>{</b>JSON<b>}</b></var><p>The data streaming session.</p><ul>
+ * <li><code>streamInfo</code><var><b>{</b>JSON<b>}</b></var><p>The data streaming information.
+ * <small>Object signature matches the <code>streamInfo</code> parameter payload received in the
+ * <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * except without the <code>chunk</code> amd <code>chunkSize</code> property.</small></p></li>
+ * <li><code>peerId</code><var><b>{</b>String<b>}</b></var><p>The sender Peer ID.</p></li>
+ * <li><code>isSelf</code><var><b>{</b>Boolean<b>}</b></var><p>The flag if Peer is User.</p></li>
+ * </p></li></ul></li></ul>
+ * @example
+ * // Example 1: Get the list of current data streaming sessions in the same Room
+ * var currentDataStreams = skylinkDemo.getCurrentDataStreamsSession();
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.getCurrentDataStreamsSession = function() {
+ var listOfDataStreams = {};
+
+ if (!(this._user && this._user.sid)) {
+ return {};
+ }
+
+ for (var prop in this._dataStreams) {
+ if (this._dataStreams.hasOwnProperty(prop) && this._dataStreams[prop]) {
+ listOfDataStreams[prop] = {
+ streamInfo: {
+ chunkType: this._dataStreams[prop].sessionChunkType === 'string' ? this.DATA_TRANSFER_DATA_TYPE.STRING :
+ this.DATA_TRANSFER_DATA_TYPE.BLOB,
+ isPrivate: this._dataStreams[prop].isPrivate,
+ isStringStream: this._dataStreams[prop].sessionChunkType === 'string',
+ senderPeerId: this._dataStreams[prop].senderPeerId
+ },
+ isSelf: this._dataStreams[prop].senderPeerId === this._user.sid,
+ peerId: this._dataStreams[prop].senderPeerId || this._user.sid
+ };
+ }
+ }
+
+ return listOfDataStreams;
+};
+
+/**
+ * Function that gets the list of current custom Peer settings sent and set.
+ * @method getPeerCustomSettings
+ * @return {JSON} The list of Peers custom settings sent and set. <ul>
+ * <li><code>#peerId</code><var><b>{</b>JSON<b>}</b></var><p>The Peer settings sent and set.</p><ul>
+ * <li><code>settings</code><var><b>{</b>JSON<b>}</b></var><p>The custom Peer settings.
+ * <small>Object signature matches the <code>peerInfo.settings</code> parameter payload received in the
+ * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small></p></li>
+ * <li><code>mediaStatus</code><var><b>{</b>JSON<b>}</b></var><p>The custom Peer Stream muted settings.
+ * <small>Object signature matches the <code>peerInfo.mediaStatus</code> parameter payload received in the
+ * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small></p></li></ul></li></ul>
+ * @example
+ * // Example 1: Get the list of current Peer custom settings
+ * var currentPeerSettings = skylinkDemo.getPeersCustomSettings();
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.getPeersCustomSettings = function () {
+ var self = this;
+ var customSettingsList = {};
+
+ for (var peerId in self._peerInformations) {
+ if (self._peerInformations.hasOwnProperty(peerId) && self._peerInformations[peerId]) {
+ customSettingsList[peerId] = {
+ settings: {
+ audio: false,
+ video: false,
+ bandwidth: clone(self._streamsBandwidthSettings.bAS),
+ googleXBandwidth: clone(self._streamsBandwidthSettings.googleX)
+ },
+ mediaStatus: {
+ audioMuted: true,
+ videoMuted: true
+ }
+ };
+
+ if (self._peerConnections[peerId] && self._peerConnections[peerId].signalingState !== self.PEER_CONNECTION_STATE.CLOSED) {
+ var streams = self._peerConnections[peerId].getLocalStreams();
+
+ for (var s = 0; s < streams.length; s++) {
+ if (self._streams.screenshare && self._streams.screenshare.stream && (streams[s].id ||
+ streams[s].label) === (self._streams.screenshare.stream.id || self._streams.screenshare.stream.label)) {
+ customSettingsList[peerId].settings.audio = clone(self._streams.screenshare.settings.audio);
+ customSettingsList[peerId].settings.video = clone(self._streams.screenshare.settings.video);
+ customSettingsList[peerId].mediaStatus = clone(self._streamsMutedSettings);
+ break;
+ } else if (self._streams.userMedia && self._streams.userMedia.stream && (streams[s].id ||
+ streams[s].label) === (self._streams.userMedia.stream.id ||
+ self._streams.userMedia.stream.label)) {
+ customSettingsList[peerId].settings.audio = clone(self._streams.userMedia.settings.audio);
+ customSettingsList[peerId].settings.video = clone(self._streams.userMedia.settings.video);
+ customSettingsList[peerId].mediaStatus = clone(self._streamsMutedSettings);
+ break;
+ } else if (window.webrtcDetectedBrowser === 'edge') {
+ customSettingsList[peerId].settings.audio = clone(self._streams.userMedia.settings.audio);
+ customSettingsList[peerId].settings.video = clone(self._streams.userMedia.settings.video);
+ customSettingsList[peerId].mediaStatus = clone(self._streamsMutedSettings);
+ if (streams[s].getAudioTracks().length === 0) {
+ customSettingsList[peerId].settings.audio = false;
+ customSettingsList[peerId].mediaStatus.audioMuted = true;
+ }
+ if (streams[s].getVideoTracks().length === 0) {
+ customSettingsList[peerId].settings.video = false;
+ customSettingsList[peerId].mediaStatus.videoMuted = true;
+ }
+ }
+ }
+ }
+
+ if (self._peerCustomConfigs[peerId]) {
+ if (self._peerCustomConfigs[peerId].bandwidth &&
+ typeof self._peerCustomConfigs[peerId].bandwidth === 'object') {
+ if (typeof self._peerCustomConfigs[peerId].bandwidth.audio === 'number') {
+ customSettingsList[peerId].settings.bandwidth.audio = self._peerCustomConfigs[peerId].bandwidth.audio;
+ }
+ if (typeof self._peerCustomConfigs[peerId].bandwidth.video === 'number') {
+ customSettingsList[peerId].settings.bandwidth.video = self._peerCustomConfigs[peerId].bandwidth.video;
+ }
+ if (typeof self._peerCustomConfigs[peerId].bandwidth.data === 'number') {
+ customSettingsList[peerId].settings.bandwidth.data = self._peerCustomConfigs[peerId].bandwidth.data;
+ }
+ }
+ if (self._peerCustomConfigs[peerId].googleXBandwidth &&
+ typeof self._peerCustomConfigs[peerId].googleXBandwidth === 'object') {
+ if (typeof self._peerCustomConfigs[peerId].googleXBandwidth.min === 'number') {
+ customSettingsList[peerId].settings.googleXBandwidth.min = self._peerCustomConfigs[peerId].googleXBandwidth.min;
+ }
+ if (typeof self._peerCustomConfigs[peerId].googleXBandwidth.max === 'number') {
+ customSettingsList[peerId].settings.googleXBandwidth.max = self._peerCustomConfigs[peerId].googleXBandwidth.max;
+ }
+ }
+ }
+
+ var agent = ((self._peerInformations[peerId] || {}).agent || {}).name || '';
+
+ // If there is Peer ID (not broadcast ENTER message) and Peer is Edge browser and User is not
+ if (customSettingsList[peerId].settings.video && (peerId ?
+ (window.webrtcDetectedBrowser !== 'edge' && agent.name === 'edge' ?
+ // If User is IE/safari and does not have H264 support, remove video support
+ ['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1 && !self._currentCodecSupport.video.h264 :
+ // If User is Edge and Peer is not and no H264 support, remove video support
+ window.webrtcDetectedBrowser === 'edge' && agent.name !== 'edge' && !self._currentCodecSupport.video.h264) :
+ // If broadcast ENTER message and User is Edge and has no H264 support
+ window.webrtcDetectedBrowser === 'edge' && !self._currentCodecSupport.video.h264)) {
+ customSettingsList[peerId].settings.video = false;
+ customSettingsList[peerId].mediaStatus.videoMuted = true;
+ }
+
+ customSettingsList[peerId].settings.audio = !self._sdpSettings.connection.audio ? false :
+ customSettingsList[peerId].settings.audio;
+ customSettingsList[peerId].settings.video = !self._sdpSettings.connection.video ? false :
+ customSettingsList[peerId].settings.video;
+ customSettingsList[peerId].mediaStatus.audioMuted = !self._sdpSettings.connection.audio ? true :
+ customSettingsList[peerId].mediaStatus.audioMuted;
+ customSettingsList[peerId].mediaStatus.videoMuted = !self._sdpSettings.connection.video ? true :
+ customSettingsList[peerId].mediaStatus.videoMuted;
+ }
+ }
+
+ return customSettingsList;
+};
+
/**
* Function that returns the User session information to be sent to Peers.
* @method _getUserInfo
@@ -424,6 +743,7 @@
File: source/peer-data.js
*/
Skylink.prototype._getUserInfo = function(peerId) {
var userInfo = clone(this.getPeerInfo());
+ var peerInfo = clone(this.getPeerInfo(peerId));
// Adhere to SM protocol without breaking the other SDKs.
if (userInfo.settings.video && typeof userInfo.settings.video === 'object') {
@@ -457,8 +777,33 @@
File: source/peer-data.js
delete userInfo.settings.bandwidth;
}
+ // If there is Peer ID (not broadcast ENTER message) and Peer is Edge browser and User is not
+ if (peerId ? (window.webrtcDetectedBrowser !== 'edge' && peerInfo.agent.name === 'edge' ?
+ // If User is IE/safari and does not have H264 support, remove video support
+ ['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1 && !this._currentCodecSupport.video.h264 :
+ // If User is Edge and Peer is not and no H264 support, remove video support
+ window.webrtcDetectedBrowser === 'edge' && peerInfo.agent.name !== 'edge' && !this._currentCodecSupport.video.h264) :
+ // If broadcast ENTER message and User is Edge and has no H264 support
+ window.webrtcDetectedBrowser === 'edge' && !this._currentCodecSupport.video.h264) {
+ userInfo.settings.video = false;
+ userInfo.mediaStatus.videoMuted = true;
+ }
+
+ if (!this._sdpSettings.connection.audio) {
+ userInfo.settings.audio = false;
+ userInfo.mediaStatus.audioMuted = true;
+ }
+
+ if (!this._sdpSettings.connection.video) {
+ userInfo.settings.video = false;
+ userInfo.mediaStatus.videoMuted = true;
+ }
+
delete userInfo.agent;
delete userInfo.room;
+ delete userInfo.config;
+ delete userInfo.parentId;
+ delete userInfo.settings.data;
return userInfo;
};
diff --git a/doc/files/source_peer-handshake.js.html b/doc/files/source_peer-handshake.js.html
index fd6459b86..8fde5a56b 100644
--- a/doc/files/source_peer-handshake.js.html
+++ b/doc/files/source_peer-handshake.js.html
@@ -2,7 +2,7 @@
- SkylinkJS 0.6.17
+ SkylinkJS 0.6.18
@@ -33,7 +33,7 @@
- JSVersion: 0.6.17
+ Version: 0.6.18
@@ -132,7 +132,7 @@
File: source/peer-handshake.js
*/
Skylink.prototype._doOffer = function(targetMid, iceRestart, peerBrowser) {
var self = this;
- var pc = self._peerConnections[targetMid] || self._addPeer(targetMid, peerBrowser);
+ var pc = self._peerConnections[targetMid];// || self._addPeer(targetMid, peerBrowser);
log.log([targetMid, null, null, 'Checking caller status'], peerBrowser);
@@ -151,46 +151,33 @@
File: source/peer-handshake.js
return;
}
- var peerIceRestartSupport = !!((self._peerInformations[targetMid] || {}).config || {}).enableIceRestart;
+ var peerAgent = ((self._peerInformations[targetMid] || {}).agent || {}).name || '';
+ var doIceRestart = !!((self._peerInformations[targetMid] || {}).config || {}).enableIceRestart &&
+ iceRestart && self._enableIceRestart;
+ var offerToReceiveAudio = !(!self._sdpSettings.connection.audio && targetMid !== 'MCU');
+ var offerToReceiveVideo = !(!self._sdpSettings.connection.video && targetMid !== 'MCU') &&
+ ((window.webrtcDetectedBrowser === 'edge' && peerAgent !== 'edge') ||
+ (['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1 && peerAgent === 'edge') ?
+ !!self._currentCodecSupport.video.h264 : true);
var offerConstraints = {
- offerToReceiveAudio: true,
- offerToReceiveVideo: true,
- iceRestart: self._enableIceRestart && peerIceRestartSupport ? iceRestart === true : false
+ offerToReceiveAudio: offerToReceiveAudio,
+ offerToReceiveVideo: offerToReceiveVideo,
+ iceRestart: doIceRestart,
+ voiceActivityDetection: self._voiceActivityDetection
};
- // NOTE: Removing ICE restart functionality as of now since Firefox does not support it yet
- // Check if ICE connection failed or disconnected, and if so, do an ICE restart
- /*if ([self.ICE_CONNECTION_STATE.DISCONNECTED, self.ICE_CONNECTION_STATE.FAILED].indexOf(pc.iceConnectionState) > -1) {
- offerConstraints.iceRestart = true;
- }*/
-
// Prevent undefined OS errors
peerBrowser.os = peerBrowser.os || '';
- /*
- Ignoring these old codes as Firefox 39 and below is no longer supported
- if (window.webrtcDetectedType === 'moz' && peerBrowser.agent === 'MCU') {
- unifiedOfferConstraints.mandatory = unifiedOfferConstraints.mandatory || {};
- unifiedOfferConstraints.mandatory.MozDontOfferDataChannel = true;
- beOfferer = true;
- }
-
- if (window.webrtcDetectedBrowser === 'firefox' && window.webrtcDetectedVersion >= 32) {
- unifiedOfferConstraints = {
- offerToReceiveAudio: true,
- offerToReceiveVideo: true
- };
- }
- */
-
// Fallback to use mandatory constraints for plugin based browsers
if (['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1) {
offerConstraints = {
mandatory: {
- OfferToReceiveAudio: true,
- OfferToReceiveVideo: true,
- iceRestart: self._enableIceRestart && peerIceRestartSupport ? iceRestart === true : false
+ OfferToReceiveAudio: offerToReceiveAudio,
+ OfferToReceiveVideo: offerToReceiveVideo,
+ iceRestart: doIceRestart,
+ voiceActivityDetection: self._voiceActivityDetection
}
};
}
@@ -201,7 +188,8 @@
* <code>options.audio</code> is not defined, it will be defined as <code>false</code>.</small>
* <small>Object signature matches the <code>options.video</code> parameter in the
* <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>.</small>
+ * @param {Boolean} [options.voiceActivityDetection=true] The flag if voice activity detection should be enabled.
+ * <small>This can only be toggled if User is and for the offerer, which is determined if User's
+ * <code>peerInfo.config.priorityWeight</code> is higher than Peer's.</small>
+ * <blockquote class="details">
+ * This works hand-in-hand with the <code>options.disableComfortNoiseCodec</code> flag in the
+ * <a href="#method_init"><code>init()</code> method</a> and the <code>options.audio.usedtx</code> setting in
+ * <a href="#method_getUserMedia"><code>getUserMedia()</code> method</a>. VAD (voice activity detection)
+ * detects if there is an active voice in the Stream, and if there is no active voice in the Stream, the
+ * <code>options.audio.usedtx</code> (if enabled) would prevent sending these empty bits. To prevent huge differences
+ * when there is a silence and an active voice later, the CN codec would produce an empty voice to
+ * make it sound better.</blockquote>
* @param {JSON} [options.bandwidth] <blockquote class="info">Note that this is currently not supported
* with Firefox browsers versions 48 and below as noted in an existing
* <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=976521#c21">bugzilla ticket here</a>.</blockquote>
@@ -281,8 +292,44 @@
File: source/room-connection.js
* Note that this feature is currently is beta, and for any enquiries on enabling and its support for MCU enabled
* Peer connections, please contact <a href="http://support.temasys.io">our support portal</a>.</blockquote></blockquote>
* The config if Peer would publish only.
- * @param {String} [options.publishOnly.parentId] The parent Peer ID to match to when Peer is connected.
+ * @param {String} [options.publishOnly.parentId] <blockquote class="info"><b>Deprecation Warning!</b>
+ * This property has been deprecated. Use <code>options.parentId</code> instead.
+ * </blockquote> The parent Peer ID to match to when Peer is connected.
* <small>This is useful for identification for users connecting the Room twice simultaneously for multi-streaming.</small>
+ * <small>If User Peer ID matches the parent Peer ID provided from Peer, User will not be connected to Peer.</small>
+ * @param {String} [options.parentId] The parent Peer ID to match to when Peer is connected.
+ * <small>Note that configuring this value overrides the <code>options.publishOnly.parentId</code> value.</small>
+ * <small>This is useful for identification for users connecting the Room twice simultaneously for multi-streaming.</small>
+ * <small>If User Peer ID matches the parent Peer ID provided from Peer, User will not be connected to Peer.</small>
+ * @param {JSON} [options.peerConnection] <blockquote class="info">
+ * Note that this is mainly used for debugging purposes, so it may cause disruptions in connections or
+ * connectivity issues when configured. </blockquote> The Peer connection constraints settings.
+ * @param {String} [options.peerConnection.bundlePolicy] The Peer connection media bundle policy.
+ * - When not provided, its value is <code>BALANCED</code>.
+ * [Rel: Skylink.BUNDLE_POLICY]
+ * @param {String} [options.peerConnection.rtcpMuxPolicy] The Peer connection RTP and RTCP ICE candidates mux policy.
+ * - When not provided, its value is <code>REQUIRE</code>.
+ * [Rel: Skylink.RTCP_MUX_POLICY]
+ * @param {Number} [options.peerConnection.iceCandidatePoolSize=0] The number of ICE candidates to gather before
+ * gathering it when setting local offer / answer session description.
+ * @param {String} [options.peerConnection.certificate] The type of certificate that Peer connection should
+ * generate and use when available.
+ * - When not provided, its value is <code>AUTO</code>.
+ * [Rel: Skylink.PEER_CERTIFICATE]
+ * @param {Boolean|JSON} [options.autoBandwidthAdjustment=false] <blockquote class="info">
+ * Note that this is an experimental feature which may be removed or changed in the future releases.
+ * This feature is also only available for non-MCU enabled Peer connections and Edge Peer connections.
+ * </blockquote> The flag if Peer connections uploading and downloading bandwidth should be automatically adjusted
+ * each time based on a specified interval.
+ * <small>Note this would cause <a href="#event_peerRestart"><code>peerRestart</code> event</a> to be triggered
+ * for each specified interval.</small>
+ * @param {Number} [options.autoBandwidthAdjustment.interval=10] The interval each time to adjust bandwidth
+ * connections in seconds.
+ * <small>Note that the minimum value is <code>10</code>.</small>
+ * @param {Number} [options.autoBandwidthAdjustment.limitAtPercentage=100] The percentage of the average bandwidth to adjust to.
+ * <small>E.g. <code>avgBandwidth * (limitPercentage / 100)</code>.</small>
+ * @param {Boolean} [options.autoBandwidthAdjustment.useUploadBwOnly=false] The flag if average bandwidth computation
+ * should only consist of the upload bandwidth.
* @param {Function} [callback] The callback function fired when request has completed.
* <small>Function parameters signature is <code>function (error, success)</code></small>
* <small>Function request completion is determined by the <a href="#event_peerJoined">
@@ -621,8 +668,7 @@
* is not loaded.
* <small>To resolve this, ensure that the AdapterJS dependency is loaded before the Skylink dependency.
* You may use the provided AdapterJS <a href="https://github.com/Temasys/AdapterJS/">CDN here</a>.</small>
+ * @param {Number} PARSE_CODECS <small>Value <code>8</code></small>
+ * The value of the failure code when codecs support cannot be parsed and retrieved.
* @type JSON
* @readOnly
* @for Skylink
@@ -222,7 +224,8 @@
US1: ''
};
+/**
+ * The list of User's priority weight schemes for <a href="#method_joinRoom">
+ * <code>joinRoom()</code> method</a> connections.
+ * @attribute PRIORITY_WEIGHT_SCHEME
+ * @param {String} ENFORCE_OFFERER <small>Value <code>"enforceOfferer"</code></small>
+ * The value of the priority weight scheme to enforce User as the offerer.
+ * @param {String} ENFORCE_ANSWERER <small>Value <code>"enforceAnswerer"</code></small>
+ * The value of the priority weight scheme to enforce User as the answerer.
+ * @param {String} AUTO <small>Value <code>"auto"</code></small>
+ * The value of the priority weight scheme to let User be offerer or answerer based on Signaling server selection.
+ * @type JSON
+ * @readOnly
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.PRIORITY_WEIGHT_SCHEME = {
+ ENFORCE_OFFERER: 'enforceOfferer',
+ ENFORCE_ANSWERER: 'enforceAnswerer',
+ AUTO: 'auto'
+};
+
/**
* Function that generates an <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">UUID</a> (Unique ID).
* @method generateUUID
@@ -279,8 +303,8 @@
File: source/room-init.js
* - When not provided or is provided as an empty string, its value is <code>options.appKey</code>.
* <small>Note that switching Rooms is not available when using <code>options.credentials</code> based authentication.
* The Room that User will be connected to is the <code>defaultRoom</code> provided.</small>
- * @param {String} [options.roomServer] The Auth server.
- * <small>Note that this is a debugging feature and is only used when instructed for debugging purposes.</small>
+ * @param {String} [options.roomServer] The Auth server for debugging purposes to use.
+ * <small>Note that this is a debugging feature and is only used when instructed for debugging purposes.</small>
* @param {Boolean} [options.enableIceTrickle=true] The flag if Peer connections should
* trickle ICE for faster connectivity.
* @param {Boolean} [options.enableDataChannel=true] <blockquote class="info">
@@ -291,9 +315,7 @@
File: source/room-init.js
* <a href="#method_sendP2PMessage"><code>sendP2PMessage()</code> method</a>.</small>
* @param {Boolean} [options.enableTURNServer=true] The flag if TURN ICE servers should
* be used when constructing Peer connections to allow TURN connections when required and enabled for the App Key.
- * @param {Boolean} [options.enableSTUNServer=true] <blockquote class="info">
- * Note that for Edge browsers, this value is overriden as <code>false</code> due to its supports.
- * </blockquote> The flag if STUN ICE servers should
+ * @param {Boolean} [options.enableSTUNServer=true] The flag if STUN ICE servers should
* be used when constructing Peer connections to allow TURN connections when required.
* @param {Boolean} [options.forceTURN=false] The flag if Peer connections should enforce
* connections over the TURN server.
@@ -366,23 +388,34 @@
File: source/room-init.js
* during request to Auth server and socket connections to Signaling server
* when accessing <code>window.location.protocol</code> value is <code>"http:"</code>.
* <small>By default, <code>"https:"</code> protocol connections uses HTTPS connections.</small>
- * @param {String} [options.audioCodec] <blockquote class="info">
+ * @param {String|JSON} [options.audioCodec] <blockquote class="info">
* Note that if the audio codec is not supported, the SDK will not configure the local <code>"offer"</code> or
* <code>"answer"</code> session description to prefer the codec.<br>
* Note that for Edge browsers, this value is set as <code>OPUS</code> due to its supports.</blockquote>
* The option to configure the preferred audio codec to use to encode sending audio data when available for Peer connection.
* - When not provided, its value is <code>AUTO</code>.
* [Rel: Skylink.AUDIO_CODEC]
- * @param {String} [options.videoCodec] <blockquote class="info">
+ * @param {String} options.audioCodec.codec The audio codec to prefer to encode sending audio data when available.
+ * <small>The value must not be <code>AUTO</code>.</small>
+ * [Rel: Skylink.AUDIO_CODEC]
+ * @param {Number} [options.audioCodec.samplingRate] The audio codec sampling to prefer to encode sending audio data when available.
+ * @param {Number} [options.audioCodec.channels] The audio codec channels to prefer to encode sending audio data when available.
+ * @param {String|JSON} [options.videoCodec] <blockquote class="info">
* Note that if the video codec is not supported, the SDK will not configure the local <code>"offer"</code> or
* <code>"answer"</code> session description to prefer the codec.<br>
* Note that for Edge browsers, this value is set as <code>H264</code> due to its supports.</blockquote>
* The option to configure the preferred video codec to use to encode sending video data when available for Peer connection.
* - When not provided, its value is <code>AUTO</code>.
* [Rel: Skylink.VIDEO_CODEC]
+ * @param {String} options.videoCodec.codec The video codec to prefer to encode sending audio data when available.
+ * <small>The value must not be <code>AUTO</code>.</small>
+ * [Rel: Skylink.VIDEO_CODEC]
+ * @param {Number} [options.videoCodec.samplingRate] The video codec sampling to prefer to encode sending video data when available.
* @param {Number} [options.socketTimeout=20000] The timeout for each attempts for socket connection
* with the Signaling server to indicate that connection has timed out and has failed to establish.
* <small>Note that the mininum timeout value is <code>5000</code>. If less, this value will be <code>5000</code>.</small>
+ * <small>Note that it is recommended to use <code>12000</code> as the lowest timeout value if Peers are connecting
+ * using Polling transports to prevent connection errors.</small>
* @param {Boolean} [options.forceTURNSSL=false] <blockquote class="info">
* Note that currently Firefox does not support the TURNS protocol, and that if TURNS is required,
* TURN ICE servers using port <code>443</code> will be used instead.<br>
@@ -415,6 +448,111 @@
File: source/room-init.js
* The flag if <a href="#method_refreshConnection"><code>
* refreshConnection()</code> method</a> should renegotiate like non-MCU enabled Peer connection for MCU
* enabled Peer connections instead of invoking <a href="#method_joinRoom"><code>joinRoom()</code> method</a> again.
+ * @param {String|Array} [options.iceServer] The ICE servers for debugging purposes to use.
+ * - When defined as string, the value is considered as <code>[options.iceServer]</code>.
+ * <small>Note that this is a debugging feature and is only used when instructed for debugging purposes.</small>
+ * @param {String} [options.iceServer.#index] The ICE server url for debugging purposes to use.
+ * @param {String|JSON} [options.socketServer] The Signaling server for debugging purposes to use.
+ * - When defined as string, the value is considered as <code>{ url: options.socketServer }</code>.
+ * <small>Note that this is a debugging feature and is only used when instructed for debugging purposes.</small>
+ * @param {String} options.socketServer.url The Signaling server URL for debugging purposes to use.
+ * @param {Array} [options.socketServer.ports] The list of Signaling server ports for debugging purposes to use.
+ * <small>If not defined, it will use the default list of ports specified.</small>
+ * @param {Number} options.socketServer.ports.#index The Signaling server port to fallback and use for debugging purposes.
+ * @param {String} [options.socketServer.protocol] The Signaling server protocol for debugging purposes to use.
+ * <small>If not defined, it will use the default protocol specified.</small>
+ * @param {JSON} [options.codecParams] <blockquote class="info">
+ * Note that some of these parameters are mainly used for experimental or debugging purposes. Toggling any of
+ * these feature may result in disruptions in connectivity.</blockquote>
+ * The audio and video codecs parameters to configure.
+ * @param {JSON} [options.codecParams.video] The video codecs parameters to configure.
+ * @param {JSON} [options.codecParams.video.h264] The H264 video codec parameters to configure.
+ * @param {String} [options.codecParams.video.h264.profileLevelId] <blockquote class="info">
+ * Note that this parameter should only be used for debugging purposes only.</blockquote>
+ * The H264 video codec base16 encoded string which indicates the H264 baseline, main, or the extended profiles.
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Boolean} [options.codecParams.video.h264.levelAsymmetryAllowed] <blockquote class="info">
+ * Note that this is an experimental parameter which may result in connectivity issues when toggled.</blockquote>
+ * The flag if streaming H264 sending video data should be encoded at a different level
+ * from receiving video data from Peer encoding to User when Peer is the offerer.
+ * <small>If Peer is the offerer instead of the User, the Peer's <code>peerInfo.config.priorityWeight</code> will be
+ * higher than User's <code>peerInfo.config.priorityWeight</code>.</small>
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Boolean} [options.codecParams.video.h264.packetizationMode] <blockquote class="info">
+ * Note that this is an experimental parameter which may result in connectivity issues when enabled. It is
+ * advisable to turn off this feature off when receiving H264 decoders do not support the packetization mode,
+ * which may result in a blank receiving video stream.</blockquote>
+ * The flag to enable H264 video codec packetization mode, which splits video frames that are larger
+ * for a RTP packet into RTP packet chunks.
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {JSON} [options.codecParams.video.vp8] The VP8 video codec parameters to configure.
+ * @param {Number} [options.codecParams.video.vp8.maxFr] <blockquote class="info">
+ * Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.</blockquote>
+ * The maximum number of fps (frames per second) that the VP8 video codec decoder is capable of
+ * decoding when receiving encoded video data packets.
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Number} [options.codecParams.video.vp8.maxFs] <blockquote class="info">
+ * Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.</blockquote>
+ * The maximum number of frame size macroblocks that the VP8 video codec decoder is capable of
+ * decoding when receiving encoded video data packets.
+ * <small>The value has to have the width and height of the frame in macroblocks less than the value of
+ * <code>parseInt(Math.sqrt(maxFs * 8))</code>. E.g. If the value is <code>1200</code>, it is capable of
+ * support <code>640x480</code> frame width and height, which heights up to <code>1552px</code>
+ * (<code>97</code> macroblocks value.</small>
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {JSON} [options.codecParams.video.vp9] The VP9 video codec parameters to configure.
+ * @param {Number} [options.codecParams.video.vp9.maxFr] <blockquote class="info">
+ * Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.</blockquote>
+ * The maximum number of fps (frames per second) that the VP9 video codec decoder is capable of
+ * decoding when receiving encoded video data packets.
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Number} [options.codecParams.video.vp9.maxFs] <blockquote class="info">
+ * Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.</blockquote>
+ * The maximum number of frame size macroblocks that the VP9 video codec decoder is capable of
+ * decoding when receiving encoded video data packets.
+ * <small>The value has to have the width and height of the frame in macroblocks less than the value of
+ * <code>parseInt(Math.sqrt(maxFs * 8))</code>. E.g. If the value is <code>1200</code>, it is capable of
+ * support <code>640x480</code> frame width and height, which heights up to <code>1552px</code>
+ * (<code>97</code> macroblocks value.</small>
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {JSON} [options.codecParams.audio] The audio codecs parameters to configure.
+ * @param {JSON} [options.codecParams.audio.opus] <blockquote class="info">
+ * Note that this is only applicable to OPUS audio codecs with a sampling rate of <code>48000</code> Hz (hertz).
+ * </blockquote> The OPUS audio codec parameters to configure.
+ * @param {Boolean} [options.codecParams.audio.opus.stereo] The flag if OPUS audio codec stereo band
+ * should be configured for sending encoded audio data.
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Boolean} [options.codecParams.audio.opus.usedtx] <blockquote class="info">
+ * Note that this feature might not work depending on the browser support and implementation.</blockquote>
+ * The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.
+ * <small>This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and
+ * goes hand-in-hand with the <code>options.voiceActivityDetection</code> flag in <a href="#method_joinRoom">
+ * <code>joinRoom()</code> method</a>.</small>
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Boolean} [options.codecParams.audio.opus.useinbandfec] <blockquote class="info">
+ * Note that this parameter should only be used for debugging purposes only.</blockquote>
+ * The flag if OPUS audio codec has the capability to take advantage of the in-band FEC
+ * (Forward Error Correction) when sending encoded audio data.
+ * <small>This helps to reduce the harm of packet loss by encoding information about the previous packet loss.</small>
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Number} [options.codecParams.audio.opus.maxplaybackrate] <blockquote class="info">
+ * Note that this parameter should only be used for debugging purposes only.</blockquote>
+ * The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving
+ * decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data
+ * would not encode at a higher sampling rate specified by this.
+ * <small>This value must be between <code>8000</code> to <code>48000</code>.</small>
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Number} [options.codecParams.minptime] <blockquote class="info">
+ * Note that this parameter should only be used for debugging purposes only.</blockquote>
+ * The OPUS audio codec receiving audio data decoder minimum length of time in milleseconds should be
+ * encapsulated in a single received encoded audio data packet.
+ * <small>This value must be between <code>3</code> to <code>120</code></small>
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {String} [options.priorityWeightScheme] <blockquote class="info">
+ * Note that this parameter should only be used for debugging purposes only and may not work when
+ * internals change.</blockquote> The User's priority weight to enforce User as offerer or answerer.
+ * - When not provided, its value is <code>AUTO</code>.
+ * [Rel: Skylink.PRIORITY_WEIGHT_SCHEME]
* @param {Function} [callback] The callback function fired when request has completed.
* <small>Function parameters signature is <code>function (error, success)</code></small>
* <small>Function request completion is determined by the <a href="#event_readyStateChange">
@@ -427,14 +565,14 @@
File: source/room-init.js
* @param {Number} callback.error.errorCode The <a href="#event_readyStateChange"><code>readyStateChange</code>
* event</a> <code>error.errorCode</code> parameter payload value.
* [Rel: Skylink.READY_STATE_CHANGE_ERROR]
- * @param {Object} callback.error.error The <a href="#event_readyStateChange"><code>readyStateChange</code>
+ * @param {Error|String} callback.error.error The <a href="#event_readyStateChange"><code>readyStateChange</code>
* event</a> <code>error.content</code> parameter payload value.
* @param {Number} callback.error.status The <a href="#event_readyStateChange"><code>readyStateChange</code>
* event</a> <code>error.status</code> parameter payload value.
* @param {JSON} callback.success The success result in request.
* <small>Defined as <code>null</code> when there are errors in request</small>
* @param {String} callback.success.serverUrl The constructed REST URL requested to Auth server.
- * @param {String} callback.success.readyState The current ready state.
+ * @param {Number} callback.success.readyState The current ready state.
* [Rel: Skylink.READY_STATE_CHANGE]
* @param {String} callback.success.selectedRoom The Room based on the current Room session token retrieved for.
* @param {String} callback.success.appKey The configured value of the <code>options.appKey</code>.
@@ -447,8 +585,8 @@
File: source/room-init.js
* @param {Boolean} callback.success.TURNTransport The configured value of the <code>options.TURNServerTransport</code>.
* @param {Boolean} callback.success.audioFallback The configured value of the <code>options.audioFallback</code>.
* @param {Boolean} callback.success.forceSSL The configured value of the <code>options.forceSSL</code>.
- * @param {String} callback.success.audioCodec The configured value of the <code>options.audioCodec</code>.
- * @param {String} callback.success.videoCodec The configured value of the <code>options.videoCodec</code>.
+ * @param {String|JSON} callback.success.audioCodec The configured value of the <code>options.audioCodec</code>.
+ * @param {String|JSON} callback.success.videoCodec The configured value of the <code>options.videoCodec</code>.
* @param {Number} callback.success.socketTimeout The configured value of the <code>options.socketTimeout</code>.
* @param {Boolean} callback.success.forceTURNSSL The configured value of the <code>options.forceTURNSSL</code>.
* @param {Boolean} callback.success.forceTURN The configured value of the <code>options.forceTURN</code>.
@@ -457,9 +595,12 @@
File: source/room-init.js
* @param {Boolean} callback.success.disableComfortNoiseCodec The configured value of the <code>options.disableComfortNoiseCodec</code>.
* @param {Boolean} callback.success.disableREMB The configured value of the <code>options.disableREMB</code>.
* @param {JSON} callback.success.filterCandidatesType The configured value of the <code>options.filterCandidatesType</code>.
- * @param {Number} callback.success.throttleIntervals The configured value of the <code>options.throttleIntervals</code>.
- * @param {Number} callback.success.throttleShouldThrowError The configured value of the <code>options.throttleShouldThrowError</code>.
- * @param {Number} callback.success.mcuUseRenegoRestart The configured value of the <code>options.mcuUseRenegoRestart</code>.
+ * @param {JSON} callback.success.throttleIntervals The configured value of the <code>options.throttleIntervals</code>.
+ * @param {Boolean} callback.success.throttleShouldThrowError The configured value of the <code>options.throttleShouldThrowError</code>.
+ * @param {JSON} callback.success.mcuUseRenegoRestart The configured value of the <code>options.mcuUseRenegoRestart</code>.
+ * @param {JSON} callback.success.iceServer The configured value of the <code>options.iceServer</code>.
+ * <small>See the <code>.urls</code> property in this object for configured value if defined.</small>
+ * @param {JSON|String} callback.success.socketServer The configured value of the <code>options.socketServer</code>.
* @example
* // Example 1: Using CORS authentication and connection to default Room
* skylinkDemo(appKey, function (error, success) {
@@ -569,6 +710,13 @@
File: source/room-init.js
};
var throttleShouldThrowError = false;
var mcuUseRenegoRestart = false;
+ var iceServer = null;
+ var socketServer = null;
+ var codecParams = {
+ audio: { opus: {} },
+ video: { h264: {}, vp8: {}, vp9: {} }
+ };
+ var priorityWeightScheme = self.PRIORITY_WEIGHT_SCHEME.AUTO;
log.log('Provided init options:', options);
@@ -615,12 +763,6 @@
File: source/room-init.js
// set the force turn ssl always option
forceTURNSSL = (typeof options.forceTURNSSL === 'boolean') ?
options.forceTURNSSL : forceTURNSSL;
- // set the preferred audio codec
- audioCodec = typeof options.audioCodec === 'string' ?
- options.audioCodec : audioCodec;
- // set the preferred video codec
- videoCodec = typeof options.videoCodec === 'string' ?
- options.videoCodec : videoCodec;
// set the force turn server option
forceTURN = (typeof options.forceTURN === 'boolean') ?
options.forceTURN : forceTURN;
@@ -640,6 +782,9 @@
File: source/room-init.js
throttleShouldThrowError = (typeof options.throttleShouldThrowError === 'boolean') ?
options.throttleShouldThrowError : throttleShouldThrowError;
// set the flag if MCU refreshConnection() should use renegotiation
+ mcuUseRenegoRestart = (typeof options.mcuUseRenegoRestart === 'boolean') ?
+ options.mcuUseRenegoRestart : mcuUseRenegoRestart;
+ // set the flag if MCU refreshConnection() should use renegotiation
mcuUseRenegoRestart = (typeof options.mcuUseRenegoRestart === 'boolean') ?
options.mcuUseRenegoRestart : mcuUseRenegoRestart;
// set the use of filtering ICE candidates
@@ -661,19 +806,169 @@
File: source/room-init.js
options.throttleIntervals.getUserMedia : throttleIntervals.getUserMedia;
}
+ // set the Signaling server url for debugging purposes
+ if (options.socketServer) {
+ if (typeof options.socketServer === 'string') {
+ socketServer = options.socketServer;
+ } else if (typeof options.socketServer === 'object' && options.socketServer.url &&
+ typeof options.socketServer.url === 'string') {
+ socketServer = {
+ url: options.socketServer.url,
+ ports: Array.isArray(options.socketServer.ports) && options.socketServer.ports.length > 0 ?
+ options.socketServer.ports : [],
+ protocol: options.socketServer.protocol && typeof options.socketServer.protocol === 'string' ?
+ options.socketServer.protocol : null
+ };
+ }
+ }
+
+ // set the Signaling server url for debugging purposes
+ if (options.iceServer) {
+ iceServer = typeof options.iceServer === 'string' ? { urls: [options.iceServer] } :
+ (Array.isArray(options.iceServer) && options.iceServer.length > 0 &&
+ options.iceServer[0] && typeof options.iceServer[0] === 'string' ? { urls: options.iceServer } : null);
+ }
+
// set turn transport option
if (typeof options.TURNServerTransport === 'string') {
// loop out for every transport option
- for (var type in self.TURN_TRANSPORT) {
- if (self.TURN_TRANSPORT.hasOwnProperty(type)) {
- // do a check if the transport option is valid
- if (self.TURN_TRANSPORT[type] === options.TURNServerTransport) {
- TURNTransport = options.TURNServerTransport;
+ for (var ttType in self.TURN_TRANSPORT) {
+ // do a check if the transport option is valid
+ if (self.TURN_TRANSPORT.hasOwnProperty(ttType) && self.TURN_TRANSPORT[ttType] === options.TURNServerTransport) {
+ TURNTransport = options.TURNServerTransport;
+ break;
+ }
+ }
+ }
+
+ // set the preferred audio codec
+ if (options.audioCodec && ((typeof options.audioCodec === 'string' &&
+ options.audioCodec !== self.AUDIO_CODEC.AUTO) || (typeof options.audioCodec === 'object' &&
+ options.audioCodec.codec && typeof options.audioCodec.codec === 'string' &&
+ options.audioCodec.codec !== self.AUDIO_CODEC.AUTO))) {
+ // loop out for every audio codec option
+ for (var acType in self.AUDIO_CODEC) {
+ // do a check if the audio codec option is valid
+ if (self.AUDIO_CODEC.hasOwnProperty(acType)) {
+ if (typeof options.audioCodec === 'string' && self.AUDIO_CODEC[acType] === options.audioCodec) {
+ audioCodec = options.audioCodec;
+ break;
+ } else if (typeof options.audioCodec === 'object' && self.AUDIO_CODEC[acType] === options.audioCodec.codec) {
+ audioCodec = {
+ codec: options.audioCodec.codec,
+ samplingRate: typeof options.audioCodec.samplingRate === 'number' &&
+ options.audioCodec.samplingRate > 0 ? options.audioCodec.samplingRate : null,
+ channels: typeof options.audioCodec.channels === 'number' &&
+ options.audioCodec.channels > 0 ? options.audioCodec.channels : null
+ };
+ break;
+ }
+ }
+ }
+ }
+
+ // set the preferred video codec
+ if (options.videoCodec && ((typeof options.videoCodec === 'string' &&
+ options.videoCodec !== self.VIDEO_CODEC.AUTO) || (typeof options.videoCodec === 'object' &&
+ options.videoCodec.codec && typeof options.videoCodec.codec === 'string' &&
+ options.videoCodec.codec !== self.VIDEO_CODEC.AUTO))) {
+ // loop out for every video codec option
+ for (var vcType in self.VIDEO_CODEC) {
+ // do a check if the video codec option is valid
+ if (self.VIDEO_CODEC.hasOwnProperty(vcType)) {
+ if (typeof options.videoCodec === 'string' && self.VIDEO_CODEC[vcType] === options.videoCodec) {
+ videoCodec = options.videoCodec;
+ break;
+ } else if (typeof options.videoCodec === 'object' && self.VIDEO_CODEC[vcType] === options.videoCodec.codec) {
+ videoCodec = {
+ codec: options.videoCodec.codec,
+ samplingRate: typeof options.videoCodec.samplingRate === 'number' &&
+ options.videoCodec.samplingRate > 0 ? options.videoCodec.samplingRate : null
+ };
break;
}
}
}
}
+
+ // set the priority weight scheme
+ if (typeof options.priorityWeightScheme === 'string') {
+ // loop out for every transport option
+ for (var pwsType in self.PRIORITY_WEIGHT_SCHEME) {
+ // do a check if the transport option is valid
+ if (self.PRIORITY_WEIGHT_SCHEME.hasOwnProperty(pwsType) &&
+ self.PRIORITY_WEIGHT_SCHEME[pwsType] === options.priorityWeightScheme) {
+ priorityWeightScheme = options.priorityWeightScheme;
+ break;
+ }
+ }
+ }
+
+ // set the codec params
+ if (options.codecParams && typeof options.codecParams === 'object') {
+ // Set audio codecs params
+ if (options.codecParams.audio && typeof options.codecParams.audio === 'object') {
+ // Set the audio codec opus params
+ if (options.codecParams.audio.opus && typeof options.codecParams.audio.opus === 'object') {
+ codecParams.audio.opus = {
+ stereo: typeof options.codecParams.audio.opus.stereo === 'boolean' ?
+ options.codecParams.audio.opus.stereo : null,
+ usedtx: typeof options.codecParams.audio.opus.usedtx === 'boolean' ?
+ options.codecParams.audio.opus.usedtx : null,
+ useinbandfec: typeof options.codecParams.audio.opus.useinbandfec === 'boolean' ?
+ options.codecParams.audio.opus.useinbandfec : null,
+ maxplaybackrate: typeof options.codecParams.audio.opus.maxplaybackrate === 'number' &&
+ options.codecParams.audio.opus.maxplaybackrate >= 8000 &&
+ options.codecParams.audio.opus.maxplaybackrate <= 48000 ?
+ options.codecParams.audio.opus.maxplaybackrate : null,
+ minptime: typeof options.codecParams.audio.opus.minptime === 'number' &&
+ options.codecParams.audio.opus.minptime >= 3 ? options.codecParams.audio.opus.minptime : null
+ };
+ }
+ }
+ // Set video codecs params
+ if (options.codecParams.video && typeof options.codecParams.video === 'object') {
+ // Set the video codec H264 params
+ if (options.codecParams.video.h264 && typeof options.codecParams.video.h264 === 'object') {
+ codecParams.video.h264 = {
+ // Only allowing profile-level-id change for experimental fixes or changes incase..
+ // Strong NOT recommended, this is like an information
+ profileLevelId: options.codecParams.video.h264.profileLevelId &&
+ typeof options.codecParams.video.h264.profileLevelId === 'string' ?
+ options.codecParams.video.h264.profileLevelId : null,
+ levelAsymmetryAllowed: typeof options.codecParams.video.h264.levelAsymmetryAllowed === 'boolean' ?
+ options.codecParams.video.h264.levelAsymmetryAllowed : null,
+ packetizationMode: typeof options.codecParams.video.h264.packetizationMode === 'boolean' ?
+ options.codecParams.video.h264.packetizationMode : null
+ };
+ }
+ // Set the video codec VP8 params
+ if (options.codecParams.video.vp8 && typeof options.codecParams.video.vp8 === 'object') {
+ // Only allowing max-fs, max-fr change for experimental fixes or changes incase..
+ // (NOT used for any other purposes)!!!!
+ // Strong NOT recommended, this is like an information
+ codecParams.video.vp8 = {
+ maxFs: typeof options.codecParams.video.vp8.maxFs === 'number' ?
+ options.codecParams.video.vp8.maxFs : null,
+ maxFr: typeof options.codecParams.video.vp8.maxFr === 'number' ?
+ options.codecParams.video.vp8.maxFr : null
+ };
+ }
+ // Set the video codec VP9 params
+ if (options.codecParams.video.vp9 && typeof options.codecParams.video.vp9 === 'object') {
+ // Only allowing max-fs, max-fr change for experimental fixes or changes incase..
+ // (NOT used for any other purposes)!!!!
+ // Strong NOT recommended, this is like an information
+ codecParams.video.vp9 = {
+ maxFs: typeof options.codecParams.video.vp9.maxFs === 'number' ?
+ options.codecParams.video.vp9.maxFs : null,
+ maxFr: typeof options.codecParams.video.vp9.maxFr === 'number' ?
+ options.codecParams.video.vp9.maxFr : null
+ };
+ }
+ }
+ }
+
// set audio fallback option
audioFallback = options.audioFallback || audioFallback;
// Custom default meeting timing and duration
@@ -701,11 +996,8 @@
/**
* Event triggered when socket connection to Signaling server has opened.
* @event channelOpen
+ * @param {JSON} session The socket connection session information.
+ * @param {String} session.serverUrl The socket connection Signaling url used.
+ * @param {String} session.transportType The socket connection transport type used.
+ * @param {JSON} session.socketOptions The socket connection options.
+ * @param {Number} session.attempts The socket connection current reconnection attempts.
+ * @param {Number} session.finalAttempts The socket connection current last attempts
+ * for the last available transports and port.
* @for Skylink
* @since 0.1.0
*/
@@ -101,6 +108,9 @@
File: source/skylink-events.js
/**
* Event triggered when socket connection to Signaling server has closed.
* @event channelClose
+ * @param {JSON} session The socket connection session information.
+ * <small>Object signature matches the <code>session</code> parameter payload received in the
+ * <a href="#event_channelOpen"><code>channelOpen</code> event</a>.</small>
* @for Skylink
* @since 0.1.0
*/
@@ -113,6 +123,9 @@
File: source/skylink-events.js
* Event triggered when receiving socket message from the Signaling server.
* @event channelMessage
* @param {JSON} message The socket message object.
+ * @param {JSON} session The socket connection session information.
+ * <small>Object signature matches the <code>session</code> parameter payload received in the
+ * <a href="#event_channelOpen"><code>channelOpen</code> event</a>.</small>
* @for Skylink
* @since 0.1.0
*/
@@ -127,6 +140,9 @@
File: source/skylink-events.js
* Event triggered when socket connection encountered exception.
* @event channelError
* @param {Error|String} error The error object.
+ * @param {JSON} session The socket connection session information.
+ * <small>Object signature matches the <code>session</code> parameter payload received in the
+ * <a href="#event_channelOpen"><code>channelOpen</code> event</a>.</small>
* @for Skylink
* @since 0.1.0
*/
@@ -137,7 +153,10 @@
File: source/skylink-events.js
* @event channelRetry
* @param {String} fallbackType The current fallback state.
* [Rel: Skylink.SOCKET_FALLBACK]
- * @param {Number} currentAttempt The current reconnection attempt.
+ * @param {Number} currentAttempt The current socket reconnection attempt.
+ * @param {JSON} session The socket connection session information.
+ * <small>Object signature matches the <code>session</code> parameter payload received in the
+ * <a href="#event_channelOpen"><code>channelOpen</code> event</a>.</small>
* @for Skylink
* @since 0.5.6
*/
@@ -151,6 +170,9 @@
File: source/skylink-events.js
* @param {Error|String|Number} error The error object.
* @param {String} type The fallback state of the socket connection attempt.
* [Rel: Skylink.SOCKET_FALLBACK]
+ * @param {JSON} session The socket connection session information.
+ * <small>Object signature matches the <code>session</code> parameter payload received in the
+ * <a href="#event_channelOpen"><code>channelOpen</code> event</a>.</small>
* @for Skylink
* @since 0.5.5
*/
@@ -322,6 +344,12 @@
File: source/skylink-events.js
* @param {JSON} peerInfo The Peer session information.
* @param {JSON|String} peerInfo.userData The Peer current custom data.
* @param {JSON} peerInfo.settings The Peer sending Stream settings.
+ * @param {Boolean|JSON} peerInfo.settings.data The flag if Peer has any Datachannel connections enabled.
+ * <small>If <code>isSelf</code> value is <code>true</code>, this determines if User allows
+ * Datachannel connections, else if value is <code>false</code>, this determines if Peer has any active
+ * Datachannel connections (where <a href="#event_dataChannelState"><code>dataChannelState</code> event</a>
+ * triggers <code>state</code> as <code>OPEN</code> and <code>channelType</code> as
+ * <code>MESSAGING</code> for Peer) with Peer.</small>
* @param {Boolean|JSON} peerInfo.settings.audio The Peer Stream audio settings.
* <small>When defined as <code>false</code>, it means there is no audio being sent from Peer.</small>
* <small>When defined as <code>true</code>, the <code>peerInfo.settings.audio.stereo</code> value is
@@ -409,6 +437,8 @@
File: source/skylink-events.js
* <small>Data may be accessing OS platform version from Web SDK.</small>
* @param {String} [peerInfo.agent.pluginVersion] The Peer Temasys Plugin version.
* <small>Defined only when Peer is using the Temasys Plugin (IE / Safari).</small>
+ * @param {String} peerInfo.agent.DTProtocolVersion The Peer data transfer (DT) protocol version.
+ * @param {String} peerInfo.agent.SMProtocolVersion The Peer signaling message (SM) protocol version.
* @param {String} peerInfo.room The Room Peer is from.
* @param {JSON} peerInfo.config The Peer connection configuration.
* @param {Boolean} peerInfo.config.enableIceTrickle The flag if Peer connection has
@@ -536,14 +566,14 @@
File: source/skylink-events.js
* @param {String} peerId The Peer ID.
* @param {JSON} transferInfo The data transfer information.
* <small>Object signature matches the <code>transferInfo</code> parameter payload received in the
- * <a href="#event_dataTransferState"><code>dataTransferState</code> event</a>.</small>
+ * <a href="#event_dataTransferState"><code>dataTransferState</code> event</a>
+ * except without the <code>data</code> property.</small>
* @param {Boolean} isSelf The flag if Peer is User.
* @for Skylink
* @since 0.6.1
*/
incomingData: [],
-
/**
* Event triggered when receiving upload data transfer from Peer.
* @event incomingDataRequest
@@ -551,13 +581,63 @@
File: source/skylink-events.js
* @param {String} peerId The Peer ID.
* @param {String} transferInfo The data transfer information.
* <small>Object signature matches the <code>transferInfo</code> parameter payload received in the
- * <a href="#event_dataTransferState"><code>dataTransferState</code> event</a>.</small>
+ * <a href="#event_dataTransferState"><code>dataTransferState</code> event</a>
+ * except without the <code>data</code> property.</small>
* @param {Boolean} isSelf The flag if Peer is User.
* @for Skylink
* @since 0.6.1
*/
incomingDataRequest: [],
+ /**
+ * Event triggered when data streaming session has been started from Peer to User.
+ * @event incomingDataStreamStarted
+ * @param {String} streamId The data streaming session ID.
+ * @param {String} peerId The Peer ID.
+ * @param {JSON} streamInfo The data streaming session information.
+ * <small>Object signature matches the <code>streamInfo</code> parameter payload received in the
+ * <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * except without the <code>chunk</code> property.</small>
+ * @param {Boolean} isSelf The flag if Peer is User.
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+ incomingDataStreamStarted: [],
+
+ /**
+ * Event triggered when data streaming session has been stopped from Peer to User.
+ * @event incomingDataStreamStopped
+ * @param {String} streamId The data streaming session ID.
+ * @param {String} peerId The Peer ID.
+ * @param {JSON} streamInfo The data streaming session information.
+ * <small>Object signature matches the <code>streamInfo</code> parameter payload received in the
+ * <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * except without the <code>chunk</code> property.</small>
+ * @param {Boolean} isSelf The flag if Peer is User.
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+ incomingDataStreamStopped: [],
+
+ /**
+ * Event triggered when data streaming session has been stopped from Peer to User.
+ * @event incomingDataStream
+ * @param {Blob|String} chunk The data chunk received.
+ * @param {String} streamId The data streaming session ID.
+ * @param {String} peerId The Peer ID.
+ * @param {JSON} streamInfo The data streaming session information.
+ * <small>Object signature matches the <code>streamInfo</code> parameter payload received in the
+ * <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
+ * except without the <code>chunk</code> property.</small>
+ * @param {Boolean} isSelf The flag if Peer is User.
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+ incomingDataStream: [],
+
/**
* Event triggered when Room locked status has changed.
* @event roomLock
@@ -586,6 +666,9 @@
File: source/skylink-events.js
* @param {String} messageType The Datachannel sending Datachannel message error type.
* <small>Defined only when <cod>state</code> payload is <code>SEND_MESSAGE_ERROR</code>.</small>
* [Rel: Skylink.DATA_CHANNEL_MESSAGE_ERROR]
+ * @param {JSON} bufferAmount The Datachannel buffered amount information.
+ * @param {Number} bufferAmount.bufferedAmountLow The size of currently queued data to send on the Datachannel connection.
+ * @param {Number} bufferAmount.bufferedAmountLowThreshold The current buffered amount low threshold configured.
* @for Skylink
* @since 0.1.0
*/
@@ -597,7 +680,10 @@
File: source/skylink-events.js
* @param {String} state The current data transfer state.
* [Rel: Skylink.DATA_TRANSFER_STATE]
* @param {String} transferId The data transfer ID.
+ * <small>Note that this is defined as <code>null</code> when <code>state</code> payload is <code>START_ERROR</code>.</small>
* @param {String} peerId The Peer ID.
+ * <small>Note that this could be defined as <code>null</code> when <code>state</code> payload is
+ * <code>START_ERROR</code> and there is no Peers to start data transfer with.</small>
* @param {JSON} transferInfo The data transfer information.
* @param {Blob|String} [transferInfo.data] The data object.
* <small>Defined only when <code>state</code> payload is <code>UPLOAD_STARTED</code> or
@@ -618,7 +704,7 @@
File: source/skylink-events.js
* data object sent MIME type information is defined.</small>
* @param {Number} transferInfo.chunkSize The data transfer data chunk size.
* @param {Number} transferInfo.percentage The data transfer percentage of completion progress.
- * @param {Number} transferInfo.timeout The flag if message is targeted or not, basing
+ * @param {Number} transferInfo.timeout The flag if data transfer is targeted or not, basing
* off the <code>targetPeerId</code> parameter being defined in
* <a href="#method_sendURLData"><code>sendURLData()</code> method</a> or
* <a href="#method_sendBlobData"><code>sendBlobData()</code> method</a>.
@@ -630,7 +716,7 @@
File: source/skylink-events.js
* [Rel: Skylink.DATA_TRANSFER_TYPE]
* @param {JSON} [error] The error result.
* <small>Defined only when <code>state</code> payload is <code>ERROR</code>, <code>CANCEL</code>,
- * <code>REJECTED</code> or <code>USER_REJECTED</code>.</small>
+ * <code>REJECTED</code>, <code>START_ERROR</code> or <code>USER_REJECTED</code>.</small>
* @param {Error|String} error.message The error object.
* @param {String} error.transferType The data transfer direction from where the error occurred.
* [Rel: Skylink.DATA_TRANSFER_TYPE]
@@ -639,6 +725,37 @@
File: source/skylink-events.js
*/
dataTransferState: [],
+ /**
+ * Event triggered when a data streaming state has changed.
+ * @event dataStreamState
+ * @param {String} state The current data streaming state.
+ * [Rel: Skylink.DATA_STREAM_STATE]
+ * @param {String} streamId The data streaming session ID.
+ * <small>Note that this is defined as <code>null</code> when <code>state</code> payload is <code>START_ERROR</code>.</small>
+ * @param {String} peerId The Peer ID.
+ * <small>Note that this could be defined as <code>null</code> when <code>state</code> payload is
+ * <code>START_ERROR</code> and there is no Peers to start data streaming with.</small>
+ * @param {JSON} streamInfo The data streaming information.
+ * @param {Blob|String} [streamInfo.chunk] The data chunk received.
+ * <small>Defined only when <code>state</code> payload is <code>RECEIVED</code> or <code>SENT</code>.</small>
+ * @param {Number} streamInfo.chunkSize The data streaming data chunk size received.
+ * @param {String} streamInfo.chunkType The data streaming data chunk type received.
+ * <small>The initial data chunks value may change depending on the currently received data chunk type or the
+ * agent supported sending type of data chunks.</small>
+ * [Rel: Skylink.DATA_TRANSFER_DATA_TYPE]
+ * @param {String} streamInfo.isStringStream The flag if data streaming data chunks are strings.
+ * @param {Boolean} streamInfo.isPrivate The flag if data streaming is targeted or not, basing
+ * off the <code>targetPeerId</code> parameter being defined in
+ * <a href="#method_startStreamingData"><code>startStreamingData()</code> method</a>.
+ * @param {String} streamInfo.senderPeerId The sender Peer ID.
+ * @param {Error} [error] The error object.
+ * <small>Defined only when <code>state</code> payload is <code>ERROR</code> or <code>START_ERROR</code>,.</small>
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+ dataStreamState: [],
+
/**
* Event triggered when Signaling server reaction state has changed.
* @event systemAction
@@ -784,14 +901,26 @@
File: source/skylink-events.js
* <small>Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.</small>
* @param {Number} stats.audio.sending.packets The Peer connection current sending audio streaming packets.
* @param {Number} stats.audio.sending.totalPackets The Peer connection total sending audio streaming packets.
- * @param {Number} stats.audio.sending.packetsLost The Peer connection current sending audio streaming packets lost.
- * @param {Number} stats.audio.sending.totalPacketsLost The Peer connection total sending audio streaming packets lost.
+ * @param {Number} stats.audio.sending.packetsLost <blockquote class="info">
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in <code>sending</code> property.
+ * </blockquote> The Peer connection current sending audio streaming packets lost.
+ * @param {Number} stats.audio.sending.totalPacketsLost <blockquote class="info">
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in <code>sending</code> property.
+ * </blockquote> The Peer connection total sending audio streaming packets lost.
* @param {Number} stats.audio.sending.ssrc The Peer connection sending audio streaming RTP packets SSRC.
* @param {Number} stats.audio.sending.rtt The Peer connection sending audio streaming RTT (Round-trip delay time).
* <small>Defined as <code>0</code> if it's not present in original raw stats before parsing.</small>
- * @param {Number} stats.audio.sending.jitter The Peer connection sending audio streaming RTP packets jitter in seconds.
+ * @param {Number} stats.audio.sending.jitter <blockquote class="info">
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in <code>sending</code> property.
+ * </blockquote> The Peer connection sending audio streaming RTP packets jitter in seconds.
* <small>Defined as <code>0</code> if it's not present in original raw stats before parsing.</small>
- * @param {Number} [stats.audio.sending.jitterBufferMs] The Peer connection sending audio streaming
+ * @param {Number} [stats.audio.sending.jitterBufferMs] <blockquote class="info">
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in <code>sending</code> property.
+ * </blockquote> The Peer connection sending audio streaming
* RTP packets jitter buffer in miliseconds.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {JSON} [stats.audio.sending.codec] The Peer connection sending audio streaming selected codec information.
@@ -822,7 +951,10 @@
File: source/skylink-events.js
* @param {Number} stats.audio.receiving.packets The Peer connection current receiving audio streaming packets.
* @param {Number} stats.audio.receiving.totalPackets The Peer connection total receiving audio streaming packets.
* @param {Number} stats.audio.receiving.packetsLost The Peer connection current receiving audio streaming packets lost.
+ * @param {Number} stats.audio.receiving.fractionLost The Peer connection current receiving audio streaming fraction packets lost.
+ * @param {Number} stats.audio.receiving.packetsDiscarded The Peer connection current receiving audio streaming packets discarded.
* @param {Number} stats.audio.receiving.totalPacketsLost The Peer connection total receiving audio streaming packets lost.
+ * @param {Number} stats.audio.receiving.totalPacketsDiscarded The Peer connection total receiving audio streaming packets discarded.
* @param {Number} stats.audio.receiving.ssrc The Peer connection receiving audio streaming RTP packets SSRC.
* @param {Number} stats.audio.receiving.jitter The Peer connection receiving audio streaming RTP packets jitter in seconds.
* <small>Defined as <code>0</code> if it's not present in original raw stats before parsing.</small>
@@ -854,15 +986,28 @@
File: source/skylink-events.js
* <small>Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.</small>
* @param {Number} stats.video.sending.packets The Peer connection current sending video streaming packets.
* @param {Number} stats.video.sending.totalPackets The Peer connection total sending video streaming packets.
- * @param {Number} stats.video.sending.packetsLost The Peer connection current sending video streaming packets lost.
- * @param {Number} stats.video.sending.totalPacketsLost The Peer connection total sending video streaming packets lost.
+ * @param {Number} stats.video.sending.packetsLost <blockquote class="info">
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in <code>sending</code> property.
+ * </blockquote> The Peer connection current sending video streaming packets lost.
+ * @param {Number} stats.video.sending.totalPacketsLost <blockquote class="info">
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in <code>sending</code> property.
+ * </blockquote> The Peer connection total sending video streaming packets lost.
* @param {Number} stats.video.sending.ssrc The Peer connection sending video streaming RTP packets SSRC.
* @param {Number} stats.video.sending.rtt The Peer connection sending video streaming RTT (Round-trip delay time).
* <small>Defined as <code>0</code> if it's not present in original raw stats before parsing.</small>
- * @param {Number} stats.video.sending.jitter The Peer connection sending video streaming RTP packets jitter in seconds.
+ * @param {Number} stats.video.sending.jitter <blockquote class="info">
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in <code>sending</code> property.
+ * </blockquote> The Peer connection sending video streaming RTP packets jitter in seconds.
* <small>Defined as <code>0</code> if it's not present in original raw stats before parsing.</small>
- * @param {Number} [stats.video.sending.jitterBufferMs] The Peer connection sending video streaming
- * RTP packets jitter buffer in miliseconds.
+ * @param {Number} [stats.video.sending.jitterBufferMs] <blockquote class="info">
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in <code>sending</code> property.
+ * </blockquote> The Peer connection sending video streaming RTP packets jitter buffer in miliseconds.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.sending.qpSum] The Peer connection sending video streaming sum of the QP values of frames passed.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {JSON} [stats.video.sending.codec] The Peer connection sending video streaming selected codec information.
* <small>Defined as <code>null</code> if local session description is not available before parsing.</small>
@@ -879,7 +1024,9 @@
File: source/skylink-events.js
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.sending.frames] The Peer connection sending video streaming frames.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
- * @param {Number} [stats.video.sending.framesInput] The Peer connection sending video streaming frames input.
+ * @param {Number} [stats.video.sending.frameRateInput] The Peer connection sending video streaming fps input.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.sending.frameRateInput] The Peer connection sending video streaming fps input.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.sending.framesDropped] The Peer connection sending video streaming frames dropped.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
@@ -887,6 +1034,14 @@
File: source/skylink-events.js
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.sending.frameRateStdDev] The Peer connection sending video streaming fps standard deviation.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.sending.framesPerSecond] The Peer connection sending video streaming fps.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.sending.framesDecoded] The Peer connection sending video streaming frames decoded.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.sending.framesCorrupted] The Peer connection sending video streaming frames corrupted.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.sending.totalFrames] The Peer connection total sending video streaming frames.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.sending.nacks] The Peer connection current sending video streaming nacks.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.sending.totalNacks] The Peer connection total sending video streaming nacks.
@@ -899,6 +1054,10 @@
File: source/skylink-events.js
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.sending.totalFirs] The Peer connection total sending video streaming firs.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.sending.slis] The Peer connection current sending video streaming slis.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.sending.totalSlis] The Peer connection total sending video streaming slis.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {JSON} stats.video.receiving The Peer connection receiving video streaming stats.
* @param {Number} stats.video.receiving.bytes The Peer connection current receiving video streaming bytes.
* <small>Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.</small>
@@ -907,9 +1066,12 @@
File: source/skylink-events.js
* @param {Number} stats.video.receiving.packets The Peer connection current receiving video streaming packets.
* @param {Number} stats.video.receiving.totalPackets The Peer connection total receiving video streaming packets.
* @param {Number} stats.video.receiving.packetsLost The Peer connection current receiving video streaming packets lost.
+ * @param {Number} stats.video.receiving.fractionLost The Peer connection current receiving video streaming fraction packets lost.
+ * @param {Number} stats.video.receiving.packetsDiscarded The Peer connection current receiving video streaming packets discarded.
* @param {Number} stats.video.receiving.totalPacketsLost The Peer connection total receiving video streaming packets lost.
+ * @param {Number} stats.video.receiving.totalPacketsDiscarded The Peer connection total receiving video streaming packets discarded.
* @param {Number} stats.video.receiving.ssrc The Peer connection receiving video streaming RTP packets SSRC.
- * @param {Number} stats.video.receiving.e2eDelay The Peer connection receiving video streaming e2e delay.
+ * @param {Number} [stats.video.receiving.e2eDelay] The Peer connection receiving video streaming e2e delay.
* <small>Defined as <code>null</code> if it's not present in original raw stats before parsing, and that
* it finds any existing audio, video or object (plugin) DOM elements that has set with the
* Peer remote stream object to parse current time. Note that <code>document.getElementsByTagName</code> function
@@ -936,7 +1098,7 @@
File: source/skylink-events.js
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.receiving.frames] The Peer connection receiving video streaming frames.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
- * @param {Number} [stats.video.receiving.framesOutput] The Peer connection receiving video streaming frames output.
+ * @param {Number} [stats.video.receiving.framesOutput] The Peer connection receiving video streaming fps output.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.receiving.framesDecoded] The Peer connection receiving video streaming frames decoded.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
@@ -944,18 +1106,30 @@
File: source/skylink-events.js
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.receiving.frameRateStdDev] The Peer connection receiving video streaming fps standard deviation.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.receiving.framesPerSecond] The Peer connection receiving video streaming fps.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.receiving.framesDecoded] The Peer connection receiving video streaming frames decoded.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.receiving.framesCorrupted] The Peer connection receiving video streaming frames corrupted.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.receiving.totalFrames] The Peer connection total receiving video streaming frames.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.receiving.nacks] The Peer connection current receiving video streaming nacks.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.receiving.totalNacks] The Peer connection total receiving video streaming nacks.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.receiving.plis] The Peer connection current receiving video streaming plis.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
- * @param {Number} [stats.video.receiving.totalPlis] The Peer connection totally receiving video streaming plis.
+ * @param {Number} [stats.video.receiving.totalPlis] The Peer connection total receiving video streaming plis.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.receiving.firs] The Peer connection current receiving video streaming firs.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {Number} [stats.video.receiving.totalFirs] The Peer connection total receiving video streaming firs.
* <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.receiving.slis] The Peer connection current receiving video streaming slis.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Number} [stats.video.receiving.totalPlis] The Peer connection total receiving video streaming slis.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {JSON} stats.selectedCandidate The Peer connection selected ICE candidate pair stats.
* @param {JSON} stats.selectedCandidate.local The Peer connection selected local ICE candidate.
* @param {String} stats.selectedCandidate.local.ipAddress The Peer connection selected
@@ -966,6 +1140,10 @@
File: source/skylink-events.js
* local ICE candidate IP transport type.
* @param {String} stats.selectedCandidate.local.candidateType The Peer connection selected
* local ICE candidate type.
+ * @param {String} [stats.selectedCandidate.local.turnMediaTransport] The Peer connection possible
+ * transport used when relaying local media to TURN server.
+ * <small>Types are <code>"UDP"</code> (UDP connections), <code>"TCP"</code> (TCP connections) and
+ * <code>"TCP/TLS"</code> (TCP over TLS connections).</small>
* @param {JSON} stats.selectedCandidate.remote The Peer connection selected remote ICE candidate.
* @param {String} stats.selectedCandidate.remote.ipAddress The Peer connection selected
* remote ICE candidate IP address.
@@ -975,6 +1153,73 @@
File: source/skylink-events.js
* remote ICE candidate IP transport type.
* @param {String} stats.selectedCandidate.remote.candidateType The Peer connection selected
* remote ICE candidate type.
+ * @param {Boolean} [stats.selectedCandidate.writable] The flag if Peer has gotten ACK to an ICE request.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {Boolean} [stats.selectedCandidate.readable] The flag if Peer has gotten a valid incoming ICE request.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.rtt] The current STUN connectivity checks RTT (Round-trip delay time).
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.totalRtt] The total STUN connectivity checks RTT (Round-trip delay time).
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {JSON} stats.selectedCandidate.requests The ICE connectivity check requests.
+ * @param {String} [stats.selectedCandidate.requests.received] The current ICE connectivity check requests received.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.requests.sent] The current ICE connectivity check requests sent.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.requests.totalReceived] The total ICE connectivity check requests received.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.requests.totalSent] The total ICE connectivity check requests sent.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {JSON} stats.selectedCandidate.responses The ICE connectivity check responses.
+ * @param {String} [stats.selectedCandidate.responses.received] The current ICE connectivity check responses received.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.responses.sent] The current ICE connectivity check responses sent.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.responses.totalReceived] The total ICE connectivity check responses received.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.responses.totalSent] The total ICE connectivity check responses sent.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {JSON} stats.selectedCandidate.consentRequests The current ICE consent requests.
+ * @param {String} [stats.selectedCandidate.consentRequests.received] The current ICE consent requests received.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.consentRequests.sent] The current ICE consent requests sent.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.consentRequests.totalReceived] The total ICE consent requests received.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.consentRequests.totalSent] The total ICE consent requests sent.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {JSON} stats.selectedCandidate.consentResponses The current ICE consent responses.
+ * @param {String} [stats.selectedCandidate.consentResponses.received] The current ICE consent responses received.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.consentResponses.sent] The current ICE consent responses sent.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.consentResponses.totalReceived] The total ICE consent responses received.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.selectedCandidate.consentResponses.totalSent] The total ICE consent responses sent.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {JSON} stats.certificate The Peer connection DTLS/SRTP exchanged certificates information.
+ * @param {JSON} stats.certificate.local The Peer connection local certificate information.
+ * @param {String} [stats.certificate.local.fingerprint] The Peer connection local certificate fingerprint.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.certificate.local.fingerprintAlgorithm] The Peer connection local
+ * certificate fingerprint algorithm.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.certificate.local.derBase64] The Peer connection local
+ * base64 certificate in binary DER format encoded in base64.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {JSON} stats.certificate.remote The Peer connection remote certificate information.
+ * @param {String} [stats.certificate.remote.fingerprint] The Peer connection remote certificate fingerprint.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.certificate.remote.fingerprintAlgorithm] The Peer connection remote
+ * certificate fingerprint algorithm.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.certificate.remote.derBase64] The Peer connection remote
+ * base64 certificate in binary DER format encoded in base64.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.certificate.srtpCipher] The certificates SRTP cipher.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
+ * @param {String} [stats.certificate.dtlsCipher] The certificates DTLS cipher.
+ * <small>Defined as <code>null</code> if it's not available in original raw stats before parsing.</small>
* @param {JSON} stats.connection The Peer connection object stats.
* @param {String} stats.connection.iceConnectionState The Peer connection ICE connection state.
* @param {String} stats.connection.iceGatheringState The Peer connection ICE gathering state.
@@ -1068,6 +1313,9 @@
File: source/skylink-events.js
* @param {String} stats.connection.dataChannels.#channelName.currentTransferId The Peer connection
* Datachannel connection current progressing transfer session ID.
* <small>Defined as <code>null</code> when there is currently no transfer session progressing on the Datachannel connection.</small>
+ * @param {String} stats.connection.dataChannels.#channelName.currentStreamId The Peer connection
+ * Datachannel connection current data streaming session ID.
+ * <small>Defined as <code>null</code> when there is currently no data streaming session on the Datachannel connection.</small>
* @param {Error} error The error object received.
* <small>Defined only when <code>state</code> payload is <code>RETRIEVE_ERROR</code>.</small>
* @for Skylink
@@ -1118,7 +1366,26 @@
File: source/skylink-events.js
* @for Skylink
* @since 0.6.16
*/
- candidateProcessingState: []
+ candidateProcessingState: [],
+
+ /**
+ * <blockquote class="info">
+ * Learn more about how ICE works in this
+ * <a href="https://temasys.com.sg/ice-what-is-this-sorcery/">article here</a>.<br>
+ * Note that this event may not be triggered for MCU enabled Peer connections as ICE candidates
+ * may be received in the session description instead.
+ * </blockquote>
+ * Event triggered when all remote ICE candidates gathering has completed and been processed.
+ * @event candidatesGathered
+ * @param {String} peerId The Peer ID.
+ * @param {JSON} length The remote ICE candidates length.
+ * @param {Number} length.expected The expected total number of remote ICE candidates to be received.
+ * @param {Number} length.received The actual total number of remote ICE candidates received.
+ * @param {Number} length.processed The total number of remote ICE candidates processed.
+ * @for Skylink
+ * @since 0.6.18
+ */
+ candidatesGathered: []
};
/**
@@ -1192,9 +1459,6 @@
/**
* Function that unsubscribes listeners from an event.
* @method off
- * @param {String} eventName The event.
+ * @param {String} [eventName] The event.
+ * - When not provided, all listeners to all events will be unsubscribed.
* @param {Function} [callback] The listener to unsubscribe.
* - When not provided, all listeners associated to the event will be unsubscribed.
* @example
@@ -1223,32 +1488,37 @@
File: source/skylink-events.js
* @since 0.5.5
*/
Skylink.prototype.off = function(eventName, callback) {
- if (callback === undefined) {
- this._EVENTS[eventName] = [];
- this._onceEvents[eventName] = [];
- log.log([null, 'Event', eventName, 'All events are unsubscribed']);
- return;
- }
- var arr = this._EVENTS[eventName];
- var once = this._onceEvents[eventName];
-
- // unsubscribe events that is triggered always
- for (var i = 0; i < arr.length; i++) {
- if (arr[i] === callback) {
- log.log([null, 'Event', eventName, 'Event is unsubscribed']);
- arr.splice(i, 1);
- break;
+ if (!(eventName && typeof eventName === 'string')) {
+ this._EVENTS = {};
+ this._onceEvents = {};
+ } else {
+ if (callback === undefined) {
+ this._EVENTS[eventName] = [];
+ this._onceEvents[eventName] = [];
+ log.log([null, 'Event', eventName, 'All events are unsubscribed']);
+ return;
}
- }
- // unsubscribe events fired only once
- if(once !== undefined) {
- for (var j = 0; j < once.length; j++) {
- if (once[j][0] === callback) {
- log.log([null, 'Event', eventName, 'One-time Event is unsubscribed']);
- once.splice(j, 1);
+ var arr = this._EVENTS[eventName] || [];
+ var once = this._onceEvents[eventName] || [];
+
+ // unsubscribe events that is triggered always
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] === callback) {
+ log.log([null, 'Event', eventName, 'Event is unsubscribed']);
+ arr.splice(i, 1);
break;
}
}
+ // unsubscribe events fired only once
+ if(once !== undefined) {
+ for (var j = 0; j < once.length; j++) {
+ if (once[j][0] === callback) {
+ log.log([null, 'Event', eventName, 'One-time Event is unsubscribed']);
+ once.splice(j, 1);
+ break;
+ }
+ }
+ }
}
};
@@ -1300,7 +1570,6 @@
* @param {String} LONG_POLLING <small>Value <code>"fallbackLongPollingNonSSL"</code></small>
* The value of the reconnection state when <code>joinRoom()</code> socket connection is reconnecting with
* another new HTTP port using Polling transports to attempt to establish connection with Signaling server.
- * @param {String} LONG_POLLING <small>Value <code>"fallbackLongPollingSSL"</code></small>
+ * @param {String} LONG_POLLING_SSL <small>Value <code>"fallbackLongPollingSSL"</code></small>
* The value of the reconnection state when <code>joinRoom()</code> socket connection is reconnecting with
* another new HTTPS port using Polling transports to attempt to establish connection with Signaling server.
* @type JSON
@@ -167,7 +167,7 @@
File: source/socket-channel.js
var throughput = 16;
if (!self._channelOpen || !self._user || !self._socket) {
- log.warn([null, 'Socket', null, 'Dropping of message as Socket connection is not opened or is at ' +
+ log.warn([message.target || 'Server', 'Socket', message.type, 'Dropping of message as Socket connection is not opened or is at ' +
'incorrect step ->'], message);
return;
}
@@ -233,10 +233,6 @@
self._socketMessageTimeout = null;
if (!self._channelOpen || !(self._user && self._user.sid) || !self._socket) {
- log.warn([null, 'Socket', null, 'Dropping of group messages as Socket connection is not opened or is at ' +
+ log.warn([message.target || 'Server', 'Socket', null, 'Dropping of group messages as Socket connection is not opened or is at ' +
'incorrect step ->'], groupMessageList);
return;
}
@@ -281,7 +277,8 @@
* The value of the option to prefer the <a href="https://en.wikipedia.org/wiki/Opus_(audio_format)">OPUS</a> audio codec.
* @param {String} ISAC <small>Value <code>"ISAC"</code></small>
* The value of the option to prefer the <a href="https://en.wikipedia.org/wiki/Internet_Speech_Audio_Codec">ISAC</a> audio codec.
+ * @param {String} ILBC <small>Value <code>"ILBC"</code></small>
+ * The value of the option to prefer the <a href="https://en.wikipedia.org/wiki/Internet_Low_Bitrate_Codec">iLBC</a> audio codec.
* @param {String} G722 <small>Value <code>"G722"</code></small>
* The value of the option to prefer the <a href="https://en.wikipedia.org/wiki/G.722">G722</a> audio codec.
+ * @param {String} PCMA <small>Value <code>"PCMA"</code></small>
+ * The value of the option to prefer the <a href="https://en.wikipedia.org/wiki/G.711">G711u</a> audio codec.
+ * @param {String} PCMU <small>Value <code>"PCMU"</code></small>
+ * The value of the option to prefer the <a href="https://en.wikipedia.org/wiki/G.711">G711a</a> audio codec.
* @type JSON
* @readOnly
* @for Skylink
@@ -147,9 +153,10 @@
* Note that the current Edge browser implementation does not support the <code>options.audio.optional</code>,
* <code>options.audio.deviceId</code>, <code>options.audio.echoCancellation</code>.</blockquote>
* The audio configuration options.
- * @param {Boolean} [options.audio.stereo=false] The flag if stereo band should be configured
- * when encoding audio codec is <a href="#attr_AUDIO_CODEC"><code>OPUS</code></a> for sending / receiving audio data.
- * <small>Note that Peers may override the "receiving" <code>stereo</code> config depending on the Peers configuration.</small>
- * @param {Boolean} [options.audio.usedtx] <blockquote class="info">
- * Note that this feature might not work depending on the browser support and implementation.</blockquote>
- * The flag if DTX (Discontinuous Transmission) should be configured when encoding audio codec
- * is <a href="#attr_AUDIO_CODEC"><code>OPUS</code></a> for sending / receiving audio data.
- * <small>This might help to reduce bandwidth it reduces the bitrate during silence or background noise.</small>
+ * @param {Boolean} [options.audio.stereo=false] <blockquote class="info"><b>Deprecation Warning!</b>
+ * This property has been deprecated. Configure this with the <code>options.codecParams.audio.opus.stereo</code>
+ * parameter in the <a href="#method_init"><code>init()</code> method</a> instead. If the
+ * <code>options.codecParams.audio.opus.stereo</code> is configured, this overrides the
+ * <code>options.audio.stereo</code> setting.</blockquote>
+ * The flag if OPUS audio codec stereo band should be configured for sending encoded audio data.
* <small>When not provided, the default browser configuration is used.</small>
- * <small>Note that Peers may override the "receiving" <code>usedtx</code> config depending on the Peers configuration.</small>
- * @param {Boolean} [options.audio.useinbandfec] <blockquote class="info">
- * Note that this feature might not work depending on the browser support and implementation.</blockquote>
- * The flag if capability to take advantage of in-band FEC (Forward Error Correction) should be
- * configured when encoding audio codec is <a href="#attr_AUDIO_CODEC"><code>OPUS</code></a> for sending / receiving audio data.
- * <small>This might help to reduce the harm of packet loss by encoding information about the previous packet.</small>
+ * @param {Boolean} [options.audio.usedtx] <blockquote class="info"><b>Deprecation Warning!</b>
+ * This property has been deprecated. Configure this with the <code>options.codecParams.audio.opus.stereo</code>
+ * parameter in the <a href="#method_init"><code>init()</code> method</a> instead. If the
+ * <code>options.codecParams.audio.opus.stereo</code> is configured, this overrides the
+ * <code>options.audio.stereo</code> setting. Note that this feature might
+ * not work depending on the browser support and implementation.</blockquote>
+ * The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.
+ * <small>This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and
+ * goes hand-in-hand with the <code>options.voiceActivityDetection</code> flag in <a href="#method_joinRoom">
+ * <code>joinRoom()</code> method</a>.</small>
* <small>When not provided, the default browser configuration is used.</small>
- * <small>Note that Peers may override the "receiving" <code>useinbandfec</code> config depending on the Peers configuration.</small>
- * @param {Number} [options.audio.maxplaybackrate] <blockquote class="info">
- * Note that this feature might not work depending on the browser support and implementation.</blockquote>
- * The maximum output sampling rate rendered in Hertz (Hz) when encoding audio codec is
- * <a href="#attr_AUDIO_CODEC"><code>OPUS</code></a> for sending / receiving audio data.
+ * @param {Boolean} [options.audio.useinbandfec] <blockquote class="info"><b>Deprecation Warning!</b>
+ * This property has been deprecated. Configure this with the <code>options.codecParams.audio.opus.useinbandfec</code>
+ * parameter in the <a href="#method_init"><code>init()</code> method</a> instead. If the
+ * <code>options.codecParams.audio.opus.useinbandfec</code> is configured, this overrides the
+ * <code>options.audio.useinbandfec</code> setting. Note that this parameter should only be used
+ * for debugging purposes only.</blockquote>
+ * The flag if OPUS audio codec has the capability to take advantage of the in-band FEC
+ * (Forward Error Correction) when sending encoded audio data.
+ * <small>This helps to reduce the harm of packet loss by encoding information about the previous packet loss.</small>
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Number} [options.audio.maxplaybackrate] <blockquote class="info"><b>Deprecation Warning!</b>
+ * This property has been deprecated. Configure this with the <code>options.codecParams.audio.opus.maxplaybackrate</code>
+ * parameter in the <a href="#method_init"><code>init()</code> method</a> instead. If the
+ * <code>options.codecParams.audio.opus.maxplaybackrate</code> is configured, this overrides the
+ * <code>options.audio.maxplaybackrate</code> setting. Note that this feature might
+ * not work depending on the browser support and implementation.
+ * Note that this parameter should only be used for debugging purposes only.</blockquote>
+ * The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving
+ * decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data
+ * would not encode at a higher sampling rate specified by this.
* <small>This value must be between <code>8000</code> to <code>48000</code>.</small>
* <small>When not provided, the default browser configuration is used.</small>
- * <small>Note that Peers may override the "receiving" <code>maxplaybackrate</code> config depending on the Peers configuration.</small>
* @param {Boolean} [options.audio.mute=false] The flag if audio tracks should be muted upon receiving them.
* <small>Providing the value as <code>false</code> does nothing to <code>peerInfo.mediaStatus.audioMuted</code>,
* but when provided as <code>true</code>, this sets the <code>peerInfo.mediaStatus.audioMuted</code> value to
@@ -381,7 +404,10 @@
File: source/stream-media.js
* <small>The list of available audio source ID can be retrieved by the <a href="https://developer.
* mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices"><code>navigator.mediaDevices.enumerateDevices</code>
* API</a>.</small>
- * @param {Boolean} [options.audio.echoCancellation=false] The flag to enable audio tracks echo cancellation.
+ * @param {Boolean} [options.audio.echoCancellation=true] <blockquote class="info">
+ * For Chrome/Opera/IE/Safari/Bowser, the echo cancellation functionality may not work and may produce a terrible
+ * feedback. It is recommended to use headphones or other microphone devices rather than the device
+ * in-built microphones.</blockquote> The flag to enable echo cancellation for audio track.
* @param {Boolean|JSON} [options.video=false] <blockquote class="info">
* Note that the current Edge browser implementation does not support the <code>options.video.optional</code>,
* <code>options.video.deviceId</code>, <code>options.video.resolution</code> and
@@ -794,7 +820,7 @@
File: source/stream-media.js
}
if (Object.keys(self._peerConnections).length > 0 || self._hasMCU) {
- self._refreshPeerConnection(Object.keys(self._peerConnections), false, function (err, success) {
+ self._refreshPeerConnection(Object.keys(self._peerConnections), false, {}, function (err, success) {
if (err) {
log.error('Failed refreshing connections for sendStream() ->', err);
if (typeof callback === 'function') {
@@ -836,6 +862,15 @@
File: source/stream-media.js
return;
}
+ if (window.webrtcDetectedBrowser === 'edge') {
+ var edgeNotSupportError = 'Edge browser currently does not support renegotiation.';
+ log.error(edgeNotSupportError, options);
+ if (typeof callback === 'function'){
+ callback(new Error(edgeNotSupportError),null);
+ }
+ return;
+ }
+
if (typeof options.getAudioTracks === 'function' || typeof options.getVideoTracks === 'function') {
var checkActiveTracksFn = function (tracks) {
for (var t = 0; t < tracks.length; t++) {
@@ -1178,27 +1213,50 @@
File: source/stream-media.js
* Function that retrieves screensharing Stream.
* @method shareScreen
* @param {JSON|Boolean} [enableAudio=false] The flag if audio tracks should be retrieved.
- * @param {Boolean} [enableAudio.stereo=false] The flag if stereo band should be configured
- * when encoding audio codec is <a href="#attr_AUDIO_CODEC"><code>OPUS</code></a> for sending audio data.
- * @param {Boolean} [enableAudio.usedtx] <blockquote class="info">
- * Note that this feature might not work depending on the browser support and implementation.</blockquote>
- * The flag if DTX (Discontinuous Transmission) should be configured when encoding audio codec
- * is <a href="#attr_AUDIO_CODEC"><code>OPUS</code></a> for sending audio data.
- * <small>This might help to reduce bandwidth it reduces the bitrate during silence or background noise.</small>
+ * @param {Boolean} [enableAudio.stereo=false] <blockquote class="info"><b>Deprecation Warning!</b>
+ * This property has been deprecated. Configure this with the <code>options.codecParams.audio.opus.stereo</code>
+ * parameter in the <a href="#method_init"><code>init()</code> method</a> instead. If the
+ * <code>options.codecParams.audio.opus.stereo</code> is configured, this overrides the
+ * <code>options.audio.stereo</code> setting.</blockquote>
+ * The flag if OPUS audio codec stereo band should be configured for sending encoded audio data.
* <small>When not provided, the default browser configuration is used.</small>
- * @param {Boolean} [enableAudio.useinbandfec] <blockquote class="info">
- * Note that this feature might not work depending on the browser support and implementation.</blockquote>
- * The flag if capability to take advantage of in-band FEC (Forward Error Correction) should be
- * configured when encoding audio codec is <a href="#attr_AUDIO_CODEC"><code>OPUS</code></a> for sending audio data.
- * <small>This might help to reduce the harm of packet loss by encoding information about the previous packet.</small>
+ * @param {Boolean} [enableAudio.usedtx] <blockquote class="info"><b>Deprecation Warning!</b>
+ * This property has been deprecated. Configure this with the <code>options.codecParams.audio.opus.stereo</code>
+ * parameter in the <a href="#method_init"><code>init()</code> method</a> instead. If the
+ * <code>options.codecParams.audio.opus.stereo</code> is configured, this overrides the
+ * <code>options.audio.stereo</code> setting. Note that this feature might
+ * not work depending on the browser support and implementation.</blockquote>
+ * The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.
+ * <small>This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and
+ * goes hand-in-hand with the <code>options.voiceActivityDetection</code> flag in <a href="#method_joinRoom">
+ * <code>joinRoom()</code> method</a>.</small>
* <small>When not provided, the default browser configuration is used.</small>
- * @param {Number} [enableAudio.maxplaybackrate] <blockquote class="info">
- * Note that this feature might not work depending on the browser support and implementation.</blockquote>
- * The maximum output sampling rate rendered in Hertz (Hz) when encoding audio codec is
- * <a href="#attr_AUDIO_CODEC"><code>OPUS</code></a> for sending audio data.
+ * @param {Boolean} [enableAudio.useinbandfec] <blockquote class="info"><b>Deprecation Warning!</b>
+ * This property has been deprecated. Configure this with the <code>options.codecParams.audio.opus.useinbandfec</code>
+ * parameter in the <a href="#method_init"><code>init()</code> method</a> instead. If the
+ * <code>options.codecParams.audio.opus.useinbandfec</code> is configured, this overrides the
+ * <code>options.audio.useinbandfec</code> setting. Note that this parameter should only be used
+ * for debugging purposes only.</blockquote>
+ * The flag if OPUS audio codec has the capability to take advantage of the in-band FEC
+ * (Forward Error Correction) when sending encoded audio data.
+ * <small>This helps to reduce the harm of packet loss by encoding information about the previous packet loss.</small>
+ * <small>When not provided, the default browser configuration is used.</small>
+ * @param {Number} [enableAudio.maxplaybackrate] <blockquote class="info"><b>Deprecation Warning!</b>
+ * This property has been deprecated. Configure this with the <code>options.codecParams.audio.opus.maxplaybackrate</code>
+ * parameter in the <a href="#method_init"><code>init()</code> method</a> instead. If the
+ * <code>options.codecParams.audio.opus.maxplaybackrate</code> is configured, this overrides the
+ * <code>options.audio.maxplaybackrate</code> setting. Note that this feature might
+ * not work depending on the browser support and implementation.
+ * Note that this parameter should only be used for debugging purposes only.</blockquote>
+ * The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving
+ * decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data
+ * would not encode at a higher sampling rate specified by this.
* <small>This value must be between <code>8000</code> to <code>48000</code>.</small>
* <small>When not provided, the default browser configuration is used.</small>
- * @param {Boolean} [enableAudio.echoCancellation=false] The flag to enable audio tracks echo cancellation.
+ * @param {Boolean} [enableAudio.echoCancellation=true] <blockquote class="info">
+ * For Chrome/Opera/IE/Safari/Bowser, the echo cancellation functionality may not work and may produce a terrible
+ * feedback. It is recommended to use headphones or other microphone devices rather than the device
+ * in-built microphones.</blockquote> The flag to enable echo cancellation for audio track.
* @param {Function} [callback] The callback function fired when request has completed.
* <small>Function parameters signature is <code>function (error, success)</code></small>
* <small>Function request completion is determined by the <a href="#event_mediaAccessSuccess">
@@ -1280,18 +1338,19 @@
SkylinkJS API Documentation
- Version: 0.6.17
+ Version: 0.6.18
diff --git a/index.html b/index.html
new file mode 100644
index 000000000..101815634
--- /dev/null
+++ b/index.html
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index 1829beae6..045162ac4 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,8 @@
{
"name": "skylinkjs",
- "description": "Temasys SkylinkJS 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.",
- "version": "0.6.17",
- "homepage": "https://temasys.github.io/",
+ "description": "Temasys 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.",
+ "version": "0.6.18",
+ "homepage": "https://temasys.io/",
"author": {
"name": "Temasys Communications Pte. Ltd.",
"email": "info@temasys.com.sg"
@@ -20,7 +20,7 @@
},
"dependencies": {
"socket.io-client": "1.4.8",
- "adapterjs": "0.14.0"
+ "adapterjs": "0.14.1"
},
"devDependencies": {
"connect": "2.x.x",
diff --git a/publish/skylink.complete.js b/publish/skylink.complete.js
index d765f689b..ee9d1011f 100644
--- a/publish/skylink.complete.js
+++ b/publish/skylink.complete.js
@@ -1,4 +1,4 @@
-/*! skylinkjs - v0.6.17 - Tue Jan 10 2017 01:58:42 GMT+0800 (SGT) */
+/*! skylinkjs - v0.6.18 - Thu Mar 02 2017 16:39:03 GMT+0800 (SGT) */
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.io = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;op;p++)t.call(n,e[p])&&c.push(e[p]);return c}}())}();
+// Date.getISOString() polyfill - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
+!function(){function t(t){return 10>t?"0"+t:t}Date.prototype.toISOString=function(){return this.getUTCFullYear()+"-"+t(this.getUTCMonth()+1)+"-"+t(this.getUTCDate())+"T"+t(this.getUTCHours())+":"+t(this.getUTCMinutes())+":"+t(this.getUTCSeconds())+"."+(this.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z"}}();
+// Date.now() polyfill
+!function(){"function"!=typeof Date.now&&(Date.now=function(){return(new Date).getTime()})}();
+// addEventListener() polyfill - https://gist.github.com/eirikbacker/2864711
+!function(e,t){function n(e){var n=t[e];t[e]=function(e){return o(n(e))}}function a(t,n,a){return(a=this).attachEvent("on"+t,function(t){var t=t||e.event;t.preventDefault=t.preventDefault||function(){t.returnValue=!1},t.stopPropagation=t.stopPropagation||function(){t.cancelBubble=!0},n.call(a,t)})}function o(e,t){if(t=e.length)for(;t--;)e[t].addEventListener=a;else e.addEventListener=a;return e}e.addEventListener||(o([t,e]),"Element"in e?e.Element.prototype.addEventListener=a:(t.attachEvent("onreadystatechange",function(){o(t.all)}),n("getElementsByTagName"),n("getElementById"),n("createElement"),o(t.all)))}(window,document);
+// performance.now() polyfill - https://gist.github.com/paulirish/5438650
+!function(){if("performance"in window==0&&(window.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in window.performance==0){var a=Date.now();performance.timing&&performance.timing.navigationStart&&(a=performance.timing.navigationStart),window.performance.now=function(){return Date.now()-a}}}();
+// BlobBuilder polyfill
+window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
+/* jshint ignore:end */
/**
* Global function that clones an object.
@@ -11776,12 +11693,23 @@ function Skylink() {
*/
this._dataTransfers = {};
+ /**
+ * Stores the list of sending data streaming sessions to Peers.
+ * @attribute _dataStreams
+ * @param {JSON} #streamId The data stream session.
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._dataStreams = {};
+
/**
* Stores the list of buffered ICE candidates that is received before
* remote session description is received and set.
* @attribute _peerCandidatesQueue
* @param {Array} <#peerId> The list of the Peer connection buffered ICE candidates received.
- * @param {Object} <#peerId>.<#index> The Peer connection buffered ICE candidate received.
+ * @param {RTCIceCandidate} <#peerId>.<#index> The Peer connection buffered ICE candidate received.
* @type JSON
* @private
* @for Skylink
@@ -11884,7 +11812,7 @@ function Skylink() {
/**
* Stores the list of the Peer connections.
* @attribute _peerConnections
- * @param {Object} <#peerId> The Peer connection.
+ * @param {RTCPeerConnection} <#peerId> The Peer connection.
* @type JSON
* @private
* @for Skylink
@@ -11895,7 +11823,7 @@ function Skylink() {
/**
* Stores the list of the Peer connections stats.
* @attribute _peerStats
- * @param {Object} <#peerId> The Peer connection stats.
+ * @param {JSON} <#peerId> The Peer connection stats.
* @type JSON
* @private
* @for Skylink
@@ -11903,6 +11831,27 @@ function Skylink() {
*/
this._peerStats = {};
+ /**
+ * Stores the list of the Peer connections stats.
+ * @attribute _peerBandwidth
+ * @param {JSON} <#peerId> The Peer connection stats.
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.16
+ */
+ this._peerBandwidth = {};
+
+ /**
+ * Stores the list of the Peer custom configs.
+ * @attribute _peerCustomConfigs
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._peerCustomConfigs = {};
+
/**
* The flag if User is using plugin.
* @attribute _isUsingPlugin
@@ -12589,13 +12538,23 @@ function Skylink() {
/**
* Stores the publish only settings.
* @attribute _publishOnly
- * @type JSON|Boolean
+ * @type Boolean
* @private
* @for Skylink
* @since 0.6.16
*/
this._publishOnly = false;
+ /**
+ * Stores the parent ID.
+ * @attribute _parentId
+ * @type String
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._parentId = null;
+
/**
* Stores the list of recordings.
* @attribute _recordings
@@ -12639,6 +12598,108 @@ function Skylink() {
* @since 0.6.16
*/
this._mcuUseRenegoRestart = false;
+
+ /**
+ * Stores the debugging TURN/STUN ICE server.
+ * @attribute _iceServer
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._iceServer = null;
+
+ /**
+ * Stores the debugging Signaling server.
+ * @attribute _socketServer
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._socketServer = null;
+
+ /**
+ * Stores the currently supported codecs.
+ * @attribute _currentCodecSupport
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._currentCodecSupport = null;
+
+ /**
+ * Stores the session description orders and info.
+ * @attribute _sdpSessions
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._sdpSessions = {};
+
+ /**
+ * Stores the flag if voice activity detection should be enabled.
+ * @attribute _voiceActivityDetection
+ * @type Boolean
+ * @default true
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._voiceActivityDetection = true;
+
+ /**
+ * Stores the datachannel binary data chunk type.
+ * @attribute _binaryChunkType
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._binaryChunkType = window.webrtcDetectedBrowser === 'firefox' ?
+ this.DATA_TRANSFER_DATA_TYPE.BLOB : this.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER;
+
+ /**
+ * Stores the RTCPeerConnection configuration.
+ * @attribute _peerConnectionConfig
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._peerConnectionConfig = {};
+
+ /**
+ * Stores the RTCPeerConnection configuration.
+ * @attribute _peerConnectionConfig
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._codecParams = {};
+
+ /**
+ * Stores the User's priority weight scheme to determine if User is offerer or answerer.
+ * @attribute _priorityWeightScheme
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._priorityWeightScheme = this.PRIORITY_WEIGHT_SCHEME.AUTO;
+
+ /**
+ * Stores the auto bandwidth settings.
+ * @attribute _bandwidthAdjuster
+ * @type JSON
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+ this._bandwidthAdjuster = null;
}
Skylink.prototype.DATA_CHANNEL_STATE = {
CONNECTING: 'connecting',
@@ -12684,7 +12745,7 @@ Skylink.prototype.DATA_CHANNEL_TYPE = {
/**
* The list of Datachannel sending message error types.
* @attribute DATA_CHANNEL_MESSAGE_ERROR
- * @param {String} MESSAGE Value "message"
+ * @param {String} MESSAGE Value "message"
* The value of the Datachannel sending message error type when encountered during
* sending P2P message from sendP2PMessage() method.
* @param {String} TRANSFER Value "transfer"
@@ -12708,24 +12769,25 @@ Skylink.prototype.DATA_CHANNEL_MESSAGE_ERROR = {
* @for Skylink
* @since 0.5.5
*/
-Skylink.prototype._createDataChannel = function(peerId, dataChannel, createAsMessagingChannel) {
+Skylink.prototype._createDataChannel = function(peerId, dataChannel, bufferThreshold, createAsMessagingChannel) {
var self = this;
+ var channelName = (self._user && self._user.sid ? self._user.sid : '-') + '_' + peerId;
+ var channelType = createAsMessagingChannel ? self.DATA_CHANNEL_TYPE.MESSAGING : self.DATA_CHANNEL_TYPE.DATA;
+ var channelProp = channelType === self.DATA_CHANNEL_TYPE.MESSAGING ? 'main' : channelName;
if (!self._user) {
- log.error([peerId, 'RTCDataChannel', null,
+ log.error([peerId, 'RTCDataChannel', channelProp,
'Aborting of creating or initializing Datachannel as User does not have Room session']);
return;
}
if (!(self._peerConnections[peerId] &&
self._peerConnections[peerId].signalingState !== self.PEER_CONNECTION_STATE.CLOSED)) {
- log.error([peerId, 'RTCDataChannel', null,
+ log.error([peerId, 'RTCDataChannel', channelProp,
'Aborting of creating or initializing Datachannel as Peer connection does not exists']);
return;
}
- var channelName = self._user.sid + '_' + peerId;
- var channelType = createAsMessagingChannel ? self.DATA_CHANNEL_TYPE.MESSAGING : self.DATA_CHANNEL_TYPE.DATA;
if (dataChannel && typeof dataChannel === 'object') {
channelName = dataChannel.label;
@@ -12737,23 +12799,26 @@ Skylink.prototype._createDataChannel = function(peerId, dataChannel, createAsMes
if (!dataChannel) {
try {
- dataChannel = self._peerConnections[peerId].createDataChannel(channelName);
+ dataChannel = self._peerConnections[peerId].createDataChannel(channelName, {
+ reliable: true,
+ ordered: true
+ });
} catch (error) {
- log.error([peerId, 'RTCDataChannel', channelName, 'Failed creating Datachannel ->'], error);
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.CREATE_ERROR, peerId, error, channelName, channelType, null);
+ log.error([peerId, 'RTCDataChannel', channelProp, 'Failed creating Datachannel ->'], error);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.CREATE_ERROR, peerId, error, channelName,
+ channelType, null, self._getDataChannelBuffer(dataChannel));
return;
}
}
if (!self._dataChannels[peerId]) {
- log.debug([peerId, 'RTCDataChannel', channelName, 'initializing main DataChannel']);
-
+ channelProp = 'main';
channelType = self.DATA_CHANNEL_TYPE.MESSAGING;
-
self._dataChannels[peerId] = {};
-
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'initializing main DataChannel']);
} else if (self._dataChannels[peerId].main && self._dataChannels[peerId].main.channel.label === channelName) {
+ channelProp = 'main';
channelType = self.DATA_CHANNEL_TYPE.MESSAGING;
}
@@ -12763,16 +12828,20 @@ Skylink.prototype._createDataChannel = function(peerId, dataChannel, createAsMes
dataChannel.onerror = function (evt) {
var channelError = evt.error || evt;
- log.error([peerId, 'RTCDataChannel', channelName, 'Datachannel has an exception ->'], channelError);
+ log.error([peerId, 'RTCDataChannel', channelProp, 'Datachannel has an exception ->'], channelError);
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.ERROR, peerId, channelError, channelName, channelType, null);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.ERROR, peerId, channelError, channelName,
+ channelType, null, self._getDataChannelBuffer(dataChannel));
};
+ // State where we can start calling .send() to queue more buffered data to be sent
+ // RTCDataChannel has an internal mechanism to queue data to be sent over
+ // This event might not be even triggered at all
dataChannel.onbufferedamountlow = function () {
- log.debug([peerId, 'RTCDataChannel', channelName, 'Datachannel buffering data transfer low']);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Datachannel buffering data transfer low']);
- // TODO: Should we add an event here
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.BUFFERED_AMOUNT_LOW, peerId, null, channelName, channelType, null);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.BUFFERED_AMOUNT_LOW, peerId, null, channelName,
+ channelType, null, self._getDataChannelBuffer(dataChannel));
};
dataChannel.onmessage = function(event) {
@@ -12780,33 +12849,44 @@ Skylink.prototype._createDataChannel = function(peerId, dataChannel, createAsMes
};
var onOpenHandlerFn = function () {
- log.debug([peerId, 'RTCDataChannel', channelName, 'Datachannel has opened']);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Datachannel has opened']);
+
+ dataChannel.bufferedAmountLowThreshold = bufferThreshold || 0;
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.OPEN, peerId, null, channelName, channelType, null);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.OPEN, peerId, null, channelName,
+ channelType, null, self._getDataChannelBuffer(dataChannel));
};
if (dataChannel.readyState === self.DATA_CHANNEL_STATE.OPEN) {
- setTimeout(onOpenHandlerFn, 500);
+ setTimeout(onOpenHandlerFn, 1); // 500);
} else {
- self._trigger('dataChannelState', dataChannel.readyState, peerId, null, channelName, channelType, null);
+ self._trigger('dataChannelState', dataChannel.readyState, peerId, null, channelName,
+ channelType, null, self._getDataChannelBuffer(dataChannel));
dataChannel.onopen = onOpenHandlerFn;
}
var onCloseHandlerFn = function () {
- log.debug([peerId, 'RTCDataChannel', channelName, 'Datachannel has closed']);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Datachannel has closed']);
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.CLOSED, peerId, null, channelName, channelType, null);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.CLOSED, peerId, null, channelName,
+ channelType, null, self._getDataChannelBuffer(dataChannel));
+
+ if (self._peerConnections[peerId] && self._peerConnections[peerId].remoteDescription &&
+ self._peerConnections[peerId].remoteDescription.sdp && (self._peerConnections[peerId].remoteDescription.sdp.indexOf(
+ 'm=application') === -1 || self._peerConnections[peerId].remoteDescription.sdp.indexOf('m=application 0') > 0)) {
+ return;
+ }
if (channelType === self.DATA_CHANNEL_TYPE.MESSAGING) {
setTimeout(function () {
if (self._peerConnections[peerId] &&
self._peerConnections[peerId].signalingState !== self.PEER_CONNECTION_STATE.CLOSED &&
(self._peerConnections[peerId].localDescription &&
- self._peerConnections[peerId].localDescription.type === self.HANDSHAKE_PROGRESS.OFFER)) {
- log.debug([peerId, 'RTCDataChannel', channelName, 'Reviving Datachannel connection']);
- self._createDataChannel(peerId, channelName, true);
+ self._peerConnections[peerId].localDescription.type === self.HANDSHAKE_PROGRESS.OFFER)) {
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Reviving Datachannel connection']);
+ self._createDataChannel(peerId, channelName, bufferThreshold, true);
}
}, 100);
}
@@ -12850,18 +12930,54 @@ Skylink.prototype._createDataChannel = function(peerId, dataChannel, createAsMes
channelName: channelName,
channelType: channelType,
transferId: null,
+ streamId: null,
channel: dataChannel
};
} else {
self._dataChannels[peerId][channelName] = {
channelName: channelName,
channelType: channelType,
- transferId: channelName,
+ transferId: null,
+ streamId: null,
channel: dataChannel
};
}
};
+/**
+ * Function that returns the Datachannel buffer threshold and amount.
+ * @method _getDataChannelBuffer
+ * @return {JSON} The buffered amount information.
+ * @private
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype._getDataChannelBuffer = function (peerId, channelProp) {
+ if (typeof peerId === 'object') {
+ return {
+ bufferedAmountLow: typeof peerId.bufferedAmountLow === 'number' ?
+ peerId.bufferedAmountLow : parseInt(peerId.bufferedAmountLow, 10) || 0,
+ bufferedAmountLowThreshold: typeof peerId.bufferedAmountLowThreshold === 'number' ?
+ peerId.bufferedAmountLowThreshold : parseInt(peerId.bufferedAmountLowThreshold, 10) || 0
+ };
+ } else if (!(this._dataChannels[peerId] && this._dataChannels[peerId][channelProp] &&
+ this._dataChannels[peerId][channelProp].channel)) {
+ return {
+ bufferedAmountLow: 0,
+ bufferedAmountLowThreshold: 0
+ };
+ }
+
+ var channel = this._dataChannels[peerId][channelProp].channel;
+
+ return {
+ bufferedAmountLow: typeof channel.bufferedAmountLow === 'number' ?
+ channel.bufferedAmountLow : parseInt(channel.bufferedAmountLow, 10) || 0,
+ bufferedAmountLowThreshold: typeof channel.bufferedAmountLowThreshold === 'number' ?
+ channel.bufferedAmountLowThreshold : parseInt(channel.bufferedAmountLowThreshold, 10) || 0
+ };
+};
+
/**
* Function that sends data over the Datachannel connection.
* @method _sendMessageToDataChannel
@@ -12879,19 +12995,19 @@ Skylink.prototype._sendMessageToDataChannel = function(peerId, data, channelProp
// TODO: What happens when we want to send binary data over or ArrayBuffers?
if (!(typeof data === 'object' && data) && !(data && typeof data === 'string')) {
- log.warn([peerId, 'RTCDataChannel', 'prop:' + channelProp, 'Dropping invalid data ->'], data);
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Dropping invalid data ->'], data);
return;
}
if (!(self._peerConnections[peerId] &&
self._peerConnections[peerId].signalingState !== self.PEER_CONNECTION_STATE.CLOSED)) {
- log.warn([peerId, 'RTCDataChannel', 'prop:' + channelProp,
+ log.warn([peerId, 'RTCDataChannel', channelProp,
'Dropping for sending message as Peer connection does not exists or is closed ->'], data);
return;
}
if (!(self._dataChannels[peerId] && self._dataChannels[peerId][channelProp])) {
- log.warn([peerId, 'RTCDataChannel', 'prop:' + channelProp,
+ log.warn([peerId, 'RTCDataChannel', channelProp,
'Dropping for sending message as Datachannel connection does not exists ->'], data);
return;
}
@@ -12906,30 +13022,32 @@ Skylink.prototype._sendMessageToDataChannel = function(peerId, data, channelProp
var notOpenError = 'Failed sending message as Datachannel connection state is not opened. Current ' +
'readyState is "' + readyState + '"';
- log.error([peerId, 'RTCDataChannel', 'prop:' + channelProp, notOpenError + ' ->'], data);
+ log.error([peerId, 'RTCDataChannel', channelProp, notOpenError + ' ->'], data);
+
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.SEND_MESSAGE_ERROR, peerId, new Error(notOpenError),
+ channelName, channelType, messageType, self._getDataChannelBuffer(peerId, channelProp));
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.SEND_MESSAGE_ERROR, peerId,
- new Error(notOpenError), channelName, channelType, messageType);
-
throw new Error(notOpenError);
}
try {
if (!doNotConvert && typeof data === 'object') {
- log.debug([peerId, 'RTCDataChannel', 'prop:' + channelProp, 'Sending message ->'], data);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Sending "' + data.type + '" protocol message ->'], data);
self._dataChannels[peerId][channelProp].channel.send(JSON.stringify(data));
} else {
- log.debug([peerId, 'RTCDataChannel', 'prop:' + channelProp, 'Sending data with size ->'], data.size || data.length);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Sending data with size ->'],
+ data.size || data.length || data.byteLength);
self._dataChannels[peerId][channelProp].channel.send(data);
}
} catch (error) {
- log.error([peerId, 'RTCDataChannel', 'prop:' + channelProp, 'Failed sending message ->'], error);
+ log.error([peerId, 'RTCDataChannel', channelProp, 'Failed sending ' + (!doNotConvert && typeof data === 'object' ?
+ '"' + data.type + '" protocol message' : 'data') + ' ->'], error);
self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.SEND_MESSAGE_ERROR, peerId,
- error, channelName, channelType, messageType);
+ error, channelName, channelType, messageType, self._getDataChannelBuffer(peerId, channelProp));
throw error;
}
@@ -12956,9 +13074,10 @@ Skylink.prototype._closeDataChannel = function(peerId, channelProp) {
var channelType = self._dataChannels[peerId][rChannelProp].channelType;
if (self._dataChannels[peerId][rChannelProp].readyState !== self.DATA_CHANNEL_STATE.CLOSED) {
- log.debug([peerId, 'RTCDataChannel', channelName, 'Closing Datachannel']);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Closing Datachannel']);
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.CLOSING, peerId, null, channelName, channelType, null);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.CLOSING, peerId, null, channelName, channelType,
+ null, self._getDataChannelBuffer(peerId, rChannelProp));
self._dataChannels[peerId][rChannelProp].channel.close();
@@ -13169,7 +13288,7 @@ Skylink.prototype._chunkDataURL = function(dataURL, chunkSize) {
return dataURLArray;
};
-Skylink.prototype.DT_PROTOCOL_VERSION = '0.1.0';
+Skylink.prototype.DT_PROTOCOL_VERSION = '0.1.3';
/**
* The list of data transfers directions.
@@ -13261,7 +13380,45 @@ Skylink.prototype.DATA_TRANSFER_STATE = {
UPLOAD_COMPLETED: 'uploadCompleted',
DOWNLOAD_COMPLETED: 'downloadCompleted',
USER_REJECTED: 'userRejected',
- USER_UPLOAD_REQUEST: 'userRequest'
+ USER_UPLOAD_REQUEST: 'userRequest',
+ START_ERROR: 'startError'
+};
+
+/**
+ * The list of data streaming states.
+ * @attribute DATA_STREAM_STATE
+ * @param {String} SENDING_STARTED Value "sendStart"
+ * The value of the state when data streaming session has started from User to Peer.
+ * @param {String} RECEIVING_STARTED Value "receiveStart"
+ * The value of the state when data streaming session has started from Peer to Peer.
+ * @param {String} RECEIVED Value "received"
+ * The value of the state when data streaming session data chunk has been received from Peer to User.
+ * @param {String} SENT Value "sent"
+ * The value of the state when data streaming session data chunk has been sent from User to Peer.
+ * @param {String} SENDING_STOPPED Value "sendStop"
+ * The value of the state when data streaming session has stopped from User to Peer.
+ * @param {String} RECEIVING_STOPPED Value "receivingStop"
+ * The value of the state when data streaming session has stopped from Peer to User.
+ * @param {String} ERROR Value "error"
+ * The value of the state when data streaming session has errors.
+ * At this stage, the data streaming state is considered SENDING_STOPPED or
+ * RECEIVING_STOPPED.
+ * @param {String} START_ERROR Value "startError"
+ * The value of the state when data streaming session failed to start from User to Peer.
+ * @type JSON
+ * @readOnly
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.DATA_STREAM_STATE = {
+ SENDING_STARTED: 'sendStart',
+ SENDING_STOPPED: 'sendStop',
+ RECEIVING_STARTED: 'receiveStart',
+ RECEIVING_STOPPED: 'receiveStop',
+ RECEIVED: 'received',
+ SENT: 'sent',
+ ERROR: 'error',
+ START_ERROR: 'startError'
};
/**
@@ -13289,20 +13446,6 @@ Skylink.prototype._DC_PROTOCOL_TYPE = {
};
/**
- * Stores the list of agent names supported by the Web for Web only functionalities.
- * @attribute _SUPPORTED_WEB_AGENTS
- * @type Array
- * @readOnly
- * @private
- * @for Skylink
- * @since 0.6.16
- */
-Skylink.prototype._SUPPORTED_WEB_AGENTS = ['chrome', 'firefox', 'safari', 'IE', 'edge' ,'opera', 'bowser', 'blink'];
-
-/**
- *
- * Note that Android, iOS and C++ SDKs do not support simultaneous data transfers.
- *
* Function that starts an uploading data transfer from User to Peers.
* @method sendBlobData
* @param {Blob} data The Blob object.
@@ -13344,6 +13487,18 @@ Skylink.prototype._SUPPORTED_WEB_AGENTS = ['chrome', 'firefox', 'safari', 'IE',
* dataTransferState event except without the
* percentage property and data.
* @trigger
+ *
Checks if Peer connection and Datachannel connection are in correct states.
*
If Peer connection or session does not exists:
* dataTransferState event triggers parameter payload state
@@ -13393,6 +13548,14 @@ Skylink.prototype._SUPPORTED_WEB_AGENTS = ['chrome', 'firefox', 'safari', 'IE',
* with all Peers targeted for the data transfer session.
If messaging Datachannel connection has a
* data transfer in-progress:
If there is any conflicting streamData()
+ * method data streaming session: If sendChunksAsBinary is provided as true,
+ * it cannot start if existing data streaming session is expected binary data chunks, and if provided as
+ * false, or method invoked is sendURLData() method,
+ * or Peer is using string data chunks fallback due to its support despite provided as true,
+ * it cannot start if existing data streaming session is expected string data chunks.
+ *
+ * Function that starts a data chunks streaming session from User to Peers.
+ * @method startStreamingData
+ * @param {Boolean} [isStringStream=false] The flag if data streaming session sending data chunks
+ * should be expected as string data chunks sent.
+ * By default, data chunks are expected to be sent in Blob or ArrayBuffer, and ArrayBuffer
+ * data chunks will be converted to Blob.
+ * @param {String|Array} [targetPeerId] The target Peer ID to send message to.
+ * - When provided as an Array, it will start streaming session to only Peers which IDs are in the list.
+ * - When not provided, it will start the streaming session to all connected Peers with Datachannel connection in the Room.
+ * @trigger
+ * @trigger
+ *
If Peer connection messaging Datachannel has not been opened: This can be checked with
+ * dataChannelState event triggering parameter
+ * payload state as OPEN and channelType as
+ * MESSAGING for Peer.
If MCU is enabled for the App Key provided in init()method and connected:
+ *
If MCU Peer connection messaging Datachannel has not been opened: This can be checked with
+ * dataChannelState event triggering parameter
+ * payload state as OPEN, peerId value as "MCU"
+ * and channelType as MESSAGING for MCU Peer.
+ *
If Peer supports simultaneous data streaming, open new data Datachannel: If MCU is connected,
+ * this opens a new data Datachannel with MCU Peer with all the Peers IDs information that supports
+ * simultaneous data transfers targeted for the data streaming session instead of opening new data Datachannel
+ * with all Peers targeted for the data streaming session.
+ *
dataChannelState event triggers parameter
+ * payload state as CONNECTING and channelType as DATA.
+ * Note that there is no timeout to wait for parameter payload state to be
+ * OPEN.
+ *
If Datachannel has been created and opened successfully:
+ *
dataChannelState event triggers parameter payload
+ * state as OPEN and channelType as DATA.
+ *
Else:
dataChannelState event
+ * triggers parameter payload state as CREATE_ERROR and channelType as
+ * DATA.
Else: If MCU is connected,
+ * this uses the messaging Datachannel with MCU Peer with all the Peers IDs information that supports
+ * simultaneous data transfers targeted for the data streaming session instead of using the messaging Datachannels
+ * with all Peers targeted for the data streaming session.
If messaging Datachannel connection has a
+ * data streaming in-progress:
If there is any conflicting streamData()
+ * method data streaming session: If isStringStream is provided as true and
+ * sendBlobData() method or
+ * sendURLData() method has an existing binary string transfer, it cannot start string data
+ * streaming session. Else if sendBlobData() method
+ * has an existing binary data transfer, it cannot start binary data streaming session.
+ *
+ * Function that sends a data chunk from User to Peers for an existing active data streaming session.
+ * @method streamData
+ * @param {String} streamId The data streaming session ID.
+ * @param {String|Blob|ArrayBuffer} chunk The data chunk.
+ * By default when it is not string data streaming, data chunks when is are expected to be
+ * sent in Blob or ArrayBuffer, and ArrayBuffer data chunks will be converted to Blob.
+ * For binary data chunks, the limit is 65456.
+ * For string data chunks, the limit is 1212.
+ * @trigger
+ *
Checks if Peer connection and Datachannel connection are in correct states.
+ *
If Peer connection (or MCU Peer connection if enabled)
+ * data streaming Datachannel has not been opened: This can be checked with
+ * dataChannelState event triggering parameter
+ * payload state as OPEN and channelType as
+ * MESSAGING for Peer.
+ * Function that stops a data chunks streaming session from User to Peers.
+ * @method stopStreamingData
+ * @param {String} streamId The data streaming session ID.
+ * @trigger
+ *
Checks if Peer connection and Datachannel connection are in correct states.
+ *
If Peer connection (or MCU Peer connection if enabled)
+ * data streaming Datachannel has not been opened: This can be checked with
+ * dataChannelState event triggering parameter
+ * payload state as OPEN and channelType as
+ * MESSAGING for Peer.
For User onlydataStreamState event
+ * triggers parameter payload state as SENDING_STOPPED.
+ *
For Peer onlydataStreamState event
+ * triggers parameter payload state as RECEIVING_STOPPED.
+ * @example
+ * skylinkDemo.stopStreamData(streamId);
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.stopStreamingData = function(transferId) {
+ var self = this;
+
+ if (!(transferId && typeof transferId === 'string')) {
+ log.error('Failed streaming data chunk as stream session ID is not provided.');
+ return;
+ }
+
+ if (!(self._inRoom && self._user && self._user.sid)) {
+ log.error('Failed streaming data chunk as User is not in the Room.');
+ return;
+ }
+
+ if (!self._dataStreams[transferId]) {
+ log.error('Failed stopping data streaming session as it does not exists.');
+ return;
+ }
+
+ if (!self._dataStreams[transferId].isUpload) {
+ log.error('Failed stopping data streaming session as it is not sending.');
+ return;
+ }
+
+ var sessionInfo = {
+ chunk: null,
+ chunkSize: 0,
+ chunkType: self._dataStreams[transferId].sessionChunkType === 'string' ?
+ self.DATA_TRANSFER_DATA_TYPE.STRING : self._binaryChunkType,
+ isPrivate: self._dataStreams[transferId].sessionChunkType.isPrivate,
+ isStringStream: self._dataStreams[transferId].sessionChunkType === 'string',
+ senderPeerId: self._user && self._user.sid ? self._user.sid : null
+ };
+
+ var peersInterop = [];
+ var peersNonInterop = [];
+ var sendDataFn = function (peerId, channelProp, targetPeers) {
+ self._sendMessageToDataChannel(peerId, {
+ type: self._DC_PROTOCOL_TYPE.WRQ,
+ transferId: transferId,
+ name: transferId,
+ size: 0,
+ originalSize: 0,
+ dataType: 'fastBinaryStop',
+ mimeType: null,
+ chunkType: self._dataStreams[transferId].sessionChunkType,
+ chunkSize: 0,
+ timeout: 0,
+ isPrivate: self._dataStreams[transferId].isPrivate,
+ sender: self._user.sid,
+ agent: window.webrtcDetectedBrowser,
+ version: window.webrtcDetectedVersion,
+ target: targetPeers ? targetPeers : peerId
+ }, channelProp);
+
+ var updatedSessionInfo = clone(sessionInfo);
+ delete updatedSessionInfo.chunk;
+
+ if (targetPeers) {
+ for (var i = 0; i < targetPeers.length; i++) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.SENDING_STOPPED, transferId, targetPeers[i], sessionInfo, null);
+ self._trigger('incomingDataStreamStopped', transferId, targetPeers[i], updatedSessionInfo, true);
+ }
+ } else {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.SENDING_STOPPED, transferId, peerId, sessionInfo, null);
+ self._trigger('incomingDataStreamStopped', transferId, peerId, updatedSessionInfo, true);
+ }
+ };
+
+ for (var peerId in self._dataStreams[transferId].sessions) {
+ if (self._dataStreams[transferId].sessions.hasOwnProperty(peerId) && self._dataStreams[transferId].sessions[peerId]) {
+ var channelProp = self._dataStreams[transferId].sessions[peerId];
+
+ if (!(self._dataChannels[self._hasMCU ? 'MCU' : peerId] && self._dataChannels[self._hasMCU ? 'MCU' : peerId][channelProp] &&
+ self._dataChannels[self._hasMCU ? 'MCU' : peerId][channelProp].channel.readyState === self.DATA_CHANNEL_STATE.OPEN &&
+ self._dataChannels[self._hasMCU ? 'MCU' : peerId][channelProp].streamId === transferId)) {
+ log.error([peerId, 'RTCDataChannel', transferId, 'Failed stopping data streaming session as channel is closed.']);
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.ERROR, transferId, peerId, sessionInfo,
+ new Error('Failed stopping data streaming session as Datachannel connection is not open or is active.'));
+ return;
+ }
+
+ if (self._hasMCU) {
+ if (self._dataStreams[transferId].sessions[peerId] === 'main') {
+ peersInterop.push(peerId);
+ } else {
+ peersNonInterop.push(peerId);
+ }
+ } else {
+ sendDataFn(peerId, channelProp);
+ }
+ }
+ }
+
+ if (self._hasMCU) {
+ if (peersInterop.length > 0) {
+ sendDataFn(peerId, 'main', peersInterop);
+ }
+ if (peersNonInterop.length > 0) {
+ sendDataFn(peerId, transferId, peersNonInterop);
+ }
+ }
+};
+
+
+/**
+ * Function that starts the data transfer to Peers.
+ * @method _startDataTransfer
+ * @private
+ * @for Skylink
+ * @since 0.6.1
+ */
+Skylink.prototype._startDataTransfer = function(data, timeout, targetPeerId, sendChunksAsBinary, callback, sessionType) {
+ var self = this;
+ var transferId = (self._user ? self._user.sid : '') + '_' + (new Date()).getTime();
+ var transferErrors = {};
+ var transferCompleted = [];
+ var chunks = [];
+ var listOfPeers = Object.keys(self._peerConnections);
+ var sessionChunkType = 'string';
+ var transferInfo = {
+ name: null,
+ size: null,
+ chunkSize: null,
+ chunkType: null,
+ dataType: null,
+ mimeType: null,
+ direction: self.DATA_TRANSFER_TYPE.UPLOAD,
+ timeout: 60,
+ isPrivate: false,
+ percentage: 0
+ };
+
+ // sendBlobData(.., timeout)
+ if (typeof timeout === 'number') {
+ transferInfo.timeout = timeout;
+ } else if (Array.isArray(timeout)) {
+ listOfPeers = timeout;
+ } else if (timeout && typeof timeout === 'string') {
+ listOfPeers = [timeout];
+ } else if (timeout && typeof timeout === 'boolean') {
+ sessionChunkType = 'binary';
+ } else if (typeof timeout === 'function') {
+ callback = timeout;
+ }
+
+ // sendBlobData(.., .., targetPeerId)
+ if (Array.isArray(targetPeerId)) {
+ listOfPeers = targetPeerId;
+ } else if (targetPeerId && typeof targetPeerId === 'string') {
+ listOfPeers = [targetPeerId];
+ } else if (targetPeerId && typeof targetPeerId === 'boolean') {
+ sessionChunkType = 'binary';
+ } else if (typeof targetPeerId === 'function') {
+ callback = targetPeerId;
+ }
+
+ // sendBlobData(.., .., .., sendChunksAsBinary)
+ if (sendChunksAsBinary && typeof sendChunksAsBinary === 'boolean') {
+ sessionChunkType = 'binary';
+ } else if (typeof sendChunksAsBinary === 'function') {
+ callback = sendChunksAsBinary;
+ }
+
+ // Remove MCU Peer as list of Peers
+ if (listOfPeers.indexOf('MCU') > -1) {
+ listOfPeers.splice(listOfPeers.indexOf('MCU'), 1);
+ }
+
+ // Function that returns the error emitted before data transfer has started
+ var emitErrorBeforeDataTransferFn = function (error) {
+ log.error(error);
+
+ if (typeof callback === 'function') {
+ var transferErrors = {};
+
+ if (listOfPeers.length === 0) {
+ transferErrors.self = new Error(error);
+ /*self._trigger('dataTransferState', self.DATA_TRANSFER_STATE.START_ERROR, null, null, transferInfo, {
+ transferType: self.DATA_TRANSFER_TYPE.DOWNLOAD,
+ message: new Error(error)
+ });*/
+ } else {
+ for (var i = 0; i < listOfPeers.length; i++) {
+ transferErrors[listOfPeers[i]] = new Error(error);
+ /*self._trigger('dataTransferState', self.DATA_TRANSFER_STATE.START_ERROR, null, listOfPeers[i], transferInfo, {
+ transferType: self.DATA_TRANSFER_TYPE.DOWNLOAD,
+ message: new Error(error)
+ });*/
+ }
+ }
+
+ callback({
+ transferId: null,
+ transferInfo: transferInfo,
+ listOfPeers: listOfPeers,
+ transferErrors: transferErrors
+ }, null);
+ }
+ };
+
+ if (sessionType === 'blob') {
+ if (self._hasMCU && sessionChunkType === 'binary') {
+ log.warn('Binary data chunks transfer is not yet supported with MCU environment. ' +
+ 'Fallbacking to binary string data chunks transfer.');
+ sessionChunkType = 'string';
+ }
+
+ var chunkSize = sessionChunkType === 'string' ? (window.webrtcDetectedBrowser === 'firefox' ?
+ self._MOZ_CHUNK_FILE_SIZE : self._CHUNK_FILE_SIZE) : (window.webrtcDetectedBrowser === 'firefox' ?
+ self._MOZ_BINARY_FILE_SIZE : self._BINARY_FILE_SIZE);
+
+ transferInfo.dataType = self.DATA_TRANSFER_SESSION_TYPE.BLOB;
+ transferInfo.chunkSize = sessionChunkType === 'string' ? 4 * Math.ceil(chunkSize / 3) : chunkSize;
+ transferInfo.chunkType = sessionChunkType === 'binary' ? self._binaryChunkType : self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING;
+
+ // Start checking if data transfer can start
+ if (!(data && typeof data === 'object' && data instanceof Blob)) {
+ emitErrorBeforeDataTransferFn('Provided data is not a Blob data');
+ return;
+ }
+
+ transferInfo.name = data.name || transferId;
+ transferInfo.mimeType = data.type || null;
+
+ if (data.size < 1) {
+ emitErrorBeforeDataTransferFn('Provided data is not a valid Blob data.');
+ return;
+ }
+
+ transferInfo.originalSize = data.size;
+ transferInfo.size = sessionChunkType === 'string' ? 4 * Math.ceil(data.size / 3) : data.size;
+ chunks = self._chunkBlobData(data, chunkSize);
+ } else {
+ transferInfo.dataType = self.DATA_TRANSFER_SESSION_TYPE.DATA_URL;
+ transferInfo.chunkSize = self._CHUNK_DATAURL_SIZE;
+ transferInfo.chunkType = self.DATA_TRANSFER_DATA_TYPE.STRING;
+
+ // Start checking if data transfer can start
+ if (!(data && typeof data === 'string')) {
+ emitErrorBeforeDataTransferFn('Provided data is not a dataURL');
+ return;
+ }
+
+ transferInfo.originalSize = transferInfo.size = data.length || data.size;
+ chunks = self._chunkDataURL(data, transferInfo.chunkSize);
+ }
+
+ if (!(self._user && self._user.sid)) {
+ emitErrorBeforeDataTransferFn('Unable to send any ' +
+ sessionType.replace('data', 'dataURL') + ' data. User is not in Room.');
+ return;
+ }
+
+ if (!self._enableDataChannel) {
+ emitErrorBeforeDataTransferFn('Unable to send any ' +
+ sessionType.replace('data', 'dataURL') + ' data. Datachannel is disabled');
+ return;
+ }
+
+ if (listOfPeers.length === 0) {
+ emitErrorBeforeDataTransferFn('Unable to send any ' +
+ sessionType.replace('data', 'dataURL') + ' data. There are no Peers to start data transfer with');
+ return;
+ }
+
+ self._dataTransfers[transferId] = clone(transferInfo);
+ self._dataTransfers[transferId].peers = {};
+ self._dataTransfers[transferId].peers.main = {};
+ self._dataTransfers[transferId].peers[transferId] = {};
+ self._dataTransfers[transferId].sessions = {};
+ self._dataTransfers[transferId].chunks = chunks;
+ self._dataTransfers[transferId].enforceBSPeers = [];
+ self._dataTransfers[transferId].enforcedBSInfo = {};
+ self._dataTransfers[transferId].sessionType = sessionType;
+ self._dataTransfers[transferId].sessionChunkType = sessionChunkType;
+ self._dataTransfers[transferId].senderPeerId = self._user.sid;
+
+ // Check if fallback chunks is required
+ if (sessionType === 'blob' && sessionChunkType === 'binary') {
+ for (var p = 0; p < listOfPeers.length; p++) {
+ var protocolVer = (((self._peerInformations[listOfPeers[p]]) || {}).agent || {}).DTProtocolVersion || '0.1.0';
+
+ // C++ SDK does not support binary file transfer for now
+ if (self._isLowerThanVersion(protocolVer, '0.1.3')) {
+ self._dataTransfers[transferId].enforceBSPeers.push(listOfPeers[p]);
+ }
+ }
+
+ if (self._dataTransfers[transferId].enforceBSPeers.length > 0) {
+ var bsChunkSize = window.webrtcDetectedBrowser === 'firefox' ? self._MOZ_CHUNK_FILE_SIZE : self._CHUNK_FILE_SIZE;
+ var bsChunks = self._chunkBlobData(new Blob(chunks), bsChunkSize);
+
+ self._dataTransfers[transferId].enforceBSInfo = {
+ chunkSize: 4 * Math.ceil(bsChunkSize / 3),
+ chunkType: self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING,
+ size: 4 * Math.ceil(transferInfo.originalSize / 3),
+ chunks: bsChunks
+ };
+ }
+ }
+
+ /**
+ * Complete Peer function.
+ */
+ var completeFn = function (peerId, error) {
+ // Ignore if already added.
+ if (transferCompleted.indexOf(peerId) > -1) {
+ return;
+ }
+
+ log.debug([peerId, 'RTCDataChannel', transferId, 'Data transfer result. Is errors present? ->'], error);
+
+ transferCompleted.push(peerId);
+
+ if (error) {
+ transferErrors[peerId] = new Error(error);
+ }
+
+ if (listOfPeers.length === transferCompleted.length) {
+ log.log([null, 'RTCDataChannel', transferId, 'Data transfer request completed']);
+
+ if (typeof callback === 'function') {
+ if (Object.keys(transferErrors).length > 0) {
+ callback({
+ transferId: transferId,
+ transferInfo: self._getTransferInfo(transferId, peerId, false, true, false),
+ transferErrors: transferErrors,
+ listOfPeers: listOfPeers
+ }, null);
+ } else {
+ callback(null, {
+ transferId: transferId,
+ transferInfo: self._getTransferInfo(transferId, peerId, false, true, false),
+ listOfPeers: listOfPeers
+ });
+ }
+ }
+ }
+ };
+
+ for (var i = 0; i < listOfPeers.length; i++) {
+ var MCUInteropStatus = self._startDataTransferToPeer(transferId, listOfPeers[i], completeFn, null, null);
+
+ if (typeof MCUInteropStatus === 'boolean') {
if (MCUInteropStatus === true) {
self._dataTransfers[transferId].peers.main[listOfPeers[i]] = true;
} else {
@@ -14463,7 +15252,7 @@ Skylink.prototype._startDataTransferToPeer = function (transferId, peerId, callb
var sendWRQFn = function () {
var size = self._dataTransfers[transferId].size;
var chunkSize = self._dataTransfers[transferId].chunkSize;
- var chunkType = self._dataTransfers[transferId].chunkType;
+ var chunkType = self._dataTransfers[transferId].sessionChunkType;
if (self._dataTransfers[transferId].enforceBSPeers.indexOf(peerId) > -1) {
log.warn([peerId, 'RTCDataChannel', transferId,
@@ -14472,7 +15261,7 @@ Skylink.prototype._startDataTransferToPeer = function (transferId, peerId, callb
size = self._dataTransfers[transferId].enforceBSInfo.size;
chunkSize = self._dataTransfers[transferId].enforceBSInfo.chunkSize;
- chunkType = self._dataTransfers[transferId].enforceBSInfo.chunkType;
+ chunkType = 'string';
}
self._sendMessageToDataChannel(peerId, {
@@ -14481,7 +15270,7 @@ Skylink.prototype._startDataTransferToPeer = function (transferId, peerId, callb
name: self._dataTransfers[transferId].name,
size: size,
originalSize: self._dataTransfers[transferId].originalSize,
- dataType: self._dataTransfers[transferId].dataType,
+ dataType: self._dataTransfers[transferId].sessionType,
mimeType: self._dataTransfers[transferId].mimeType,
chunkType: chunkType,
chunkSize: chunkSize,
@@ -14594,11 +15383,28 @@ Skylink.prototype._startDataTransferToPeer = function (transferId, peerId, callb
return;
}
- var agentName = (self._peerInformations[peerId].agent || {}).name || '';
- var requireInterop = self._SUPPORTED_WEB_AGENTS.indexOf(agentName) === -1 && agentName !== 'cpp';
+ var streamId = self._dataChannels[peerId].main.streamId;
+
+ if (streamId && channelProp === 'main' && self._dataStreams[streamId] &&
+ // Check if session chunk streaming is string and sending is string for Peer
+ ((self._dataStreams[streamId].sessionChunkType === 'string' &&
+ (self._dataTransfers[transferId].sessionChunkType === 'string' ||
+ self._dataTransfers[transferId].enforceBSPeers.indexOf(peerId) > -1)) ||
+ // Check if session chunk streaming is binary and sending is binary for Peer
+ (self._dataStreams[streamId].sessionChunkType === 'binary' &&
+ self._dataStreams[streamId].sessionChunkType === 'binary' &&
+ self._dataTransfers[transferId].enforceBSPeers.indexOf(peerId) === -1))) {
+ returnErrorBeforeTransferFn('Unable to start data transfer as Peer Datachannel currently has an active ' +
+ self._dataStreams[streamId].sessionChunkType + ' data streaming session.');
+ return;
+ }
+
+ var protocolVer = (self._peerInformations[peerId].agent || {}).DTProtocolVersion || '0.1.0';
+ var requireInterop = self._isLowerThanVersion(protocolVer, '0.1.2');
// Prevent DATA_URL (or "string" dataType transfers) with Android / iOS / C++ SDKs
- if ((requireInterop || agentName === 'cpp') && self._dataTransfers[transferId].dataType === self.DATA_TRANSFER_SESSION_TYPE.DATA_URL) {
+ if (self._isLowerThanVersion(protocolVer, '0.1.2') && self._dataTransfers[transferId].sessionType === 'data' &&
+ self._dataTransfers[transferId].sessionChunkType === 'string') {
returnErrorBeforeTransferFn('Unable to start data transfer as Peer do not support DATA_URL type of data transfers');
return;
}
@@ -14656,6 +15462,7 @@ Skylink.prototype._startDataTransferToPeer = function (transferId, peerId, callb
if (evtPeerId === peerId && (channelType === self.DATA_CHANNEL_TYPE.DATA ? channelName === transferId : true)) {
if (state === self.DATA_CHANNEL_STATE.OPEN && channelType === self.DATA_CHANNEL_TYPE.DATA &&
channelName === transferId) {
+ self._dataChannels[peerId][channelProp].transferId = transferId;
sendWRQFn();
return false;
}
@@ -14667,12 +15474,12 @@ Skylink.prototype._startDataTransferToPeer = function (transferId, peerId, callb
// Create new Datachannel for Peer to start data transfer
if (!((requireInterop && peerId !== 'MCU') || channelProp === 'main')) {
channelProp = transferId;
-
- self._createDataChannel(peerId, transferId);
-
+ self._createDataChannel(peerId, transferId, self._dataTransfers[transferId].sessionType === 'data' ?
+ self._CHUNK_DATAURL_SIZE : (self._dataTransfers[transferId].sessionChunkType === 'string' ?
+ (window.webrtcDetectedBrowser === 'firefox' ? 16384 : 65546) : // After conversion to base64 string computed size
+ (window.webrtcDetectedBrowser === 'firefox' ? self._MOZ_BINARY_FILE_SIZE : self._BINARY_FILE_SIZE)));
} else {
self._dataChannels[peerId].main.transferId = transferId;
-
sendWRQFn();
}
};
@@ -14818,7 +15625,7 @@ Skylink.prototype._handleDataTransferTimeoutForPeer = function (transferId, peer
return;
}
- if (!self._user) {
+ if (!(self._user && self._user.sid)) {
log.debug([peerId, 'RTCDataChannel', transferId, 'User is not in Room. Ignoring expired timeout.']);
return;
}
@@ -14889,16 +15696,23 @@ Skylink.prototype._processDataChannelData = function(rawData, peerId, channelNam
var self = this;
var channelProp = channelType === self.DATA_CHANNEL_TYPE.MESSAGING ? 'main' : channelName;
- var transferId = channelProp === 'main' ? self._dataChannels[peerId].main.transferId : channelName;
+ var transferId = self._dataChannels[peerId][channelProp].transferId || null;
+ var streamId = self._dataChannels[peerId][channelProp].streamId || null;
+ var isStreamChunk = false;
+
+ if (streamId && self._dataStreams[streamId]) {
+ isStreamChunk = self._dataStreams[streamId].sessionChunkType === 'string' ? typeof rawData === 'string' :
+ typeof rawData === 'object';
+ }
if (!self._peerConnections[peerId]) {
- log.warn([peerId, 'RTCDataChannel', channelName, 'Dropping data received from Peer ' +
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Dropping data received from Peer ' +
'as connection is not present ->'], rawData);
return;
}
if (!(self._dataChannels[peerId] && self._dataChannels[peerId][channelProp])) {
- log.warn([peerId, 'RTCDataChannel', channelName, 'Dropping data received from Peer ' +
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Dropping data received from Peer ' +
'as Datachannel connection is not present ->'], rawData);
return;
}
@@ -14907,8 +15721,9 @@ Skylink.prototype._processDataChannelData = function(rawData, peerId, channelNam
if (typeof rawData === 'string') {
try {
var protocolData = JSON.parse(rawData);
+ isStreamChunk = false;
- log.debug([peerId, 'RTCDataChannel', channelProp, 'Received protocol message ->'], protocolData);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Received protocol "' + protocolData.type + '" message ->'], protocolData);
// Ignore ACK, ERROR and CANCEL if there is no data transfer session in-progress
if ([self._DC_PROTOCOL_TYPE.ACK, self._DC_PROTOCOL_TYPE.ERROR, self._DC_PROTOCOL_TYPE.CANCEL].indexOf(protocolData.type) > -1 &&
@@ -14923,7 +15738,7 @@ Skylink.prototype._processDataChannelData = function(rawData, peerId, channelNam
// Discard iOS bidirectional upload when Datachannel is in-progress for data transfers
if (transferId && self._dataTransfers[transferId] && self._dataTransfers[transferId].sessions[peerId]) {
log.warn([peerId, 'RTCDataChannel', channelProp, 'Rejecting bidirectional data transfer request as ' +
- 'it is currently not supported in the SDK']);
+ 'it is currently not supported in the SDK ->'], protocolData);
self._sendMessageToDataChannel(peerId, {
type: self._DC_PROTOCOL_TYPE.ACK,
@@ -14947,33 +15762,39 @@ Skylink.prototype._processDataChannelData = function(rawData, peerId, channelNam
self._MESSAGEProtocolHandler(peerId, protocolData, channelProp);
break;
default:
- log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded unknown protocol message ->'], protocolData);
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded unknown "' + protocolData.type + '" message ->'], protocolData);
}
} catch (error) {
if (rawData.indexOf('{') > -1 && rawData.indexOf('}') > 0) {
- log.error([peerId, 'RTCDataChannel', channelProp, 'Received error ->'], error);
+ log.error([peerId, 'RTCDataChannel', channelProp, 'Failed parsing protocol step data error ->'], {
+ data: rawData,
+ error: error
+ });
- self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.ERROR, peerId, error, channelName, channelType, null);
+ self._trigger('dataChannelState', self.DATA_CHANNEL_STATE.ERROR, peerId, error, channelName,
+ channelType, null, self._getDataChannelBuffer(peerId, channelProp));
throw error;
}
- if (!(transferId && self._dataTransfers[transferId] && self._dataTransfers[transferId].sessions[peerId])) {
- log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded data chunk as data transfer session ' +
- 'is not present ->'], rawData);
+ if (!isStreamChunk && !(transferId && self._dataTransfers[transferId] && self._dataTransfers[transferId].sessions[peerId])) {
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded data chunk without session ->'], rawData);
return;
}
- if (self._dataTransfers[transferId].chunks[self._dataTransfers[transferId].sessions[peerId].ackN]) {
- log.warn([peerId, 'RTCDataChannel', transferId, 'Dropping data chunk as it has already been added ->'], rawData);
- return;
+ if (!isStreamChunk && transferId) {
+ if (self._dataTransfers[transferId].chunks[self._dataTransfers[transferId].sessions[peerId].ackN]) {
+ log.warn([peerId, 'RTCDataChannel', transferId, 'Dropping data chunk ' + (!isStreamChunk ? '@' +
+ self._dataTransfers[transferId].sessions[peerId].ackN : '') + ' as it has already been added ->'], rawData);
+ return;
+ }
}
var chunkType = self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING;
- if (self._dataTransfers[transferId].dataType === self.DATA_TRANSFER_SESSION_TYPE.DATA_URL) {
- log.debug([peerId, 'RTCDataChannel', channelProp, 'Received string data chunk @' +
- self._dataTransfers[transferId].sessions[peerId].ackN + ' with size ->'], rawData.length || rawData.size);
+ if (!isStreamChunk ? self._dataTransfers[transferId].dataType === self.DATA_TRANSFER_SESSION_TYPE.DATA_URL : true) {
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Received string data chunk ' + (!isStreamChunk ? '@' +
+ self._dataTransfers[transferId].sessions[peerId].ackN : '') + ' with size ->'], rawData.length || rawData.size);
self._DATAProtocolHandler(peerId, rawData, self.DATA_TRANSFER_DATA_TYPE.STRING,
rawData.length || rawData.size || 0, channelProp);
@@ -14990,24 +15811,49 @@ Skylink.prototype._processDataChannelData = function(rawData, peerId, channelNam
}
}
} else {
+ if (!isStreamChunk && !(transferId && self._dataTransfers[transferId] && self._dataTransfers[transferId].sessions[peerId])) {
+ log.warn([peerId, 'RTCDataChannel', channelProp, 'Discarded data chunk without session ->'], rawData);
+ return;
+ }
+
+ if (!isStreamChunk && transferId) {
+ if (self._dataTransfers[transferId].chunks[self._dataTransfers[transferId].sessions[peerId].ackN]) {
+ log.warn([peerId, 'RTCDataChannel', transferId, 'Dropping data chunk ' + (!isStreamChunk ? '@' +
+ self._dataTransfers[transferId].sessions[peerId].ackN : '') + ' as it has already been added ->'], rawData);
+ return;
+ }
+ }
+
if (rawData instanceof Blob) {
- log.debug([peerId, 'RTCDataChannel', channelProp, 'Received blob data chunk @' +
- self._dataTransfers[transferId].sessions[peerId].ackN + ' with size ->'], rawData.size);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Received blob data chunk ' + (isStreamChunk ? '' :
+ '@' + self._dataTransfers[transferId].sessions[peerId].ackN) + ' with size ->'], rawData.size);
self._DATAProtocolHandler(peerId, rawData, self.DATA_TRANSFER_DATA_TYPE.BLOB, rawData.size, channelProp);
} else {
var byteArray = rawData;
+ var blob = null;
+ // Plugin binary handling
if (rawData.constructor && rawData.constructor.name === 'Array') {
// Need to re-parse on some browsers
byteArray = new Int8Array(rawData);
}
- var blob = new Blob([byteArray]);
+ // Fallback for older IE versions
+ if (window.webrtcDetectedBrowser === 'IE') {
+ if (window.BlobBuilder) {
+ var bb = new BlobBuilder();
+ bb.append(rawData.constructor && rawData.constructor.name === 'ArrayBuffer' ?
+ byteArray : (new Uint8Array(byteArray)).buffer);
+ blob = bb.getBlob();
+ }
+ } else {
+ blob = new Blob([byteArray]);
+ }
- log.debug([peerId, 'RTCDataChannel', channelProp, 'Received arraybuffer data chunk @' +
- self._dataTransfers[transferId].sessions[peerId].ackN + ' with size ->'], blob.size);
+ log.debug([peerId, 'RTCDataChannel', channelProp, 'Received arraybuffer data chunk ' + (isStreamChunk ? '' :
+ '@' + self._dataTransfers[transferId].sessions[peerId].ackN) + ' with size ->'], blob.size);
self._DATAProtocolHandler(peerId, blob, self.DATA_TRANSFER_DATA_TYPE.ARRAY_BUFFER, blob.size, channelProp);
}
@@ -15023,37 +15869,138 @@ Skylink.prototype._processDataChannelData = function(rawData, peerId, channelNam
*/
Skylink.prototype._WRQProtocolHandler = function(peerId, data, channelProp) {
var self = this;
- var transferId = channelProp === 'main' ? data.transferId || peerId + '_' + (new Date()).getTime() : channelProp;
+ var transferId = channelProp === 'main' ? data.transferId || null : channelProp;
var senderPeerId = data.sender || peerId;
- self._dataTransfers[transferId] = {
- name: data.name || transferId,
- size: data.size || 0,
- chunkSize: data.chunkSize,
- originalSize: data.originalSize || 0,
- timeout: data.timeout || 60,
- isPrivate: !!data.isPrivate,
- senderPeerId: data.sender || peerId,
- dataType: data.dataType || self.DATA_TRANSFER_SESSION_TYPE.BLOB,
- mimeType: data.mimeType || null,
- chunkType: data.chunkType || self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING,
- direction: self.DATA_TRANSFER_TYPE.DOWNLOAD,
- chunks: [],
- sessions: {}
- };
+ if (['fastBinaryStart', 'fastBinaryStop'].indexOf(data.dataType) > -1) {
+ if (data.dataType === 'fastBinaryStart') {
+ if (!transferId) {
+ transferId = 'stream_' + peerId + '_' + (new Date()).getTime();
+ }
+ self._dataStreams[transferId] = {
+ chunkSize: 0,
+ chunkType: data.chunkType === 'string' ? self.DATA_TRANSFER_DATA_TYPE.STRING : self._binaryChunkType,
+ sessionChunkType: data.chunkType,
+ isPrivate: !!data.isPrivate,
+ isStringStream: data.chunkType === 'string',
+ senderPeerId: senderPeerId,
+ isUpload: false
+ };
+ self._dataChannels[peerId][channelProp].streamId = transferId;
+ var hasStarted = false;
+ self.once('dataChannelState', function () {}, function (state, evtPeerId, channelName, channelType, error) {
+ if (!self._dataStreams[transferId]) {
+ return true;
+ }
- self._dataChannels[peerId][channelProp].transferId = transferId;
- self._dataTransfers[transferId].sessions[peerId] = {
- timer: null,
- ackN: 0,
- receivedSize: 0
- };
+ if (!(evtPeerId === peerId && (channelProp === 'main' ? channelType === self.DATA_CHANNEL_TYPE.MESSAGING :
+ channelName === transferId && channelType === self.DATA_CHANNEL_TYPE.DATA))) {
+ return;
+ }
+
+ if ([self.DATA_CHANNEL_STATE.ERROR, self.DATA_CHANNEL_STATE.CLOSED].indexOf(state) > -1) {
+ var updatedError = new Error(error && error.message ? error.message :
+ 'Failed data transfer as datachannel state is "' + state + '".');
+
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.ERROR, transferId, senderPeerId, {
+ chunk: null,
+ chunkSize: 0,
+ chunkType: self._dataStreams[transferId].chunkType,
+ isPrivate: self._dataStreams[transferId].isPrivate,
+ isStringStream: self._dataStreams[transferId].sessionChunkType === 'string',
+ senderPeerId: senderPeerId
+ }, updatedError);
+ return true;
+ }
+ });
- self._trigger('incomingDataRequest', transferId, senderPeerId,
- self._getTransferInfo(transferId, peerId, false, false, false), false);
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.RECEIVING_STARTED, transferId, senderPeerId, {
+ chunk: null,
+ chunkSize: 0,
+ chunkType: self._dataStreams[transferId].chunkType,
+ isPrivate: self._dataStreams[transferId].isPrivate,
+ isStringStream: self._dataStreams[transferId].sessionChunkType === 'string',
+ senderPeerId: senderPeerId
+ }, null);
+ self._trigger('incomingDataStreamStarted', transferId, senderPeerId, {
+ chunkSize: 0,
+ chunkType: self._dataStreams[transferId].chunkType,
+ isPrivate: self._dataStreams[transferId].isPrivate,
+ isStringStream: self._dataStreams[transferId].sessionChunkType === 'string',
+ senderPeerId: senderPeerId
+ }, false);
- self._trigger('dataTransferState', self.DATA_TRANSFER_STATE.UPLOAD_REQUEST, transferId, senderPeerId,
- self._getTransferInfo(transferId, peerId, true, false, false), null);
+ } else {
+ transferId = self._dataChannels[peerId][channelProp].streamId;
+ if (self._dataStreams[transferId] && !self._dataStreams[transferId].isUpload) {
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.RECEIVING_STOPPED, transferId, senderPeerId, {
+ chunk: null,
+ chunkSize: 0,
+ chunkType: self._dataStreams[transferId].chunkType,
+ isPrivate: self._dataStreams[transferId].isPrivate,
+ isStringStream: self._dataStreams[transferId].sessionChunkType === 'string',
+ senderPeerId: senderPeerId
+ }, null);
+ self._trigger('incomingDataStreamStopped', transferId, senderPeerId, {
+ chunkSize: 0,
+ chunkType: self._dataStreams[transferId].chunkType,
+ isPrivate: self._dataStreams[transferId].isPrivate,
+ isStringStream: self._dataStreams[transferId].sessionChunkType === 'string',
+ senderPeerId: senderPeerId
+ }, false);
+ self._dataChannels[peerId][channelProp].streamId = null;
+ if (channelProp !== 'main') {
+ self._closeDataChannel(peerId, channelProp);
+ }
+
+ delete self._dataStreams[transferId];
+ }
+ }
+ } else {
+ if (!transferId) {
+ transferId = 'transfer_' + peerId + '_' + (new Date()).getTime();
+ }
+
+ self._dataTransfers[transferId] = {
+ name: data.name || transferId,
+ size: data.size || 0,
+ chunkSize: data.chunkSize,
+ originalSize: data.originalSize || 0,
+ timeout: data.timeout || 60,
+ isPrivate: !!data.isPrivate,
+ senderPeerId: data.sender || peerId,
+ dataType: self.DATA_TRANSFER_SESSION_TYPE.BLOB,
+ mimeType: data.mimeType || null,
+ chunkType: self.DATA_TRANSFER_DATA_TYPE.BINARY_STRING,
+ direction: self.DATA_TRANSFER_TYPE.DOWNLOAD,
+ chunks: [],
+ sessions: {},
+ sessionType: data.dataType || 'blob',
+ sessionChunkType: data.chunkType || 'string'
+ };
+
+ if (self._dataTransfers[transferId].sessionType === 'data' &&
+ self._dataTransfers[transferId].sessionChunkType === 'string') {
+ self._dataTransfers[transferId].dataType = self.DATA_TRANSFER_SESSION_TYPE.DATA_URL;
+ self._dataTransfers[transferId].chunkType = self.DATA_TRANSFER_DATA_TYPE.STRING;
+ } else if (self._dataTransfers[transferId].sessionType === 'blob' &&
+ self._dataTransfers[transferId].sessionChunkType === 'binary') {
+ self._dataTransfers[transferId].chunkType = self._binaryChunkType;
+ }
+
+ self._dataChannels[peerId][channelProp].transferId = transferId;
+ self._dataTransfers[transferId].sessions[peerId] = {
+ timer: null,
+ ackN: 0,
+ receivedSize: 0
+ };
+
+ self._trigger('incomingDataRequest', transferId, senderPeerId,
+ self._getTransferInfo(transferId, peerId, false, false, false), false);
+
+ self._trigger('dataTransferState', self.DATA_TRANSFER_STATE.UPLOAD_REQUEST, transferId, senderPeerId,
+ self._getTransferInfo(transferId, peerId, true, false, false), null);
+ }
};
/**
@@ -15291,6 +16238,34 @@ Skylink.prototype._DATAProtocolHandler = function(peerId, chunk, chunkType, chun
var transferId = channelProp;
var senderPeerId = peerId;
+ if (!(self._dataChannels[peerId] && self._dataChannels[peerId][channelProp])) {
+ return;
+ }
+
+ var streamId = self._dataChannels[peerId][channelProp].streamId;
+
+ if (streamId && self._dataStreams[streamId] && ((typeof chunk === 'string' &&
+ self._dataStreams[streamId].sessionChunkType === 'string') || (chunk instanceof Blob &&
+ self._dataStreams[streamId].sessionChunkType === 'binary'))) {
+ senderPeerId = self._dataStreams[streamId].senderPeerId || peerId;
+ self._trigger('dataStreamState', self.DATA_STREAM_STATE.RECEIVED, streamId, senderPeerId, {
+ chunk: chunk,
+ chunkSize: chunkSize,
+ chunkType: chunkType,
+ isPrivate: self._dataStreams[streamId].sessionChunkType.isPrivate,
+ isStringStream: self._dataStreams[streamId].sessionChunkType === 'string',
+ senderPeerId: senderPeerId
+ }, null);
+ self._trigger('incomingDataStream', chunk, transferId, senderPeerId, {
+ chunkSize: chunkSize,
+ chunkType: chunkType,
+ isPrivate: self._dataStreams[streamId].sessionChunkType.isPrivate,
+ isStringStream: self._dataStreams[streamId].sessionChunkType === 'string',
+ senderPeerId: senderPeerId
+ }, false);
+ return;
+ }
+
if (channelProp === 'main') {
transferId = self._dataChannels[peerId].main.transferId;
}
@@ -15306,7 +16281,7 @@ Skylink.prototype._DATAProtocolHandler = function(peerId, chunk, chunkType, chun
self._dataTransfers[transferId].chunks[self._dataTransfers[transferId].sessions[peerId].ackN] = chunk;
if (self._dataTransfers[transferId].sessions[peerId].receivedSize >= self._dataTransfers[transferId].size) {
- log.log([peerId, 'RTCDataChannel', channelProp, 'Data transfer has been completed. Computed size ->'],
+ log.log([peerId, 'RTCDataChannel', channelProp, 'Data transfer has been completed. Computed size ->'],
self._dataTransfers[transferId].sessions[peerId].receivedSize);
// Send last ACK to Peer to indicate completion of data transfers
@@ -15410,9 +16385,11 @@ Skylink.prototype._onIceCandidate = function(targetMid, candidate) {
log.debug([targetMid, 'RTCIceCandidate', candidateType, 'Generated ICE candidate ->'], candidate);
- if (candidateType === 'endOfCandidates') {
+ if (candidateType === 'endOfCandidates' || !(self._peerConnections[targetMid] &&
+ self._peerConnections[targetMid].localDescription && self._peerConnections[targetMid].localDescription.sdp &&
+ self._peerConnections[targetMid].localDescription.sdp.indexOf('\r\na=mid:' + candidate.sdpMid + '\r\n') > -1)) {
log.warn([targetMid, 'RTCIceCandidate', candidateType, 'Dropping of sending ICE candidate ' +
- 'end-of-candidates signal to prevent errors ->'], candidate);
+ 'end-of-candidates signal or unused ICE candidates to prevent errors ->'], candidate);
return;
}
@@ -15462,6 +16439,10 @@ Skylink.prototype._onIceCandidate = function(targetMid, candidate) {
} else {
log.log([targetMid, 'RTCIceCandidate', null, 'ICE gathering has completed.']);
+ if (pc.gathered) {
+ return;
+ }
+
pc.gathering = false;
pc.gathered = true;
@@ -15482,7 +16463,7 @@ Skylink.prototype._onIceCandidate = function(targetMid, candidate) {
type: sessionDescription.type,
sdp: self._addSDPMediaStreamTrackIDs(targetMid, sessionDescription),
mid: self._user.sid,
- userInfo: self._getUserInfo(),
+ userInfo: self._getUserInfo(targetMid),
target: targetMid,
rid: self._room.id
});
@@ -15545,7 +16526,8 @@ Skylink.prototype._addIceCandidateFromQueue = function(targetMid) {
this._addIceCandidate(targetMid, canArray[0], canArray[1]);
} else if (this._peerConnections[targetMid] &&
- this._peerConnections[targetMid].signalingState !== this.PEER_CONNECTION_STATE.CLOSED) {
+ this._peerConnections[targetMid].signalingState !== this.PEER_CONNECTION_STATE.CLOSED &&
+ AdapterJS && !this._isLowerThanVersion(AdapterJS.VERSION, '0.14.0')) {
log.debug([targetMid, 'RTCPeerConnection', null, 'Signaling of end-of-candidates remote ICE gathering.']);
this._peerConnections[targetMid].addIceCandidate(null);
}
@@ -15599,7 +16581,10 @@ Skylink.prototype._addIceCandidate = function (targetMid, canId, candidate) {
}, null);
if (!(self._peerConnections[targetMid] &&
- self._peerConnections[targetMid].signalingState !== self.PEER_CONNECTION_STATE.CLOSED)) {
+ self._peerConnections[targetMid].signalingState !== self.PEER_CONNECTION_STATE.CLOSED &&
+ self._peerConnections[targetMid].remoteDescription &&
+ self._peerConnections[targetMid].remoteDescription.sdp &&
+ self._peerConnections[targetMid].remoteDescription.sdp.indexOf('\r\na=mid:' + candidate.sdpMid + '\r\n') > -1)) {
log.warn([targetMid, 'RTCIceCandidate', canId + ':' + candidateType, 'Dropping ICE candidate ' +
'as Peer connection does not exists or is closed']);
self._trigger('candidateProcessingState', self.CANDIDATE_PROCESSING_STATE.DROPPED,
@@ -15682,6 +16667,7 @@ Skylink.prototype.TURN_TRANSPORT = {
* @since 0.5.4
*/
Skylink.prototype._setIceServers = function(givenConfig) {
+ var self = this;
var givenIceServers = clone(givenConfig.iceServers);
var iceServersList = {};
var newIceServers = [];
@@ -15691,7 +16677,7 @@ Skylink.prototype._setIceServers = function(givenConfig) {
- if (this._forceTURNSSL) {
+ if (self._forceTURNSSL) {
if (window.webrtcDetectedBrowser === 'chrome' ||
window.webrtcDetectedBrowser === 'safari' ||
window.webrtcDetectedBrowser === 'IE') {
@@ -15735,18 +16721,18 @@ Skylink.prototype._setIceServers = function(givenConfig) {
}
if (server.url.indexOf('stun') === 0) {
- if (!this._enableSTUN) {
+ if (!self._enableSTUN) {
log.warn('Ignoring STUN server provided at index ' + i, clone(server));
continue;
}
- if (!this._usePublicSTUN && server.url.indexOf('temasys') === -1) {
+ if (!self._usePublicSTUN && server.url.indexOf('temasys') === -1) {
log.warn('Ignoring public STUN server provided at index ' + i, clone(server));
continue;
}
} else if (server.url.indexOf('turn') === 0) {
- if (!this._enableTURN) {
+ if (!self._enableTURN) {
log.warn('Ignoring TURN server provided at index ' + i, clone(server));
continue;
}
@@ -15783,7 +16769,7 @@ Skylink.prototype._setIceServers = function(givenConfig) {
var credential = typeof server.credential === 'string' ? server.credential : 'none';
if (server.url.indexOf('turn') === 0) {
- if (this._TURNTransport === this.TURN_TRANSPORT.ANY) {
+ if (self._TURNTransport === self.TURN_TRANSPORT.ANY) {
pushIceServer(username, credential, server.url);
} else {
@@ -15793,17 +16779,17 @@ Skylink.prototype._setIceServers = function(givenConfig) {
rawUrl = rawUrl.split('?transport=')[0];
}
- if (this._TURNTransport === this.TURN_TRANSPORT.NONE) {
+ if (self._TURNTransport === self.TURN_TRANSPORT.NONE) {
pushIceServer(username, credential, rawUrl);
- } else if (this._TURNTransport === this.TURN_TRANSPORT.UDP) {
+ } else if (self._TURNTransport === self.TURN_TRANSPORT.UDP) {
pushIceServer(username, credential, rawUrl + '?transport=udp');
- } else if (this._TURNTransport === this.TURN_TRANSPORT.TCP) {
+ } else if (self._TURNTransport === self.TURN_TRANSPORT.TCP) {
pushIceServer(username, credential, rawUrl + '?transport=tcp');
- } else if (this._TURNTransport === this.TURN_TRANSPORT.ALL) {
+ } else if (self._TURNTransport === self.TURN_TRANSPORT.ALL) {
pushIceServer(username, credential, rawUrl + '?transport=tcp');
pushIceServer(username, credential, rawUrl + '?transport=udp');
} else {
- log.warn('Invalid TURN transport option "' + this._TURNTransport +
+ log.warn('Invalid TURN transport option "' + self._TURNTransport +
'". Ignoring TURN server at index' + i, clone(server));
continue;
}
@@ -15814,7 +16800,7 @@ Skylink.prototype._setIceServers = function(givenConfig) {
}
// add mozilla STUN for firefox
- if (this._enableSTUN && this._usePublicSTUN && window.webrtcDetectedBrowser === 'firefox') {
+ if (self._enableSTUN && self._usePublicSTUN && window.webrtcDetectedBrowser === 'firefox') {
pushIceServer('none', 'none', 'stun:stun.services.mozilla.com', 0);
}
@@ -15886,6 +16872,23 @@ Skylink.prototype._setIceServers = function(givenConfig) {
}
}
+ if (self._iceServer) {
+ var nUsername = null, nCredential = null;
+ for (i = 0; i < newIceServers.length; i++) {
+ if (newIceServers[i].username) {
+ nUsername = newIceServers[i].username;
+ }
+ if (newIceServers[i].credential) {
+ nCredential = newIceServers[i].credential;
+ }
+ }
+ newIceServers = [{
+ urls: self._iceServer.urls,
+ username: nUsername,
+ credential: nCredential
+ }];
+ }
+
log.log('Output iceServers configuration:', newIceServers);
return {
@@ -15941,6 +16944,83 @@ Skylink.prototype.SERVER_PEER_TYPE = {
/**
*
+ * Learn more about how ICE works in this
+ * article here.
+ *
+ * The list of available Peer connection bundle policies.
+ * @attribute BUNDLE_POLICY
+ * @param {String} MAX_COMPAT Value "max-compat"
+ * The value of the bundle policy to generate ICE candidates for each media type
+ * so each media type flows through different transports.
+ * @param {String} MAX_BUNDLE Value "max-bundle"
+ * The value of the bundle policy to generate ICE candidates for one media type
+ * so all media type flows through a single transport.
+ * @param {String} BALANCED Value "balanced"
+ * The value of the bundle policy to use MAX_BUNDLE if Peer supports it,
+ * else fallback to MAX_COMPAT.
+ * @param {String} NONE Value "none"
+ * The value of the bundle policy to not use any media bundle.
+ * This removes the a=group:BUNDLE line from session descriptions.
+ * @type JSON
+ * @readOnly
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.BUNDLE_POLICY = {
+ MAX_COMPAT: 'max-compat',
+ BALANCED: 'balanced',
+ MAX_BUNDLE: 'max-bundle',
+ NONE: 'none'
+};
+
+/**
+ *
+ * Learn more about how ICE works in this
+ * article here.
+ *
+ * The list of available Peer connection RTCP mux policies.
+ * @attribute RTCP_MUX_POLICY
+ * @param {String} REQUIRE Value "require"
+ * The value of the RTCP mux policy to generate ICE candidates for RTP only and RTCP shares the same ICE candidates.
+ * @param {String} NEGOTIATE Value "negotiate"
+ * The value of the RTCP mux policy to generate ICE candidates for both RTP and RTCP each.
+ * @type JSON
+ * @readOnly
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.RTCP_MUX_POLICY = {
+ REQUIRE: 'require',
+ NEGOTIATE: 'negotiate'
+};
+
+/**
+ *
+ * Learn more about how ICE works in this
+ * article here.
+ *
+ * The list of available Peer connection certificates cryptographic algorithm to use.
+ * @attribute PEER_CERTIFICATE
+ * @param {String} RSA Value "RSA"
+ * The value of the Peer connection certificate algorithm to use RSA-1024.
+ * @param {String} ECDSA Value "ECDSA"
+ * The value of the Peer connection certificate algorithm to use ECDSA.
+ * @param {String} AUTO Value "AUTO"
+ * The value of the Peer connection to use the default certificate generated.
+ * @type JSON
+ * @readOnly
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.PEER_CERTIFICATE = {
+ RSA: 'RSA',
+ ECDSA: 'ECDSA',
+ AUTO: 'AUTO'
+};
+
+/**
+ *
+ * Note that Edge browser does not support renegotiation.
* For MCU enabled Peer connections with options.mcuUseRenegoRestart set to false
* in the init() method, the restart functionality may differ, you
* may learn more about how to workaround it
@@ -15968,6 +17048,17 @@ Skylink.prototype.SERVER_PEER_TYPE = {
* The flag if ICE connections should restart when refreshing Peer connections.
* This is used when ICE connection state is FAILED or DISCONNECTED, which state
* can be retrieved with the iceConnectionState event.
+ * @param {JSON} [options]
+ * Note that for MCU connections, the bandwidth or googleXBandwidth
+ * settings will override for all Peers or the current Room connection session settings.
* @example
- * // Example 1: Get the list of currently connected Peers in the same Room
+ * // Example 1: Get the list of current Peers Streams in the same Room
* var streams = skylinkDemo.getPeersStream();
* @for Skylink
* @since 0.6.16
@@ -17716,6 +19491,266 @@ Skylink.prototype.getPeersStream = function() {
return listOfPeersStreams;
};
+/**
+ * Function that gets the current list of connected Peers Datachannel connections in the Room.
+ * @method getPeersDatachannels
+ * @return {JSON} The list of Peers Stream.
+ *
#peerId{JSON}
The Peer Datachannels information.
+ *
#channelName{JSON}
The Datachannel information.
+ *
channelName{String}
The Datachannel ID..
+ *
channelType{String}
The Datachannel type.
+ * [Rel: Skylink.DATA_CHANNEL_TYPE]
+ *
channelProp{String}
The Datachannel property.
+ *
currentTransferId{String}
The Datachannel connection
+ * current progressing transfer session. Defined as null when there is
+ * currently no transfer session progressing on the Datachannel connection.
+ *
currentStreamId{String}
The Datachannel connection
+ * current data streaming session ID. Defined as null when there is currently
+ * no data streaming session on the Datachannel connection.
+ *
readyState{String}
The Datachannel connection readyState.
+ * [Rel: Skylink.DATA_CHANNEL_STATE]
+ *
bufferedAmountLow{Number}
The Datachannel buffered amount.
+ *
bufferedAmountLowThreshold{Number}
The Datachannel
+ * buffered amount threshold.
+ *
+ * @example
+ * // Example 1: Get the list of current Peers Datachannels in the same Room
+ * var channels = skylinkDemo.getPeersDatachannels();
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.getPeersDatachannels = function() {
+ var listOfPeersDatachannels = {};
+ var listOfPeers = Object.keys(this._peerConnections);
+
+ for (var i = 0; i < listOfPeers.length; i++) {
+ listOfPeersDatachannels[listOfPeers[i]] = {};
+
+ if (this._dataChannels[listOfPeers[i]]) {
+ for (var channelProp in this._dataChannels[listOfPeers[i]]) {
+ if (this._dataChannels[listOfPeers[i]].hasOwnProperty(channelProp) &&
+ this._dataChannels[listOfPeers[i]][channelProp]) {
+ var channel = this._dataChannels[listOfPeers[i]][channelProp];
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName] = this._getDataChannelBuffer(listOfPeers[i], channelProp);
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].channelName = channel.channelName;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].channelType = channel.channelType;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].channelProp = channelProp;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].currentTransferId = channel.transferId;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].currentStreamId = channel.streamId;
+ listOfPeersDatachannels[listOfPeers[i]][channel.channelName].readyState = channel.channel ?
+ channel.channel.readyState : self.DATA_CHANNEL_STATE.CREATE_ERROR;
+ }
+ }
+ }
+ }
+
+ return listOfPeersDatachannels;
+};
+
+/**
+ * Function that gets the list of current data transfers.
+ * @method getCurrentDataTransfers
+ * @return {JSON} The list of Peers Stream.
+ *
#transferId{JSON}
The data transfer session.
+ *
transferInfo{JSON}
The data transfer information.
+ * Object signature matches the transferInfo parameter payload received in the
+ * dataTransferState event
+ * except without the data property.
+ *
peerId{String}
The sender Peer ID.
+ *
isSelf{Boolean}
The flag if Peer is User.
+ *
+ * @example
+ * // Example 1: Get the list of current data transfers in the same Room
+ * var currentTransfers = skylinkDemo.getCurrentDataTransfers();
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.getCurrentDataTransfers = function() {
+ var listOfDataTransfers = {};
+
+ if (!(this._user && this._user.sid)) {
+ return {};
+ }
+
+ for (var prop in this._dataTransfers) {
+ if (this._dataTransfers.hasOwnProperty(prop) && this._dataTransfers[prop]) {
+ listOfDataTransfers[prop] = {
+ transferInfo: this._getTransferInfo(prop, this._user.sid, true, true, true),
+ isSelf: this._dataTransfers[prop].senderPeerId === this._user.sid,
+ peerId: this._dataTransfers[prop].senderPeerId || this._user.sid
+ };
+ }
+ }
+
+ return listOfDataTransfers;
+};
+
+/**
+ * Function that gets the list of current data streaming sessions.
+ * @method getCurrentDataStreamsSession
+ * @return {JSON} The list of Peers Stream.
+ *
#streamId{JSON}
The data streaming session.
+ *
streamInfo{JSON}
The data streaming information.
+ * Object signature matches the streamInfo parameter payload received in the
+ * dataStreamState event
+ * except without the chunk amd chunkSize property.
+ *
peerId{String}
The sender Peer ID.
+ *
isSelf{Boolean}
The flag if Peer is User.
+ *
+ * @example
+ * // Example 1: Get the list of current data streaming sessions in the same Room
+ * var currentDataStreams = skylinkDemo.getCurrentDataStreamsSession();
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.getCurrentDataStreamsSession = function() {
+ var listOfDataStreams = {};
+
+ if (!(this._user && this._user.sid)) {
+ return {};
+ }
+
+ for (var prop in this._dataStreams) {
+ if (this._dataStreams.hasOwnProperty(prop) && this._dataStreams[prop]) {
+ listOfDataStreams[prop] = {
+ streamInfo: {
+ chunkType: this._dataStreams[prop].sessionChunkType === 'string' ? this.DATA_TRANSFER_DATA_TYPE.STRING :
+ this.DATA_TRANSFER_DATA_TYPE.BLOB,
+ isPrivate: this._dataStreams[prop].isPrivate,
+ isStringStream: this._dataStreams[prop].sessionChunkType === 'string',
+ senderPeerId: this._dataStreams[prop].senderPeerId
+ },
+ isSelf: this._dataStreams[prop].senderPeerId === this._user.sid,
+ peerId: this._dataStreams[prop].senderPeerId || this._user.sid
+ };
+ }
+ }
+
+ return listOfDataStreams;
+};
+
+/**
+ * Function that gets the list of current custom Peer settings sent and set.
+ * @method getPeerCustomSettings
+ * @return {JSON} The list of Peers custom settings sent and set.
+ *
#peerId{JSON}
The Peer settings sent and set.
+ *
settings{JSON}
The custom Peer settings.
+ * Object signature matches the peerInfo.settings parameter payload received in the
+ * peerJoined event.
+ *
mediaStatus{JSON}
The custom Peer Stream muted settings.
+ * Object signature matches the peerInfo.mediaStatus parameter payload received in the
+ * peerJoined event.
+ * @example
+ * // Example 1: Get the list of current Peer custom settings
+ * var currentPeerSettings = skylinkDemo.getPeersCustomSettings();
+ * @for Skylink
+ * @since 0.6.18
+ */
+Skylink.prototype.getPeersCustomSettings = function () {
+ var self = this;
+ var customSettingsList = {};
+
+ for (var peerId in self._peerInformations) {
+ if (self._peerInformations.hasOwnProperty(peerId) && self._peerInformations[peerId]) {
+ customSettingsList[peerId] = {
+ settings: {
+ audio: false,
+ video: false,
+ bandwidth: clone(self._streamsBandwidthSettings.bAS),
+ googleXBandwidth: clone(self._streamsBandwidthSettings.googleX)
+ },
+ mediaStatus: {
+ audioMuted: true,
+ videoMuted: true
+ }
+ };
+
+ if (self._peerConnections[peerId] && self._peerConnections[peerId].signalingState !== self.PEER_CONNECTION_STATE.CLOSED) {
+ var streams = self._peerConnections[peerId].getLocalStreams();
+
+ for (var s = 0; s < streams.length; s++) {
+ if (self._streams.screenshare && self._streams.screenshare.stream && (streams[s].id ||
+ streams[s].label) === (self._streams.screenshare.stream.id || self._streams.screenshare.stream.label)) {
+ customSettingsList[peerId].settings.audio = clone(self._streams.screenshare.settings.audio);
+ customSettingsList[peerId].settings.video = clone(self._streams.screenshare.settings.video);
+ customSettingsList[peerId].mediaStatus = clone(self._streamsMutedSettings);
+ break;
+ } else if (self._streams.userMedia && self._streams.userMedia.stream && (streams[s].id ||
+ streams[s].label) === (self._streams.userMedia.stream.id ||
+ self._streams.userMedia.stream.label)) {
+ customSettingsList[peerId].settings.audio = clone(self._streams.userMedia.settings.audio);
+ customSettingsList[peerId].settings.video = clone(self._streams.userMedia.settings.video);
+ customSettingsList[peerId].mediaStatus = clone(self._streamsMutedSettings);
+ break;
+ } else if (window.webrtcDetectedBrowser === 'edge') {
+ customSettingsList[peerId].settings.audio = clone(self._streams.userMedia.settings.audio);
+ customSettingsList[peerId].settings.video = clone(self._streams.userMedia.settings.video);
+ customSettingsList[peerId].mediaStatus = clone(self._streamsMutedSettings);
+ if (streams[s].getAudioTracks().length === 0) {
+ customSettingsList[peerId].settings.audio = false;
+ customSettingsList[peerId].mediaStatus.audioMuted = true;
+ }
+ if (streams[s].getVideoTracks().length === 0) {
+ customSettingsList[peerId].settings.video = false;
+ customSettingsList[peerId].mediaStatus.videoMuted = true;
+ }
+ }
+ }
+ }
+
+ if (self._peerCustomConfigs[peerId]) {
+ if (self._peerCustomConfigs[peerId].bandwidth &&
+ typeof self._peerCustomConfigs[peerId].bandwidth === 'object') {
+ if (typeof self._peerCustomConfigs[peerId].bandwidth.audio === 'number') {
+ customSettingsList[peerId].settings.bandwidth.audio = self._peerCustomConfigs[peerId].bandwidth.audio;
+ }
+ if (typeof self._peerCustomConfigs[peerId].bandwidth.video === 'number') {
+ customSettingsList[peerId].settings.bandwidth.video = self._peerCustomConfigs[peerId].bandwidth.video;
+ }
+ if (typeof self._peerCustomConfigs[peerId].bandwidth.data === 'number') {
+ customSettingsList[peerId].settings.bandwidth.data = self._peerCustomConfigs[peerId].bandwidth.data;
+ }
+ }
+ if (self._peerCustomConfigs[peerId].googleXBandwidth &&
+ typeof self._peerCustomConfigs[peerId].googleXBandwidth === 'object') {
+ if (typeof self._peerCustomConfigs[peerId].googleXBandwidth.min === 'number') {
+ customSettingsList[peerId].settings.googleXBandwidth.min = self._peerCustomConfigs[peerId].googleXBandwidth.min;
+ }
+ if (typeof self._peerCustomConfigs[peerId].googleXBandwidth.max === 'number') {
+ customSettingsList[peerId].settings.googleXBandwidth.max = self._peerCustomConfigs[peerId].googleXBandwidth.max;
+ }
+ }
+ }
+
+ var agent = ((self._peerInformations[peerId] || {}).agent || {}).name || '';
+
+ // If there is Peer ID (not broadcast ENTER message) and Peer is Edge browser and User is not
+ if (customSettingsList[peerId].settings.video && (peerId ?
+ (window.webrtcDetectedBrowser !== 'edge' && agent.name === 'edge' ?
+ // If User is IE/safari and does not have H264 support, remove video support
+ ['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1 && !self._currentCodecSupport.video.h264 :
+ // If User is Edge and Peer is not and no H264 support, remove video support
+ window.webrtcDetectedBrowser === 'edge' && agent.name !== 'edge' && !self._currentCodecSupport.video.h264) :
+ // If broadcast ENTER message and User is Edge and has no H264 support
+ window.webrtcDetectedBrowser === 'edge' && !self._currentCodecSupport.video.h264)) {
+ customSettingsList[peerId].settings.video = false;
+ customSettingsList[peerId].mediaStatus.videoMuted = true;
+ }
+
+ customSettingsList[peerId].settings.audio = !self._sdpSettings.connection.audio ? false :
+ customSettingsList[peerId].settings.audio;
+ customSettingsList[peerId].settings.video = !self._sdpSettings.connection.video ? false :
+ customSettingsList[peerId].settings.video;
+ customSettingsList[peerId].mediaStatus.audioMuted = !self._sdpSettings.connection.audio ? true :
+ customSettingsList[peerId].mediaStatus.audioMuted;
+ customSettingsList[peerId].mediaStatus.videoMuted = !self._sdpSettings.connection.video ? true :
+ customSettingsList[peerId].mediaStatus.videoMuted;
+ }
+ }
+
+ return customSettingsList;
+};
+
/**
* Function that returns the User session information to be sent to Peers.
* @method _getUserInfo
@@ -17725,6 +19760,7 @@ Skylink.prototype.getPeersStream = function() {
*/
Skylink.prototype._getUserInfo = function(peerId) {
var userInfo = clone(this.getPeerInfo());
+ var peerInfo = clone(this.getPeerInfo(peerId));
// Adhere to SM protocol without breaking the other SDKs.
if (userInfo.settings.video && typeof userInfo.settings.video === 'object') {
@@ -17758,8 +19794,33 @@ Skylink.prototype._getUserInfo = function(peerId) {
delete userInfo.settings.bandwidth;
}
+ // If there is Peer ID (not broadcast ENTER message) and Peer is Edge browser and User is not
+ if (peerId ? (window.webrtcDetectedBrowser !== 'edge' && peerInfo.agent.name === 'edge' ?
+ // If User is IE/safari and does not have H264 support, remove video support
+ ['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1 && !this._currentCodecSupport.video.h264 :
+ // If User is Edge and Peer is not and no H264 support, remove video support
+ window.webrtcDetectedBrowser === 'edge' && peerInfo.agent.name !== 'edge' && !this._currentCodecSupport.video.h264) :
+ // If broadcast ENTER message and User is Edge and has no H264 support
+ window.webrtcDetectedBrowser === 'edge' && !this._currentCodecSupport.video.h264) {
+ userInfo.settings.video = false;
+ userInfo.mediaStatus.videoMuted = true;
+ }
+
+ if (!this._sdpSettings.connection.audio) {
+ userInfo.settings.audio = false;
+ userInfo.mediaStatus.audioMuted = true;
+ }
+
+ if (!this._sdpSettings.connection.video) {
+ userInfo.settings.video = false;
+ userInfo.mediaStatus.videoMuted = true;
+ }
+
delete userInfo.agent;
delete userInfo.room;
+ delete userInfo.config;
+ delete userInfo.parentId;
+ delete userInfo.settings.data;
return userInfo;
};
@@ -17780,7 +19841,7 @@ Skylink.prototype.HANDSHAKE_PROGRESS = {
*/
Skylink.prototype._doOffer = function(targetMid, iceRestart, peerBrowser) {
var self = this;
- var pc = self._peerConnections[targetMid] || self._addPeer(targetMid, peerBrowser);
+ var pc = self._peerConnections[targetMid];// || self._addPeer(targetMid, peerBrowser);
log.log([targetMid, null, null, 'Checking caller status'], peerBrowser);
@@ -17799,46 +19860,33 @@ Skylink.prototype._doOffer = function(targetMid, iceRestart, peerBrowser) {
return;
}
- var peerIceRestartSupport = !!((self._peerInformations[targetMid] || {}).config || {}).enableIceRestart;
+ var peerAgent = ((self._peerInformations[targetMid] || {}).agent || {}).name || '';
+ var doIceRestart = !!((self._peerInformations[targetMid] || {}).config || {}).enableIceRestart &&
+ iceRestart && self._enableIceRestart;
+ var offerToReceiveAudio = !(!self._sdpSettings.connection.audio && targetMid !== 'MCU');
+ var offerToReceiveVideo = !(!self._sdpSettings.connection.video && targetMid !== 'MCU') &&
+ ((window.webrtcDetectedBrowser === 'edge' && peerAgent !== 'edge') ||
+ (['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1 && peerAgent === 'edge') ?
+ !!self._currentCodecSupport.video.h264 : true);
var offerConstraints = {
- offerToReceiveAudio: true,
- offerToReceiveVideo: true,
- iceRestart: self._enableIceRestart && peerIceRestartSupport ? iceRestart === true : false
+ offerToReceiveAudio: offerToReceiveAudio,
+ offerToReceiveVideo: offerToReceiveVideo,
+ iceRestart: doIceRestart,
+ voiceActivityDetection: self._voiceActivityDetection
};
- // NOTE: Removing ICE restart functionality as of now since Firefox does not support it yet
- // Check if ICE connection failed or disconnected, and if so, do an ICE restart
- /*if ([self.ICE_CONNECTION_STATE.DISCONNECTED, self.ICE_CONNECTION_STATE.FAILED].indexOf(pc.iceConnectionState) > -1) {
- offerConstraints.iceRestart = true;
- }*/
-
// Prevent undefined OS errors
peerBrowser.os = peerBrowser.os || '';
- /*
- Ignoring these old codes as Firefox 39 and below is no longer supported
- if (window.webrtcDetectedType === 'moz' && peerBrowser.agent === 'MCU') {
- unifiedOfferConstraints.mandatory = unifiedOfferConstraints.mandatory || {};
- unifiedOfferConstraints.mandatory.MozDontOfferDataChannel = true;
- beOfferer = true;
- }
-
- if (window.webrtcDetectedBrowser === 'firefox' && window.webrtcDetectedVersion >= 32) {
- unifiedOfferConstraints = {
- offerToReceiveAudio: true,
- offerToReceiveVideo: true
- };
- }
- */
-
// Fallback to use mandatory constraints for plugin based browsers
if (['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1) {
offerConstraints = {
mandatory: {
- OfferToReceiveAudio: true,
- OfferToReceiveVideo: true,
- iceRestart: self._enableIceRestart && peerIceRestartSupport ? iceRestart === true : false
+ OfferToReceiveAudio: offerToReceiveAudio,
+ OfferToReceiveVideo: offerToReceiveVideo,
+ iceRestart: doIceRestart,
+ voiceActivityDetection: self._voiceActivityDetection
}
};
}
@@ -17849,7 +19897,8 @@ Skylink.prototype._doOffer = function(targetMid, iceRestart, peerBrowser) {
}
if (self._enableDataChannel && self._peerInformations[targetMid] &&
- self._peerInformations[targetMid].config.enableDataChannel) {
+ self._peerInformations[targetMid].config.enableDataChannel &&
+ !(!self._sdpSettings.connection.data && targetMid !== 'MCU')) {
// Edge doesn't support datachannels yet
if (!(self._dataChannels[targetMid] && self._dataChannels[targetMid].main)) {
self._createDataChannel(targetMid);
@@ -17904,10 +19953,17 @@ Skylink.prototype._doAnswer = function(targetMid) {
}
// Add stream only at offer/answer end
- if (!self._hasMCU || targetMid === 'MCU') {
+ if ((!self._hasMCU || targetMid === 'MCU') && window.webrtcDetectedBrowser !== 'edge') {
self._addLocalMediaStreams(targetMid);
}
+ var peerAgent = ((self._peerInformations[targetMid] || {}).agent || {}).name || '';
+ var offerToReceiveAudio = !(!self._sdpSettings.connection.audio && targetMid !== 'MCU');
+ var offerToReceiveVideo = !(!self._sdpSettings.connection.video && targetMid !== 'MCU') &&
+ ((window.webrtcDetectedBrowser === 'edge' && peerAgent !== 'edge') ||
+ (['IE', 'safari'].indexOf(window.webrtcDetectedBrowser) > -1 && peerAgent === 'edge') ?
+ !!self._currentCodecSupport.video.h264 : true);
+
// No ICE restart constraints for createAnswer as it fails in chrome 48
// { iceRestart: true }
pc.createAnswer(function(answer) {
@@ -17916,7 +19972,11 @@ Skylink.prototype._doAnswer = function(targetMid) {
}, function(error) {
log.error([targetMid, null, null, 'Failed creating an answer:'], error);
self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.ERROR, targetMid, error);
- });
+ }, window.webrtcDetectedBrowser === 'edge' ? {
+ offerToReceiveVideo: offerToReceiveVideo,
+ offerToReceiveAudio: offerToReceiveAudio,
+ voiceActivityDetection: self._voiceActivityDetection
+ } : undefined);
};
/**
@@ -17966,14 +20026,20 @@ Skylink.prototype._setLocalAndSendMessage = function(targetMid, sessionDescripti
pc.processingLocalSDP = true;
+ // Set them as first
+ if (window.webrtcDetectedBrowser === 'edge') {
+ sessionDescription.sdp = self._setSDPCodec(targetMid, sessionDescription, {
+ audio: self.AUDIO_CODEC.OPUS,
+ video: self.VIDEO_CODEC.H264
+ });
+ }
+
// Sets and expected receiving codecs etc.
- //sessionDescription.sdp = self._setSDPOpusConfig(targetMid, sessionDescription);
- //sessionDescription.sdp = self._setSDPCodec(targetMid, sessionDescription);
sessionDescription.sdp = self._removeSDPFirefoxH264Pref(targetMid, sessionDescription);
- sessionDescription.sdp = self._removeSDPH264VP9AptRtxForOlderPlugin(targetMid, sessionDescription);
+ sessionDescription.sdp = self._setSDPCodecParams(targetMid, sessionDescription);
+ sessionDescription.sdp = self._removeSDPUnknownAptRtx(targetMid, sessionDescription);
sessionDescription.sdp = self._removeSDPCodecs(targetMid, sessionDescription);
- sessionDescription.sdp = self._handleSDPConnectionSettings(targetMid, sessionDescription);
- //sessionDescription.sdp = self._setSDPBitrate(targetMid, sessionDescription);
+ sessionDescription.sdp = self._handleSDPConnectionSettings(targetMid, sessionDescription, 'local');
sessionDescription.sdp = self._removeSDPREMBPackets(targetMid, sessionDescription);
log.log([targetMid, 'RTCSessionDescription', sessionDescription.type,
@@ -18005,7 +20071,7 @@ Skylink.prototype._setLocalAndSendMessage = function(targetMid, sessionDescripti
mid: self._user.sid,
target: targetMid,
rid: self._room.id,
- userInfo: self._getUserInfo()
+ userInfo: self._getUserInfo(targetMid)
});
}, function(error) {
@@ -18311,6 +20377,17 @@ Skylink.prototype.SYSTEM_ACTION_REASON = {
* options.audio is not defined, it will be defined as false.
* Object signature matches the options.video parameter in the
* getUserMedia() method.
+ * @param {Boolean} [options.voiceActivityDetection=true] The flag if voice activity detection should be enabled.
+ * This can only be toggled if User is and for the offerer, which is determined if User's
+ * peerInfo.config.priorityWeight is higher than Peer's.
+ *
+ * This works hand-in-hand with the options.disableComfortNoiseCodec flag in the
+ * init() method and the options.audio.usedtx setting in
+ * getUserMedia() method. VAD (voice activity detection)
+ * detects if there is an active voice in the Stream, and if there is no active voice in the Stream, the
+ * options.audio.usedtx (if enabled) would prevent sending these empty bits. To prevent huge differences
+ * when there is a silence and an active voice later, the CN codec would produce an empty voice to
+ * make it sound better.
* @param {JSON} [options.bandwidth]
Note that this is currently not supported
* with Firefox browsers versions 48 and below as noted in an existing
* bugzilla ticket here.
@@ -18379,8 +20456,44 @@ Skylink.prototype.SYSTEM_ACTION_REASON = {
* Note that this feature is currently is beta, and for any enquiries on enabling and its support for MCU enabled
* Peer connections, please contact our support portal.
* The config if Peer would publish only.
- * @param {String} [options.publishOnly.parentId] The parent Peer ID to match to when Peer is connected.
+ * @param {String} [options.publishOnly.parentId]
Deprecation Warning!
+ * This property has been deprecated. Use options.parentId instead.
+ *
The parent Peer ID to match to when Peer is connected.
+ * This is useful for identification for users connecting the Room twice simultaneously for multi-streaming.
+ * If User Peer ID matches the parent Peer ID provided from Peer, User will not be connected to Peer.
+ * @param {String} [options.parentId] The parent Peer ID to match to when Peer is connected.
+ * Note that configuring this value overrides the options.publishOnly.parentId value.
* This is useful for identification for users connecting the Room twice simultaneously for multi-streaming.
+ * If User Peer ID matches the parent Peer ID provided from Peer, User will not be connected to Peer.
+ * @param {JSON} [options.peerConnection]
+ * Note that this is mainly used for debugging purposes, so it may cause disruptions in connections or
+ * connectivity issues when configured.
The Peer connection constraints settings.
+ * @param {String} [options.peerConnection.bundlePolicy] The Peer connection media bundle policy.
+ * - When not provided, its value is BALANCED.
+ * [Rel: Skylink.BUNDLE_POLICY]
+ * @param {String} [options.peerConnection.rtcpMuxPolicy] The Peer connection RTP and RTCP ICE candidates mux policy.
+ * - When not provided, its value is REQUIRE.
+ * [Rel: Skylink.RTCP_MUX_POLICY]
+ * @param {Number} [options.peerConnection.iceCandidatePoolSize=0] The number of ICE candidates to gather before
+ * gathering it when setting local offer / answer session description.
+ * @param {String} [options.peerConnection.certificate] The type of certificate that Peer connection should
+ * generate and use when available.
+ * - When not provided, its value is AUTO.
+ * [Rel: Skylink.PEER_CERTIFICATE]
+ * @param {Boolean|JSON} [options.autoBandwidthAdjustment=false]
+ * Note that this is an experimental feature which may be removed or changed in the future releases.
+ * This feature is also only available for non-MCU enabled Peer connections and Edge Peer connections.
+ *
* @param {Boolean} [options.enableTURNServer=true] The flag if TURN ICE servers should
* be used when constructing Peer connections to allow TURN connections when required and enabled for the App Key.
- * @param {Boolean} [options.enableSTUNServer=true]
- * Note that for Edge browsers, this value is overriden as false due to its supports.
- *
The flag if STUN ICE servers should
+ * @param {Boolean} [options.enableSTUNServer=true] The flag if STUN ICE servers should
* be used when constructing Peer connections to allow TURN connections when required.
* @param {Boolean} [options.forceTURN=false] The flag if Peer connections should enforce
* connections over the TURN server.
@@ -19218,23 +21429,34 @@ Skylink.prototype.generateUUID = function() {
* during request to Auth server and socket connections to Signaling server
* when accessing window.location.protocol value is "http:".
* By default, "https:" protocol connections uses HTTPS connections.
- * @param {String} [options.audioCodec]
+ * @param {String|JSON} [options.audioCodec]
* Note that if the audio codec is not supported, the SDK will not configure the local "offer" or
* "answer" session description to prefer the codec.
* Note that for Edge browsers, this value is set as OPUS due to its supports.
* The option to configure the preferred audio codec to use to encode sending audio data when available for Peer connection.
* - When not provided, its value is AUTO.
* [Rel: Skylink.AUDIO_CODEC]
- * @param {String} [options.videoCodec]
+ * @param {String} options.audioCodec.codec The audio codec to prefer to encode sending audio data when available.
+ * The value must not be AUTO.
+ * [Rel: Skylink.AUDIO_CODEC]
+ * @param {Number} [options.audioCodec.samplingRate] The audio codec sampling to prefer to encode sending audio data when available.
+ * @param {Number} [options.audioCodec.channels] The audio codec channels to prefer to encode sending audio data when available.
+ * @param {String|JSON} [options.videoCodec]
* Note that if the video codec is not supported, the SDK will not configure the local "offer" or
* "answer" session description to prefer the codec.
* Note that for Edge browsers, this value is set as H264 due to its supports.
* The option to configure the preferred video codec to use to encode sending video data when available for Peer connection.
* - When not provided, its value is AUTO.
* [Rel: Skylink.VIDEO_CODEC]
+ * @param {String} options.videoCodec.codec The video codec to prefer to encode sending audio data when available.
+ * The value must not be AUTO.
+ * [Rel: Skylink.VIDEO_CODEC]
+ * @param {Number} [options.videoCodec.samplingRate] The video codec sampling to prefer to encode sending video data when available.
* @param {Number} [options.socketTimeout=20000] The timeout for each attempts for socket connection
* with the Signaling server to indicate that connection has timed out and has failed to establish.
* Note that the mininum timeout value is 5000. If less, this value will be 5000.
+ * Note that it is recommended to use 12000 as the lowest timeout value if Peers are connecting
+ * using Polling transports to prevent connection errors.
* @param {Boolean} [options.forceTURNSSL=false]
* Note that currently Firefox does not support the TURNS protocol, and that if TURNS is required,
* TURN ICE servers using port 443 will be used instead.
@@ -19267,6 +21489,111 @@ Skylink.prototype.generateUUID = function() {
* The flag if
* refreshConnection() method should renegotiate like non-MCU enabled Peer connection for MCU
* enabled Peer connections instead of invoking joinRoom() method again.
+ * @param {String|Array} [options.iceServer] The ICE servers for debugging purposes to use.
+ * - When defined as string, the value is considered as [options.iceServer].
+ * Note that this is a debugging feature and is only used when instructed for debugging purposes.
+ * @param {String} [options.iceServer.#index] The ICE server url for debugging purposes to use.
+ * @param {String|JSON} [options.socketServer] The Signaling server for debugging purposes to use.
+ * - When defined as string, the value is considered as { url: options.socketServer }.
+ * Note that this is a debugging feature and is only used when instructed for debugging purposes.
+ * @param {String} options.socketServer.url The Signaling server URL for debugging purposes to use.
+ * @param {Array} [options.socketServer.ports] The list of Signaling server ports for debugging purposes to use.
+ * If not defined, it will use the default list of ports specified.
+ * @param {Number} options.socketServer.ports.#index The Signaling server port to fallback and use for debugging purposes.
+ * @param {String} [options.socketServer.protocol] The Signaling server protocol for debugging purposes to use.
+ * If not defined, it will use the default protocol specified.
+ * @param {JSON} [options.codecParams]
+ * Note that some of these parameters are mainly used for experimental or debugging purposes. Toggling any of
+ * these feature may result in disruptions in connectivity.
+ * The audio and video codecs parameters to configure.
+ * @param {JSON} [options.codecParams.video] The video codecs parameters to configure.
+ * @param {JSON} [options.codecParams.video.h264] The H264 video codec parameters to configure.
+ * @param {String} [options.codecParams.video.h264.profileLevelId]
+ * Note that this parameter should only be used for debugging purposes only.
+ * The H264 video codec base16 encoded string which indicates the H264 baseline, main, or the extended profiles.
+ * When not provided, the default browser configuration is used.
+ * @param {Boolean} [options.codecParams.video.h264.levelAsymmetryAllowed]
+ * Note that this is an experimental parameter which may result in connectivity issues when toggled.
+ * The flag if streaming H264 sending video data should be encoded at a different level
+ * from receiving video data from Peer encoding to User when Peer is the offerer.
+ * If Peer is the offerer instead of the User, the Peer's peerInfo.config.priorityWeight will be
+ * higher than User's peerInfo.config.priorityWeight.
+ * When not provided, the default browser configuration is used.
+ * @param {Boolean} [options.codecParams.video.h264.packetizationMode]
+ * Note that this is an experimental parameter which may result in connectivity issues when enabled. It is
+ * advisable to turn off this feature off when receiving H264 decoders do not support the packetization mode,
+ * which may result in a blank receiving video stream.
+ * The flag to enable H264 video codec packetization mode, which splits video frames that are larger
+ * for a RTP packet into RTP packet chunks.
+ * When not provided, the default browser configuration is used.
+ * @param {JSON} [options.codecParams.video.vp8] The VP8 video codec parameters to configure.
+ * @param {Number} [options.codecParams.video.vp8.maxFr]
+ * Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
+ * The maximum number of fps (frames per second) that the VP8 video codec decoder is capable of
+ * decoding when receiving encoded video data packets.
+ * When not provided, the default browser configuration is used.
+ * @param {Number} [options.codecParams.video.vp8.maxFs]
+ * Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
+ * The maximum number of frame size macroblocks that the VP8 video codec decoder is capable of
+ * decoding when receiving encoded video data packets.
+ * The value has to have the width and height of the frame in macroblocks less than the value of
+ * parseInt(Math.sqrt(maxFs * 8)). E.g. If the value is 1200, it is capable of
+ * support 640x480 frame width and height, which heights up to 1552px
+ * (97 macroblocks value.
+ * When not provided, the default browser configuration is used.
+ * @param {JSON} [options.codecParams.video.vp9] The VP9 video codec parameters to configure.
+ * @param {Number} [options.codecParams.video.vp9.maxFr]
+ * Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
+ * The maximum number of fps (frames per second) that the VP9 video codec decoder is capable of
+ * decoding when receiving encoded video data packets.
+ * When not provided, the default browser configuration is used.
+ * @param {Number} [options.codecParams.video.vp9.maxFs]
+ * Note that this parameter should only be used for debugging purposes only. Do not toggle this otherwise.
+ * The maximum number of frame size macroblocks that the VP9 video codec decoder is capable of
+ * decoding when receiving encoded video data packets.
+ * The value has to have the width and height of the frame in macroblocks less than the value of
+ * parseInt(Math.sqrt(maxFs * 8)). E.g. If the value is 1200, it is capable of
+ * support 640x480 frame width and height, which heights up to 1552px
+ * (97 macroblocks value.
+ * When not provided, the default browser configuration is used.
+ * @param {JSON} [options.codecParams.audio] The audio codecs parameters to configure.
+ * @param {JSON} [options.codecParams.audio.opus]
+ * Note that this is only applicable to OPUS audio codecs with a sampling rate of 48000 Hz (hertz).
+ *
The OPUS audio codec parameters to configure.
+ * @param {Boolean} [options.codecParams.audio.opus.stereo] The flag if OPUS audio codec stereo band
+ * should be configured for sending encoded audio data.
+ * When not provided, the default browser configuration is used.
+ * @param {Boolean} [options.codecParams.audio.opus.usedtx]
+ * Note that this feature might not work depending on the browser support and implementation.
+ * The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.
+ * This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and
+ * goes hand-in-hand with the options.voiceActivityDetection flag in
+ * joinRoom() method.
+ * When not provided, the default browser configuration is used.
+ * @param {Boolean} [options.codecParams.audio.opus.useinbandfec]
+ * Note that this parameter should only be used for debugging purposes only.
+ * The flag if OPUS audio codec has the capability to take advantage of the in-band FEC
+ * (Forward Error Correction) when sending encoded audio data.
+ * This helps to reduce the harm of packet loss by encoding information about the previous packet loss.
+ * When not provided, the default browser configuration is used.
+ * @param {Number} [options.codecParams.audio.opus.maxplaybackrate]
+ * Note that this parameter should only be used for debugging purposes only.
+ * The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving
+ * decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data
+ * would not encode at a higher sampling rate specified by this.
+ * This value must be between 8000 to 48000.
+ * When not provided, the default browser configuration is used.
+ * @param {Number} [options.codecParams.minptime]
+ * Note that this parameter should only be used for debugging purposes only.
+ * The OPUS audio codec receiving audio data decoder minimum length of time in milleseconds should be
+ * encapsulated in a single received encoded audio data packet.
+ * This value must be between 3 to 120
+ * When not provided, the default browser configuration is used.
+ * @param {String} [options.priorityWeightScheme]
+ * Note that this parameter should only be used for debugging purposes only and may not work when
+ * internals change.
The User's priority weight to enforce User as offerer or answerer.
+ * - When not provided, its value is AUTO.
+ * [Rel: Skylink.PRIORITY_WEIGHT_SCHEME]
* @param {Function} [callback] The callback function fired when request has completed.
* Function parameters signature is function (error, success)
* Function request completion is determined by the
@@ -19279,14 +21606,14 @@ Skylink.prototype.generateUUID = function() {
* @param {Number} callback.error.errorCode The readyStateChange
* eventerror.errorCode parameter payload value.
* [Rel: Skylink.READY_STATE_CHANGE_ERROR]
- * @param {Object} callback.error.error The readyStateChange
+ * @param {Error|String} callback.error.error The readyStateChange
* eventerror.content parameter payload value.
* @param {Number} callback.error.status The readyStateChange
* eventerror.status parameter payload value.
* @param {JSON} callback.success The success result in request.
* Defined as null when there are errors in request
* @param {String} callback.success.serverUrl The constructed REST URL requested to Auth server.
- * @param {String} callback.success.readyState The current ready state.
+ * @param {Number} callback.success.readyState The current ready state.
* [Rel: Skylink.READY_STATE_CHANGE]
* @param {String} callback.success.selectedRoom The Room based on the current Room session token retrieved for.
* @param {String} callback.success.appKey The configured value of the options.appKey.
@@ -19299,8 +21626,8 @@ Skylink.prototype.generateUUID = function() {
* @param {Boolean} callback.success.TURNTransport The configured value of the options.TURNServerTransport.
* @param {Boolean} callback.success.audioFallback The configured value of the options.audioFallback.
* @param {Boolean} callback.success.forceSSL The configured value of the options.forceSSL.
- * @param {String} callback.success.audioCodec The configured value of the options.audioCodec.
- * @param {String} callback.success.videoCodec The configured value of the options.videoCodec.
+ * @param {String|JSON} callback.success.audioCodec The configured value of the options.audioCodec.
+ * @param {String|JSON} callback.success.videoCodec The configured value of the options.videoCodec.
* @param {Number} callback.success.socketTimeout The configured value of the options.socketTimeout.
* @param {Boolean} callback.success.forceTURNSSL The configured value of the options.forceTURNSSL.
* @param {Boolean} callback.success.forceTURN The configured value of the options.forceTURN.
@@ -19309,9 +21636,12 @@ Skylink.prototype.generateUUID = function() {
* @param {Boolean} callback.success.disableComfortNoiseCodec The configured value of the options.disableComfortNoiseCodec.
* @param {Boolean} callback.success.disableREMB The configured value of the options.disableREMB.
* @param {JSON} callback.success.filterCandidatesType The configured value of the options.filterCandidatesType.
- * @param {Number} callback.success.throttleIntervals The configured value of the options.throttleIntervals.
- * @param {Number} callback.success.throttleShouldThrowError The configured value of the options.throttleShouldThrowError.
- * @param {Number} callback.success.mcuUseRenegoRestart The configured value of the options.mcuUseRenegoRestart.
+ * @param {JSON} callback.success.throttleIntervals The configured value of the options.throttleIntervals.
+ * @param {Boolean} callback.success.throttleShouldThrowError The configured value of the options.throttleShouldThrowError.
+ * @param {JSON} callback.success.mcuUseRenegoRestart The configured value of the options.mcuUseRenegoRestart.
+ * @param {JSON} callback.success.iceServer The configured value of the options.iceServer.
+ * See the .urls property in this object for configured value if defined.
+ * @param {JSON|String} callback.success.socketServer The configured value of the options.socketServer.
* @example
* // Example 1: Using CORS authentication and connection to default Room
* skylinkDemo(appKey, function (error, success) {
@@ -19421,6 +21751,13 @@ Skylink.prototype.init = function(options, callback) {
};
var throttleShouldThrowError = false;
var mcuUseRenegoRestart = false;
+ var iceServer = null;
+ var socketServer = null;
+ var codecParams = {
+ audio: { opus: {} },
+ video: { h264: {}, vp8: {}, vp9: {} }
+ };
+ var priorityWeightScheme = self.PRIORITY_WEIGHT_SCHEME.AUTO;
log.log('Provided init options:', options);
@@ -19466,13 +21803,7 @@ Skylink.prototype.init = function(options, callback) {
socketTimeout = (socketTimeout < 5000) ? 5000 : socketTimeout;
// set the force turn ssl always option
forceTURNSSL = (typeof options.forceTURNSSL === 'boolean') ?
- options.forceTURNSSL : forceTURNSSL;
- // set the preferred audio codec
- audioCodec = typeof options.audioCodec === 'string' ?
- options.audioCodec : audioCodec;
- // set the preferred video codec
- videoCodec = typeof options.videoCodec === 'string' ?
- options.videoCodec : videoCodec;
+ options.forceTURNSSL : forceTURNSSL;
// set the force turn server option
forceTURN = (typeof options.forceTURN === 'boolean') ?
options.forceTURN : forceTURN;
@@ -19492,6 +21823,9 @@ Skylink.prototype.init = function(options, callback) {
throttleShouldThrowError = (typeof options.throttleShouldThrowError === 'boolean') ?
options.throttleShouldThrowError : throttleShouldThrowError;
// set the flag if MCU refreshConnection() should use renegotiation
+ mcuUseRenegoRestart = (typeof options.mcuUseRenegoRestart === 'boolean') ?
+ options.mcuUseRenegoRestart : mcuUseRenegoRestart;
+ // set the flag if MCU refreshConnection() should use renegotiation
mcuUseRenegoRestart = (typeof options.mcuUseRenegoRestart === 'boolean') ?
options.mcuUseRenegoRestart : mcuUseRenegoRestart;
// set the use of filtering ICE candidates
@@ -19513,19 +21847,169 @@ Skylink.prototype.init = function(options, callback) {
options.throttleIntervals.getUserMedia : throttleIntervals.getUserMedia;
}
+ // set the Signaling server url for debugging purposes
+ if (options.socketServer) {
+ if (typeof options.socketServer === 'string') {
+ socketServer = options.socketServer;
+ } else if (typeof options.socketServer === 'object' && options.socketServer.url &&
+ typeof options.socketServer.url === 'string') {
+ socketServer = {
+ url: options.socketServer.url,
+ ports: Array.isArray(options.socketServer.ports) && options.socketServer.ports.length > 0 ?
+ options.socketServer.ports : [],
+ protocol: options.socketServer.protocol && typeof options.socketServer.protocol === 'string' ?
+ options.socketServer.protocol : null
+ };
+ }
+ }
+
+ // set the Signaling server url for debugging purposes
+ if (options.iceServer) {
+ iceServer = typeof options.iceServer === 'string' ? { urls: [options.iceServer] } :
+ (Array.isArray(options.iceServer) && options.iceServer.length > 0 &&
+ options.iceServer[0] && typeof options.iceServer[0] === 'string' ? { urls: options.iceServer } : null);
+ }
+
// set turn transport option
if (typeof options.TURNServerTransport === 'string') {
// loop out for every transport option
- for (var type in self.TURN_TRANSPORT) {
- if (self.TURN_TRANSPORT.hasOwnProperty(type)) {
- // do a check if the transport option is valid
- if (self.TURN_TRANSPORT[type] === options.TURNServerTransport) {
- TURNTransport = options.TURNServerTransport;
+ for (var ttType in self.TURN_TRANSPORT) {
+ // do a check if the transport option is valid
+ if (self.TURN_TRANSPORT.hasOwnProperty(ttType) && self.TURN_TRANSPORT[ttType] === options.TURNServerTransport) {
+ TURNTransport = options.TURNServerTransport;
+ break;
+ }
+ }
+ }
+
+ // set the preferred audio codec
+ if (options.audioCodec && ((typeof options.audioCodec === 'string' &&
+ options.audioCodec !== self.AUDIO_CODEC.AUTO) || (typeof options.audioCodec === 'object' &&
+ options.audioCodec.codec && typeof options.audioCodec.codec === 'string' &&
+ options.audioCodec.codec !== self.AUDIO_CODEC.AUTO))) {
+ // loop out for every audio codec option
+ for (var acType in self.AUDIO_CODEC) {
+ // do a check if the audio codec option is valid
+ if (self.AUDIO_CODEC.hasOwnProperty(acType)) {
+ if (typeof options.audioCodec === 'string' && self.AUDIO_CODEC[acType] === options.audioCodec) {
+ audioCodec = options.audioCodec;
+ break;
+ } else if (typeof options.audioCodec === 'object' && self.AUDIO_CODEC[acType] === options.audioCodec.codec) {
+ audioCodec = {
+ codec: options.audioCodec.codec,
+ samplingRate: typeof options.audioCodec.samplingRate === 'number' &&
+ options.audioCodec.samplingRate > 0 ? options.audioCodec.samplingRate : null,
+ channels: typeof options.audioCodec.channels === 'number' &&
+ options.audioCodec.channels > 0 ? options.audioCodec.channels : null
+ };
+ break;
+ }
+ }
+ }
+ }
+
+ // set the preferred video codec
+ if (options.videoCodec && ((typeof options.videoCodec === 'string' &&
+ options.videoCodec !== self.VIDEO_CODEC.AUTO) || (typeof options.videoCodec === 'object' &&
+ options.videoCodec.codec && typeof options.videoCodec.codec === 'string' &&
+ options.videoCodec.codec !== self.VIDEO_CODEC.AUTO))) {
+ // loop out for every video codec option
+ for (var vcType in self.VIDEO_CODEC) {
+ // do a check if the video codec option is valid
+ if (self.VIDEO_CODEC.hasOwnProperty(vcType)) {
+ if (typeof options.videoCodec === 'string' && self.VIDEO_CODEC[vcType] === options.videoCodec) {
+ videoCodec = options.videoCodec;
+ break;
+ } else if (typeof options.videoCodec === 'object' && self.VIDEO_CODEC[vcType] === options.videoCodec.codec) {
+ videoCodec = {
+ codec: options.videoCodec.codec,
+ samplingRate: typeof options.videoCodec.samplingRate === 'number' &&
+ options.videoCodec.samplingRate > 0 ? options.videoCodec.samplingRate : null
+ };
break;
}
}
}
}
+
+ // set the priority weight scheme
+ if (typeof options.priorityWeightScheme === 'string') {
+ // loop out for every transport option
+ for (var pwsType in self.PRIORITY_WEIGHT_SCHEME) {
+ // do a check if the transport option is valid
+ if (self.PRIORITY_WEIGHT_SCHEME.hasOwnProperty(pwsType) &&
+ self.PRIORITY_WEIGHT_SCHEME[pwsType] === options.priorityWeightScheme) {
+ priorityWeightScheme = options.priorityWeightScheme;
+ break;
+ }
+ }
+ }
+
+ // set the codec params
+ if (options.codecParams && typeof options.codecParams === 'object') {
+ // Set audio codecs params
+ if (options.codecParams.audio && typeof options.codecParams.audio === 'object') {
+ // Set the audio codec opus params
+ if (options.codecParams.audio.opus && typeof options.codecParams.audio.opus === 'object') {
+ codecParams.audio.opus = {
+ stereo: typeof options.codecParams.audio.opus.stereo === 'boolean' ?
+ options.codecParams.audio.opus.stereo : null,
+ usedtx: typeof options.codecParams.audio.opus.usedtx === 'boolean' ?
+ options.codecParams.audio.opus.usedtx : null,
+ useinbandfec: typeof options.codecParams.audio.opus.useinbandfec === 'boolean' ?
+ options.codecParams.audio.opus.useinbandfec : null,
+ maxplaybackrate: typeof options.codecParams.audio.opus.maxplaybackrate === 'number' &&
+ options.codecParams.audio.opus.maxplaybackrate >= 8000 &&
+ options.codecParams.audio.opus.maxplaybackrate <= 48000 ?
+ options.codecParams.audio.opus.maxplaybackrate : null,
+ minptime: typeof options.codecParams.audio.opus.minptime === 'number' &&
+ options.codecParams.audio.opus.minptime >= 3 ? options.codecParams.audio.opus.minptime : null
+ };
+ }
+ }
+ // Set video codecs params
+ if (options.codecParams.video && typeof options.codecParams.video === 'object') {
+ // Set the video codec H264 params
+ if (options.codecParams.video.h264 && typeof options.codecParams.video.h264 === 'object') {
+ codecParams.video.h264 = {
+ // Only allowing profile-level-id change for experimental fixes or changes incase..
+ // Strong NOT recommended, this is like an information
+ profileLevelId: options.codecParams.video.h264.profileLevelId &&
+ typeof options.codecParams.video.h264.profileLevelId === 'string' ?
+ options.codecParams.video.h264.profileLevelId : null,
+ levelAsymmetryAllowed: typeof options.codecParams.video.h264.levelAsymmetryAllowed === 'boolean' ?
+ options.codecParams.video.h264.levelAsymmetryAllowed : null,
+ packetizationMode: typeof options.codecParams.video.h264.packetizationMode === 'boolean' ?
+ options.codecParams.video.h264.packetizationMode : null
+ };
+ }
+ // Set the video codec VP8 params
+ if (options.codecParams.video.vp8 && typeof options.codecParams.video.vp8 === 'object') {
+ // Only allowing max-fs, max-fr change for experimental fixes or changes incase..
+ // (NOT used for any other purposes)!!!!
+ // Strong NOT recommended, this is like an information
+ codecParams.video.vp8 = {
+ maxFs: typeof options.codecParams.video.vp8.maxFs === 'number' ?
+ options.codecParams.video.vp8.maxFs : null,
+ maxFr: typeof options.codecParams.video.vp8.maxFr === 'number' ?
+ options.codecParams.video.vp8.maxFr : null
+ };
+ }
+ // Set the video codec VP9 params
+ if (options.codecParams.video.vp9 && typeof options.codecParams.video.vp9 === 'object') {
+ // Only allowing max-fs, max-fr change for experimental fixes or changes incase..
+ // (NOT used for any other purposes)!!!!
+ // Strong NOT recommended, this is like an information
+ codecParams.video.vp9 = {
+ maxFs: typeof options.codecParams.video.vp9.maxFs === 'number' ?
+ options.codecParams.video.vp9.maxFs : null,
+ maxFr: typeof options.codecParams.video.vp9.maxFr === 'number' ?
+ options.codecParams.video.vp9.maxFr : null
+ };
+ }
+ }
+ }
+
// set audio fallback option
audioFallback = options.audioFallback || audioFallback;
// Custom default meeting timing and duration
@@ -19553,11 +22037,8 @@ Skylink.prototype.init = function(options, callback) {
}
if (window.webrtcDetectedBrowser === 'edge') {
- enableSTUNServer = false;
forceTURNSSL = false;
TURNTransport = self.TURN_TRANSPORT.UDP;
- audioCodec = self.AUDIO_CODEC.OPUS;
- videoCodec = self.VIDEO_CODEC.H264;
enableDataChannel = false;
}
@@ -19599,6 +22080,10 @@ Skylink.prototype.init = function(options, callback) {
self._throttlingShouldThrowError = throttleShouldThrowError;
self._disableREMB = disableREMB;
self._mcuUseRenegoRestart = mcuUseRenegoRestart;
+ self._iceServer = iceServer;
+ self._socketServer = socketServer;
+ self._codecParams = codecParams;
+ self._priorityWeightScheme = priorityWeightScheme;
log.log('Init configuration:', {
serverUrl: self._path,
@@ -19626,7 +22111,11 @@ Skylink.prototype.init = function(options, callback) {
filterCandidatesType: self._filterCandidatesType,
throttleIntervals: self._throttlingTimeouts,
throttleShouldThrowError: self._throttlingShouldThrowError,
- mcuUseRenegoRestart: self._mcuUseRenegoRestart
+ mcuUseRenegoRestart: self._mcuUseRenegoRestart,
+ iceServer: self._iceServer,
+ socketServer: self._socketServer,
+ codecParams: self._codecParams,
+ priorityWeightScheme: self._priorityWeightScheme
});
// trigger the readystate
self._readyState = 0;
@@ -19668,7 +22157,11 @@ Skylink.prototype.init = function(options, callback) {
filterCandidatesType: self._filterCandidatesType,
throttleIntervals: self._throttlingTimeouts,
throttleShouldThrowError: self._throttlingShouldThrowError,
- mcuUseRenegoRestart: self._mcuUseRenegoRestart
+ mcuUseRenegoRestart: self._mcuUseRenegoRestart,
+ iceServer: self._iceServer,
+ socketServer: self._socketServer,
+ codecParams: self._codecParams,
+ priorityWeightScheme: self._priorityWeightScheme
});
} else if (readyState === self.READY_STATE_CHANGE.ERROR) {
log.log([null, 'Socket', null, 'Firing callback. ' +
@@ -19788,10 +22281,7 @@ Skylink.prototype._parseInfo = function(info) {
this._key = info.cid;
this._appKeyOwner = info.apiOwner;
-
this._signalingServer = info.ipSigserver;
- this._signalingServerPort = null;
-
this._isPrivileged = info.isPrivileged;
this._autoIntroduce = info.autoIntroduce;
@@ -19899,34 +22389,72 @@ Skylink.prototype._loadInfo = function() {
adapter.webRTCReady(function () {
self._isUsingPlugin = !!adapter.WebRTCPlugin.plugin && !!adapter.WebRTCPlugin.plugin.VERSION;
- if (!window.RTCPeerConnection) {
- log.error('WebRTC not supported. Please upgrade your browser');
+ // Prevent empty object returned when constructing the RTCPeerConnection object
+ if (!(function () {
+ try {
+ var p = new window.RTCPeerConnection(null);
+ // IE returns as typeof object
+ return ['object', 'function'].indexOf(typeof p.createOffer) > -1 && p.createOffer !== null;
+ } catch (e) {
+ return false;
+ }
+ })()) {
+ if (window.RTCPeerConnection && self._isUsingPlugin) {
+ log.error('Plugin is not available. Please check plugin status.');
+ } else {
+ log.error('WebRTC not supported. Please upgrade your browser');
+ }
self._readyState = -1;
self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, {
status: null,
- content: 'WebRTC not available',
+ content: self._isUsingPlugin && window.RTCPeerConnection ? 'Plugin is not available' : 'WebRTC not available',
errorCode: self.READY_STATE_CHANGE_ERROR.NO_WEBRTC_SUPPORT
}, self._selectedRoom);
return;
}
- self._readyState = 1;
- self._trigger('readyStateChange', self.READY_STATE_CHANGE.LOADING, null, self._selectedRoom);
- self._requestServerInfo('GET', self._path, function(status, response) {
- if (status !== 200) {
- // 403 - Room is locked
- // 401 - API Not authorized
- // 402 - run out of credits
- var errorMessage = 'XMLHttpRequest status not OK\nStatus was: ' + status;
- self._readyState = 0;
+
+ self._getCodecsSupport(function (error) {
+ if (error) {
+ log.error(error);
+ self._readyState = -1;
+ self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, {
+ status: null,
+ content: error.message || error.toString(),
+ errorCode: self.READY_STATE_CHANGE_ERROR.PARSE_CODECS
+ }, self._selectedRoom);
+ return;
+ }
+
+ if (Object.keys(self._currentCodecSupport.audio).length === 0 && Object.keys(self._currentCodecSupport.video).length === 0) {
+ log.error('No audio/video codecs available to start connection.');
+ self._readyState = -1;
self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, {
- status: status,
- content: (response) ? (response.info || errorMessage) : errorMessage,
- errorCode: response.error ||
- self.READY_STATE_CHANGE_ERROR.INVALID_XMLHTTPREQUEST_STATUS
+ status: null,
+ content: 'No audio/video codecs available to start connection',
+ errorCode: self.READY_STATE_CHANGE_ERROR.PARSE_CODECS
}, self._selectedRoom);
return;
}
- self._parseInfo(response);
+
+ self._readyState = 1;
+ self._trigger('readyStateChange', self.READY_STATE_CHANGE.LOADING, null, self._selectedRoom);
+ self._requestServerInfo('GET', self._path, function(status, response) {
+ if (status !== 200) {
+ // 403 - Room is locked
+ // 401 - API Not authorized
+ // 402 - run out of credits
+ var errorMessage = 'XMLHttpRequest status not OK\nStatus was: ' + status;
+ self._readyState = 0;
+ self._trigger('readyStateChange', self.READY_STATE_CHANGE.ERROR, {
+ status: status,
+ content: (response) ? (response.info || errorMessage) : errorMessage,
+ errorCode: response.error ||
+ self.READY_STATE_CHANGE_ERROR.INVALID_XMLHTTPREQUEST_STATUS
+ }, self._selectedRoom);
+ return;
+ }
+ self._parseInfo(response);
+ });
});
});
};
@@ -19968,7 +22496,11 @@ Skylink.prototype._initSelectedRoom = function(room, callback) {
filterCandidatesType: self._filterCandidatesType,
throttleIntervals: self._throttlingTimeouts,
throttleShouldThrowError: self._throttlingShouldThrowError,
- mcuUseRenegoRestart: self._mcuUseRenegoRestart
+ mcuUseRenegoRestart: self._mcuUseRenegoRestart,
+ iceServer: self._iceServer ? self._iceServer.urls : null,
+ socketServer: self._socketServer ? self._socketServer : null,
+ codecParams: self._codecParams ? self._codecParams : null,
+ priorityWeightScheme: self._priorityWeightScheme ? self._priorityWeightScheme : null
};
if (self._roomCredentials) {
initOptions.credentials = {
@@ -20153,7 +22685,7 @@ var _printAllStoredLogsFn = function () {
* @for Skylink
* @since 0.5.5
*/
-window.SkylinkLogs = {
+var SkylinkLogs = {
/**
* Function that gets the current stored SDK console logs.
* @property SkylinkLogs.getLogs
@@ -20408,6 +22940,13 @@ var _eventsDocs = {
/**
* Event triggered when socket connection to Signaling server has opened.
* @event channelOpen
+ * @param {JSON} session The socket connection session information.
+ * @param {String} session.serverUrl The socket connection Signaling url used.
+ * @param {String} session.transportType The socket connection transport type used.
+ * @param {JSON} session.socketOptions The socket connection options.
+ * @param {Number} session.attempts The socket connection current reconnection attempts.
+ * @param {Number} session.finalAttempts The socket connection current last attempts
+ * for the last available transports and port.
* @for Skylink
* @since 0.1.0
*/
@@ -20416,6 +22955,9 @@ var _eventsDocs = {
/**
* Event triggered when socket connection to Signaling server has closed.
* @event channelClose
+ * @param {JSON} session The socket connection session information.
+ * Object signature matches the session parameter payload received in the
+ * channelOpen event.
* @for Skylink
* @since 0.1.0
*/
@@ -20428,6 +22970,9 @@ var _eventsDocs = {
* Event triggered when receiving socket message from the Signaling server.
* @event channelMessage
* @param {JSON} message The socket message object.
+ * @param {JSON} session The socket connection session information.
+ * Object signature matches the session parameter payload received in the
+ * channelOpen event.
* @for Skylink
* @since 0.1.0
*/
@@ -20442,6 +22987,9 @@ var _eventsDocs = {
* Event triggered when socket connection encountered exception.
* @event channelError
* @param {Error|String} error The error object.
+ * @param {JSON} session The socket connection session information.
+ * Object signature matches the session parameter payload received in the
+ * channelOpen event.
* @for Skylink
* @since 0.1.0
*/
@@ -20452,7 +23000,10 @@ var _eventsDocs = {
* @event channelRetry
* @param {String} fallbackType The current fallback state.
* [Rel: Skylink.SOCKET_FALLBACK]
- * @param {Number} currentAttempt The current reconnection attempt.
+ * @param {Number} currentAttempt The current socket reconnection attempt.
+ * @param {JSON} session The socket connection session information.
+ * Object signature matches the session parameter payload received in the
+ * channelOpen event.
* @for Skylink
* @since 0.5.6
*/
@@ -20466,6 +23017,9 @@ var _eventsDocs = {
* @param {Error|String|Number} error The error object.
* @param {String} type The fallback state of the socket connection attempt.
* [Rel: Skylink.SOCKET_FALLBACK]
+ * @param {JSON} session The socket connection session information.
+ * Object signature matches the session parameter payload received in the
+ * channelOpen event.
* @for Skylink
* @since 0.5.5
*/
@@ -20637,6 +23191,12 @@ var _eventsDocs = {
* @param {JSON} peerInfo The Peer session information.
* @param {JSON|String} peerInfo.userData The Peer current custom data.
* @param {JSON} peerInfo.settings The Peer sending Stream settings.
+ * @param {Boolean|JSON} peerInfo.settings.data The flag if Peer has any Datachannel connections enabled.
+ * If isSelf value is true, this determines if User allows
+ * Datachannel connections, else if value is false, this determines if Peer has any active
+ * Datachannel connections (where dataChannelState event
+ * triggers state as OPEN and channelType as
+ * MESSAGING for Peer) with Peer.
* @param {Boolean|JSON} peerInfo.settings.audio The Peer Stream audio settings.
* When defined as false, it means there is no audio being sent from Peer.
* When defined as true, the peerInfo.settings.audio.stereo value is
@@ -20724,6 +23284,8 @@ var _eventsDocs = {
* Data may be accessing OS platform version from Web SDK.
* @param {String} [peerInfo.agent.pluginVersion] The Peer Temasys Plugin version.
* Defined only when Peer is using the Temasys Plugin (IE / Safari).
+ * @param {String} peerInfo.agent.DTProtocolVersion The Peer data transfer (DT) protocol version.
+ * @param {String} peerInfo.agent.SMProtocolVersion The Peer signaling message (SM) protocol version.
* @param {String} peerInfo.room The Room Peer is from.
* @param {JSON} peerInfo.config The Peer connection configuration.
* @param {Boolean} peerInfo.config.enableIceTrickle The flag if Peer connection has
@@ -20851,14 +23413,14 @@ var _eventsDocs = {
* @param {String} peerId The Peer ID.
* @param {JSON} transferInfo The data transfer information.
* Object signature matches the transferInfo parameter payload received in the
- * dataTransferState event.
+ * dataTransferState event
+ * except without the data property.
* @param {Boolean} isSelf The flag if Peer is User.
* @for Skylink
* @since 0.6.1
*/
incomingData: [],
-
/**
* Event triggered when receiving upload data transfer from Peer.
* @event incomingDataRequest
@@ -20866,13 +23428,63 @@ var _eventsDocs = {
* @param {String} peerId The Peer ID.
* @param {String} transferInfo The data transfer information.
* Object signature matches the transferInfo parameter payload received in the
- * dataTransferState event.
+ * dataTransferState event
+ * except without the data property.
* @param {Boolean} isSelf The flag if Peer is User.
* @for Skylink
* @since 0.6.1
*/
incomingDataRequest: [],
+ /**
+ * Event triggered when data streaming session has been started from Peer to User.
+ * @event incomingDataStreamStarted
+ * @param {String} streamId The data streaming session ID.
+ * @param {String} peerId The Peer ID.
+ * @param {JSON} streamInfo The data streaming session information.
+ * Object signature matches the streamInfo parameter payload received in the
+ * dataStreamState event
+ * except without the chunk property.
+ * @param {Boolean} isSelf The flag if Peer is User.
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+ incomingDataStreamStarted: [],
+
+ /**
+ * Event triggered when data streaming session has been stopped from Peer to User.
+ * @event incomingDataStreamStopped
+ * @param {String} streamId The data streaming session ID.
+ * @param {String} peerId The Peer ID.
+ * @param {JSON} streamInfo The data streaming session information.
+ * Object signature matches the streamInfo parameter payload received in the
+ * dataStreamState event
+ * except without the chunk property.
+ * @param {Boolean} isSelf The flag if Peer is User.
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+ incomingDataStreamStopped: [],
+
+ /**
+ * Event triggered when data streaming session has been stopped from Peer to User.
+ * @event incomingDataStream
+ * @param {Blob|String} chunk The data chunk received.
+ * @param {String} streamId The data streaming session ID.
+ * @param {String} peerId The Peer ID.
+ * @param {JSON} streamInfo The data streaming session information.
+ * Object signature matches the streamInfo parameter payload received in the
+ * dataStreamState event
+ * except without the chunk property.
+ * @param {Boolean} isSelf The flag if Peer is User.
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+ incomingDataStream: [],
+
/**
* Event triggered when Room locked status has changed.
* @event roomLock
@@ -20901,6 +23513,9 @@ var _eventsDocs = {
* @param {String} messageType The Datachannel sending Datachannel message error type.
* Defined only when state payload is SEND_MESSAGE_ERROR.
* [Rel: Skylink.DATA_CHANNEL_MESSAGE_ERROR]
+ * @param {JSON} bufferAmount The Datachannel buffered amount information.
+ * @param {Number} bufferAmount.bufferedAmountLow The size of currently queued data to send on the Datachannel connection.
+ * @param {Number} bufferAmount.bufferedAmountLowThreshold The current buffered amount low threshold configured.
* @for Skylink
* @since 0.1.0
*/
@@ -20912,7 +23527,10 @@ var _eventsDocs = {
* @param {String} state The current data transfer state.
* [Rel: Skylink.DATA_TRANSFER_STATE]
* @param {String} transferId The data transfer ID.
+ * Note that this is defined as null when state payload is START_ERROR.
* @param {String} peerId The Peer ID.
+ * Note that this could be defined as null when state payload is
+ * START_ERROR and there is no Peers to start data transfer with.
* @param {JSON} transferInfo The data transfer information.
* @param {Blob|String} [transferInfo.data] The data object.
* Defined only when state payload is UPLOAD_STARTED or
@@ -20933,7 +23551,7 @@ var _eventsDocs = {
* data object sent MIME type information is defined.
* @param {Number} transferInfo.chunkSize The data transfer data chunk size.
* @param {Number} transferInfo.percentage The data transfer percentage of completion progress.
- * @param {Number} transferInfo.timeout The flag if message is targeted or not, basing
+ * @param {Number} transferInfo.timeout The flag if data transfer is targeted or not, basing
* off the targetPeerId parameter being defined in
* sendURLData() method or
* sendBlobData() method.
@@ -20945,7 +23563,7 @@ var _eventsDocs = {
* [Rel: Skylink.DATA_TRANSFER_TYPE]
* @param {JSON} [error] The error result.
* Defined only when state payload is ERROR, CANCEL,
- * REJECTED or USER_REJECTED.
+ * REJECTED, START_ERROR or USER_REJECTED.
* @param {Error|String} error.message The error object.
* @param {String} error.transferType The data transfer direction from where the error occurred.
* [Rel: Skylink.DATA_TRANSFER_TYPE]
@@ -20954,6 +23572,37 @@ var _eventsDocs = {
*/
dataTransferState: [],
+ /**
+ * Event triggered when a data streaming state has changed.
+ * @event dataStreamState
+ * @param {String} state The current data streaming state.
+ * [Rel: Skylink.DATA_STREAM_STATE]
+ * @param {String} streamId The data streaming session ID.
+ * Note that this is defined as null when state payload is START_ERROR.
+ * @param {String} peerId The Peer ID.
+ * Note that this could be defined as null when state payload is
+ * START_ERROR and there is no Peers to start data streaming with.
+ * @param {JSON} streamInfo The data streaming information.
+ * @param {Blob|String} [streamInfo.chunk] The data chunk received.
+ * Defined only when state payload is RECEIVED or SENT.
+ * @param {Number} streamInfo.chunkSize The data streaming data chunk size received.
+ * @param {String} streamInfo.chunkType The data streaming data chunk type received.
+ * The initial data chunks value may change depending on the currently received data chunk type or the
+ * agent supported sending type of data chunks.
+ * [Rel: Skylink.DATA_TRANSFER_DATA_TYPE]
+ * @param {String} streamInfo.isStringStream The flag if data streaming data chunks are strings.
+ * @param {Boolean} streamInfo.isPrivate The flag if data streaming is targeted or not, basing
+ * off the targetPeerId parameter being defined in
+ * startStreamingData() method.
+ * @param {String} streamInfo.senderPeerId The sender Peer ID.
+ * @param {Error} [error] The error object.
+ * Defined only when state payload is ERROR or START_ERROR,.
+ * @beta
+ * @for Skylink
+ * @since 0.6.18
+ */
+ dataStreamState: [],
+
/**
* Event triggered when Signaling server reaction state has changed.
* @event systemAction
@@ -21099,14 +23748,26 @@ var _eventsDocs = {
* Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
* @param {Number} stats.audio.sending.packets The Peer connection current sending audio streaming packets.
* @param {Number} stats.audio.sending.totalPackets The Peer connection total sending audio streaming packets.
- * @param {Number} stats.audio.sending.packetsLost The Peer connection current sending audio streaming packets lost.
- * @param {Number} stats.audio.sending.totalPacketsLost The Peer connection total sending audio streaming packets lost.
+ * @param {Number} stats.audio.sending.packetsLost
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in sending property.
+ *
The Peer connection current sending audio streaming packets lost.
+ * @param {Number} stats.audio.sending.totalPacketsLost
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in sending property.
+ *
The Peer connection total sending audio streaming packets lost.
* @param {Number} stats.audio.sending.ssrc The Peer connection sending audio streaming RTP packets SSRC.
* @param {Number} stats.audio.sending.rtt The Peer connection sending audio streaming RTT (Round-trip delay time).
* Defined as 0 if it's not present in original raw stats before parsing.
- * @param {Number} stats.audio.sending.jitter The Peer connection sending audio streaming RTP packets jitter in seconds.
+ * @param {Number} stats.audio.sending.jitter
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in sending property.
+ *
The Peer connection sending audio streaming RTP packets jitter in seconds.
* Defined as 0 if it's not present in original raw stats before parsing.
- * @param {Number} [stats.audio.sending.jitterBufferMs] The Peer connection sending audio streaming
+ * @param {Number} [stats.audio.sending.jitterBufferMs]
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in sending property.
+ *
The Peer connection sending audio streaming
* RTP packets jitter buffer in miliseconds.
* Defined as null if it's not available in original raw stats before parsing.
* @param {JSON} [stats.audio.sending.codec] The Peer connection sending audio streaming selected codec information.
@@ -21137,7 +23798,10 @@ var _eventsDocs = {
* @param {Number} stats.audio.receiving.packets The Peer connection current receiving audio streaming packets.
* @param {Number} stats.audio.receiving.totalPackets The Peer connection total receiving audio streaming packets.
* @param {Number} stats.audio.receiving.packetsLost The Peer connection current receiving audio streaming packets lost.
+ * @param {Number} stats.audio.receiving.fractionLost The Peer connection current receiving audio streaming fraction packets lost.
+ * @param {Number} stats.audio.receiving.packetsDiscarded The Peer connection current receiving audio streaming packets discarded.
* @param {Number} stats.audio.receiving.totalPacketsLost The Peer connection total receiving audio streaming packets lost.
+ * @param {Number} stats.audio.receiving.totalPacketsDiscarded The Peer connection total receiving audio streaming packets discarded.
* @param {Number} stats.audio.receiving.ssrc The Peer connection receiving audio streaming RTP packets SSRC.
* @param {Number} stats.audio.receiving.jitter The Peer connection receiving audio streaming RTP packets jitter in seconds.
* Defined as 0 if it's not present in original raw stats before parsing.
@@ -21169,15 +23833,28 @@ var _eventsDocs = {
* Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
* @param {Number} stats.video.sending.packets The Peer connection current sending video streaming packets.
* @param {Number} stats.video.sending.totalPackets The Peer connection total sending video streaming packets.
- * @param {Number} stats.video.sending.packetsLost The Peer connection current sending video streaming packets lost.
- * @param {Number} stats.video.sending.totalPacketsLost The Peer connection total sending video streaming packets lost.
+ * @param {Number} stats.video.sending.packetsLost
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in sending property.
+ *
The Peer connection current sending video streaming packets lost.
+ * @param {Number} stats.video.sending.totalPacketsLost
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in sending property.
+ *
The Peer connection total sending video streaming packets lost.
* @param {Number} stats.video.sending.ssrc The Peer connection sending video streaming RTP packets SSRC.
* @param {Number} stats.video.sending.rtt The Peer connection sending video streaming RTT (Round-trip delay time).
* Defined as 0 if it's not present in original raw stats before parsing.
- * @param {Number} stats.video.sending.jitter The Peer connection sending video streaming RTP packets jitter in seconds.
+ * @param {Number} stats.video.sending.jitter
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in sending property.
+ *
The Peer connection sending video streaming RTP packets jitter in seconds.
* Defined as 0 if it's not present in original raw stats before parsing.
- * @param {Number} [stats.video.sending.jitterBufferMs] The Peer connection sending video streaming
- * RTP packets jitter buffer in miliseconds.
+ * @param {Number} [stats.video.sending.jitterBufferMs]
+ * This property has been deprecated and would be removed in future releases
+ * as it should not be in sending property.
+ *
The Peer connection sending video streaming RTP packets jitter buffer in miliseconds.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.sending.qpSum] The Peer connection sending video streaming sum of the QP values of frames passed.
* Defined as null if it's not available in original raw stats before parsing.
* @param {JSON} [stats.video.sending.codec] The Peer connection sending video streaming selected codec information.
* Defined as null if local session description is not available before parsing.
@@ -21194,7 +23871,9 @@ var _eventsDocs = {
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.sending.frames] The Peer connection sending video streaming frames.
* Defined as null if it's not available in original raw stats before parsing.
- * @param {Number} [stats.video.sending.framesInput] The Peer connection sending video streaming frames input.
+ * @param {Number} [stats.video.sending.frameRateInput] The Peer connection sending video streaming fps input.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.sending.frameRateInput] The Peer connection sending video streaming fps input.
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.sending.framesDropped] The Peer connection sending video streaming frames dropped.
* Defined as null if it's not available in original raw stats before parsing.
@@ -21202,6 +23881,14 @@ var _eventsDocs = {
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.sending.frameRateStdDev] The Peer connection sending video streaming fps standard deviation.
* Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.sending.framesPerSecond] The Peer connection sending video streaming fps.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.sending.framesDecoded] The Peer connection sending video streaming frames decoded.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.sending.framesCorrupted] The Peer connection sending video streaming frames corrupted.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.sending.totalFrames] The Peer connection total sending video streaming frames.
+ * Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.sending.nacks] The Peer connection current sending video streaming nacks.
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.sending.totalNacks] The Peer connection total sending video streaming nacks.
@@ -21214,6 +23901,10 @@ var _eventsDocs = {
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.sending.totalFirs] The Peer connection total sending video streaming firs.
* Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.sending.slis] The Peer connection current sending video streaming slis.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.sending.totalSlis] The Peer connection total sending video streaming slis.
+ * Defined as null if it's not available in original raw stats before parsing.
* @param {JSON} stats.video.receiving The Peer connection receiving video streaming stats.
* @param {Number} stats.video.receiving.bytes The Peer connection current receiving video streaming bytes.
* Note that value is in bytes so you have to convert that to bits for displaying for an example kbps.
@@ -21222,9 +23913,12 @@ var _eventsDocs = {
* @param {Number} stats.video.receiving.packets The Peer connection current receiving video streaming packets.
* @param {Number} stats.video.receiving.totalPackets The Peer connection total receiving video streaming packets.
* @param {Number} stats.video.receiving.packetsLost The Peer connection current receiving video streaming packets lost.
+ * @param {Number} stats.video.receiving.fractionLost The Peer connection current receiving video streaming fraction packets lost.
+ * @param {Number} stats.video.receiving.packetsDiscarded The Peer connection current receiving video streaming packets discarded.
* @param {Number} stats.video.receiving.totalPacketsLost The Peer connection total receiving video streaming packets lost.
+ * @param {Number} stats.video.receiving.totalPacketsDiscarded The Peer connection total receiving video streaming packets discarded.
* @param {Number} stats.video.receiving.ssrc The Peer connection receiving video streaming RTP packets SSRC.
- * @param {Number} stats.video.receiving.e2eDelay The Peer connection receiving video streaming e2e delay.
+ * @param {Number} [stats.video.receiving.e2eDelay] The Peer connection receiving video streaming e2e delay.
* Defined as null if it's not present in original raw stats before parsing, and that
* it finds any existing audio, video or object (plugin) DOM elements that has set with the
* Peer remote stream object to parse current time. Note that document.getElementsByTagName function
@@ -21251,7 +23945,7 @@ var _eventsDocs = {
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.receiving.frames] The Peer connection receiving video streaming frames.
* Defined as null if it's not available in original raw stats before parsing.
- * @param {Number} [stats.video.receiving.framesOutput] The Peer connection receiving video streaming frames output.
+ * @param {Number} [stats.video.receiving.framesOutput] The Peer connection receiving video streaming fps output.
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.receiving.framesDecoded] The Peer connection receiving video streaming frames decoded.
* Defined as null if it's not available in original raw stats before parsing.
@@ -21259,18 +23953,30 @@ var _eventsDocs = {
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.receiving.frameRateStdDev] The Peer connection receiving video streaming fps standard deviation.
* Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.receiving.framesPerSecond] The Peer connection receiving video streaming fps.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.receiving.framesDecoded] The Peer connection receiving video streaming frames decoded.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.receiving.framesCorrupted] The Peer connection receiving video streaming frames corrupted.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.receiving.totalFrames] The Peer connection total receiving video streaming frames.
+ * Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.receiving.nacks] The Peer connection current receiving video streaming nacks.
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.receiving.totalNacks] The Peer connection total receiving video streaming nacks.
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.receiving.plis] The Peer connection current receiving video streaming plis.
* Defined as null if it's not available in original raw stats before parsing.
- * @param {Number} [stats.video.receiving.totalPlis] The Peer connection totally receiving video streaming plis.
+ * @param {Number} [stats.video.receiving.totalPlis] The Peer connection total receiving video streaming plis.
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.receiving.firs] The Peer connection current receiving video streaming firs.
* Defined as null if it's not available in original raw stats before parsing.
* @param {Number} [stats.video.receiving.totalFirs] The Peer connection total receiving video streaming firs.
* Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.receiving.slis] The Peer connection current receiving video streaming slis.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Number} [stats.video.receiving.totalPlis] The Peer connection total receiving video streaming slis.
+ * Defined as null if it's not available in original raw stats before parsing.
* @param {JSON} stats.selectedCandidate The Peer connection selected ICE candidate pair stats.
* @param {JSON} stats.selectedCandidate.local The Peer connection selected local ICE candidate.
* @param {String} stats.selectedCandidate.local.ipAddress The Peer connection selected
@@ -21281,6 +23987,10 @@ var _eventsDocs = {
* local ICE candidate IP transport type.
* @param {String} stats.selectedCandidate.local.candidateType The Peer connection selected
* local ICE candidate type.
+ * @param {String} [stats.selectedCandidate.local.turnMediaTransport] The Peer connection possible
+ * transport used when relaying local media to TURN server.
+ * Types are "UDP" (UDP connections), "TCP" (TCP connections) and
+ * "TCP/TLS" (TCP over TLS connections).
* @param {JSON} stats.selectedCandidate.remote The Peer connection selected remote ICE candidate.
* @param {String} stats.selectedCandidate.remote.ipAddress The Peer connection selected
* remote ICE candidate IP address.
@@ -21290,6 +24000,73 @@ var _eventsDocs = {
* remote ICE candidate IP transport type.
* @param {String} stats.selectedCandidate.remote.candidateType The Peer connection selected
* remote ICE candidate type.
+ * @param {Boolean} [stats.selectedCandidate.writable] The flag if Peer has gotten ACK to an ICE request.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {Boolean} [stats.selectedCandidate.readable] The flag if Peer has gotten a valid incoming ICE request.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.rtt] The current STUN connectivity checks RTT (Round-trip delay time).
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.totalRtt] The total STUN connectivity checks RTT (Round-trip delay time).
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {JSON} stats.selectedCandidate.requests The ICE connectivity check requests.
+ * @param {String} [stats.selectedCandidate.requests.received] The current ICE connectivity check requests received.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.requests.sent] The current ICE connectivity check requests sent.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.requests.totalReceived] The total ICE connectivity check requests received.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.requests.totalSent] The total ICE connectivity check requests sent.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {JSON} stats.selectedCandidate.responses The ICE connectivity check responses.
+ * @param {String} [stats.selectedCandidate.responses.received] The current ICE connectivity check responses received.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.responses.sent] The current ICE connectivity check responses sent.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.responses.totalReceived] The total ICE connectivity check responses received.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.responses.totalSent] The total ICE connectivity check responses sent.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {JSON} stats.selectedCandidate.consentRequests The current ICE consent requests.
+ * @param {String} [stats.selectedCandidate.consentRequests.received] The current ICE consent requests received.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.consentRequests.sent] The current ICE consent requests sent.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.consentRequests.totalReceived] The total ICE consent requests received.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.consentRequests.totalSent] The total ICE consent requests sent.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {JSON} stats.selectedCandidate.consentResponses The current ICE consent responses.
+ * @param {String} [stats.selectedCandidate.consentResponses.received] The current ICE consent responses received.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.consentResponses.sent] The current ICE consent responses sent.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.consentResponses.totalReceived] The total ICE consent responses received.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.selectedCandidate.consentResponses.totalSent] The total ICE consent responses sent.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {JSON} stats.certificate The Peer connection DTLS/SRTP exchanged certificates information.
+ * @param {JSON} stats.certificate.local The Peer connection local certificate information.
+ * @param {String} [stats.certificate.local.fingerprint] The Peer connection local certificate fingerprint.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.certificate.local.fingerprintAlgorithm] The Peer connection local
+ * certificate fingerprint algorithm.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.certificate.local.derBase64] The Peer connection local
+ * base64 certificate in binary DER format encoded in base64.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {JSON} stats.certificate.remote The Peer connection remote certificate information.
+ * @param {String} [stats.certificate.remote.fingerprint] The Peer connection remote certificate fingerprint.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.certificate.remote.fingerprintAlgorithm] The Peer connection remote
+ * certificate fingerprint algorithm.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.certificate.remote.derBase64] The Peer connection remote
+ * base64 certificate in binary DER format encoded in base64.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.certificate.srtpCipher] The certificates SRTP cipher.
+ * Defined as null if it's not available in original raw stats before parsing.
+ * @param {String} [stats.certificate.dtlsCipher] The certificates DTLS cipher.
+ * Defined as null if it's not available in original raw stats before parsing.
* @param {JSON} stats.connection The Peer connection object stats.
* @param {String} stats.connection.iceConnectionState The Peer connection ICE connection state.
* @param {String} stats.connection.iceGatheringState The Peer connection ICE gathering state.
@@ -21383,6 +24160,9 @@ var _eventsDocs = {
* @param {String} stats.connection.dataChannels.#channelName.currentTransferId The Peer connection
* Datachannel connection current progressing transfer session ID.
* Defined as null when there is currently no transfer session progressing on the Datachannel connection.
+ * @param {String} stats.connection.dataChannels.#channelName.currentStreamId The Peer connection
+ * Datachannel connection current data streaming session ID.
+ * Defined as null when there is currently no data streaming session on the Datachannel connection.
* @param {Error} error The error object received.
* Defined only when state payload is RETRIEVE_ERROR.
* @for Skylink
@@ -21433,7 +24213,26 @@ var _eventsDocs = {
* @for Skylink
* @since 0.6.16
*/
- candidateProcessingState: []
+ candidateProcessingState: [],
+
+ /**
+ *
+ * Learn more about how ICE works in this
+ * article here.
+ * Note that this event may not be triggered for MCU enabled Peer connections as ICE candidates
+ * may be received in the session description instead.
+ *
+ * Event triggered when all remote ICE candidates gathering has completed and been processed.
+ * @event candidatesGathered
+ * @param {String} peerId The Peer ID.
+ * @param {JSON} length The remote ICE candidates length.
+ * @param {Number} length.expected The expected total number of remote ICE candidates to be received.
+ * @param {Number} length.received The actual total number of remote ICE candidates received.
+ * @param {Number} length.processed The total number of remote ICE candidates processed.
+ * @for Skylink
+ * @since 0.6.18
+ */
+ candidatesGathered: []
};
/**
@@ -21507,9 +24306,6 @@ Skylink.prototype.once = function(eventName, callback, condition, fireAlways) {
} : condition;
if (typeof callback === 'function') {
-
- this._EVENTS[eventName] = this._EVENTS[eventName] || [];
- // prevent undefined error
this._onceEvents[eventName] = this._onceEvents[eventName] || [];
this._onceEvents[eventName].push([callback, condition, fireAlways]);
log.log([null, 'Event', eventName, 'Event is subscribed on condition']);
@@ -21521,7 +24317,8 @@ Skylink.prototype.once = function(eventName, callback, condition, fireAlways) {
/**
* Function that unsubscribes listeners from an event.
* @method off
- * @param {String} eventName The event.
+ * @param {String} [eventName] The event.
+ * - When not provided, all listeners to all events will be unsubscribed.
* @param {Function} [callback] The listener to unsubscribe.
* - When not provided, all listeners associated to the event will be unsubscribed.
* @example
@@ -21538,32 +24335,37 @@ Skylink.prototype.once = function(eventName, callback, condition, fireAlways) {
* @since 0.5.5
*/
Skylink.prototype.off = function(eventName, callback) {
- if (callback === undefined) {
- this._EVENTS[eventName] = [];
- this._onceEvents[eventName] = [];
- log.log([null, 'Event', eventName, 'All events are unsubscribed']);
- return;
- }
- var arr = this._EVENTS[eventName];
- var once = this._onceEvents[eventName];
-
- // unsubscribe events that is triggered always
- for (var i = 0; i < arr.length; i++) {
- if (arr[i] === callback) {
- log.log([null, 'Event', eventName, 'Event is unsubscribed']);
- arr.splice(i, 1);
- break;
+ if (!(eventName && typeof eventName === 'string')) {
+ this._EVENTS = {};
+ this._onceEvents = {};
+ } else {
+ if (callback === undefined) {
+ this._EVENTS[eventName] = [];
+ this._onceEvents[eventName] = [];
+ log.log([null, 'Event', eventName, 'All events are unsubscribed']);
+ return;
}
- }
- // unsubscribe events fired only once
- if(once !== undefined) {
- for (var j = 0; j < once.length; j++) {
- if (once[j][0] === callback) {
- log.log([null, 'Event', eventName, 'One-time Event is unsubscribed']);
- once.splice(j, 1);
+ var arr = this._EVENTS[eventName] || [];
+ var once = this._onceEvents[eventName] || [];
+
+ // unsubscribe events that is triggered always
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] === callback) {
+ log.log([null, 'Event', eventName, 'Event is unsubscribed']);
+ arr.splice(i, 1);
break;
}
}
+ // unsubscribe events fired only once
+ if(once !== undefined) {
+ for (var j = 0; j < once.length; j++) {
+ if (once[j][0] === callback) {
+ log.log([null, 'Event', eventName, 'One-time Event is unsubscribed']);
+ once.splice(j, 1);
+ break;
+ }
+ }
+ }
}
};
@@ -21615,7 +24417,6 @@ Skylink.prototype._trigger = function(eventName) {
}
}
}
-
log.log([null, 'Event', eventName, 'Event is triggered']);
};
@@ -21727,7 +24528,7 @@ Skylink.prototype.SOCKET_ERROR = {
* @param {String} LONG_POLLING Value "fallbackLongPollingNonSSL"
* The value of the reconnection state when joinRoom() socket connection is reconnecting with
* another new HTTP port using Polling transports to attempt to establish connection with Signaling server.
- * @param {String} LONG_POLLING Value "fallbackLongPollingSSL"
+ * @param {String} LONG_POLLING_SSL Value "fallbackLongPollingSSL"
* The value of the reconnection state when joinRoom() socket connection is reconnecting with
* another new HTTPS port using Polling transports to attempt to establish connection with Signaling server.
* @type JSON
@@ -21756,7 +24557,7 @@ Skylink.prototype._sendChannelMessage = function(message) {
var throughput = 16;
if (!self._channelOpen || !self._user || !self._socket) {
- log.warn([null, 'Socket', null, 'Dropping of message as Socket connection is not opened or is at ' +
+ log.warn([message.target || 'Server', 'Socket', message.type, 'Dropping of message as Socket connection is not opened or is at ' +
'incorrect step ->'], message);
return;
}
@@ -21822,10 +24623,6 @@ Skylink.prototype._sendChannelMessage = function(message) {
isDataChannel: false,
senderPeerId: self._user.sid
}, self._user.sid, self.getPeerInfo(), true);
-
- } else if (eventMessage.type === self._SIG_MESSAGE_TYPE.ROOM_LOCK) {
- self._roomLocked = !!eventMessage.lock;
- self._trigger('roomLock', !!eventMessage.lock, self._user.sid, self.getPeerInfo(), true);
}
};
@@ -21833,7 +24630,7 @@ Skylink.prototype._sendChannelMessage = function(message) {
self._socketMessageTimeout = null;
if (!self._channelOpen || !(self._user && self._user.sid) || !self._socket) {
- log.warn([null, 'Socket', null, 'Dropping of group messages as Socket connection is not opened or is at ' +
+ log.warn([message.target || 'Server', 'Socket', null, 'Dropping of group messages as Socket connection is not opened or is at ' +
'incorrect step ->'], groupMessageList);
return;
}
@@ -21870,7 +24667,8 @@ Skylink.prototype._sendChannelMessage = function(message) {
groupMessageList[i].stamp < stamps.audioMuted) ||
(groupMessageList[i].type === self._SIG_MESSAGE_TYPE.MUTE_VIDEO &&
groupMessageList[i].stamp < stamps.videoMuted)) {
- log.warn([null, 'Socket', null, 'Dropping of outdated status message ->'], clone(groupMessageList[i]));
+ log.warn([message.target || 'Server', 'Socket', groupMessageList[i], 'Dropping of outdated status message ->'],
+ clone(groupMessageList[i]));
groupMessageList.splice(i, 1);
i--;
continue;
@@ -21886,7 +24684,8 @@ Skylink.prototype._sendChannelMessage = function(message) {
rid: self._room.id
};
- log.debug([null, 'Socket', null, 'Sending queued messages (max: 16 per group) ->'], groupMessage);
+ log.debug([message.target || 'Server', 'Socket', groupMessage.type,
+ 'Sending queued grouped message (max: 16 per group) ->'], clone(groupMessage));
self._socket.send(JSON.stringify(groupMessage));
self._timestamp.socketMessage = (new Date()).getTime();
@@ -21912,12 +24711,13 @@ Skylink.prototype._sendChannelMessage = function(message) {
if (self._groupMessageList.indexOf(message.type) > -1) {
if (!(self._timestamp.socketMessage && ((new Date ()).getTime() - self._timestamp.socketMessage) <= interval)) {
if (!checkStampFn(message)) {
- log.warn([null, 'Socket', null, 'Dropping of outdated status message ->'], message);
+ log.warn([message.target || 'Server', 'Socket', message.type, 'Dropping of outdated status message ->'], clone(message));
return;
}
if (self._socketMessageTimeout) {
clearTimeout(self._socketMessageTimeout);
}
+ log.warn([message.target || 'Server', 'Socket', message.type, 'Sending message ->'], clone(message));
self._socket.send(JSON.stringify(message));
setStampFn(message);
triggerEventFn(message);
@@ -21925,7 +24725,8 @@ Skylink.prototype._sendChannelMessage = function(message) {
self._timestamp.socketMessage = (new Date()).getTime();
} else {
- log.warn([null, 'Socket', null, 'Queueing socket message to prevent message drop ->'], message);
+ log.warn([message.target || 'Server', 'Socket', message.type,
+ 'Queueing socket message to prevent message drop ->'], clone(message));
self._socketMessageQueue.push(message);
@@ -21934,7 +24735,15 @@ Skylink.prototype._sendChannelMessage = function(message) {
}
}
} else {
+ log.debug([message.target || 'Server', 'Socket', message.type, 'Sending message ->'], clone(message));
self._socket.send(JSON.stringify(message));
+
+ // If Peer sends "bye" on its own, we trigger it as session disconnected abruptly
+ if (message.type === self._SIG_MESSAGE_TYPE.BYE && self._inRoom &&
+ self._user && self._user.sid && message.mid === self._user.sid) {
+ self.leaveRoom(false);
+ self._trigger('sessionDisconnect', self._user.sid, self.getPeerInfo());
+ }
}
};
@@ -21947,158 +24756,169 @@ Skylink.prototype._sendChannelMessage = function(message) {
*/
Skylink.prototype._createSocket = function (type) {
var self = this;
-
var options = {
forceNew: true,
- //'sync disconnect on unload' : true,
- reconnection: false,
- timeout: self._socketTimeout
+ reconnection: true,
+ timeout: self._socketTimeout,
+ reconnectionAttempts: 2,
+ reconnectionDelayMax: 5000,
+ reconnectionDelay: 1000,
+ transports: ['websocket']
};
-
- var ports = self._socketPorts[self._signalingServerProtocol];
- var connectionType = null;
+ var ports = self._socketServer && typeof self._socketServer === 'object' && Array.isArray(self._socketServer.ports) &&
+ self._socketServer.ports.length > 0 ? self._socketServer.ports : self._socketPorts[self._signalingServerProtocol];
+ var fallbackType = null;
// just beginning
if (self._signalingServerPort === null) {
self._signalingServerPort = ports[0];
- connectionType = self.SOCKET_FALLBACK.NON_FALLBACK;
+ fallbackType = self.SOCKET_FALLBACK.NON_FALLBACK;
// reached the end of the last port for the protocol type
- } else if ( ports.indexOf(self._signalingServerPort) === ports.length - 1 ) {
-
+ } else if (ports.indexOf(self._signalingServerPort) === ports.length - 1 || typeof self._socketServer === 'string') {
// re-refresh to long-polling port
if (type === 'WebSocket') {
type = 'Polling';
self._signalingServerPort = ports[0];
-
- } else if (type === 'Polling') {
- options.reconnection = true;
- options.reconnectionAttempts = 4;
- options.reconectionDelayMax = 1000;
+ } else {
+ self._socketSession.finalAttempts++;
}
-
// move to the next port
} else {
self._signalingServerPort = ports[ ports.indexOf(self._signalingServerPort) + 1 ];
}
- var url = self._signalingServerProtocol + '//' + self._signalingServer + ':' + self._signalingServerPort;
- //'http://ec2-52-8-93-170.us-west-1.compute.amazonaws.com:6001';
-
- if (type === 'WebSocket') {
- options.transports = ['websocket'];
- } else if (type === 'Polling') {
+ if (type === 'Polling') {
+ options.reconnectionDelayMax = 1000;
+ options.reconnectionAttempts = 4;
options.transports = ['xhr-polling', 'jsonp-polling', 'polling'];
}
- // if socket instance already exists, exit
- if (self._socket) {
- self._socket.removeAllListeners('connect_error');
- self._socket.removeAllListeners('reconnect_attempt');
- self._socket.removeAllListeners('reconnect_error');
- self._socket.removeAllListeners('reconnect_failed');
- self._socket.removeAllListeners('connect');
- self._socket.removeAllListeners('reconnect');
- self._socket.removeAllListeners('error');
- self._socket.removeAllListeners('disconnect');
- self._socket.removeAllListeners('message');
- self._socket.disconnect();
- self._socket = null;
- }
-
- self._channelOpen = false;
+ var url = self._signalingServerProtocol + '//' + self._signalingServer + ':' + self._signalingServerPort;
+ var retries = 0;
- log.log('Opening channel with signaling server url:', {
- url: url,
- useXDR: self._socketUseXDR,
- options: options
- });
+ if (self._socketServer) {
+ // Provided as string, make it as just the fixed server
+ url = typeof self._socketServer === 'string' ? self._socketServer :
+ (self._socketServer.protocol ? self._socketServer.protocol : self._signalingServerProtocol) + '//' +
+ self._socketServer.url + ':' + self._signalingServerPort;
+ }
- self._socketSession = {
- type: type,
- options: options,
- url: url
- };
+ self._socketSession.transportType = type;
+ self._socketSession.socketOptions = options;
+ self._socketSession.socketServer = url;
- self._socket = io.connect(url, options);
+ if (fallbackType === null) {
+ fallbackType = self._signalingServerProtocol === 'http:' ?
+ (type === 'Polling' ? self.SOCKET_FALLBACK.LONG_POLLING : self.SOCKET_FALLBACK.FALLBACK_PORT) :
+ (type === 'Polling' ? self.SOCKET_FALLBACK.LONG_POLLING_SSL : self.SOCKET_FALLBACK.FALLBACK_SSL_PORT);
- if (connectionType === null) {
- connectionType = self._signalingServerProtocol === 'http:' ?
- (type === 'Polling' ? self.SOCKET_FALLBACK.LONG_POLLING :
- self.SOCKET_FALLBACK.FALLBACK_PORT) :
- (type === 'Polling' ? self.SOCKET_FALLBACK.LONG_POLLING_SSL :
- self.SOCKET_FALLBACK.FALLBACK_SSL_PORT);
+ self._socketSession.attempts++;
+ self._trigger('socketError', self.SOCKET_ERROR.RECONNECTION_ATTEMPT, null, fallbackType, clone(self._socketSession));
+ self._trigger('channelRetry', fallbackType, self._socketSession.attempts, clone(self._socketSession));
}
- self._socket.on('connect_error', function (error) {
- self._channelOpen = false;
+ // if socket instance already exists, exit
+ if (self._socket) {
+ self._closeChannel();
+ }
- self._trigger('socketError', self.SOCKET_ERROR.CONNECTION_FAILED,
- error, connectionType);
+ self._channelOpen = false;
- self._trigger('channelRetry', connectionType, 1);
+ log.log('Opening channel with signaling server url:', clone(self._socketSession));
- if (options.reconnection === false) {
- self._createSocket(type);
+ try {
+ self._socket = io.connect(url, options);
+ } catch (error){
+ log.error('Failed creating socket connection object ->', error);
+ if (fallbackType === self.SOCKET_FALLBACK.NON_FALLBACK) {
+ self._trigger('socketError', self.SOCKET_ERROR.CONNECTION_FAILED, error, fallbackType, clone(self._socketSession));
+ } else {
+ self._trigger('socketError', self.SOCKET_ERROR.RECONNECTION_FAILED, error, fallbackType, clone(self._socketSession));
}
- });
+ self._trigger('socketError', self.SOCKET_ERROR.RECONNECTION_ABORTED, new Error('Reconnection aborted as ' +
+ 'there no more available ports, transports and final attempts left.'), fallbackType, clone(self._socketSession));
+ return;
+ }
self._socket.on('reconnect_attempt', function (attempt) {
- self._channelOpen = false;
- self._trigger('socketError', self.SOCKET_ERROR.RECONNECTION_ATTEMPT,
- attempt, connectionType);
-
- self._trigger('channelRetry', connectionType, attempt);
+ retries++;
+ self._socketSession.attempts++;
+ self._trigger('channelRetry', fallbackType, self._socketSession.attempts, clone(self._socketSession));
});
- self._socket.on('reconnect_error', function (error) {
- self._channelOpen = false;
- self._trigger('socketError', self.SOCKET_ERROR.RECONNECTION_FAILED,
- error, connectionType);
- });
+ self._socket.on('reconnect_failed', function () {
+ if (fallbackType === self.SOCKET_FALLBACK.NON_FALLBACK) {
+ self._trigger('socketError', self.SOCKET_ERROR.CONNECTION_FAILED, new Error('Failed connection with transport "' +
+ type + '" and port ' + self._signalingServerPort + '.'), fallbackType, clone(self._socketSession));
+ } else {
+ self._trigger('socketError', self.SOCKET_ERROR.RECONNECTION_FAILED, new Error('Failed reconnection with transport "' +
+ type + '" and port ' + self._signalingServerPort + '.'), fallbackType, clone(self._socketSession));
+ }
- self._socket.on('reconnect_failed', function (error) {
- self._channelOpen = false;
- self._trigger('socketError', self.SOCKET_ERROR.RECONNECTION_ABORTED,
- error, connectionType);
+ if (self._socketSession.finalAttempts < 2) {
+ self._createSocket(type);
+ } else {
+ self._trigger('socketError', self.SOCKET_ERROR.RECONNECTION_ABORTED, new Error('Reconnection aborted as ' +
+ 'there no more available ports, transports and final attempts left.'), fallbackType, clone(self._socketSession));
+ }
});
self._socket.on('connect', function () {
if (!self._channelOpen) {
- self._channelOpen = true;
- self._trigger('channelOpen');
log.log([null, 'Socket', null, 'Channel opened']);
+ self._channelOpen = true;
+ self._trigger('channelOpen', clone(self._socketSession));
}
});
self._socket.on('reconnect', function () {
if (!self._channelOpen) {
- self._channelOpen = true;
- self._trigger('channelOpen');
log.log([null, 'Socket', null, 'Channel opened']);
+ self._channelOpen = true;
+ self._trigger('channelOpen', clone(self._socketSession));
}
});
self._socket.on('error', function(error) {
- self._channelOpen = false;
- self._trigger('channelError', error);
- log.error([null, 'Socket', null, 'Exception occurred:'], error);
+ if (error ? error.message.indexOf('xhr poll error') > -1 : false) {
+ log.error([null, 'Socket', null, 'XHR poll connection unstable. Disconnecting.. ->'], error);
+ self._closeChannel();
+ return;
+ }
+ log.error([null, 'Socket', null, 'Exception occurred ->'], error);
+ self._trigger('channelError', error, clone(self._socketSession));
});
self._socket.on('disconnect', function() {
- self._channelOpen = false;
- self._trigger('channelClose');
- log.log([null, 'Socket', null, 'Channel closed']);
+ if (self._channelOpen) {
+ self._channelOpen = false;
+ self._trigger('channelClose', clone(self._socketSession));
+ log.log([null, 'Socket', null, 'Channel closed']);
- if (self._inRoom) {
- self.leaveRoom(false);
- self._trigger('sessionDisconnect', self._user.sid, self.getPeerInfo());
+ if (self._inRoom && self._user && self._user.sid) {
+ self.leaveRoom(false);
+ self._trigger('sessionDisconnect', self._user.sid, self.getPeerInfo());
+ }
}
});
- self._socket.on('message', function(message) {
- log.log([null, 'Socket', null, 'Received message']);
- self._processSigMessage(message);
+ self._socket.on('message', function(messageStr) {
+ var message = JSON.parse(messageStr);
+
+ log.log([null, 'Socket', null, 'Received message ->'], message);
+
+ if (message.type === self._SIG_MESSAGE_TYPE.GROUP) {
+ log.debug('Bundle of ' + message.lists.length + ' messages');
+ for (var i = 0; i < message.lists.length; i++) {
+ var indiMessage = JSON.parse(message.lists[i]);
+ self._processSigMessage(indiMessage);
+ self._trigger('channelMessage', indiMessage, clone(self._socketSession));
+ }
+ } else {
+ self._processSigMessage(message);
+ self._trigger('channelMessage', message, clone(self._socketSession));
+ }
});
};
@@ -22138,6 +24958,8 @@ Skylink.prototype._openChannel = function() {
socketType = 'Polling';
}
+ self._socketSession.finalAttempts = 0;
+ self._socketSession.attempts = 0;
self._signalingServerPort = null;
// Begin with a websocket connection
@@ -22152,9 +24974,6 @@ Skylink.prototype._openChannel = function() {
* @since 0.5.5
*/
Skylink.prototype._closeChannel = function() {
- if (!this._channelOpen) {
- return;
- }
if (this._socket) {
this._socket.removeAllListeners('connect_error');
this._socket.removeAllListeners('reconnect_attempt');
@@ -22165,11 +24984,25 @@ Skylink.prototype._closeChannel = function() {
this._socket.removeAllListeners('error');
this._socket.removeAllListeners('disconnect');
this._socket.removeAllListeners('message');
- this._socket.disconnect();
- this._socket = null;
}
- this._channelOpen = false;
- this._trigger('channelClose');
+
+ if (this._channelOpen) {
+ if (this._socket) {
+ this._socket.disconnect();
+ }
+
+ log.log([null, 'Socket', null, 'Channel closed']);
+
+ this._channelOpen = false;
+ this._trigger('channelClose', clone(this._socketSession));
+
+ if (this._inRoom && this._user && this._user.sid) {
+ this.leaveRoom(false);
+ this._trigger('sessionDisconnect', this._user.sid, this.getPeerInfo());
+ }
+ }
+
+ this._socket = null;
};
Skylink.prototype.SM_PROTOCOL_VERSION = '0.1.2.3';
@@ -22588,47 +25421,27 @@ Skylink.prototype.stopRecording = function (callback, callbackSuccessWhenLink) {
* @for Skylink
* @since 0.6.16
*/
-Skylink.prototype.getRecordings = function () {
- return clone(this._recordings);
-};
-
-/**
- * Function that process and parses the socket message string received from the Signaling.
- * @method _processSigMessage
- * @private
- * @for Skylink
- * @since 0.1.0
- */
-Skylink.prototype._processSigMessage = function(messageString) {
- var message = JSON.parse(messageString);
- if (message.type === this._SIG_MESSAGE_TYPE.GROUP) {
- log.debug('Bundle of ' + message.lists.length + ' messages');
- for (var i = 0; i < message.lists.length; i++) {
- this._processSingleMessage(JSON.parse(message.lists[i]));
- }
- } else {
- this._processSingleMessage(message);
- }
+Skylink.prototype.getRecordings = function () {
+ return clone(this._recordings);
};
/**
* Function that handles and processes the socket message received.
- * @method _processingSingleMessage
+ * @method _processSigMessage
* @private
* @for Skylink
* @since 0.1.0
*/
-Skylink.prototype._processSingleMessage = function(message) {
- this._trigger('channelMessage', message);
+Skylink.prototype._processSigMessage = function(message, session) {
var origin = message.mid;
if (!origin || origin === this._user.sid) {
origin = 'Server';
}
- log.debug([origin, null, null, 'Received from peer ->'], message.type);
+ log.debug([origin, 'Socket', message.type, 'Received from peer ->'], clone(message));
if (message.mid === this._user.sid &&
message.type !== this._SIG_MESSAGE_TYPE.REDIRECT &&
message.type !== this._SIG_MESSAGE_TYPE.IN_ROOM) {
- log.debug([origin, null, null, 'Ignoring message ->'], message.type);
+ log.debug([origin, 'Socket', message.type, 'Ignoring message ->'], clone(message));
return;
}
switch (message.type) {
@@ -22698,7 +25511,7 @@ Skylink.prototype._processSingleMessage = function(message) {
this._endOfCandidatesHandler(message);
break;
default:
- log.error([message.mid, null, null, 'Unsupported message ->'], message.type);
+ log.error([message.mid, 'Socket', message.type, 'Unsupported message ->'], clone(message));
break;
}
};
@@ -22796,9 +25609,10 @@ Skylink.prototype._approachEventHandler = function(message){
enterMsg.publishOnly = {
type: self._streams.screenshare && self._streams.screenshare.stream ? 'screenshare' : 'video'
};
- if (self._publishOnly.parentId) {
- enterMsg.parentId = self._publishOnly.parentId;
- }
+ }
+
+ if (self._parentId) {
+ enterMsg.parentId = self._parentId;
}
self._sendChannelMessage(enterMsg);
@@ -23154,7 +25968,8 @@ Skylink.prototype._inRoomHandler = function(message) {
self._room.connection.peerConfig = self._setIceServers(message.pc_config);
self._inRoom = true;
self._user.sid = message.sid;
- self._peerPriorityWeight = message.tieBreaker;
+ self._peerPriorityWeight = message.tieBreaker + (self._priorityWeightScheme === self.PRIORITY_WEIGHT_SCHEME.AUTO ?
+ 0 : (self._priorityWeightScheme === self.PRIORITY_WEIGHT_SCHEME.ENFORCE_OFFERER ? 2e+15 : -(2e+15)));
self._trigger('peerJoined', self._user.sid, self.getPeerInfo(), true);
self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.ENTER, self._user.sid);
@@ -23195,9 +26010,10 @@ Skylink.prototype._inRoomHandler = function(message) {
enterMsg.publishOnly = {
type: self._streams.screenshare && self._streams.screenshare.stream ? 'screenshare' : 'video'
};
- if (self._publishOnly.parentId) {
- enterMsg.parentId = self._publishOnly.parentId;
- }
+ }
+
+ if (self._parentId) {
+ enterMsg.parentId = self._parentId;
}
self._sendChannelMessage(enterMsg);
@@ -23252,82 +26068,109 @@ Skylink.prototype._enterHandler = function(message) {
SMProtocolVersion: message.SMProtocolVersion && typeof message.SMProtocolVersion === 'string' ?
message.SMProtocolVersion : '0.1.1',
DTProtocolVersion: message.DTProtocolVersion && typeof message.DTProtocolVersion === 'string' ?
- message.DTProtocolVersion : '0.1.0'
+ message.DTProtocolVersion : (self._hasMCU || targetMid === 'MCU' ? '0.1.2' : '0.1.0')
};
log.log([targetMid, 'RTCPeerConnection', null, 'Peer "enter" received ->'], message);
- if (self._publishOnly && ((self._hasMCU && targetMid !== 'MCU') || (self._publishOnly.parentId &&
- self._publishOnly.parentId === targetMid))) {
- log.warn([targetMid, 'RTCPeerConnection', null, 'Discarding "enter" for publishOnly case ->'], message);
+ if (targetMid !== 'MCU' && self._parentId && self._parentId === targetMid) {
+ log.warn([targetMid, 'RTCPeerConnection', null, 'Discarding "enter" for parentId case ->'], message);
return;
}
- if (!self._peerInformations[targetMid]) {
- isNewPeer = true;
+ var processPeerFn = function (cert) {
+ if (!self._peerInformations[targetMid]) {
+ isNewPeer = true;
- self._peerInformations[targetMid] = userInfo;
+ self._peerInformations[targetMid] = userInfo;
- var hasScreenshare = userInfo.settings.video && typeof userInfo.settings.video === 'object' &&
- !!userInfo.settings.video.screenshare;
+ var hasScreenshare = userInfo.settings.video && typeof userInfo.settings.video === 'object' &&
+ !!userInfo.settings.video.screenshare;
- self._addPeer(targetMid, {
- agent: userInfo.agent.name,
- version: userInfo.agent.version,
- os: userInfo.agent.os
- }, false, false, message.receiveOnly, hasScreenshare);
+ self._addPeer(targetMid, cert || null, {
+ agent: userInfo.agent.name,
+ version: userInfo.agent.version,
+ os: userInfo.agent.os
+ }, false, false, message.receiveOnly, hasScreenshare);
- if (targetMid === 'MCU') {
- log.info([targetMid, 'RTCPeerConnection', null, 'MCU feature has been enabled']);
+ if (targetMid === 'MCU') {
+ log.info([targetMid, 'RTCPeerConnection', null, 'MCU feature has been enabled']);
- self._hasMCU = true;
- self._trigger('serverPeerJoined', targetMid, self.SERVER_PEER_TYPE.MCU);
+ self._hasMCU = true;
+ self._trigger('serverPeerJoined', targetMid, self.SERVER_PEER_TYPE.MCU);
- } else {
- self._trigger('peerJoined', targetMid, self.getPeerInfo(targetMid), false);
+ } else {
+ self._trigger('peerJoined', targetMid, self.getPeerInfo(targetMid), false);
+ }
+
+ self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.ENTER, targetMid);
}
- self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.ENTER, targetMid);
- }
+ self._peerMessagesStamps[targetMid] = self._peerMessagesStamps[targetMid] || {
+ userData: 0,
+ audioMuted: 0,
+ videoMuted: 0
+ };
- self._peerMessagesStamps[targetMid] = self._peerMessagesStamps[targetMid] || {
- userData: 0,
- audioMuted: 0,
- videoMuted: 0
- };
+ var welcomeMsg = {
+ type: self._SIG_MESSAGE_TYPE.WELCOME,
+ mid: self._user.sid,
+ rid: self._room.id,
+ enableIceTrickle: self._enableIceTrickle,
+ enableDataChannel: self._enableDataChannel,
+ enableIceRestart: self._enableIceRestart,
+ agent: window.webrtcDetectedBrowser,
+ version: (window.webrtcDetectedVersion || 0).toString(),
+ receiveOnly: self.getPeerInfo().config.receiveOnly,
+ os: window.navigator.platform,
+ userInfo: self._getUserInfo(targetMid),
+ target: targetMid,
+ weight: self._peerPriorityWeight,
+ temasysPluginVersion: AdapterJS.WebRTCPlugin.plugin ? AdapterJS.WebRTCPlugin.plugin.VERSION : null,
+ SMProtocolVersion: self.SM_PROTOCOL_VERSION,
+ DTProtocolVersion: self.DT_PROTOCOL_VERSION
+ };
- var welcomeMsg = {
- type: self._SIG_MESSAGE_TYPE.WELCOME,
- mid: self._user.sid,
- rid: self._room.id,
- enableIceTrickle: self._enableIceTrickle,
- enableDataChannel: self._enableDataChannel,
- enableIceRestart: self._enableIceRestart,
- agent: window.webrtcDetectedBrowser,
- version: (window.webrtcDetectedVersion || 0).toString(),
- receiveOnly: self.getPeerInfo().config.receiveOnly,
- os: window.navigator.platform,
- userInfo: self._getUserInfo(),
- target: targetMid,
- weight: self._peerPriorityWeight,
- temasysPluginVersion: AdapterJS.WebRTCPlugin.plugin ? AdapterJS.WebRTCPlugin.plugin.VERSION : null,
- SMProtocolVersion: self.SM_PROTOCOL_VERSION,
- DTProtocolVersion: self.DT_PROTOCOL_VERSION
- };
+ if (self._publishOnly) {
+ welcomeMsg.publishOnly = {
+ type: self._streams.screenshare && self._streams.screenshare.stream ? 'screenshare' : 'video'
+ };
+ }
- if (self._publishOnly) {
- welcomeMsg.publishOnly = {
- type: self._streams.screenshare && self._streams.screenshare.stream ? 'screenshare' : 'video'
- };
- if (self._publishOnly.parentId) {
- welcomeMsg.parentId = self._publishOnly.parentId;
+ if (self._parentId) {
+ welcomeMsg.parentId = self._parentId;
}
- }
- self._sendChannelMessage(welcomeMsg);
+ self._sendChannelMessage(welcomeMsg);
+
+ if (isNewPeer) {
+ self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.WELCOME, targetMid);
+ }
+ };
- if (isNewPeer) {
- self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.WELCOME, targetMid);
+ if (self._peerConnectionConfig.certificate !== self.PEER_CERTIFICATE.AUTO &&
+ typeof RTCPeerConnection.generateCertificate === 'function') {
+ var certOptions = {};
+ if (self._peerConnectionConfig.certificate === self.PEER_CERTIFICATE.ECDSA) {
+ certOptions = {
+ name: 'ECDSA',
+ namedCurve: 'P-256'
+ };
+ } else {
+ certOptions = {
+ name: 'RSASSA-PKCS1-v1_5',
+ modulusLength: 2048,
+ publicExponent: new Uint8Array([1, 0, 1]),
+ hash: 'SHA-256'
+ };
+ }
+ RTCPeerConnection.generateCertificate(certOptions).then(function (cert) {
+ processPeerFn(cert);
+ }, function () {
+ processPeerFn();
+ });
+ } else {
+ processPeerFn();
}
};
@@ -23379,7 +26222,7 @@ Skylink.prototype._restartHandler = function(message){
SMProtocolVersion: message.SMProtocolVersion && typeof message.SMProtocolVersion === 'string' ?
message.SMProtocolVersion : '0.1.1',
DTProtocolVersion: message.DTProtocolVersion && typeof message.DTProtocolVersion === 'string' ?
- message.DTProtocolVersion : '0.1.0'
+ message.DTProtocolVersion : (self._hasMCU || targetMid === 'MCU' ? '0.1.2' : '0.1.0')
};
log.log([targetMid, 'RTCPeerConnection', null, 'Peer "restart" received ->'], message);
@@ -23389,6 +26232,11 @@ Skylink.prototype._restartHandler = function(message){
return;
}
+ if (targetMid !== 'MCU' && self._parentId && self._parentId === targetMid) {
+ log.warn([targetMid, 'RTCPeerConnection', null, 'Discarding "restart" for parentId case ->'], message);
+ return;
+ }
+
if (self._hasMCU && !self._mcuUseRenegoRestart) {
log.warn([targetMid, 'RTCPeerConnection', null, 'Dropping restart request as MCU does not support re-negotiation. ' +
'Restart workaround is to re-join Room for Peer.']);
@@ -23406,7 +26254,7 @@ Skylink.prototype._restartHandler = function(message){
self._peerEndOfCandidatesCounter[targetMid].len = 0;
// Make peer with highest weight do the offer
- if (self._hasMCU ? message.isRestartResend : self._peerPriorityWeight > message.weight) {
+ if (self._peerPriorityWeight > message.weight) {
log.debug([targetMid, 'RTCPeerConnection', null, 'Re-negotiating new offer/answer.']);
if (self._peerMessagesStamps[targetMid].hasRestart) {
@@ -23431,7 +26279,7 @@ Skylink.prototype._restartHandler = function(message){
agent: window.webrtcDetectedBrowser,
version: (window.webrtcDetectedVersion || 0).toString(),
os: window.navigator.platform,
- userInfo: self._getUserInfo(),
+ userInfo: self._getUserInfo(targetMid),
target: targetMid,
weight: self._peerPriorityWeight,
enableIceTrickle: self._enableIceTrickle,
@@ -23449,9 +26297,10 @@ Skylink.prototype._restartHandler = function(message){
restartMsg.publishOnly = {
type: self._streams.screenshare && self._streams.screenshare.stream ? 'screenshare' : 'video'
};
- if (self._publishOnly.parentId) {
- restartMsg.parentId = self._publishOnly.parentId;
- }
+ }
+
+ if (self._parentId) {
+ restartMsg.parentId = self._parentId;
}
self._sendChannelMessage(restartMsg);
@@ -23509,99 +26358,126 @@ Skylink.prototype._welcomeHandler = function(message) {
SMProtocolVersion: message.SMProtocolVersion && typeof message.SMProtocolVersion === 'string' ?
message.SMProtocolVersion : '0.1.1',
DTProtocolVersion: message.DTProtocolVersion && typeof message.DTProtocolVersion === 'string' ?
- message.DTProtocolVersion : '0.1.0'
+ message.DTProtocolVersion : (self._hasMCU || targetMid === 'MCU' ? '0.1.2' : '0.1.0')
};
log.log([targetMid, 'RTCPeerConnection', null, 'Peer "welcome" received ->'], message);
- if (self._publishOnly && ((self._hasMCU && targetMid !== 'MCU') || (self._publishOnly.parentId &&
- self._publishOnly.parentId === targetMid))) {
- log.warn([targetMid, 'RTCPeerConnection', null, 'Discarding "welcome" for publishOnly case ->'], message);
+ if (targetMid !== 'MCU' && self._parentId && self._parentId === targetMid) {
+ log.warn([targetMid, 'RTCPeerConnection', null, 'Discarding "welcome" for parentId case ->'], message);
return;
}
- if (!self._peerInformations[targetMid]) {
- isNewPeer = true;
+ var processPeerFn = function (cert) {
+ if (!self._peerInformations[targetMid]) {
+ isNewPeer = true;
- self._peerInformations[targetMid] = userInfo;
+ self._peerInformations[targetMid] = userInfo;
- var hasScreenshare = userInfo.settings.video && typeof userInfo.settings.video === 'object' &&
- !!userInfo.settings.video.screenshare;
+ var hasScreenshare = userInfo.settings.video && typeof userInfo.settings.video === 'object' &&
+ !!userInfo.settings.video.screenshare;
- self._addPeer(targetMid, {
- agent: userInfo.agent.name,
- version: userInfo.agent.version,
- os: userInfo.agent.os
- }, false, false, message.receiveOnly, hasScreenshare);
+ self._addPeer(targetMid, cert || null, {
+ agent: userInfo.agent.name,
+ version: userInfo.agent.version,
+ os: userInfo.agent.os
+ }, false, false, message.receiveOnly, hasScreenshare);
- if (targetMid === 'MCU') {
- log.info([targetMid, 'RTCPeerConnection', null, 'MCU feature has been enabled']);
+ if (targetMid === 'MCU') {
+ log.info([targetMid, 'RTCPeerConnection', null, 'MCU feature has been enabled']);
- self._hasMCU = true;
- self._trigger('serverPeerJoined', targetMid, self.SERVER_PEER_TYPE.MCU);
+ self._hasMCU = true;
+ self._trigger('serverPeerJoined', targetMid, self.SERVER_PEER_TYPE.MCU);
- } else {
- self._trigger('peerJoined', targetMid, self.getPeerInfo(targetMid), false);
+ } else {
+ self._trigger('peerJoined', targetMid, self.getPeerInfo(targetMid), false);
+ }
+
+ self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.ENTER, targetMid);
+ self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.WELCOME, targetMid);
}
- self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.ENTER, targetMid);
- self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.WELCOME, targetMid);
- }
+ self._peerMessagesStamps[targetMid] = self._peerMessagesStamps[targetMid] || {
+ userData: 0,
+ audioMuted: 0,
+ videoMuted: 0,
+ hasWelcome: false
+ };
- self._peerMessagesStamps[targetMid] = self._peerMessagesStamps[targetMid] || {
- userData: 0,
- audioMuted: 0,
- videoMuted: 0,
- hasWelcome: false
- };
+ if (self._hasMCU || self._peerPriorityWeight > message.weight) {
+ if (self._peerMessagesStamps[targetMid].hasWelcome) {
+ log.warn([targetMid, 'RTCPeerConnection', null, 'Discarding extra "welcome" received.']);
+ return;
+ }
- if (self._hasMCU || self._peerPriorityWeight > message.weight) {
- if (self._peerMessagesStamps[targetMid].hasWelcome) {
- log.warn([targetMid, 'RTCPeerConnection', null, 'Discarding extra "welcome" received.']);
- return;
- }
+ log.debug([targetMid, 'RTCPeerConnection', null, 'Starting negotiation']);
- log.debug([targetMid, 'RTCPeerConnection', null, 'Starting negotiation']);
+ self._peerMessagesStamps[targetMid].hasWelcome = true;
+ self._doOffer(targetMid, false, {
+ agent: userInfo.agent.name,
+ version: userInfo.agent.version,
+ os: userInfo.agent.os
+ }, true);
- self._peerMessagesStamps[targetMid].hasWelcome = true;
- self._doOffer(targetMid, false, {
- agent: userInfo.agent.name,
- version: userInfo.agent.version,
- os: userInfo.agent.os
- }, true);
+ } else {
+ log.debug([targetMid, 'RTCPeerConnection', null, 'Waiting for peer to start negotiation.']);
- } else {
- log.debug([targetMid, 'RTCPeerConnection', null, 'Waiting for peer to start negotiation.']);
+ var welcomeMsg = {
+ type: self._SIG_MESSAGE_TYPE.WELCOME,
+ mid: self._user.sid,
+ rid: self._room.id,
+ enableIceTrickle: self._enableIceTrickle,
+ enableDataChannel: self._enableDataChannel,
+ enableIceRestart: self._enableIceRestart,
+ receiveOnly: self.getPeerInfo().config.receiveOnly,
+ agent: window.webrtcDetectedBrowser,
+ version: (window.webrtcDetectedVersion || 0).toString(),
+ os: window.navigator.platform,
+ userInfo: self._getUserInfo(targetMid),
+ target: targetMid,
+ weight: self._peerPriorityWeight,
+ temasysPluginVersion: AdapterJS.WebRTCPlugin.plugin ? AdapterJS.WebRTCPlugin.plugin.VERSION : null,
+ SMProtocolVersion: self.SM_PROTOCOL_VERSION,
+ DTProtocolVersion: self.DT_PROTOCOL_VERSION
+ };
- var welcomeMsg = {
- type: self._SIG_MESSAGE_TYPE.WELCOME,
- mid: self._user.sid,
- rid: self._room.id,
- enableIceTrickle: self._enableIceTrickle,
- enableDataChannel: self._enableDataChannel,
- enableIceRestart: self._enableIceRestart,
- receiveOnly: self.getPeerInfo().config.receiveOnly,
- agent: window.webrtcDetectedBrowser,
- version: (window.webrtcDetectedVersion || 0).toString(),
- os: window.navigator.platform,
- userInfo: self._getUserInfo(),
- target: targetMid,
- weight: self._peerPriorityWeight,
- temasysPluginVersion: AdapterJS.WebRTCPlugin.plugin ? AdapterJS.WebRTCPlugin.plugin.VERSION : null,
- SMProtocolVersion: self.SM_PROTOCOL_VERSION,
- DTProtocolVersion: self.DT_PROTOCOL_VERSION
- };
+ if (self._publishOnly) {
+ welcomeMsg.publishOnly = {
+ type: self._streams.screenshare && self._streams.screenshare.stream ? 'screenshare' : 'video'
+ };
+ }
- if (self._publishOnly) {
- welcomeMsg.publishOnly = {
- type: self._streams.screenshare && self._streams.screenshare.stream ? 'screenshare' : 'video'
- };
- if (self._publishOnly.parentId) {
- welcomeMsg.parentId = self._publishOnly.parentId;
+ if (self._parentId) {
+ welcomeMsg.parentId = self._parentId;
}
+
+ self._sendChannelMessage(welcomeMsg);
}
+ };
- self._sendChannelMessage(welcomeMsg);
+ if (self._peerConnectionConfig.certificate !== self.PEER_CERTIFICATE.AUTO &&
+ typeof RTCPeerConnection.generateCertificate === 'function') {
+ var certOptions = {};
+ if (self._peerConnectionConfig.certificate === self.PEER_CERTIFICATE.ECDSA) {
+ certOptions = {
+ name: 'ECDSA',
+ namedCurve: 'P-256'
+ };
+ } else {
+ certOptions = {
+ name: 'RSASSA-PKCS1-v1_5',
+ modulusLength: 2048,
+ publicExponent: new Uint8Array([1, 0, 1]),
+ hash: 'SHA-256'
+ };
+ }
+ RTCPeerConnection.generateCertificate(certOptions).then(function (cert) {
+ processPeerFn(cert);
+ }, function () {
+ processPeerFn();
+ });
+ } else {
+ processPeerFn();
}
};
@@ -23644,8 +26520,8 @@ Skylink.prototype._offerHandler = function(message) {
'Session description:'], clone(message));
var offer = new RTCSessionDescription({
- type: message.type,
- sdp: self._hasMCU ? message.sdp.split('\n').join('\r\n') : message.sdp
+ type: 'offer',
+ sdp: self._hasMCU ? message.sdp.replace(/\r\n/g, '\n').split('\n').join('\r\n') : message.sdp
});
log.log([targetMid, 'RTCSessionDescription', message.type,
'Session description object created'], offer);
@@ -23653,9 +26529,10 @@ Skylink.prototype._offerHandler = function(message) {
offer.sdp = self._removeSDPFilteredCandidates(targetMid, offer);
offer.sdp = self._setSDPCodec(targetMid, offer);
offer.sdp = self._setSDPBitrate(targetMid, offer);
- offer.sdp = self._setSDPOpusConfig(targetMid, offer);
+ offer.sdp = self._setSDPCodecParams(targetMid, offer);
offer.sdp = self._removeSDPCodecs(targetMid, offer);
offer.sdp = self._removeSDPREMBPackets(targetMid, offer);
+ offer.sdp = self._handleSDPConnectionSettings(targetMid, offer, 'remote');
log.log([targetMid, 'RTCSessionDescription', message.type, 'Updated remote offer ->'], offer.sdp);
@@ -23679,6 +26556,11 @@ Skylink.prototype._offerHandler = function(message) {
pc.processingRemoteSDP = true;
+ // Edge FIXME problem: Add stream only at offer/answer end
+ if (window.webrtcDetectedBrowser === 'edge' && (!self._hasMCU || targetMid === 'MCU')) {
+ self._addLocalMediaStreams(targetMid);
+ }
+
pc.setRemoteDescription(offer, function() {
log.debug([targetMid, 'RTCSessionDescription', message.type, 'Remote description set']);
pc.setOffer = 'remote';
@@ -23691,7 +26573,11 @@ Skylink.prototype._offerHandler = function(message) {
pc.processingRemoteSDP = false;
- log.error([targetMid, null, message.type, 'Failed setting remote description:'], error);
+ log.error([targetMid, null, message.type, 'Failed setting remote description:'], {
+ error: error,
+ state: pc.signalingState,
+ offer: offer
+ });
});
};
@@ -23738,7 +26624,7 @@ Skylink.prototype._candidateHandler = function(message) {
if (!(this._peerConnections[targetMid] &&
this._peerConnections[targetMid].signalingState !== this.PEER_CONNECTION_STATE.CLOSED)) {
log.warn([targetMid, 'RTCIceCandidate', canId + ':' + candidateType, 'Dropping ICE candidate ' +
- 'as Peer connection does not exists or is closed'], this._peerConnections[targetMid].signalingState);
+ 'as Peer connection does not exists or is closed']);
this._trigger('candidateProcessingState', this.CANDIDATE_PROCESSING_STATE.DROPPED,
targetMid, canId, candidateType, {
candidate: candidate.candidate,
@@ -23825,8 +26711,8 @@ Skylink.prototype._answerHandler = function(message) {
}
var answer = new RTCSessionDescription({
- type: message.type,
- sdp: self._hasMCU ? message.sdp.split('\n').join('\r\n') : message.sdp
+ type: 'answer',
+ sdp: self._hasMCU ? message.sdp.replace(/\r\n/g, '\n').split('\n').join('\r\n') : message.sdp
});
log.log([targetMid, 'RTCSessionDescription', message.type,
@@ -23847,9 +26733,10 @@ Skylink.prototype._answerHandler = function(message) {
answer.sdp = self._removeSDPFilteredCandidates(targetMid, answer);
answer.sdp = self._setSDPCodec(targetMid, answer);
answer.sdp = self._setSDPBitrate(targetMid, answer);
- answer.sdp = self._setSDPOpusConfig(targetMid, answer);
+ answer.sdp = self._setSDPCodecParams(targetMid, answer);
answer.sdp = self._removeSDPCodecs(targetMid, answer);
answer.sdp = self._removeSDPREMBPackets(targetMid, answer);
+ answer.sdp = self._handleSDPConnectionSettings(targetMid, answer, 'remote');
log.log([targetMid, 'RTCSessionDescription', message.type, 'Updated remote answer ->'], answer.sdp);
@@ -23885,6 +26772,12 @@ Skylink.prototype._answerHandler = function(message) {
self._peerMessagesStamps[targetMid].hasRestart = false;
}
+ if (self._dataChannels[targetMid] && (pc.remoteDescription.sdp.indexOf('m=application') === -1 ||
+ pc.remoteDescription.sdp.indexOf('m=application 0') > 0)) {
+ log.warn([targetMid, 'RTCPeerConnection', null, 'Closing all datachannels as they were rejected.']);
+ self._closeDataChannel(targetMid);
+ }
+
}, function(error) {
self._trigger('handshakeProgress', self.HANDSHAKE_PROGRESS.ERROR, targetMid, error);
@@ -23892,7 +26785,8 @@ Skylink.prototype._answerHandler = function(message) {
log.error([targetMid, null, message.type, 'Failed setting remote description:'], {
error: error,
- state: pc.signalingState
+ state: pc.signalingState,
+ answer: answer
});
});
};
@@ -23941,8 +26835,14 @@ Skylink.prototype.VIDEO_CODEC = {
* The value of the option to prefer the OPUS audio codec.
* @param {String} ISAC Value "ISAC"
* The value of the option to prefer the ISAC audio codec.
+ * @param {String} ILBC Value "ILBC"
+ * The value of the option to prefer the iLBC audio codec.
* @param {String} G722 Value "G722"
* The value of the option to prefer the G722 audio codec.
+ * @param {String} PCMA Value "PCMA"
+ * The value of the option to prefer the G711u audio codec.
+ * @param {String} PCMU Value "PCMU"
+ * The value of the option to prefer the G711a audio codec.
* @type JSON
* @readOnly
* @for Skylink
@@ -23952,9 +26852,10 @@ Skylink.prototype.AUDIO_CODEC = {
AUTO: 'auto',
ISAC: 'ISAC',
OPUS: 'opus',
- //ILBC: 'ILBC',
- //G711: 'G711',
- G722: 'G722'
+ ILBC: 'ILBC',
+ G722: 'G722',
+ PCMU: 'PCMU',
+ PCMA: 'PCMA',
//SILK: 'SILK'
};
@@ -24146,30 +27047,46 @@ Skylink.prototype.RECORDING_STATE = {
* Note that the current Edge browser implementation does not support the options.audio.optional,
* options.audio.deviceId, options.audio.echoCancellation.
* The audio configuration options.
- * @param {Boolean} [options.audio.stereo=false] The flag if stereo band should be configured
- * when encoding audio codec is OPUS for sending / receiving audio data.
- * Note that Peers may override the "receiving" stereo config depending on the Peers configuration.
- * @param {Boolean} [options.audio.usedtx]
- * Note that this feature might not work depending on the browser support and implementation.
- * The flag if DTX (Discontinuous Transmission) should be configured when encoding audio codec
- * is OPUS for sending / receiving audio data.
- * This might help to reduce bandwidth it reduces the bitrate during silence or background noise.
+ * @param {Boolean} [options.audio.stereo=false]
Deprecation Warning!
+ * This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo
+ * parameter in the init() method instead. If the
+ * options.codecParams.audio.opus.stereo is configured, this overrides the
+ * options.audio.stereo setting.
+ * The flag if OPUS audio codec stereo band should be configured for sending encoded audio data.
* When not provided, the default browser configuration is used.
- * Note that Peers may override the "receiving" usedtx config depending on the Peers configuration.
- * @param {Boolean} [options.audio.useinbandfec]
- * Note that this feature might not work depending on the browser support and implementation.
- * The flag if capability to take advantage of in-band FEC (Forward Error Correction) should be
- * configured when encoding audio codec is OPUS for sending / receiving audio data.
- * This might help to reduce the harm of packet loss by encoding information about the previous packet.
+ * @param {Boolean} [options.audio.usedtx]
Deprecation Warning!
+ * This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo
+ * parameter in the init() method instead. If the
+ * options.codecParams.audio.opus.stereo is configured, this overrides the
+ * options.audio.stereo setting. Note that this feature might
+ * not work depending on the browser support and implementation.
+ * The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.
+ * This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and
+ * goes hand-in-hand with the options.voiceActivityDetection flag in
+ * joinRoom() method.
* When not provided, the default browser configuration is used.
- * Note that Peers may override the "receiving" useinbandfec config depending on the Peers configuration.
- * @param {Number} [options.audio.maxplaybackrate]
- * Note that this feature might not work depending on the browser support and implementation.
- * The maximum output sampling rate rendered in Hertz (Hz) when encoding audio codec is
- * OPUS for sending / receiving audio data.
+ * @param {Boolean} [options.audio.useinbandfec]
Deprecation Warning!
+ * This property has been deprecated. Configure this with the options.codecParams.audio.opus.useinbandfec
+ * parameter in the init() method instead. If the
+ * options.codecParams.audio.opus.useinbandfec is configured, this overrides the
+ * options.audio.useinbandfec setting. Note that this parameter should only be used
+ * for debugging purposes only.
+ * The flag if OPUS audio codec has the capability to take advantage of the in-band FEC
+ * (Forward Error Correction) when sending encoded audio data.
+ * This helps to reduce the harm of packet loss by encoding information about the previous packet loss.
+ * When not provided, the default browser configuration is used.
+ * @param {Number} [options.audio.maxplaybackrate]
Deprecation Warning!
+ * This property has been deprecated. Configure this with the options.codecParams.audio.opus.maxplaybackrate
+ * parameter in the init() method instead. If the
+ * options.codecParams.audio.opus.maxplaybackrate is configured, this overrides the
+ * options.audio.maxplaybackrate setting. Note that this feature might
+ * not work depending on the browser support and implementation.
+ * Note that this parameter should only be used for debugging purposes only.
+ * The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving
+ * decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data
+ * would not encode at a higher sampling rate specified by this.
* This value must be between 8000 to 48000.
* When not provided, the default browser configuration is used.
- * Note that Peers may override the "receiving" maxplaybackrate config depending on the Peers configuration.
* @param {Boolean} [options.audio.mute=false] The flag if audio tracks should be muted upon receiving them.
* Providing the value as false does nothing to peerInfo.mediaStatus.audioMuted,
* but when provided as true, this sets the peerInfo.mediaStatus.audioMuted value to
@@ -24186,7 +27103,10 @@ Skylink.prototype.RECORDING_STATE = {
* The list of available audio source ID can be retrieved by the navigator.mediaDevices.enumerateDevices
* API.
- * @param {Boolean} [options.audio.echoCancellation=false] The flag to enable audio tracks echo cancellation.
+ * @param {Boolean} [options.audio.echoCancellation=true]
+ * For Chrome/Opera/IE/Safari/Bowser, the echo cancellation functionality may not work and may produce a terrible
+ * feedback. It is recommended to use headphones or other microphone devices rather than the device
+ * in-built microphones.
The flag to enable echo cancellation for audio track.
* @param {Boolean|JSON} [options.video=false]
* Note that the current Edge browser implementation does not support the options.video.optional,
* options.video.deviceId, options.video.resolution and
@@ -24599,7 +27519,7 @@ Skylink.prototype.sendStream = function(options, callback) {
}
if (Object.keys(self._peerConnections).length > 0 || self._hasMCU) {
- self._refreshPeerConnection(Object.keys(self._peerConnections), false, function (err, success) {
+ self._refreshPeerConnection(Object.keys(self._peerConnections), false, {}, function (err, success) {
if (err) {
log.error('Failed refreshing connections for sendStream() ->', err);
if (typeof callback === 'function') {
@@ -24641,6 +27561,15 @@ Skylink.prototype.sendStream = function(options, callback) {
return;
}
+ if (window.webrtcDetectedBrowser === 'edge') {
+ var edgeNotSupportError = 'Edge browser currently does not support renegotiation.';
+ log.error(edgeNotSupportError, options);
+ if (typeof callback === 'function'){
+ callback(new Error(edgeNotSupportError),null);
+ }
+ return;
+ }
+
if (typeof options.getAudioTracks === 'function' || typeof options.getVideoTracks === 'function') {
var checkActiveTracksFn = function (tracks) {
for (var t = 0; t < tracks.length; t++) {
@@ -24983,27 +27912,50 @@ Skylink.prototype.disableVideo = function() {
* Function that retrieves screensharing Stream.
* @method shareScreen
* @param {JSON|Boolean} [enableAudio=false] The flag if audio tracks should be retrieved.
- * @param {Boolean} [enableAudio.stereo=false] The flag if stereo band should be configured
- * when encoding audio codec is OPUS for sending audio data.
- * @param {Boolean} [enableAudio.usedtx]
- * Note that this feature might not work depending on the browser support and implementation.
- * The flag if DTX (Discontinuous Transmission) should be configured when encoding audio codec
- * is OPUS for sending audio data.
- * This might help to reduce bandwidth it reduces the bitrate during silence or background noise.
+ * @param {Boolean} [enableAudio.stereo=false]
Deprecation Warning!
+ * This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo
+ * parameter in the init() method instead. If the
+ * options.codecParams.audio.opus.stereo is configured, this overrides the
+ * options.audio.stereo setting.
+ * The flag if OPUS audio codec stereo band should be configured for sending encoded audio data.
* When not provided, the default browser configuration is used.
- * @param {Boolean} [enableAudio.useinbandfec]
- * Note that this feature might not work depending on the browser support and implementation.
- * The flag if capability to take advantage of in-band FEC (Forward Error Correction) should be
- * configured when encoding audio codec is OPUS for sending audio data.
- * This might help to reduce the harm of packet loss by encoding information about the previous packet.
+ * @param {Boolean} [enableAudio.usedtx]
Deprecation Warning!
+ * This property has been deprecated. Configure this with the options.codecParams.audio.opus.stereo
+ * parameter in the init() method instead. If the
+ * options.codecParams.audio.opus.stereo is configured, this overrides the
+ * options.audio.stereo setting. Note that this feature might
+ * not work depending on the browser support and implementation.
+ * The flag if OPUS audio codec should enable DTX (Discontinuous Transmission) for sending encoded audio data.
+ * This might help to reduce bandwidth as it reduces the bitrate during silence or background noise, and
+ * goes hand-in-hand with the options.voiceActivityDetection flag in
+ * joinRoom() method.
* When not provided, the default browser configuration is used.
- * @param {Number} [enableAudio.maxplaybackrate]
- * Note that this feature might not work depending on the browser support and implementation.
- * The maximum output sampling rate rendered in Hertz (Hz) when encoding audio codec is
- * OPUS for sending audio data.
+ * @param {Boolean} [enableAudio.useinbandfec]
Deprecation Warning!
+ * This property has been deprecated. Configure this with the options.codecParams.audio.opus.useinbandfec
+ * parameter in the init() method instead. If the
+ * options.codecParams.audio.opus.useinbandfec is configured, this overrides the
+ * options.audio.useinbandfec setting. Note that this parameter should only be used
+ * for debugging purposes only.
+ * The flag if OPUS audio codec has the capability to take advantage of the in-band FEC
+ * (Forward Error Correction) when sending encoded audio data.
+ * This helps to reduce the harm of packet loss by encoding information about the previous packet loss.
+ * When not provided, the default browser configuration is used.
+ * @param {Number} [enableAudio.maxplaybackrate]
Deprecation Warning!
+ * This property has been deprecated. Configure this with the options.codecParams.audio.opus.maxplaybackrate
+ * parameter in the init() method instead. If the
+ * options.codecParams.audio.opus.maxplaybackrate is configured, this overrides the
+ * options.audio.maxplaybackrate setting. Note that this feature might
+ * not work depending on the browser support and implementation.
+ * Note that this parameter should only be used for debugging purposes only.
+ * The OPUS audio codec maximum output sampling rate in Hz (hertz) that is is capable of receiving
+ * decoded audio data, to adjust to the hardware limitations and ensure that any sending audio data
+ * would not encode at a higher sampling rate specified by this.
* This value must be between 8000 to 48000.
* When not provided, the default browser configuration is used.
- * @param {Boolean} [enableAudio.echoCancellation=false] The flag to enable audio tracks echo cancellation.
+ * @param {Boolean} [enableAudio.echoCancellation=true]
+ * For Chrome/Opera/IE/Safari/Bowser, the echo cancellation functionality may not work and may produce a terrible
+ * feedback. It is recommended to use headphones or other microphone devices rather than the device
+ * in-built microphones.