Video.html 4.8 KB

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