File: source/peer-data.js

  1. /**
  2. * Function that overwrites the User current custom data.
  3. * @method setUserData
  4. * @param {JSON|String} userData The updated custom data.
  5. * @trigger <ol class="desc-seq">
  6. * <li>Updates User custom data. <ol>
  7. * <li>If User is in Room: <ol>
  8. * <li><a href="#event_peerUpdated"><code>peerUpdated</code> event</a> triggers with parameter payload
  9. * <code>isSelf</code> value as <code>true</code>.</li></ol></li></ol></li></ol>
  10. * @example
  11. * // Example 1: Set/Update User custom data before joinRoom()
  12. * var userData = "beforejoin";
  13. *
  14. * skylinkDemo.setUserData(userData);
  15. *
  16. * skylinkDemo.joinRoom(function (error, success) {
  17. * if (error) return;
  18. * if (success.peerInfo.userData === userData) {
  19. * console.log("User data is sent");
  20. * }
  21. * });
  22. *
  23. * // Example 2: Update User custom data after joinRoom()
  24. * var userData = "afterjoin";
  25. *
  26. * skylinkDemo.joinRoom(function (error, success) {
  27. * if (error) return;
  28. * skylinkDemo.setUserData(userData);
  29. * if (skylinkDemo.getPeerInfo().userData === userData) {
  30. * console.log("User data is updated and sent");
  31. * }
  32. * });
  33. * @for Skylink
  34. * @since 0.5.5
  35. */
  36. Skylink.prototype.setUserData = function(userData) {
  37. var self = this;
  38. var updatedUserData = '';
  39.  
  40. if (!(typeof userData === 'undefined' || userData === null)) {
  41. updatedUserData = userData;
  42. }
  43.  
  44. this._userData = updatedUserData;
  45.  
  46. if (self._inRoom) {
  47. log.log('Updated userData -> ', updatedUserData);
  48. self._sendChannelMessage({
  49. type: self._SIG_MESSAGE_TYPE.UPDATE_USER,
  50. mid: self._user.sid,
  51. rid: self._room.id,
  52. userData: updatedUserData,
  53. stamp: (new Date()).getTime()
  54. });
  55. self._trigger('peerUpdated', self._user.sid, self.getPeerInfo(), true);
  56. } else {
  57. log.warn('User is not in the room. Broadcast of updated information will be dropped');
  58. }
  59. };
  60.  
  61. /**
  62. * Function that returns the User / Peer current custom data.
  63. * @method getUserData
  64. * @param {String} [peerId] The Peer ID to return the current custom data from.
  65. * - When not provided or that the Peer ID is does not exists, it will return
  66. * the User current custom data.
  67. * @return {JSON|String} The User / Peer current custom data.
  68. * @example
  69. * // Example 1: Get Peer current custom data
  70. * var peerUserData = skylinkDemo.getUserData(peerId);
  71. *
  72. * // Example 2: Get User current custom data
  73. * var userUserData = skylinkDemo.getUserData();
  74. * @for Skylink
  75. * @since 0.5.10
  76. */
  77. Skylink.prototype.getUserData = function(peerId) {
  78. if (peerId && this._peerInformations[peerId]) {
  79. var userData = this._peerInformations[peerId].userData;
  80. if (!(userData !== null && typeof userData !== 'undefined')) {
  81. userData = '';
  82. }
  83. return userData;
  84. }
  85. return this._userData;
  86. };
  87.  
  88. /**
  89. * Function that returns the User / Peer current session information.
  90. * @method getPeerInfo
  91. * @param {String} [peerId] The Peer ID to return the current session information from.
  92. * - When not provided or that the Peer ID is does not exists, it will return
  93. * the User current session information.
  94. * @return {JSON} The User / Peer current session information.
  95. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  96. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small>
  97. * @example
  98. * // Example 1: Get Peer current session information
  99. * var peerPeerInfo = skylinkDemo.getPeerInfo(peerId);
  100. *
  101. * // Example 2: Get User current session information
  102. * var userPeerInfo = skylinkDemo.getPeerInfo();
  103. * @for Skylink
  104. * @since 0.4.0
  105. */
  106. Skylink.prototype.getPeerInfo = function(peerId) {
  107. var peerInfo = null;
  108.  
  109. if (typeof peerId === 'string' && typeof this._peerInformations[peerId] === 'object') {
  110. peerInfo = clone(this._peerInformations[peerId]);
  111. peerInfo.room = clone(this._selectedRoom);
  112. peerInfo.settings.bandwidth = peerInfo.settings.bandwidth || {};
  113. peerInfo.settings.googleXBandwidth = peerInfo.settings.googleXBandwidth || {};
  114.  
  115. if (!(typeof peerInfo.settings.video === 'boolean' || (peerInfo.settings.video &&
  116. typeof peerInfo.settings.video === 'object'))) {
  117. peerInfo.settings.video = false;
  118. peerInfo.mediaStatus.audioMuted = true;
  119. }
  120.  
  121. if (!(typeof peerInfo.settings.audio === 'boolean' || (peerInfo.settings.audio &&
  122. typeof peerInfo.settings.audio === 'object'))) {
  123. peerInfo.settings.audio = false;
  124. peerInfo.mediaStatus.audioMuted = true;
  125. }
  126.  
  127. if (typeof peerInfo.mediaStatus.audioMuted !== 'boolean') {
  128. peerInfo.mediaStatus.audioMuted = true;
  129. }
  130.  
  131. if (typeof peerInfo.mediaStatus.videoMuted !== 'boolean') {
  132. peerInfo.mediaStatus.videoMuted = true;
  133. }
  134.  
  135. if (peerInfo.settings.maxBandwidth) {
  136. peerInfo.settings.bandwidth = clone(peerInfo.settings.maxBandwidth);
  137. delete peerInfo.settings.maxBandwidth;
  138. }
  139.  
  140. if (peerInfo.settings.video && typeof peerInfo.settings.video === 'object' &&
  141. peerInfo.settings.video.customSettings && typeof peerInfo.settings.video.customSettings === 'object') {
  142. if (peerInfo.settings.video.customSettings.frameRate) {
  143. peerInfo.settings.video.frameRate = clone(peerInfo.settings.video.customSettings.frameRate);
  144. }
  145. if (peerInfo.settings.video.customSettings.facingMode) {
  146. peerInfo.settings.video.facingMode = clone(peerInfo.settings.video.customSettings.facingMode);
  147. }
  148. if (peerInfo.settings.video.customSettings.width) {
  149. peerInfo.settings.video.resolution = peerInfo.settings.video.resolution || {};
  150. peerInfo.settings.video.resolution.width = clone(peerInfo.settings.video.customSettings.width);
  151. }
  152. if (peerInfo.settings.video.customSettings.height) {
  153. peerInfo.settings.video.resolution = peerInfo.settings.video.resolution || {};
  154. peerInfo.settings.video.resolution.height = clone(peerInfo.settings.video.customSettings.height);
  155. }
  156. if (peerInfo.settings.video.customSettings.facingMode) {
  157. peerInfo.settings.video.facingMode = clone(peerInfo.settings.video.customSettings.facingMode);
  158. }
  159. }
  160.  
  161. if (peerInfo.settings.audio && typeof peerInfo.settings.audio === 'object') {
  162. peerInfo.settings.audio.stereo = peerInfo.settings.audio.stereo === true;
  163. }
  164.  
  165. if (!(peerInfo.userData !== null && typeof peerInfo.userData !== 'undefined')) {
  166. peerInfo.userData = '';
  167. }
  168.  
  169. peerInfo.parentId = peerInfo.parentId || null;
  170.  
  171. if (peerId === 'MCU') {
  172. peerInfo.config.receiveOnly = true;
  173. peerInfo.config.publishOnly = false;
  174. } else if (this._hasMCU) {
  175. peerInfo.config.receiveOnly = false;
  176. peerInfo.config.publishOnly = true;
  177. }
  178.  
  179. if (!this._sdpSettings.direction.audio.receive) {
  180. peerInfo.settings.audio = false;
  181. peerInfo.mediaStatus.audioMuted = true;
  182. }
  183.  
  184. if (!this._sdpSettings.direction.video.receive) {
  185. peerInfo.settings.video = false;
  186. peerInfo.mediaStatus.videoMuted = true;
  187. }
  188.  
  189. if (!this._sdpSettings.connection.audio) {
  190. peerInfo.settings.audio = false;
  191. peerInfo.mediaStatus.audioMuted = true;
  192. }
  193.  
  194. if (!this._sdpSettings.connection.video) {
  195. peerInfo.settings.video = false;
  196. peerInfo.mediaStatus.videoMuted = true;
  197. }
  198.  
  199. peerInfo.settings.data = !!(this._dataChannels[peerId] && this._dataChannels[peerId].main &&
  200. this._dataChannels[peerId].main.channel &&
  201. this._dataChannels[peerId].main.channel.readyState === this.DATA_CHANNEL_STATE.OPEN);
  202. peerInfo.connected = this._peerConnStatus[peerId] && !!this._peerConnStatus[peerId].connected;
  203. peerInfo.init = this._peerConnStatus[peerId] && !!this._peerConnStatus[peerId].init;
  204.  
  205. // Makes sense to be send direction since we are retrieving information if Peer is sending anything to us
  206. if (this._sdpSessions[peerId] && this._sdpSessions[peerId].remote &&
  207. this._sdpSessions[peerId].remote.connection && typeof this._sdpSessions[peerId].remote.connection === 'object') {
  208. if (!(this._sdpSessions[peerId].remote.connection.audio &&
  209. this._sdpSessions[peerId].remote.connection.audio.indexOf('send') > -1)) {
  210. peerInfo.settings.audio = false;
  211. peerInfo.mediaStatus.audioMuted = true;
  212. }
  213. if (!(this._sdpSessions[peerId].remote.connection.video &&
  214. this._sdpSessions[peerId].remote.connection.video.indexOf('send') > -1)) {
  215. peerInfo.settings.video = false;
  216. peerInfo.mediaStatus.videoMuted = true;
  217. }
  218. if (!(this._sdpSessions[peerId].remote.connection.data &&
  219. this._sdpSessions[peerId].remote.connection.data.indexOf('send') > -1)) {
  220. peerInfo.settings.data = false;
  221. }
  222. }
  223.  
  224. } else {
  225. peerInfo = {
  226. userData: clone(this._userData),
  227. settings: {
  228. audio: false,
  229. video: false
  230. },
  231. mediaStatus: clone(this._streamsMutedSettings),
  232. agent: {
  233. name: AdapterJS.webrtcDetectedBrowser,
  234. version: AdapterJS.webrtcDetectedVersion,
  235. os: window.navigator.platform,
  236. pluginVersion: AdapterJS.WebRTCPlugin.plugin ? AdapterJS.WebRTCPlugin.plugin.VERSION : null,
  237. SMProtocolVersion: this.SMProtocolVersion,
  238. DTProtocolVersion: this.DTProtocolVersion
  239. },
  240. room: clone(this._selectedRoom),
  241. config: {
  242. enableDataChannel: this._initOptions.enableDataChannel,
  243. enableIceTrickle: this._initOptions.enableIceTrickle,
  244. enableIceRestart: this._enableIceRestart,
  245. priorityWeight: this._peerPriorityWeight,
  246. receiveOnly: false,
  247. publishOnly: !!this._publishOnly
  248. },
  249. connected: null,
  250. init: null
  251. };
  252.  
  253. if (!(peerInfo.userData !== null && typeof peerInfo.userData !== 'undefined')) {
  254. peerInfo.userData = '';
  255. }
  256.  
  257. if (this._streams.screenshare) {
  258. peerInfo.settings = clone(this._streams.screenshare.settings);
  259. } else if (this._streams.userMedia) {
  260. peerInfo.settings = clone(this._streams.userMedia.settings);
  261. }
  262.  
  263. peerInfo.settings.bandwidth = clone(this._streamsBandwidthSettings.bAS);
  264. peerInfo.settings.googleXBandwidth = clone(this._streamsBandwidthSettings.googleX);
  265. peerInfo.parentId = this._parentId ? this._parentId : null;
  266. peerInfo.config.receiveOnly = !peerInfo.settings.video && !peerInfo.settings.audio;
  267. peerInfo.settings.data = this._initOptions.enableDataChannel && this._sdpSettings.connection.data;
  268.  
  269. if (peerInfo.settings.audio && typeof peerInfo.settings.audio === 'object') {
  270. // Override the settings.audio.usedtx
  271. if (typeof this._initOptions.codecParams.audio.opus.stereo === 'boolean') {
  272. peerInfo.settings.audio.stereo = this._initOptions.codecParams.audio.opus.stereo;
  273. }
  274. // Override the settings.audio.usedtx
  275. if (typeof this._initOptions.codecParams.audio.opus.usedtx === 'boolean') {
  276. peerInfo.settings.audio.usedtx = this._initOptions.codecParams.audio.opus.usedtx;
  277. }
  278. // Override the settings.audio.maxplaybackrate
  279. if (typeof this._initOptions.codecParams.audio.opus.maxplaybackrate === 'number') {
  280. peerInfo.settings.audio.maxplaybackrate = this._initOptions.codecParams.audio.opus.maxplaybackrate;
  281. }
  282. // Override the settings.audio.useinbandfec
  283. if (typeof this._initOptions.codecParams.audio.opus.useinbandfec === 'boolean') {
  284. peerInfo.settings.audio.useinbandfec = this._initOptions.codecParams.audio.opus.useinbandfec;
  285. }
  286. }
  287. }
  288.  
  289. if (!peerInfo.settings.audio) {
  290. peerInfo.mediaStatus.audioMuted = true;
  291. }
  292.  
  293. if (!peerInfo.settings.video) {
  294. peerInfo.mediaStatus.videoMuted = true;
  295. }
  296.  
  297. if (!peerInfo.settings.audio && !peerInfo.settings.video) {
  298. peerInfo.config.receiveOnly = true;
  299. peerInfo.config.publishOnly = false;
  300. }
  301.  
  302. return peerInfo;
  303. };
  304.  
  305. /**
  306. * Function that gets the list of connected Peers in the Room.
  307. * @method getPeersInRoom
  308. * @return {JSON} The list of connected Peers. <ul>
  309. * <li><code>#peerId</code><var><b>{</b>JSON<b>}</b></var><p>The Peer information.
  310. * <small>Object signature matches the <code>peerInfo</code> parameter payload received in the
  311. * <a href="#event_peerJoined"><code>peerJoined</code> event</a> except there is
  312. * the <code>isSelf</code> flag that determines if Peer is User or not.</small></p></li></ul>
  313. * @example
  314. * // Example 1: Get the list of currently connected Peers in the same Room
  315. * var peers = skylinkDemo.getPeersInRoom();
  316. * @for Skylink
  317. * @since 0.6.16
  318. */
  319. Skylink.prototype.getPeersInRoom = function() {
  320. var listOfPeersInfo = {};
  321. var listOfPeers = Object.keys(this._peerInformations);
  322.  
  323. for (var i = 0; i < listOfPeers.length; i++) {
  324. listOfPeersInfo[listOfPeers[i]] = clone(this.getPeerInfo(listOfPeers[i]));
  325. listOfPeersInfo[listOfPeers[i]].isSelf = false;
  326. }
  327.  
  328. if (this._user && this._user.sid) {
  329. listOfPeersInfo[this._user.sid] = clone(this.getPeerInfo());
  330. listOfPeersInfo[this._user.sid].isSelf = true;
  331. }
  332.  
  333. return listOfPeersInfo;
  334. };
  335.  
  336. /**
  337. * Function that gets the list of connected Peers Streams in the Room.
  338. * @method getPeersStream
  339. * @return {JSON} The list of Peers Stream. <ul>
  340. * <li><code>#peerId</code><var><b>{</b>JSON<b>}</b></var><p>The Peer Stream.</p><ul>
  341. * <li><code>stream</code><var><b>{</b>MediaStream<b>}</b></var><p>The Stream object.</p></li>
  342. * <li><code>streamId</code><var><b>{</b>String<b>}</b></var><p>The Stream ID.</p></li>
  343. * <li><code>isSelf</code><var><b>{</b>Boolean<b>}</b></var><p>The flag if Peer is User.</p></li>
  344. * </p></li></ul></li></ul>
  345. * @example
  346. * // Example 1: Get the list of current Peers Streams in the same Room
  347. * var streams = skylinkDemo.getPeersStream();
  348. * @for Skylink
  349. * @since 0.6.16
  350. */
  351. Skylink.prototype.getPeersStream = function() {
  352. var listOfPeersStreams = {};
  353. var listOfPeers = Object.keys(this._peerConnections);
  354.  
  355. for (var i = 0; i < listOfPeers.length; i++) {
  356. var stream = null;
  357. var streamId = null;
  358.  
  359. if (this._peerConnections[listOfPeers[i]] &&
  360. this._peerConnections[listOfPeers[i]].remoteDescription &&
  361. this._peerConnections[listOfPeers[i]].remoteDescription.sdp &&
  362. (this._sdpSettings.direction.audio.receive || this._sdpSettings.direction.video.receive)) {
  363. stream = this._peerConnections[listOfPeers[i]].remoteStream;
  364. streamId = stream && (this._peerConnections[listOfPeers[i]].remoteStreamId || stream.id || stream.label);
  365. }
  366.  
  367. listOfPeersStreams[listOfPeers[i]] = {
  368. streamId: streamId,
  369. stream: stream,
  370. isSelf: false
  371. };
  372. }
  373.  
  374. if (this._user && this._user.sid) {
  375. var selfStream = null;
  376.  
  377. if (this._streams.screenshare && this._streams.screenshare.stream) {
  378. selfStream = this._streams.screenshare.stream;
  379. } else if (this._streams.userMedia && this._streams.userMedia.stream) {
  380. selfStream = this._streams.userMedia.stream;
  381. }
  382.  
  383. listOfPeersStreams[this._user.sid] = {
  384. streamId: selfStream ? selfStream.id || selfStream.label || null : null,
  385. stream: selfStream,
  386. isSelf: true
  387. };
  388. }
  389.  
  390. return listOfPeersStreams;
  391. };
  392.  
  393. /**
  394. * Function that gets the current list of connected Peers Datachannel connections in the Room.
  395. * @method getPeersDatachannels
  396. * @return {JSON} The list of Peers Stream. <ul>
  397. * <li><code>#peerId</code><var><b>{</b>JSON<b>}</b></var><p>The Peer Datachannels information.</p><ul>
  398. * <li><code>#channelName</code><var><b>{</b>JSON<b>}</b></var><p>The Datachannel information.</p><ul>
  399. * <li><code>channelName</code><var><b>{</b>String<b>}</b></var><p>The Datachannel ID..</p><ul>
  400. * <li><code>channelType</code><var><b>{</b>String<b>}</b></var><p>The Datachannel type.
  401. * [Rel: Skylink.DATA_CHANNEL_TYPE]</p></li>
  402. * <li><code>channelProp</code><var><b>{</b>String<b>}</b></var><p>The Datachannel property.</p></li>
  403. * <li><code>currentTransferId</code><var><b>{</b>String<b>}</b></var><p>The Datachannel connection
  404. * current progressing transfer session. <small>Defined as <code>null</code> when there is
  405. * currently no transfer session progressing on the Datachannel connection.</small></p></li>
  406. * <li><code>currentStreamId</code><var><b>{</b>String<b>}</b></var><p>The Datachannel connection
  407. * current data streaming session ID. <small>Defined as <code>null</code> when there is currently
  408. * no data streaming session on the Datachannel connection.</small></p></li>
  409. * <li><code>readyState</code><var><b>{</b>String<b>}</b></var><p>The Datachannel connection readyState.
  410. * [Rel: Skylink.DATA_CHANNEL_STATE]</p></li>
  411. * <li><code>bufferedAmountLow</code><var><b>{</b>Number<b>}</b></var><p>The Datachannel buffered amount.</p></li>
  412. * <li><code>bufferedAmountLowThreshold</code><var><b>{</b>Number<b>}</b></var><p>The Datachannel
  413. * buffered amount threshold.</p></li>
  414. * </p></li></p></li></ul></li></ul></li></ul>
  415. * @example
  416. * // Example 1: Get the list of current Peers Datachannels in the same Room
  417. * var channels = skylinkDemo.getPeersDatachannels();
  418. * @for Skylink
  419. * @since 0.6.18
  420. */
  421. Skylink.prototype.getPeersDatachannels = function() {
  422. var listOfPeersDatachannels = {};
  423. var listOfPeers = Object.keys(this._peerConnections);
  424.  
  425. for (var i = 0; i < listOfPeers.length; i++) {
  426. listOfPeersDatachannels[listOfPeers[i]] = {};
  427.  
  428. if (this._dataChannels[listOfPeers[i]]) {
  429. for (var channelProp in this._dataChannels[listOfPeers[i]]) {
  430. if (this._dataChannels[listOfPeers[i]].hasOwnProperty(channelProp) &&
  431. this._dataChannels[listOfPeers[i]][channelProp]) {
  432. var channel = this._dataChannels[listOfPeers[i]][channelProp];
  433. listOfPeersDatachannels[listOfPeers[i]][channel.channelName] = this._getDataChannelBuffer(listOfPeers[i], channelProp);
  434. listOfPeersDatachannels[listOfPeers[i]][channel.channelName].channelName = channel.channelName;
  435. listOfPeersDatachannels[listOfPeers[i]][channel.channelName].channelType = channel.channelType;
  436. listOfPeersDatachannels[listOfPeers[i]][channel.channelName].channelProp = channelProp;
  437. listOfPeersDatachannels[listOfPeers[i]][channel.channelName].currentTransferId = channel.transferId;
  438. listOfPeersDatachannels[listOfPeers[i]][channel.channelName].currentStreamId = channel.streamId;
  439. listOfPeersDatachannels[listOfPeers[i]][channel.channelName].readyState = channel.channel ?
  440. channel.channel.readyState : self.DATA_CHANNEL_STATE.CREATE_ERROR;
  441. }
  442. }
  443. }
  444. }
  445.  
  446. return listOfPeersDatachannels;
  447. };
  448.  
  449. /**
  450. * Function that gets the list of current data transfers.
  451. * @method getCurrentDataTransfers
  452. * @return {JSON} The list of Peers Stream. <ul>
  453. * <li><code>#transferId</code><var><b>{</b>JSON<b>}</b></var><p>The data transfer session.</p><ul>
  454. * <li><code>transferInfo</code><var><b>{</b>JSON<b>}</b></var><p>The data transfer information.
  455. * <small>Object signature matches the <code>transferInfo</code> parameter payload received in the
  456. * <a href="#event_dataTransferState"><code>dataTransferState</code> event</a>
  457. * except without the <code>data</code> property.</small></p></li>
  458. * <li><code>peerId</code><var><b>{</b>String<b>}</b></var><p>The sender Peer ID.</p></li>
  459. * <li><code>isSelf</code><var><b>{</b>Boolean<b>}</b></var><p>The flag if Peer is User.</p></li>
  460. * </p></li></ul></li></ul>
  461. * @example
  462. * // Example 1: Get the list of current data transfers in the same Room
  463. * var currentTransfers = skylinkDemo.getCurrentDataTransfers();
  464. * @for Skylink
  465. * @since 0.6.18
  466. */
  467. Skylink.prototype.getCurrentDataTransfers = function() {
  468. var listOfDataTransfers = {};
  469.  
  470. if (!(this._user && this._user.sid)) {
  471. return {};
  472. }
  473.  
  474. for (var prop in this._dataTransfers) {
  475. if (this._dataTransfers.hasOwnProperty(prop) && this._dataTransfers[prop]) {
  476. listOfDataTransfers[prop] = {
  477. transferInfo: this._getTransferInfo(prop, this._user.sid, true, true, true),
  478. isSelf: this._dataTransfers[prop].senderPeerId === this._user.sid,
  479. peerId: this._dataTransfers[prop].senderPeerId || this._user.sid
  480. };
  481. }
  482. }
  483.  
  484. return listOfDataTransfers;
  485. };
  486.  
  487. /**
  488. * Function that gets the list of current data streaming sessions.
  489. * @method getCurrentDataStreamsSession
  490. * @return {JSON} The list of Peers Stream. <ul>
  491. * <li><code>#streamId</code><var><b>{</b>JSON<b>}</b></var><p>The data streaming session.</p><ul>
  492. * <li><code>streamInfo</code><var><b>{</b>JSON<b>}</b></var><p>The data streaming information.
  493. * <small>Object signature matches the <code>streamInfo</code> parameter payload received in the
  494. * <a href="#event_dataStreamState"><code>dataStreamState</code> event</a>
  495. * except without the <code>chunk</code> amd <code>chunkSize</code> property.</small></p></li>
  496. * <li><code>peerId</code><var><b>{</b>String<b>}</b></var><p>The sender Peer ID.</p></li>
  497. * <li><code>isSelf</code><var><b>{</b>Boolean<b>}</b></var><p>The flag if Peer is User.</p></li>
  498. * </p></li></ul></li></ul>
  499. * @example
  500. * // Example 1: Get the list of current data streaming sessions in the same Room
  501. * var currentDataStreams = skylinkDemo.getCurrentDataStreamsSession();
  502. * @for Skylink
  503. * @since 0.6.18
  504. */
  505. Skylink.prototype.getCurrentDataStreamsSession = function() {
  506. var listOfDataStreams = {};
  507.  
  508. if (!(this._user && this._user.sid)) {
  509. return {};
  510. }
  511.  
  512. for (var prop in this._dataStreams) {
  513. if (this._dataStreams.hasOwnProperty(prop) && this._dataStreams[prop]) {
  514. listOfDataStreams[prop] = {
  515. streamInfo: {
  516. chunkType: this._dataStreams[prop].sessionChunkType === 'string' ? this.DATA_TRANSFER_DATA_TYPE.STRING :
  517. this.DATA_TRANSFER_DATA_TYPE.BLOB,
  518. isPrivate: this._dataStreams[prop].isPrivate,
  519. isStringStream: this._dataStreams[prop].sessionChunkType === 'string',
  520. senderPeerId: this._dataStreams[prop].senderPeerId
  521. },
  522. isSelf: this._dataStreams[prop].senderPeerId === this._user.sid,
  523. peerId: this._dataStreams[prop].senderPeerId || this._user.sid
  524. };
  525. }
  526. }
  527.  
  528. return listOfDataStreams;
  529. };
  530.  
  531. /**
  532. * Function that gets the list of current custom Peer settings sent and set.
  533. * @method getPeerCustomSettings
  534. * @return {JSON} The list of Peers custom settings sent and set. <ul>
  535. * <li><code>#peerId</code><var><b>{</b>JSON<b>}</b></var><p>The Peer settings sent and set.</p><ul>
  536. * <li><code>settings</code><var><b>{</b>JSON<b>}</b></var><p>The custom Peer settings.
  537. * <small>Object signature matches the <code>peerInfo.settings</code> parameter payload received in the
  538. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small></p></li>
  539. * <li><code>mediaStatus</code><var><b>{</b>JSON<b>}</b></var><p>The custom Peer Stream muted settings.
  540. * <small>Object signature matches the <code>peerInfo.mediaStatus</code> parameter payload received in the
  541. * <a href="#event_peerJoined"><code>peerJoined</code> event</a>.</small></p></li></ul></li></ul>
  542. * @example
  543. * // Example 1: Get the list of current Peer custom settings
  544. * var currentPeerSettings = skylinkDemo.getPeersCustomSettings();
  545. * @for Skylink
  546. * @since 0.6.18
  547. */
  548. Skylink.prototype.getPeersCustomSettings = function () {
  549. var self = this;
  550. var customSettingsList = {};
  551.  
  552. for (var peerId in self._peerInformations) {
  553. if (self._peerInformations.hasOwnProperty(peerId) && self._peerInformations[peerId]) {
  554. customSettingsList[peerId] = self._getPeerCustomSettings(peerId);
  555. }
  556. }
  557.  
  558. return customSettingsList;
  559. };
  560.  
  561. /**
  562. * Function that returns the Peer custom settings.
  563. * @method _getPeerCustomSettings
  564. * @private
  565. * @for Skylink
  566. * @since 0.6.21
  567. */
  568. Skylink.prototype._getPeerCustomSettings = function (peerId) {
  569. var self = this;
  570. var customSettings = {
  571. settings: {
  572. audio: false,
  573. video: false,
  574. data: false,
  575. bandwidth: clone(self._streamsBandwidthSettings.bAS),
  576. googleXBandwidth: clone(self._streamsBandwidthSettings.googleX)
  577. },
  578. mediaStatus: {
  579. audioMuted: true,
  580. videoMuted: true
  581. }
  582. };
  583.  
  584. var usePeerId = self._hasMCU ? 'MCU' : peerId;
  585.  
  586. if (!self._peerInformations[usePeerId]) {
  587. return customSettings;
  588. }
  589.  
  590.  
  591. if (self._peerConnections[usePeerId] && self._peerConnections[usePeerId].signalingState !== self.PEER_CONNECTION_STATE.CLOSED) {
  592. var stream = self._peerConnections[usePeerId].localStream;
  593. var streamId = self._peerConnections[usePeerId].localStreamId || (stream && (stream.id || stream.label));
  594.  
  595. customSettings.settings.data = self._initOptions.enableDataChannel && self._peerInformations[usePeerId].config.enableDataChannel;
  596.  
  597. if (stream) {
  598. if (self._streams.screenshare && self._streams.screenshare.stream &&
  599. streamId === (self._streams.screenshare.stream.id || self._streams.screenshare.stream.label)) {
  600. customSettings.settings.audio = clone(self._streams.screenshare.settings.audio);
  601. customSettings.settings.video = clone(self._streams.screenshare.settings.video);
  602. customSettings.mediaStatus = clone(self._streamsMutedSettings);
  603.  
  604. } else if (self._streams.userMedia && self._streams.userMedia.stream &&
  605. streamId === (self._streams.userMedia.stream.id || self._streams.userMedia.stream.label)) {
  606. customSettings.settings.audio = clone(self._streams.userMedia.settings.audio);
  607. customSettings.settings.video = clone(self._streams.userMedia.settings.video);
  608. customSettings.mediaStatus = clone(self._streamsMutedSettings);
  609. }
  610.  
  611. if (typeof self._peerConnections[usePeerId].getSenders === 'function' &&
  612. !(self._initOptions.useEdgeWebRTC && window.msRTCPeerConnection)) {
  613. var senders = self._peerConnections[usePeerId].getSenders();
  614. var hasSendAudio = false;
  615. var hasSendVideo = false;
  616.  
  617. for (var i = 0; i < senders.length; i++) {
  618. if (!(senders[i] && senders[i].track && senders[i].track.kind)) {
  619. continue;
  620. }
  621. if (senders[i].track.kind === 'audio') {
  622. hasSendAudio = true;
  623. } else if (senders[i].track.kind === 'video') {
  624. hasSendVideo = true;
  625. }
  626. }
  627.  
  628. if (!hasSendAudio) {
  629. customSettings.settings.audio = false;
  630. customSettings.mediaStatus.audioMuted = true;
  631. }
  632.  
  633. if (!hasSendVideo) {
  634. customSettings.settings.video = false;
  635. customSettings.mediaStatus.videoMuted = true;
  636. }
  637. }
  638. }
  639. }
  640.  
  641. if (self._peerCustomConfigs[usePeerId]) {
  642. if (self._peerCustomConfigs[usePeerId].bandwidth &&
  643. typeof self._peerCustomConfigs[usePeerId].bandwidth === 'object') {
  644. if (typeof self._peerCustomConfigs[usePeerId].bandwidth.audio === 'number') {
  645. customSettings.settings.bandwidth.audio = self._peerCustomConfigs[usePeerId].bandwidth.audio;
  646. }
  647. if (typeof self._peerCustomConfigs[usePeerId].bandwidth.video === 'number') {
  648. customSettings.settings.bandwidth.video = self._peerCustomConfigs[usePeerId].bandwidth.video;
  649. }
  650. if (typeof self._peerCustomConfigs[usePeerId].bandwidth.data === 'number') {
  651. customSettings.settings.bandwidth.data = self._peerCustomConfigs[usePeerId].bandwidth.data;
  652. }
  653. }
  654. if (self._peerCustomConfigs[usePeerId].googleXBandwidth &&
  655. typeof self._peerCustomConfigs[usePeerId].googleXBandwidth === 'object') {
  656. if (typeof self._peerCustomConfigs[usePeerId].googleXBandwidth.min === 'number') {
  657. customSettings.settings.googleXBandwidth.min = self._peerCustomConfigs[usePeerId].googleXBandwidth.min;
  658. }
  659. if (typeof self._peerCustomConfigs[usePeerId].googleXBandwidth.max === 'number') {
  660. customSettings.settings.googleXBandwidth.max = self._peerCustomConfigs[usePeerId].googleXBandwidth.max;
  661. }
  662. }
  663. }
  664.  
  665. // Check we are going to send data to peer
  666. if (self._sdpSessions[usePeerId] && self._sdpSessions[usePeerId].local &&
  667. self._sdpSessions[usePeerId].local.connection && typeof self._sdpSessions[usePeerId].local.connection === 'object') {
  668. if (!(self._sdpSessions[usePeerId].local.connection.audio &&
  669. self._sdpSessions[usePeerId].local.connection.audio.indexOf('send') > -1)) {
  670. customSettings.settings.audio = false;
  671. customSettings.mediaStatus.audioMuted = true;
  672. }
  673. if (!(self._sdpSessions[usePeerId].local.connection.video &&
  674. self._sdpSessions[usePeerId].local.connection.video.indexOf('send') > -1)) {
  675. customSettings.settings.video = false;
  676. customSettings.mediaStatus.videoMuted = true;
  677. }
  678. if (!(self._sdpSessions[usePeerId].local.connection.data &&
  679. self._sdpSessions[usePeerId].local.connection.data.indexOf('send') > -1)) {
  680. customSettings.settings.data = false;
  681. }
  682. }
  683.  
  684. return customSettings;
  685. };
  686.  
  687. /**
  688. * Function that returns the User session information to be sent to Peers.
  689. * @method _getUserInfo
  690. * @private
  691. * @for Skylink
  692. * @since 0.4.0
  693. */
  694. Skylink.prototype._getUserInfo = function(peerId) {
  695. var userInfo = clone(this.getPeerInfo());
  696. var userCustomInfoForPeer = peerId ? this._getPeerCustomSettings(peerId) : null;
  697.  
  698. if (userCustomInfoForPeer && typeof userCustomInfoForPeer === 'object') {
  699. userInfo.settings = userCustomInfoForPeer.settings;
  700. userInfo.mediaStatus = userCustomInfoForPeer.mediaStatus;
  701. }
  702.  
  703. // Adhere to SM protocol without breaking the other SDKs.
  704. if (userInfo.settings.video && typeof userInfo.settings.video === 'object') {
  705. userInfo.settings.video.customSettings = {};
  706.  
  707. if (userInfo.settings.video.frameRate && typeof userInfo.settings.video.frameRate === 'object') {
  708. userInfo.settings.video.customSettings.frameRate = clone(userInfo.settings.video.frameRate);
  709. userInfo.settings.video.frameRate = -1;
  710. }
  711.  
  712. if (userInfo.settings.video.facingMode && typeof userInfo.settings.video.facingMode === 'object') {
  713. userInfo.settings.video.customSettings.facingMode = clone(userInfo.settings.video.facingMode);
  714. userInfo.settings.video.facingMode = '-1';
  715. }
  716.  
  717. if (userInfo.settings.video.resolution && typeof userInfo.settings.video.resolution === 'object') {
  718. if (userInfo.settings.video.resolution.width && typeof userInfo.settings.video.resolution.width === 'object') {
  719. userInfo.settings.video.customSettings.width = clone(userInfo.settings.video.width);
  720. userInfo.settings.video.resolution.width = -1;
  721. }
  722.  
  723. if (userInfo.settings.video.resolution.height && typeof userInfo.settings.video.resolution.height === 'object') {
  724. userInfo.settings.video.customSettings.height = clone(userInfo.settings.video.height);
  725. userInfo.settings.video.resolution.height = -1;
  726. }
  727. }
  728. }
  729.  
  730. if (userInfo.settings.bandwidth) {
  731. userInfo.settings.maxBandwidth = clone(userInfo.settings.bandwidth);
  732. delete userInfo.settings.bandwidth;
  733. }
  734.  
  735. if (!this._getSDPCommonSupports(peerId).video) {
  736. userInfo.settings.video = false;
  737. userInfo.mediaStatus.videoMuted = true;
  738. }
  739.  
  740. if (!this._getSDPCommonSupports(peerId).audio) {
  741. userInfo.settings.audio = false;
  742. userInfo.mediaStatus.audioMuted = true;
  743. }
  744.  
  745. delete userInfo.agent;
  746. delete userInfo.room;
  747. delete userInfo.config;
  748. delete userInfo.parentId;
  749. delete userInfo.settings.data;
  750. return userInfo;
  751. };
  752.