index.html 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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>IM通话</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 class="Bvideo" id="Big_video" preload autoplay onclick="Bvideoselc()"></video>
  28. <!-- <video class="Svideo" id="sm_video" preload muted autoplay onclick="Svideoselc()"></video> -->
  29. <!-- <audio id="my_audio" autoplay></audio> -->
  30. <div class="bottomView" style="width: 100%;">
  31. <div class="contentColumnC">
  32. <img class="guadanImg" style="margin-top: 5px;" src="./img/guaduandd.png" alt="" onclick="guaduan()"/>
  33. <div class="contentInRowC" style="width: 100%;margin-top: 10px;">
  34. <div id="markNote"></div>
  35. <img class="calling" src="./img/loading2.gif" alt="" />
  36. </div>
  37. </div>
  38. </div>
  39. </body>
  40. <script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
  41. <script>
  42. let localStream = null;
  43. let localCall = 0;
  44. let localCandidata=null;
  45. let peer = null;
  46. let video=null;
  47. // const Big_video = document.getElementById('Big_video');
  48. // const sm_video = document.getElementById('sm_video');
  49. // const my_audio = document.getElementById('my_audio');
  50. const markNote = document.getElementById('markNote');
  51. //====================================================
  52. function Bvideoselc(){
  53. if(localStream!=null){
  54. //Big_video.srcObject =localStream;
  55. Big_video.setAttribute('autoplay', true); /* THIS */
  56. }
  57. }
  58. function Svideoselc(){
  59. if(localStream!=null){
  60. //sm_video.srcObject =localStream;
  61. sm_video.setAttribute('autoplay', true); /* THIS */
  62. }
  63. }
  64. function guaduan(){
  65. peer.close();
  66. uni.postMessage({
  67. data: {
  68. data:'', // 回传
  69. type:88
  70. },
  71. });
  72. }
  73. //====================================================
  74. function appAct (obj) {
  75. if(obj.type==1){//主动发起im通话
  76. localCall=1;
  77. startWebRct(obj.type);
  78. markNote.innerHTML='拨打中'
  79. }
  80. else if(obj.type==2){//收到推送消息
  81. if(localCall==1){
  82. markNote.innerHTML='接通中'
  83. RCremoteData(obj.payload);
  84. }
  85. else{
  86. RCstartWebRct(obj.payload);
  87. }
  88. }
  89. else if(obj.type==3){//收到candidate
  90. markNote.innerHTML='接通中'
  91. for(var i=0;i<obj.payload.length;i++){
  92. peer.addIceCandidate(obj.payload[i]);
  93. }
  94. if(localCall!=1){
  95. uni.postMessage({
  96. data: {
  97. data:localCandidata, //应答方回应candidate
  98. type:3
  99. },
  100. });
  101. }
  102. }
  103. }
  104. async function startCapture(displayMediaOptions) {
  105. try {
  106. localStream = await navigator.mediaDevices.getUserMedia(displayMediaOptions);
  107. // Big_video.srcObject =localStream;
  108. // Big_video.setAttribute('autoplay', true); /* THIS */
  109. uni.postMessage({
  110. data: {
  111. data:'', // 回传
  112. type:99
  113. },
  114. });
  115. } catch(err) {
  116. console.error(err);
  117. }
  118. }
  119. async function startWebRct(type){
  120. peer = new RTCPeerConnection(
  121. {
  122. iceServers:[
  123. {
  124. urls:'stun:stun.l.google.com:19302',
  125. }
  126. ]
  127. }
  128. );
  129. //添加本地音视频
  130. localStream.getTracks().forEach((track) => {
  131. peer.addTrack(track, localStream)
  132. });
  133. //创建本地offer
  134. const offer = peer.createOffer({
  135. offerToReceiveAudio:1,
  136. offerToReceiveVideo:1
  137. });
  138. //记录本地offer
  139. offer.then(value => {
  140. peer.setLocalDescription(value);
  141. uni.postMessage({
  142. data: {
  143. data:value, // 回传并推送offer
  144. type:2
  145. },
  146. });
  147. }).catch(error => {
  148. });
  149. peer.oniceconnectionstatechange = function (ev) {
  150. if(peer.connectionState=="closed"){
  151. markNote.innerHTML='结束通话'
  152. }
  153. if(peer.connectionState=="connected"){
  154. markNote.innerHTML='已接通'
  155. }
  156. if(peer.connectionState=="connecting"){
  157. markNote.innerHTML='连接中'
  158. }
  159. if(peer.connectionState=="disconnected"){
  160. markNote.innerHTML='对方挂断'
  161. }
  162. };
  163. localCandidata=[]
  164. peer.onicecandidate = function (event) {
  165. if (event.candidate){
  166. localCandidata.push(event.candidate);
  167. }
  168. }
  169. startCommunicate();
  170. }
  171. async function RCremoteData(rcData){//收到remoteAnswer
  172. //记录远端offer
  173. await peer.setRemoteDescription(rcData)
  174. uni.postMessage({
  175. data: {
  176. data:localCandidata, // 发起方先发candidate
  177. type:3
  178. },
  179. });
  180. }
  181. function startCommunicate(){
  182. peer.ontrack = (e) => {
  183. if(e.streams[0]){
  184. //var otherVideos = document.querySelector('#my_audio');
  185. var otherVideos = document.querySelector('#Big_video');
  186. otherVideos.srcObject = e.streams[0];
  187. }
  188. // sm_video.srcObject =localStream;
  189. // sm_video.setAttribute('autoplay', true); /* THIS */
  190. }
  191. }
  192. async function RCstartWebRct(payload){
  193. peer = new RTCPeerConnection(
  194. {
  195. iceServers:[
  196. {
  197. urls:'stun:stun.l.google.com:19302',
  198. }
  199. ]
  200. }
  201. );
  202. //添加本地音视频
  203. localStream.getTracks().forEach((track) => {
  204. peer.addTrack(track, localStream)
  205. })
  206. localCandidata=[];
  207. peer.onicecandidate = function (event) {
  208. if (event.candidate){
  209. //let strcandidate=JSON.stringify(event.candidate);
  210. localCandidata.push(event.candidate);
  211. }
  212. }
  213. startCommunicate();
  214. //记录远端offer
  215. await peer.setRemoteDescription(payload)
  216. const remoteAnswer = await peer.createAnswer();
  217. //记录本地offer
  218. await peer.setLocalDescription(remoteAnswer);
  219. //推送remoteAnswer
  220. uni.postMessage({
  221. data: {
  222. data:remoteAnswer, // 回传并推送offer
  223. type:2
  224. },
  225. });
  226. }
  227. function initRtc() {
  228. markNote.innerHTML='IM通话'
  229. setTimeout(() => {
  230. startCapture({ video: true, audio: true});
  231. //startCapture({audio: true});
  232. }, 1000)
  233. return;
  234. }
  235. function releaseTack(){
  236. if(peer){
  237. peer.close();
  238. }
  239. }
  240. window.onload=initRtc;
  241. window.onunload=releaseTack;
  242. </script>
  243. </html>