callingAudio.html 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <!DOCTYPE html>
  2. <html lang="zh">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>语音通话</title>
  7. <link rel="stylesheet" href="./css/video-call.css" />
  8. </head>
  9. <body>
  10. <div id="app">
  11. <!-- <video v-if="showVideo" ref="mainVideo" poster="./images/mt/pt.png" autoplay class="main-video"></video> -->
  12. <div class="friend-info">
  13. <img :src="friendAvatar" style="width: 60px;height:60px;border-radius: 5px;margin-top: 100px;" alt=""/>
  14. <div class="friend-name" style="color:black;">{{friendName}}</div>
  15. <div class="friend-tips" style="color:black;">{{isConnect?'正在通话中...':'正在等待对方接听'}}</div>
  16. </div>
  17. <!-- <video v-if="showVideo" ref="localVideo" :muted="true" poster="./images/mt/pt.png" autoplay class="local-video"></video> -->
  18. <audio id="rcSound" ref="my_audio" autoplay></audio>
  19. <div class="video-menus">
  20. <div>
  21. <img @click="closeCalling" src="./images/mt/icon_off.png" class="menu-close"/>
  22. </div>
  23. </div>
  24. <audio id="bgSound" src="./images/calling.mp3" autoplay loop style='display: none'></audio>
  25. </div>
  26. <script src="./js/vue.global.js"></script>
  27. <script src="./js/uni.webview.1.5.4.js"></script>
  28. <script src="./js/peerjs.min.js"></script>
  29. <script src="./js/video-call.js"></script>
  30. <script>
  31. const {createApp, ref, onMounted} = Vue
  32. document.addEventListener('UniAppJSBridgeReady', function () {
  33. uni.getEnv(function () {
  34. createApp({
  35. setup() {
  36. const id = ref('')
  37. const name = ref('')
  38. const friendId = ref('')
  39. const friendAvatar = ref('')
  40. const friendName = ref('')
  41. const localData = ref({
  42. audio: false,
  43. video: false
  44. })
  45. const friendData = ref({
  46. audio: false,
  47. video: false
  48. })
  49. const speaker = ref(true)
  50. const showVideo = ref(false)
  51. const isConnect = ref(false)
  52. const mainVideo = ref()
  53. const localVideo = ref()
  54. const my_audio = ref()
  55. const localMedia = ref()
  56. onMounted(() => {
  57. id.value = getQueryVariable("id")
  58. name.value = decodeURI(getQueryVariable("name"))
  59. friendId.value = getQueryVariable("friendId")
  60. friendName.value = decodeURI(getQueryVariable("friendName"))
  61. friendAvatar.value = getQueryVariable("friendAvatar")
  62. showVideo.value = getQueryVariable("showVideo") === 'true'
  63. getLocalUserMedia({audio: true, video: showVideo.value})
  64. .then((userMedia) => {
  65. localMedia.value = userMedia
  66. const localPeer = initPeer()
  67. if (showVideo.value) {
  68. localVideo.value.srcObject = userMedia
  69. localVideo.value.muted = true
  70. }
  71. localPeer.on('call', (mediaConnection) => {
  72. friendData.value.video = true;
  73. mediaConnection.answer(userMedia)
  74. mediaConnection.on('stream', (otherUserMedia) => {
  75. document.getElementById('bgSound').pause()
  76. isConnect.value = true
  77. // mainVideo.value.srcObject = otherUserMedia
  78. // mainVideo.value.muted = false
  79. my_audio.value.srcObject=otherUserMedia
  80. //告诉VideoCalling.vue 已经接通
  81. uni.postMessage({
  82. data: {
  83. type: 'connect',
  84. data:{}
  85. }
  86. })
  87. })
  88. })
  89. //这里是接受视频请求,但是有可能是多个人同时请求,所以这里需要判断是否已经在通话中
  90. localPeer.on('connection', (dataConnection) => {
  91. dataConnection.on('data', (data) => {
  92. if (data.cmd === PeerCmd.ringOff) {
  93. closeCalling()
  94. } else if (data.cmd === PeerCmd.request) {
  95. if (isConnect.value) {
  96. dataConnection.send({
  97. cmd: PeerCmd.busy
  98. })
  99. } else {
  100. isConnect.value = true
  101. dataConnection.send({
  102. cmd: PeerCmd.accept
  103. })
  104. }
  105. } else if (data.cmd === PeerCmd.reject) {
  106. closeCalling()
  107. }
  108. })
  109. })
  110. localPeer.on('error', () => {
  111. closeCalling()
  112. })
  113. //给对方发送自己的peerId
  114. localPeer.on('open', (localPeerId) => {
  115. uni.postMessage({
  116. data: {
  117. type: 'ws',
  118. data: {
  119. code: SendVideoCode.VIDEO,
  120. message: {
  121. chatId: friendId.value,
  122. fromId: id.value,
  123. peerId: localPeerId,
  124. showVideo: showVideo.value,
  125. timestamp: new Date().getTime(),
  126. }
  127. }
  128. }
  129. })
  130. })
  131. })
  132. .catch((err) => {
  133. isConnect.value = false
  134. closeCalling()
  135. })
  136. })
  137. const muteAudio = (boo) => {
  138. console.log(boo)
  139. }
  140. const changeSpeaker = () => {
  141. }
  142. const changeCamera = () => {
  143. console.log('changeCamera')
  144. }
  145. const closeCalling = () => {
  146. //关闭视频流
  147. localMedia.value?.getTracks().forEach((track) => {
  148. track.stop()
  149. })
  150. uni.postMessage({
  151. data: {
  152. type: 'close',
  153. data:{calling:true}
  154. }
  155. })
  156. }
  157. return {
  158. id,
  159. name,
  160. friendId,
  161. friendAvatar,
  162. friendName,
  163. localData,
  164. showVideo,
  165. friendData,
  166. isConnect,
  167. changeCamera,
  168. changeSpeaker,
  169. muteAudio,
  170. mainVideo,
  171. localVideo,
  172. my_audio,
  173. closeCalling,
  174. speaker
  175. }
  176. }
  177. }).mount('#app')
  178. });
  179. });
  180. </script>
  181. </body>
  182. </html>