Videoanswer.html 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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>视频通话</title>
  9. <style>
  10. html, body {
  11. height: 100%;
  12. }
  13. body {
  14. margin: 0;
  15. }
  16. </style>
  17. </head>
  18. <body>
  19. <video class="Bvideo" id="Big_video" preload autoplay onclick="Bvideoselc()"></video>
  20. <video class="Svideo" id="sm_video" preload muted autoplay onclick="Svideoselc()"></video>
  21. <div class="bottomView" style="width: 100%;">
  22. <div class="contentColumnC">
  23. <div class="contentInRowC">
  24. <img class="guadanImg" style="margin-top: 5px;" src="./img/icon_off.png" alt="" onclick="guaduan()"/>
  25. <img id='dianhua_Img' class="guadanImg" style="margin-top: 5px;margin-left: 30px;" src="./img/icon_on.png" alt="" onclick="actjietong()"/>
  26. </div>
  27. <div class="contentInRowC" style="width: 100%;margin-top: 10px;">
  28. <div id="markNote"></div>
  29. <img class="calling" src="./img/loading2.gif" alt="" />
  30. </div>
  31. </div>
  32. </div>
  33. </body>
  34. <script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
  35. <script>
  36. let state1,state2,state3,state4,state5;
  37. const markNote = document.getElementById('markNote');
  38. const Big_video = document.getElementById('Big_video');
  39. const sm_video = document.getElementById('sm_video');
  40. let localStream = null;
  41. let localCall = null;
  42. let localCandidata=null;
  43. let peer = null;
  44. let video=null;
  45. let jietong=false;
  46. let payload=null;
  47. let markindex=0;
  48. const dianhua_Img = document.getElementById('dianhua_Img');
  49. //====================================================
  50. function getQueryVariable(variable) {
  51. var query = decodeURI(window.location.search.substring(1));
  52. var vars = query.split("&");
  53. for (var i = 0; i < vars.length; i++) {
  54. var pair = vars[i].split("=");
  55. if (pair[0] == variable) {
  56. return pair[1];
  57. }
  58. }
  59. return (false);
  60. }
  61. function Bvideoselc(){
  62. }
  63. function Svideoselc(){
  64. }
  65. function actjietong(){
  66. jietong=true;
  67. dianhua_Img.style.display='none'
  68. markNote.innerHTML=state2;
  69. uni.postMessage({
  70. data: {
  71. data:'', // 回传
  72. type:'accept'
  73. },
  74. });
  75. }
  76. function guaduan(){
  77. if(peer){
  78. peer.close();
  79. }
  80. uni.postMessage({
  81. data: {
  82. data:'', // 回传
  83. type:'close'
  84. },
  85. });
  86. }
  87. //====================================================
  88. function appAct (obj) {
  89. if(obj.type=='offer'){//收到发起方sdp offer
  90. if(jietong){
  91. markNote.innerHTML=state2;
  92. RCstartWebRct(obj);//启动wbrtc
  93. }
  94. }
  95. }
  96. function appActcandidate (obj){//发起方收到candidate 添加到Rct
  97. for(var i=0;i<obj.length;i++){
  98. peer.addIceCandidate(obj[i]);
  99. }
  100. //推送candidate
  101. uni.postMessage({
  102. data: {
  103. data:localCandidata, // 回传并推送offer
  104. type:"candidate"
  105. },
  106. });
  107. }
  108. async function startCapture(displayMediaOptions) {
  109. try {
  110. localStream = await navigator.mediaDevices.getUserMedia(displayMediaOptions);
  111. sm_video.srcObject=localStream;
  112. } catch(err) {
  113. console.error(err);
  114. }
  115. }
  116. function startCommunicate(){
  117. peer.ontrack = (e) => {
  118. if(e.streams[0]){
  119. localCall=e.streams[0];
  120. var otherVideos = document.querySelector('#Big_video');
  121. otherVideos.srcObject = localCall
  122. }
  123. }
  124. }
  125. async function RCstartWebRct(payload){
  126. peer = new RTCPeerConnection(
  127. {
  128. iceServers:[
  129. {
  130. urls: ["stun:203.175.169.52:3478",
  131. "turn:203.175.169.52:3478"
  132. ],
  133. username: 'aaaaa',
  134. credential: 'bbbbb'
  135. }
  136. ],
  137. offerExtmapAllowMixed:false
  138. }
  139. );
  140. //添加本地音视频
  141. localStream.getTracks().forEach((track) => {
  142. peer.addTrack(track, localStream)
  143. })
  144. localCandidata=[];
  145. peer.onicecandidate = function (event) {
  146. if (event.candidate){
  147. localCandidata.push(event.candidate);
  148. }
  149. }
  150. startCommunicate();
  151. peer.onconnectionstatechange = function (ev) {
  152. if(peer.connectionState=="closed"){
  153. markNote.innerHTML=state5;
  154. }
  155. if(peer.connectionState=="connected"){
  156. markNote.innerHTML=state3;
  157. }
  158. if(peer.connectionState=="connecting"){
  159. markNote.innerHTML=state2;
  160. }
  161. if(peer.connectionState=="disconnected"){
  162. markNote.innerHTML=state4;
  163. }
  164. };
  165. //记录远端offer
  166. const offer = new RTCSessionDescription(payload);
  167. await peer.setRemoteDescription(offer);
  168. const remoteAnswer = await peer.createAnswer();
  169. //记录本地offer
  170. await peer.setLocalDescription(remoteAnswer);
  171. //推送remoteAnswer
  172. uni.postMessage({
  173. data: {
  174. data:remoteAnswer, // 回传并推送offer
  175. type:"answer"
  176. },
  177. });
  178. }
  179. function initRtc() {
  180. title='语音通话';
  181. state1='正在呼叫';
  182. state2='正在接通';
  183. state3='已接通';
  184. state4='已挂断';
  185. state5='结束通话';
  186. //document.getElementById('Name').innerHTML=getQueryVariable('friendName');;
  187. //document.getElementById('Avatar').src=getQueryVariable('friendAvatar');;
  188. //markNote.innerHTML=state1;
  189. setTimeout(() => {
  190. startCapture({ video: true, audio: true});
  191. //startCapture({audio: true});
  192. }, 1000)
  193. return;
  194. }
  195. function releaseTack(){
  196. if(peer){
  197. peer.close();
  198. }
  199. }
  200. window.onload=initRtc;
  201. window.onunload=releaseTack;
  202. </script>
  203. </html>