audioserver.html 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <link rel="stylesheet" type="text/css" href="./css/index.css" />
  8. <title id="title"></title>
  9. <style>
  10. html, body {
  11. height: 100%;
  12. }
  13. body {
  14. margin: 0;
  15. }
  16. video {
  17. width: 100%;
  18. height: 100%;
  19. position: absolute;
  20. left: 0;
  21. top: 0;
  22. z-index: -1;
  23. }
  24. </style>
  25. </head>
  26. <body>
  27. <video id="localVideo" playsinline autoplay muted></video>
  28. <div class="box">
  29. <button id="startButton">Start</button>
  30. <button id="callButton">Call</button>
  31. <button id="hangupButton">Hang Up</button>
  32. </div>
  33. </body>
  34. <script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
  35. <script>
  36. const startButton = document.getElementById('startButton');
  37. const callButton = document.getElementById('callButton');
  38. const hangupButton = document.getElementById('hangupButton');
  39. callButton.disabled = true;
  40. hangupButton.disabled = true;
  41. let localCandidata=null;
  42. startButton.addEventListener('click', start);
  43. callButton.addEventListener('click', call);
  44. hangupButton.addEventListener('click', hangup);
  45. const localVideo = document.getElementById('localVideo');
  46. localVideo.addEventListener('loadedmetadata', function () {
  47. console.log(`Local video videoWidth: ${this.videoWidth}px, videoHeight: ${this.videoHeight}px`);
  48. });
  49. let localStream;
  50. let pc1;
  51. let whipLocation;
  52. const offerOptions = {
  53. offerToReceiveAudio: 1,
  54. offerToReceiveVideo: 1
  55. };
  56. const configuration = {
  57. iceServers: [
  58. {
  59. urls: "stun:stun.l.google.com:19302"
  60. }
  61. ]
  62. };
  63. async function start() {
  64. console.log('Requesting local stream');
  65. startButton.disabled = true;
  66. try {
  67. const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: { width: 1280, height: 720, frameRate: 30 } });
  68. console.log('Received local stream');
  69. localVideo.srcObject = stream;
  70. localStream = stream;
  71. callButton.disabled = false;
  72. } catch (e) {
  73. alert(`getUserMedia() error: ${e.name}`);
  74. }
  75. }
  76. async function call() {
  77. callButton.disabled = true;
  78. hangupButton.disabled = false;
  79. console.log('Starting call');
  80. const videoTracks = localStream.getVideoTracks();
  81. const audioTracks = localStream.getAudioTracks();
  82. if (videoTracks.length > 0) {
  83. console.log(`Using video device: ${videoTracks[0].label}`);
  84. }
  85. if (audioTracks.length > 0) {
  86. console.log(`Using audio device: ${audioTracks[0].label}`);
  87. }
  88. console.log('RTCPeerConnection configuration:', configuration);
  89. pc1 = new RTCPeerConnection(configuration);
  90. console.log('Created local peer connection object pc1');
  91. // pc1.addEventListener('icecandidate', e => onIceCandidate(pc1, e));
  92. //pc1.onicegatheringstatechange = gatheringStateChange;
  93. //pc1.addEventListener('iceconnectionstatechange', e => onIceStateChange(pc1, e));
  94. localCandidata=[];
  95. pc1.onicecandidate = function (event) {
  96. if (event.candidate){
  97. localCandidata.push(event.candidate);
  98. uni.postMessage({
  99. data: {
  100. data:localCandidata, // 发起方先发candidate
  101. type:34567111
  102. },
  103. });
  104. }
  105. }
  106. pc1.onconnectionstatechange = function (ev) {
  107. uni.postMessage({
  108. data: {
  109. data:pc1.connectionState, // 发起方先发candidate
  110. type:34567
  111. },
  112. });
  113. }
  114. localStream.getTracks().forEach(track => pc1.addTrack(track, localStream));
  115. console.log('Added local stream to pc1');
  116. try {
  117. console.log('pc1 createOffer start');
  118. const offer = await pc1.createOffer(offerOptions);
  119. uni.postMessage({
  120. data: {
  121. data:offer, // 发起方先发candidate
  122. type:345671
  123. },
  124. });
  125. await pc1.setLocalDescription(offer);
  126. const answer = await postSDPOffer("https://203.175.169.44:8443/live/user111.whip", pc1.localDescription.sdp);
  127. uni.postMessage({
  128. data: {
  129. data:answer, // 发起方先发candidate
  130. type:345672
  131. },
  132. });
  133. await pc1.setRemoteDescription(answer);
  134. console.log('setRemoteDescription');
  135. whipLocation = answer.location;
  136. // await onCreateOfferSuccess(offer);
  137. } catch (e) {
  138. onCreateSessionDescriptionError(e);
  139. }
  140. }
  141. async function postSDPOffer(url, sdp) {
  142. let result = {
  143. status: 0,
  144. type: 'answer',
  145. };
  146. try {
  147. const response = await fetch(url, {
  148. method: 'POST',
  149. headers: {
  150. 'Content-Type': 'application/sdp',
  151. "video-bitrate": 2_000_000,
  152. "video-keyint": 3,
  153. "audio-bitrate": 64_000
  154. },
  155. body: sdp
  156. });
  157. result.status = response.status;
  158. result.sdp = await response.text();
  159. result.location = response.headers.get("Location");
  160. uni.postMessage({
  161. data: {
  162. data:JSON.stringify(result), // 发起方先发candidate
  163. type:345673
  164. },
  165. });
  166. } catch (error) {
  167. result.error = error;
  168. uni.postMessage({
  169. data: {
  170. data:JSON.stringify(error), // 发起方先发candidate
  171. type:345674
  172. },
  173. });
  174. }
  175. return result;
  176. }
  177. function hangup() {
  178. console.log('Ending call');
  179. pc1.close();
  180. pc1 = null;
  181. hangupButton.disabled = true;
  182. callButton.disabled = false;
  183. fetch(whipLocation, { method: "DELETE" });
  184. }
  185. window.onunload=releaseTack;
  186. </script>
  187. </html>