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