Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

load-test-participant.js 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /* global $, config, JitsiMeetJS */
  2. import 'jquery';
  3. import { setConfigFromURLParams } from '../../react/features/base/config/functions';
  4. import { parseURLParams } from '../../react/features/base/util/parseURLParams';
  5. import { parseURIString } from '../../react/features/base/util/uri';
  6. setConfigFromURLParams(config, {}, {}, window.location);
  7. const params = parseURLParams(window.location, false, 'hash');
  8. const { isHuman = false } = params;
  9. const {
  10. localVideo = config.startWithVideoMuted !== true,
  11. remoteVideo = isHuman,
  12. remoteAudio = isHuman,
  13. autoPlayVideo = config.testing.noAutoPlayVideo !== true,
  14. // Whether to create local audio even if muted
  15. autoCreateLocalAudio = config.testing.noAutoLocalAudio !== true
  16. } = params;
  17. let {
  18. localAudio = config.startWithAudioMuted !== true,
  19. } = params;
  20. const { room: roomName } = parseURIString(window.location.toString());
  21. let connection = null;
  22. let room = null;
  23. let numParticipants = 1;
  24. let localTracks = [];
  25. const remoteTracks = {};
  26. let maxFrameHeight = 0;
  27. window.APP = {
  28. conference: {
  29. getStats() {
  30. return room.connectionQuality.getStats();
  31. },
  32. getConnectionState() {
  33. return room && room.getConnectionState();
  34. },
  35. muteAudio(mute) {
  36. // Note: will have no effect if !autoCreateLocalAudio
  37. localAudio = mute;
  38. for (let i = 0; i < localTracks.length; i++) {
  39. if (localTracks[i].getType() === 'audio') {
  40. if (mute) {
  41. localTracks[i].mute();
  42. }
  43. else {
  44. localTracks[i].unmute();
  45. }
  46. }
  47. }
  48. }
  49. },
  50. get room() {
  51. return room;
  52. },
  53. get connection() {
  54. return connection;
  55. },
  56. get numParticipants() {
  57. return numParticipants;
  58. },
  59. get localTracks() {
  60. return localTracks;
  61. },
  62. get remoteTracks() {
  63. return remoteTracks;
  64. },
  65. get params() {
  66. return {
  67. roomName,
  68. localAudio,
  69. localVideo,
  70. remoteVideo,
  71. remoteAudio,
  72. autoPlayVideo
  73. };
  74. }
  75. };
  76. /**
  77. * Simple emulation of jitsi-meet's screen layout behavior
  78. */
  79. function updateMaxFrameHeight() {
  80. let newMaxFrameHeight;
  81. if (numParticipants <= 2) {
  82. newMaxFrameHeight = 720;
  83. } else if (numParticipants <= 4) {
  84. newMaxFrameHeight = 360;
  85. } else {
  86. newMaxFrameHeight = 180;
  87. }
  88. if (room && maxFrameHeight !== newMaxFrameHeight) {
  89. maxFrameHeight = newMaxFrameHeight;
  90. room.setReceiverVideoConstraint(maxFrameHeight);
  91. }
  92. }
  93. /**
  94. *
  95. */
  96. function setNumberOfParticipants() {
  97. $('#participants').text(numParticipants);
  98. updateMaxFrameHeight();
  99. }
  100. /**
  101. * Handles local tracks.
  102. * @param tracks Array with JitsiTrack objects
  103. */
  104. function onLocalTracks(tracks = []) {
  105. localTracks = tracks;
  106. for (let i = 0; i < localTracks.length; i++) {
  107. if (localTracks[i].getType() === 'video') {
  108. $('body').append(`<video ${autoPlayVideo ? 'autoplay="1" ' : ''}id='localVideo${i}' />`);
  109. localTracks[i].attach($(`#localVideo${i}`)[0]);
  110. } else {
  111. if (!localAudio) {
  112. localTracks[i].mute();
  113. }
  114. $('body').append(
  115. `<audio autoplay='1' muted='true' id='localAudio${i}' />`);
  116. localTracks[i].attach($(`#localAudio${i}`)[0]);
  117. }
  118. room.addTrack(localTracks[i]);
  119. }
  120. }
  121. /**
  122. * Handles remote tracks
  123. * @param track JitsiTrack object
  124. */
  125. function onRemoteTrack(track) {
  126. if (track.isLocal()
  127. || (track.getType() === 'video' && !remoteVideo) || (track.getType() === 'audio' && !remoteAudio)) {
  128. return;
  129. }
  130. const participant = track.getParticipantId();
  131. if (!remoteTracks[participant]) {
  132. remoteTracks[participant] = [];
  133. }
  134. const idx = remoteTracks[participant].push(track);
  135. const id = participant + track.getType() + idx;
  136. if (track.getType() === 'video') {
  137. $('body').append(`<video autoplay='1' id='${id}' />`);
  138. } else {
  139. $('body').append(`<audio autoplay='1' id='${id}' />`);
  140. }
  141. track.attach($(`#${id}`)[0]);
  142. }
  143. /**
  144. * That function is executed when the conference is joined
  145. */
  146. function onConferenceJoined() {
  147. console.log('Conference joined');
  148. }
  149. /**
  150. * Handles start muted events, when audio and/or video are muted due to
  151. * startAudioMuted or startVideoMuted policy.
  152. */
  153. function onStartMuted() {
  154. // Give it some time, as it may be currently in the process of muting
  155. setTimeout(() => {
  156. const localAudioTrack = room.getLocalAudioTrack();
  157. if (localAudio && localAudioTrack && localAudioTrack.isMuted()) {
  158. localAudioTrack.unmute();
  159. }
  160. const localVideoTrack = room.getLocalVideoTrack();
  161. if (localVideo && localVideoTrack && localVideoTrack.isMuted()) {
  162. localVideoTrack.unmute();
  163. }
  164. }, 2000);
  165. }
  166. /**
  167. *
  168. * @param id
  169. */
  170. function onUserLeft(id) {
  171. numParticipants--;
  172. setNumberOfParticipants();
  173. if (!remoteTracks[id]) {
  174. return;
  175. }
  176. const tracks = remoteTracks[id];
  177. for (let i = 0; i < tracks.length; i++) {
  178. const container = $(`#${id}${tracks[i].getType()}${i + 1}`)[0];
  179. if (container) {
  180. tracks[i].detach(container);
  181. container.parentElement.removeChild(container);
  182. }
  183. }
  184. }
  185. /**
  186. * That function is called when connection is established successfully
  187. */
  188. function onConnectionSuccess() {
  189. room = connection.initJitsiConference(roomName.toLowerCase(), config);
  190. room.on(JitsiMeetJS.events.conference.STARTED_MUTED, onStartMuted);
  191. room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
  192. room.on(JitsiMeetJS.events.conference.CONFERENCE_JOINED, onConferenceJoined);
  193. room.on(JitsiMeetJS.events.conference.USER_JOINED, id => {
  194. numParticipants++;
  195. setNumberOfParticipants();
  196. remoteTracks[id] = [];
  197. });
  198. room.on(JitsiMeetJS.events.conference.USER_LEFT, onUserLeft);
  199. const devices = [];
  200. if (localVideo) {
  201. devices.push('video');
  202. }
  203. if (localAudio || autoCreateLocalAudio) {
  204. devices.push('audio');
  205. }
  206. if (devices.length > 0) {
  207. JitsiMeetJS.createLocalTracks({ devices })
  208. .then(onLocalTracks)
  209. .then(() => {
  210. room.join();
  211. })
  212. .catch(error => {
  213. throw error;
  214. });
  215. } else {
  216. room.join();
  217. }
  218. updateMaxFrameHeight();
  219. }
  220. /**
  221. * This function is called when the connection fail.
  222. */
  223. function onConnectionFailed() {
  224. console.error('Connection Failed!');
  225. }
  226. /**
  227. * This function is called when we disconnect.
  228. */
  229. function disconnect() {
  230. console.log('disconnect!');
  231. connection.removeEventListener(
  232. JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,
  233. onConnectionSuccess);
  234. connection.removeEventListener(
  235. JitsiMeetJS.events.connection.CONNECTION_FAILED,
  236. onConnectionFailed);
  237. connection.removeEventListener(
  238. JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED,
  239. disconnect);
  240. }
  241. /**
  242. *
  243. */
  244. function unload() {
  245. for (let i = 0; i < localTracks.length; i++) {
  246. localTracks[i].dispose();
  247. }
  248. room.leave();
  249. connection.disconnect();
  250. }
  251. $(window).bind('beforeunload', unload);
  252. $(window).bind('unload', unload);
  253. JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.ERROR);
  254. JitsiMeetJS.init(config);
  255. config.serviceUrl = config.bosh = `${config.websocket || config.bosh}?room=${roomName.toLowerCase()}`;
  256. if (config.websocketKeepAliveUrl) {
  257. config.websocketKeepAliveUrl += `?room=${roomName.toLowerCase()}`;
  258. }
  259. connection = new JitsiMeetJS.JitsiConnection(null, null, config);
  260. connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED, onConnectionSuccess);
  261. connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_FAILED, onConnectionFailed);
  262. connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED, disconnect);
  263. connection.connect();