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.

176 lines
4.6 KiB

3 years ago
3 years ago
  1. // create Agora client
  2. var client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
  3. // Rtm
  4. var rtm_client = AgoraRTM.createInstance(window._APPID);
  5. rtm_client.login({ uid: window._MY_NAME, token: window._RTM_TOKEN});
  6. var rtm_channel = null;
  7. var localTracks = {
  8. audioTrack: null
  9. };
  10. var remoteUsers = {};
  11. // Agora client options
  12. var options = {
  13. appid: window._APPID,
  14. channel: null,
  15. uid: window._UID,
  16. token: null
  17. };
  18. function add_chat_text(s) {
  19. $('#chat-box').append($('<p></p>').text(s));
  20. $('#chat-box').animate({
  21. scrollTop: $("#chat-box")[0].scrollHeight
  22. }, 300);
  23. }
  24. $('.leave-btn').hide();
  25. $('#local-volume-range').on('input change', function() {
  26. if (localTracks.audioTrack)
  27. localTracks.audioTrack.setVolume(Math.floor($(this).val()**2));
  28. });
  29. $('.send-message').submit(async function (e) {
  30. e.preventDefault();
  31. if (!rtm_channel) {
  32. alert("还没有加入房间");
  33. return;
  34. }
  35. var inp = $(this).find('input');
  36. rtm_channel.sendMessage({'text': inp.val()}).then(() => {
  37. add_chat_text(window._MY_NAME + ': ' + inp.val());
  38. inp.val('');
  39. }).catch(error => {
  40. alert('发送失败', error);
  41. });
  42. });
  43. $('.join-form').submit(async function (e) {
  44. e.preventDefault();
  45. $(".join-btn").hide();
  46. $(this).serializeArray().forEach((v) => {
  47. options[v.name] = v.value;
  48. });
  49. options.uid = parseInt(options.uid);
  50. console.log(options);
  51. try {
  52. await join();
  53. $('.u-cnt').hide();
  54. rtm_channel = rtm_client.createChannel(options.channel);
  55. rtm_channel.join();
  56. rtm_channel.on('ChannelMessage', (message, user) => {
  57. console.log(message, user);
  58. if (message.messageType === 'TEXT') {
  59. add_chat_text(user + ': ' + message.text);
  60. }
  61. });
  62. rtm_channel.on('MemberJoined', memberId => {
  63. add_chat_text(`[${memberId} 加入了]`)
  64. });
  65. rtm_channel.on('MemberLeft', memberId => {
  66. add_chat_text(`[${memberId} 离开了]`)
  67. });
  68. } catch (error) {
  69. console.error(error);
  70. alert('出错啦\n' + error);
  71. window.location.reload();
  72. } finally {
  73. $(this).find(".leave-btn").show();
  74. }
  75. })
  76. $(".leave-btn").click(function (e) {
  77. leave();
  78. rtm_channel.leave();
  79. rtm_channel = null;
  80. $('#chat-box').empty();
  81. })
  82. function set_soundmeter(ele, at) {
  83. $(ele).val(($(ele).val() + at.getVolumeLevel())/2);
  84. }
  85. async function join() {
  86. // add event listener to play remote tracks when remote user publishs.
  87. client.on("user-published", handleUserPublished);
  88. client.on("user-unpublished", handleUserUnpublished);
  89. // join a channel and create local tracks, we can use Promise.all to run them concurrently
  90. [ options.uid, localTracks.audioTrack] = await Promise.all([
  91. // join the channel
  92. client.join(options.appid, options.channel, options.token || null, options.uid),
  93. // create local tracks, using microphone and camera
  94. AgoraRTC.createMicrophoneAudioTrack(),
  95. ]);
  96. localTracks.audioTrack.intervalId = window.setInterval(set_soundmeter, 25, '#local-player progress', localTracks.audioTrack);
  97. // publish local tracks to channel
  98. await client.publish(Object.values(localTracks));
  99. console.log("publish success");
  100. }
  101. async function leave() {
  102. var track = localTracks.audioTrack;
  103. if(track) {
  104. track.stop();
  105. track.close();
  106. window.clearInterval(track.intervalId);
  107. track = undefined;
  108. }
  109. // remove remote users and player views
  110. remoteUsers = {};
  111. $("#remote-playerlist").html("");
  112. // leave the channel
  113. await client.leave();
  114. $(".join-btn").show();
  115. $('.leave-btn').hide();
  116. console.log("client leaves channel success");
  117. }
  118. async function subscribe(user, mediaType) {
  119. const uid = user.uid;
  120. // subscribe to a remote user
  121. await client.subscribe(user, mediaType);
  122. console.log("subscribe success");
  123. $.getJSON(`api/user/${uid}`, function (user) {
  124. console.log(user);
  125. const player = $(`
  126. <div class="qbox" id="player-${uid}">
  127. <p>
  128. <a href="${user.url}" target="_blank">
  129. <img class="rounded-circle" src="${user.avat}" width="20">
  130. ${user.disp} @${user.acct}
  131. </a>
  132. )
  133. </p>
  134. <progress value="0" max="1"></progress>
  135. </div>
  136. `);
  137. $("#remote-playerlist").append(player);
  138. });
  139. user.audioTrack.play();
  140. user.intervalId = window.setInterval(set_soundmeter, 25, `#player-${uid} progress`, user.audioTrack);
  141. }
  142. function handleUserPublished(user, mediaType) {
  143. const id = user.uid;
  144. remoteUsers[id] = user;
  145. subscribe(user, mediaType);
  146. }
  147. function handleUserUnpublished(user) {
  148. window.clearInterval(user.intervalId);
  149. const id = user.uid;
  150. delete remoteUsers[id];
  151. $(`#player-${id}`).remove();
  152. }