audio.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  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 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="contentColumnC" style="width: 100%;margin-top: 60px;"">
  31. <div id="userName"></div>
  32. <img id='icon_Img' class="iconImg" style="margin-top: 5px;" src="./img/logo.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 style="width: 100%;margin-top: 100px;">
  39. <div class="contentColumnC">
  40. <img class="guadanImg" style="margin-top: 5px;" src="./img/guaduandd.png" alt="" onclick="guaduan()"/>
  41. </div>
  42. </div>
  43. </body>
  44. <script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
  45. <script>
  46. let language =getQueryVariable('language');
  47. let title,state1,state2,state3,state4,state5;
  48. let localStream = null;
  49. let localCall = 0;
  50. let localCandidata=null;
  51. let peer = null;
  52. let video=null;
  53. // const Big_video = document.getElementById('Big_video');
  54. // const sm_video = document.getElementById('sm_video');
  55. // const my_audio = document.getElementById('my_audio');
  56. const userName = document.getElementById('userName');
  57. const markNote = document.getElementById('markNote');
  58. const icon_Img = document.getElementById('icon_Img');
  59. const title_div = document.getElementById('title');
  60. //====================================================
  61. function getQueryVariable(variable) {
  62. var query = decodeURI(window.location.search.substring(1));
  63. var vars = query.split("&");
  64. for (var i = 0; i < vars.length; i++) {
  65. var pair = vars[i].split("=");
  66. if (pair[0] == variable) {
  67. return pair[1];
  68. }
  69. }
  70. return (false);
  71. }
  72. function Bvideoselc(){
  73. if(localStream!=null){
  74. //Big_video.srcObject =localStream;
  75. Big_video.setAttribute('autoplay', true); /* THIS */
  76. }
  77. }
  78. function Svideoselc(){
  79. if(localStream!=null){
  80. //sm_video.srcObject =localStream;
  81. sm_video.setAttribute('autoplay', true); /* THIS */
  82. }
  83. }
  84. function guaduan(){
  85. if(peer){
  86. peer.close();
  87. }
  88. uni.postMessage({
  89. data: {
  90. data:'', // 回传
  91. type:88
  92. },
  93. });
  94. }
  95. function duifangguaduan(){
  96. if(peer){
  97. peer.close();
  98. }
  99. markNote.innerHTML=state4;
  100. }
  101. //====================================================
  102. function appAct (obj) {
  103. if(obj.type==1){//主动发起im通话
  104. localCall=1;
  105. startWebRct(obj.type);
  106. markNote.innerHTML=state1;
  107. userName.innerHTML=obj.payload.userName;
  108. icon_Img.src=obj.payload.avatar;
  109. }
  110. else if(obj.type==2){//收到推送消息
  111. if(localCall==1){
  112. //markNote.innerHTML=state2;
  113. RCremoteData(obj.payload);
  114. }
  115. else{
  116. RCstartWebRct(obj.payload);
  117. }
  118. }
  119. else if(obj.type==3){//收到candidate
  120. //markNote.innerHTML=state2;
  121. for(var i=0;i<obj.payload.length;i++){
  122. peer.addIceCandidate(obj.payload[i]);
  123. }
  124. if(localCall!=1){
  125. uni.postMessage({
  126. data: {
  127. data:localCandidata, //应答方回应candidate
  128. type:3
  129. },
  130. });
  131. }
  132. else{
  133. // uni.postMessage({
  134. // data: {
  135. // data:'kaishi 通话', //应答方回应candidate
  136. // type:12343
  137. // },
  138. // });
  139. }
  140. }
  141. }
  142. async function startCapture(displayMediaOptions) {
  143. try {
  144. localStream = await navigator.mediaDevices.getUserMedia(displayMediaOptions);
  145. // Big_video.srcObject =localStream;
  146. // Big_video.setAttribute('autoplay', true); /* THIS */
  147. // var otherVideos = document.querySelector('#my_audio');
  148. // otherVideos.srcObject = localStream;
  149. uni.postMessage({
  150. data: {
  151. data:'', // 回传
  152. type:99
  153. },
  154. });
  155. } catch(err) {
  156. console.error(err);
  157. }
  158. }
  159. async function startWebRct(type){
  160. peer = new RTCPeerConnection(
  161. {
  162. iceServers:[
  163. {
  164. urls:'stun:stun.l.google.com:19302',
  165. }
  166. ],
  167. offerExtmapAllowMixed:false
  168. }
  169. );
  170. //添加本地音视频
  171. localStream.getTracks().forEach((track) => {
  172. peer.addTrack(track, localStream)
  173. });
  174. //创建本地offer
  175. const offer = peer.createOffer({
  176. offerToReceiveAudio:1,
  177. offerToReceiveVideo:1
  178. });
  179. //记录本地offer
  180. offer.then(value => {
  181. peer.setLocalDescription(value);
  182. uni.postMessage({
  183. data: {
  184. data:value, // 回传并推送offer
  185. type:2
  186. },
  187. });
  188. }).catch(error => {
  189. });
  190. localCandidata=[]
  191. peer.onicecandidate = function (event) {
  192. if (event.candidate){
  193. localCandidata.push(event.candidate);
  194. }
  195. }
  196. peer.onconnectionstatechange = function (ev) {
  197. uni.postMessage({
  198. data: {
  199. data:peer.connectionState, // 发起方先发candidate
  200. type:34567
  201. },
  202. });
  203. if(peer.connectionState=="closed"){
  204. markNote.innerHTML=state5;
  205. }
  206. if(peer.connectionState=="connected"){
  207. markNote.innerHTML=state3;
  208. }
  209. if(peer.connectionState=="connecting"){
  210. markNote.innerHTML=state2;
  211. }
  212. if(peer.connectionState=="disconnected"){
  213. markNote.innerHTML=state4;
  214. }
  215. };
  216. startCommunicate();
  217. }
  218. async function RCremoteData(rcData){//收到remoteAnswer
  219. //记录远端offer
  220. await peer.setRemoteDescription(rcData)
  221. uni.postMessage({
  222. data: {
  223. data:localCandidata, // 发起方先发candidate
  224. type:3
  225. },
  226. });
  227. }
  228. function startCommunicate(){
  229. peer.ontrack = (e) => {
  230. if(e.streams[0]){
  231. var otherVideos = document.querySelector('#my_audio');
  232. otherVideos.srcObject = e.streams[0];
  233. //otherVideos.srcObject = localStream;
  234. }
  235. // sm_video.srcObject =localStream;
  236. // sm_video.setAttribute('autoplay', true); /* THIS */
  237. }
  238. }
  239. async function RCstartWebRct(payload){
  240. peer = new RTCPeerConnection(
  241. {
  242. iceServers:[
  243. {
  244. urls:'stun:stun.l.google.com:19302',
  245. }
  246. ]
  247. }
  248. );
  249. //添加本地音视频
  250. localStream.getTracks().forEach((track) => {
  251. peer.addTrack(track, localStream)
  252. })
  253. localCandidata=[];
  254. peer.onicecandidate = function (event) {
  255. if (event.candidate){
  256. //let strcandidate=JSON.stringify(event.candidate);
  257. localCandidata.push(event.candidate);
  258. }
  259. }
  260. startCommunicate();
  261. peer.onconnectionstatechange = function (ev) {
  262. if(peer.connectionState=="closed"){
  263. markNote.innerHTML=state5;
  264. }
  265. if(peer.connectionState=="connected"){
  266. markNote.innerHTML=state3;
  267. }
  268. if(peer.connectionState=="connecting"){
  269. markNote.innerHTML=state2;
  270. }
  271. if(peer.connectionState=="disconnected"){
  272. markNote.innerHTML=state4;
  273. }
  274. };
  275. //记录远端offer
  276. const offer = new RTCSessionDescription(payload);
  277. await peer.setRemoteDescription(offer);
  278. const remoteAnswer = await peer.createAnswer();
  279. //记录本地offer
  280. await peer.setLocalDescription(remoteAnswer);
  281. //推送remoteAnswer
  282. uni.postMessage({
  283. data: {
  284. data:remoteAnswer, // 回传并推送offer
  285. type:2
  286. },
  287. });
  288. }
  289. function initRtc() {
  290. markNote.innerHTML=language;
  291. if(language=='yuenan'){//越南语
  292. title='IM Cuộc gọi thoại';
  293. state1='Đang gọi';
  294. state2='Đang kết nối';
  295. state3='Đã kết nối';
  296. state4='Bị treo';
  297. state5='Kết thúc cuộc gọi';
  298. }
  299. if(language=='zh-Hans'){//简体中文
  300. title='IM 语音通话';
  301. state1='正在呼叫';
  302. state2='正在接通';
  303. state3='已接通';
  304. state4='已挂断';
  305. state5='结束通话';
  306. }
  307. if(language=='zh-Hant'){//繁体中文
  308. title='IM 語音通話';
  309. state1='正在呼叫';
  310. state2='正在接通';
  311. state3='已接通';
  312. state4='已掛斷';
  313. state5='結束通話';
  314. }
  315. markNote.innerHTML=title;
  316. title_div.innerHTML=title;
  317. // uni.postMessage({
  318. // data: {
  319. // data:'', // 回传
  320. // type:9999
  321. // },
  322. // });
  323. setTimeout(() => {
  324. startCapture({ video: true, audio: true});
  325. //startCapture({audio: true});
  326. }, 1000)
  327. return;
  328. }
  329. function releaseTack(){
  330. if(peer){
  331. peer.close();
  332. }
  333. }
  334. //window.onload=initRtc;
  335. // 正确的做法,使用匿名函数的方式来扩展现有的行为
  336. window.onload = function() {
  337. markNote.innerHTML=language;
  338. if(language=='yuenan'){//越南语
  339. title='IM Cuộc gọi thoại';
  340. state1='Đang gọi';
  341. state2='Đang kết nối';
  342. state3='Đã kết nối';
  343. state4='Bị treo';
  344. state5='Kết thúc cuộc gọi';
  345. }
  346. if(language=='zh-Hans'){//简体中文
  347. title='IM 语音通话';
  348. state1='正在呼叫';
  349. state2='正在接通';
  350. state3='已接通';
  351. state4='已挂断';
  352. state5='结束通话';
  353. }
  354. if(language=='zh-Hant'){//繁体中文
  355. title='IM 語音通話';
  356. state1='正在呼叫';
  357. state2='正在接通';
  358. state3='已接通';
  359. state4='已掛斷';
  360. state5='結束通話';
  361. }
  362. markNote.innerHTML=title;
  363. title_div.innerHTML=title;
  364. // uni.postMessage({
  365. // data: {
  366. // data:'', // 回传
  367. // type:9999
  368. // },
  369. // });
  370. setTimeout(() => {
  371. startCapture({ video: true, audio: true});
  372. //startCapture({audio: true});
  373. }, 1000)
  374. return;
  375. };
  376. window.onload = window.onload || function() {
  377. markNote.innerHTML=language;
  378. if(language=='yuenan'){//越南语
  379. title='IM Cuộc gọi thoại';
  380. state1='Đang gọi';
  381. state2='Đang kết nối';
  382. state3='Đã kết nối';
  383. state4='Bị treo';
  384. state5='Kết thúc cuộc gọi';
  385. }
  386. if(language=='zh-Hans'){//简体中文
  387. title='IM 语音通话';
  388. state1='正在呼叫';
  389. state2='正在接通';
  390. state3='已接通';
  391. state4='已挂断';
  392. state5='结束通话';
  393. }
  394. if(language=='zh-Hant'){//繁体中文
  395. title='IM 語音通話';
  396. state1='正在呼叫';
  397. state2='正在接通';
  398. state3='已接通';
  399. state4='已掛斷';
  400. state5='結束通話';
  401. }
  402. markNote.innerHTML=title;
  403. title_div.innerHTML=title;
  404. // uni.postMessage({
  405. // data: {
  406. // data:'', // 回传
  407. // type:9999
  408. // },
  409. // });
  410. setTimeout(() => {
  411. startCapture({ video: true, audio: true});
  412. //startCapture({audio: true});
  413. }, 1000)
  414. return;
  415. };
  416. window.onunload=releaseTack;
  417. </script>
  418. </html>