room.html 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>SRS</title>
  5. <meta charset="utf-8">
  6. <style>
  7. body{
  8. padding-top: 30px;
  9. }
  10. </style>
  11. <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
  12. <script type="text/javascript" src="js/jquery-1.12.2.min.js"></script>
  13. <script type="text/javascript" src="js/adapter-7.4.0.min.js"></script>
  14. <script type="text/javascript" src="js/srs.sdk.js"></script>
  15. <script type="text/javascript" src="js/srs.sig.js"></script>
  16. </head>
  17. <body>
  18. <img src='https://ossrs.net/gif/v1/sls.gif?site=ossrs.net&path=/player/room'/>
  19. <div class="navbar navbar-fixed-top">
  20. <div class="navbar-inner">
  21. <div class="container">
  22. <a class="brand" href="https://github.com/ossrs/srs">SRS</a>
  23. <div class="nav-collapse collapse">
  24. <ul class="nav srs_nav">
  25. <li><a href="one2one.html">一对一通话</a></li>
  26. <li class="active"><a href="room.html">多人通话</a></li>
  27. <li class="srs_ignore">
  28. <a href="https://github.com/ossrs/signaling">
  29. <img alt="GitHub Repo stars" src="img/shields-io-signaling.svg">
  30. </a>
  31. </li>
  32. </ul>
  33. </div>
  34. </div>
  35. </div>
  36. </div>
  37. <div class="container">
  38. <div class="form-inline">
  39. SRS:
  40. <input type="text" id="txt_host" class="input-medium" value="">
  41. Room:
  42. <input type="text" id="txt_room" class="input-small" value="live">
  43. Display:
  44. <input type="text" id="txt_display" class="input-small" value="">
  45. <button class="btn btn-primary" id="btn_start">加入房间</button>
  46. </div>
  47. <div class="row srs_players">
  48. <div class="span4 hide" id="publisher">
  49. <label></label>
  50. <video id="rtc_media_publisher" width="310" autoplay muted controls></video>
  51. <label></label>
  52. <span id='self'></span>
  53. </div>
  54. <div class="span4 hide" id="player">
  55. <label></label>
  56. <video id="rtc_media_player" width="310" autoplay muted controls></video>
  57. <label></label>
  58. <span id='peer'></span>
  59. </div>
  60. </div>
  61. </div>
  62. <script type="text/javascript">
  63. var sig = null;
  64. var publisher = null;
  65. var players = {}; // Key is display, value is a player object.
  66. $(function(){
  67. console.log('?wss=x to specify the websocket schema, ws or wss');
  68. console.log('?wsh=x to specify the websocket server ip');
  69. console.log('?wsp=x to specify the websocket server port');
  70. console.log('?host=x to specify the SRS server');
  71. console.log('?room=x to specify the room to join');
  72. console.log('?display=x to specify your nick name');
  73. var startDemo = async function () {
  74. var host = $('#txt_host').val();
  75. var room = $('#txt_room').val();
  76. var display = $('#txt_display').val();
  77. // Connect to signaling first.
  78. if (sig) {
  79. sig.close();
  80. }
  81. sig = new SrsRtcSignalingAsync();
  82. sig.onmessage = function (msg) {
  83. console.log('Notify: ', msg);
  84. // Subscribe if new user start to publish.
  85. if (msg.event === 'publish') {
  86. if (msg.peer && msg.peer.publishing && msg.peer.display !== display) {
  87. startPlay(host, room, msg.peer.display);
  88. }
  89. }
  90. // Remove dead players.
  91. if (msg.event === 'join' || msg.event === 'leave') {
  92. $.each(players, function(k, obj) {
  93. let stillAlive = false;
  94. msg.participants.forEach(function (participant) {
  95. if (participant.display === k) stillAlive = true;
  96. });
  97. if (!stillAlive) {
  98. obj.player.close();
  99. obj.ui.remove();
  100. }
  101. });
  102. }
  103. };
  104. await sig.connect(conf.wsSchema, conf.wsHost, room, display);
  105. let r0 = await sig.send({action:'join', room:room, display:display});
  106. console.log('Signaling: join ok', r0);
  107. // Start publish media if signaling is ok.
  108. await startPublish(host, room, display);
  109. let r1 = await sig.send({action:'publish', room:room, display:display});
  110. console.log('Signaling: publish ok', r1);
  111. // Play the stream already in room.
  112. r0.participants.forEach(function(participant) {
  113. if (participant.display === display || !participant.publishing) return;
  114. startPlay(host, room, participant.display);
  115. });
  116. };
  117. var startPublish = function (host, room, display) {
  118. $(".ff_first").each(function(i,e) {
  119. $(e).text(display);
  120. });
  121. var url = 'webrtc://' + host + '/' + room + '/' + display + conf.query;
  122. $('#rtc_media_publisher').show();
  123. $('#publisher').show();
  124. if (publisher) {
  125. publisher.close();
  126. }
  127. publisher = new SrsRtcPublisherAsync();
  128. $('#rtc_media_publisher').prop('srcObject', publisher.stream);
  129. return publisher.publish(url).then(function(session){
  130. $('#self').text('Self: ' + url);
  131. }).catch(function (reason) {
  132. publisher.close();
  133. $('#rtc_media_publisher').hide();
  134. console.error(reason);
  135. });
  136. };
  137. var startPlay = function (host, room, display) {
  138. $(".ff_second").each(function(i,e) {
  139. $(e).text(display);
  140. });
  141. // Remove exists.
  142. if (players[display]) {
  143. players[display].ui.remove();
  144. players[display].player.close();
  145. }
  146. // Clone a player from template.
  147. let ui = $('#player').clone().attr('id', 'player-' + display);
  148. let video = ui.children('#rtc_media_player');
  149. console.log(video.length);
  150. let player = new SrsRtcPlayerAsync();
  151. players[display] = {ui:ui, video:video, player:player};
  152. $('.srs_players').append(ui);
  153. // Start play for this user.
  154. var url = 'webrtc://' + host + '/' + room + '/' + display + conf.query;
  155. video.show();
  156. ui.show();
  157. video.prop('srcObject', player.stream);
  158. player.play(url).then(function(session){
  159. ui.children('#peer').text('Peer: ' + url);
  160. video.prop('muted', false);
  161. }).catch(function (reason) {
  162. player.close();
  163. video.hide();
  164. console.error(reason);
  165. });
  166. };
  167. // Pass-by to SRS url.
  168. let conf = SrsRtcSignalingParse(window.location);
  169. $('#txt_host').val(conf.host);
  170. conf.room && $('#txt_room').val(conf.room);
  171. $('#txt_display').val(conf.display);
  172. // Update href for all navs.
  173. $('ul.srs_nav').children('li').not('.srs_ignore').children('a').each(function (i, e) {
  174. $(e).attr('href', $(e).attr('href') + conf.rawQuery);
  175. });
  176. $("#btn_start").click(startDemo);
  177. // Never play util windows loaded @see https://github.com/ossrs/srs/issues/2732
  178. if (conf.autostart) {
  179. window.addEventListener("load", function(){ startDemo(); });
  180. }
  181. });
  182. </script>