You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

example.js 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /* global $, JitsiMeetJS */
  2. var options = {
  3. hosts: {
  4. domain: 'jitsi-meet.example.com',
  5. muc: 'conference.jitsi-meet.example.com', // FIXME: use XEP-0030
  6. },
  7. bosh: '//jitsi-meet.example.com/http-bind', // FIXME: use xep-0156 for that
  8. clientNode: 'http://jitsi.org/jitsimeet', // The name of client node advertised in XEP-0115 'c' stanza
  9. };
  10. var confOptions = {
  11. openSctp: true
  12. };
  13. var isJoined = false;
  14. /**
  15. * Handles local tracks.
  16. * @param tracks Array with JitsiTrack objects
  17. */
  18. function onLocalTracks(tracks){
  19. localTracks = tracks;
  20. for(var i = 0; i < localTracks.length; i++) {
  21. localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
  22. function (audioLevel) {
  23. console.log("Audio Level local: " + audioLevel);
  24. });
  25. localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
  26. function () {
  27. console.log("local track muted");
  28. });
  29. localTracks[i].addEventListener(JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
  30. function () {
  31. console.log("local track stoped");
  32. });
  33. localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,
  34. function (deviceId) {
  35. console.log("track audio output device was changed to " + deviceId);
  36. });
  37. if(localTracks[i].getType() == "video") {
  38. $("body").append("<video autoplay='1' id='localVideo" + i + "' />");
  39. localTracks[i].attach($("#localVideo" + i)[0]);
  40. } else {
  41. $("body").append("<audio autoplay='1' muted='true' id='localAudio" + i + "' />");
  42. localTracks[i].attach($("#localAudio" + i)[0]);
  43. }
  44. if(isJoined) {
  45. room.addTrack(localTracks[i]);
  46. }
  47. }
  48. }
  49. /**
  50. * Handles remote tracks
  51. * @param track JitsiTrack object
  52. */
  53. function onRemoteTrack(track) {
  54. if(track.isLocal()) {
  55. return;
  56. }
  57. var participant = track.getParticipantId();
  58. if(!remoteTracks[participant]) {
  59. remoteTracks[participant] = [];
  60. }
  61. var idx = remoteTracks[participant].push(track);
  62. track.addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
  63. function (audioLevel) {
  64. console.log("Audio Level remote: " + audioLevel);
  65. });
  66. track.addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
  67. function () {
  68. console.log("remote track muted");
  69. });
  70. track.addEventListener(JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
  71. function () {
  72. console.log("remote track stoped");
  73. });
  74. track.addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,
  75. function (deviceId) {
  76. console.log("track audio output device was changed to " + deviceId);
  77. });
  78. var id = participant + track.getType() + idx;
  79. if(track.getType() == "video") {
  80. $("body").append("<video autoplay='1' id='" + participant + "video" + idx + "' />");
  81. } else {
  82. $("body").append("<audio autoplay='1' id='" + participant + "audio" + idx + "' />");
  83. }
  84. track.attach($("#" + id)[0]);
  85. }
  86. /**
  87. * That function is executed when the conference is joined
  88. */
  89. function onConferenceJoined () {
  90. console.log("conference joined!");
  91. isJoined = true;
  92. for(var i = 0; i < localTracks.length; i++) {
  93. room.addTrack(localTracks[i]);
  94. }
  95. }
  96. function onUserLeft(id) {
  97. console.log("user left");
  98. if(!remoteTracks[id]) {
  99. return;
  100. }
  101. var tracks = remoteTracks[id];
  102. for(var i = 0; i< tracks.length; i++) {
  103. tracks[i].detach($("#" + id + tracks[i].getType()));
  104. }
  105. }
  106. /**
  107. * That function is called when connection is established successfully
  108. */
  109. function onConnectionSuccess(){
  110. room = connection.initJitsiConference("conference", confOptions);
  111. room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
  112. room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, function (track) {
  113. console.log("track removed!!!" + track);
  114. });
  115. room.on(JitsiMeetJS.events.conference.CONFERENCE_JOINED, onConferenceJoined);
  116. room.on(JitsiMeetJS.events.conference.USER_JOINED, function(id){
  117. console.log("user join");remoteTracks[id] = [];
  118. });
  119. room.on(JitsiMeetJS.events.conference.USER_LEFT, onUserLeft);
  120. room.on(JitsiMeetJS.events.conference.TRACK_MUTE_CHANGED, function (track) {
  121. console.log(track.getType() + " - " + track.isMuted());
  122. });
  123. room.on(JitsiMeetJS.events.conference.DISPLAY_NAME_CHANGED, function (userID, displayName) {
  124. console.log(userID + " - " + displayName);
  125. });
  126. room.on(JitsiMeetJS.events.conference.TRACK_AUDIO_LEVEL_CHANGED,
  127. function(userID, audioLevel){
  128. console.log(userID + " - " + audioLevel);
  129. });
  130. room.on(JitsiMeetJS.events.conference.RECORDER_STATE_CHANGED, function () {
  131. console.log(room.isRecordingSupported() + " - " +
  132. room.getRecordingState() + " - " +
  133. room.getRecordingURL());
  134. });
  135. room.on(JitsiMeetJS.events.conference.PHONE_NUMBER_CHANGED, function () {
  136. console.log(
  137. room.getPhoneNumber() + " - " +
  138. room.getPhonePin());
  139. });
  140. room.join();
  141. }
  142. /**
  143. * This function is called when the connection fail.
  144. */
  145. function onConnectionFailed() {
  146. console.error("Connection Failed!");
  147. }
  148. /**
  149. * This function is called when the connection fail.
  150. */
  151. function onDeviceListChanged(devices) {
  152. console.info('current devices', devices);
  153. }
  154. /**
  155. * This function is called when we disconnect.
  156. */
  157. function disconnect(){
  158. console.log("disconnect!");
  159. connection.removeEventListener(JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED, onConnectionSuccess);
  160. connection.removeEventListener(JitsiMeetJS.events.connection.CONNECTION_FAILED, onConnectionFailed);
  161. connection.removeEventListener(JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED, disconnect);
  162. }
  163. function unload() {
  164. for(var i = 0; i < localTracks.length; i++) {
  165. localTracks[i].stop();
  166. }
  167. room.leave();
  168. connection.disconnect();
  169. }
  170. var isVideo = true;
  171. function switchVideo() { // eslint-disable-line no-unused-vars
  172. isVideo = !isVideo;
  173. if(localTracks[1]) {
  174. localTracks[1].dispose();
  175. localTracks.pop();
  176. }
  177. JitsiMeetJS.createLocalTracks({devices: isVideo? ["video"] : ["desktop"]}).
  178. then(function (tracks) {
  179. localTracks.push(tracks[0]);
  180. localTracks[1].addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
  181. function () {
  182. console.log("local track muted");
  183. });
  184. localTracks[1].addEventListener(JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
  185. function () {
  186. console.log("local track stoped");
  187. });
  188. localTracks[1].attach($("#localVideo1")[0]);
  189. room.addTrack(localTracks[1]);
  190. }).catch(function (error) {
  191. console.log(error);
  192. });
  193. }
  194. function changeAudioOutput(selected) { // eslint-disable-line no-unused-vars
  195. JitsiMeetJS.mediaDevices.setAudioOutputDevice(selected.value);
  196. }
  197. $(window).bind('beforeunload', unload);
  198. $(window).bind('unload', unload);
  199. // JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.ERROR);
  200. var initOptions = {
  201. disableAudioLevels: true,
  202. // The ID of the jidesha extension for Chrome.
  203. desktopSharingChromeExtId: 'mbocklcggfhnbahlnepmldehdhpjfcjp',
  204. // Whether desktop sharing should be disabled on Chrome.
  205. desktopSharingChromeDisabled: false,
  206. // The media sources to use when using screen sharing with the Chrome
  207. // extension.
  208. desktopSharingChromeSources: ['screen', 'window'],
  209. // Required version of Chrome extension
  210. desktopSharingChromeMinExtVersion: '0.1',
  211. // The ID of the jidesha extension for Firefox. If null, we assume that no
  212. // extension is required.
  213. desktopSharingFirefoxExtId: null,
  214. // Whether desktop sharing should be disabled on Firefox.
  215. desktopSharingFirefoxDisabled: true,
  216. // The maximum version of Firefox which requires a jidesha extension.
  217. // Example: if set to 41, we will require the extension for Firefox versions
  218. // up to and including 41. On Firefox 42 and higher, we will run without the
  219. // extension.
  220. // If set to -1, an extension will be required for all versions of Firefox.
  221. desktopSharingFirefoxMaxVersionExtRequired: -1,
  222. // The URL to the Firefox extension for desktop sharing.
  223. desktopSharingFirefoxExtensionURL: null
  224. };
  225. JitsiMeetJS.init(initOptions).then(function(){
  226. connection = new JitsiMeetJS.JitsiConnection(null, null, options);
  227. connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED, onConnectionSuccess);
  228. connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_FAILED, onConnectionFailed);
  229. connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED, disconnect);
  230. JitsiMeetJS.mediaDevices.addEventListener(JitsiMeetJS.events.mediaDevices.DEVICE_LIST_CHANGED, onDeviceListChanged);
  231. connection.connect();
  232. JitsiMeetJS.createLocalTracks({devices: ["audio", "video"]}).
  233. then(onLocalTracks).catch(function (error) {
  234. throw error;
  235. });
  236. }).catch(function (error) {
  237. console.log(error);
  238. });
  239. if (JitsiMeetJS.mediaDevices.isDeviceChangeAvailable('output')) {
  240. JitsiMeetJS.mediaDevices.enumerateDevices(function(devices) {
  241. var audioOutputDevices = devices.filter(function(d) {
  242. return d.kind === 'audiooutput';
  243. });
  244. if (audioOutputDevices.length > 1) {
  245. $('#audioOutputSelect').html(
  246. audioOutputDevices.map(function (d) {
  247. return '<option value="' + d.deviceId + '">' + d.label + '</option>';
  248. }).join('\n')
  249. );
  250. $('#audioOutputSelectWrapper').show();
  251. }
  252. });
  253. }
  254. var connection = null;
  255. var room = null;
  256. var localTracks = [];
  257. var remoteTracks = {};