diff --git a/im-platform/src/main/java/com/bx/implatform/config/ICEServer.java b/im-platform/src/main/java/com/bx/implatform/config/ICEServer.java new file mode 100644 index 0000000..d29c182 --- /dev/null +++ b/im-platform/src/main/java/com/bx/implatform/config/ICEServer.java @@ -0,0 +1,19 @@ +package com.bx.implatform.config; + + +import lombok.Data; + + +@Data +public class ICEServer { + + + private String urls; + + + private String username; + + + private String credential; + +} diff --git a/im-platform/src/main/java/com/bx/implatform/config/ICEServerConfig.java b/im-platform/src/main/java/com/bx/implatform/config/ICEServerConfig.java new file mode 100644 index 0000000..43b1b52 --- /dev/null +++ b/im-platform/src/main/java/com/bx/implatform/config/ICEServerConfig.java @@ -0,0 +1,17 @@ +package com.bx.implatform.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Data +@Component +@ConfigurationProperties(prefix="webrtc") +public class ICEServerConfig { + + private List iceServers = new ArrayList<>(); + +} diff --git a/im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java b/im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java index 75c6cc5..b1fccd4 100644 --- a/im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java +++ b/im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java @@ -3,13 +3,13 @@ package com.bx.implatform.controller; import com.bx.imclient.IMClient; import com.bx.imcommon.model.PrivateMessageInfo; +import com.bx.implatform.config.ICEServerConfig; import com.bx.implatform.enums.MessageType; import com.bx.implatform.result.Result; import com.bx.implatform.result.ResultUtils; import com.bx.implatform.session.SessionContext; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -21,6 +21,8 @@ public class WebrtcController { @Autowired private IMClient imClient; + @Autowired + private ICEServerConfig iceServerConfig; @ApiOperation(httpMethod = "POST", value = "呼叫视频通话") @PostMapping("/call") @@ -115,4 +117,10 @@ public class WebrtcController { imClient.sendPrivateMessage(uid,message); return ResultUtils.success(); } + + @GetMapping("/iceservers") + @ApiOperation(httpMethod = "GET", value = "获取iceservers") + public Result iceservers() { + return ResultUtils.success(iceServerConfig.getIceServers()); + } } diff --git a/im-platform/src/main/resources/application.yml b/im-platform/src/main/resources/application.yml index a75e938..8a35ae1 100644 --- a/im-platform/src/main/resources/application.yml +++ b/im-platform/src/main/resources/application.yml @@ -36,3 +36,8 @@ minio: bucketName: box-im imagePath: image filePath: file + +webrtc: + iceServers: + - urls: stun:stun.l.google.com:19302 + diff --git a/im-ui/src/assets/audio/call.wav b/im-ui/src/assets/audio/call.wav new file mode 100644 index 0000000..754e33c Binary files /dev/null and b/im-ui/src/assets/audio/call.wav differ diff --git a/im-ui/src/assets/audio/tip.wav b/im-ui/src/assets/audio/tip.wav new file mode 100644 index 0000000..adc45dd Binary files /dev/null and b/im-ui/src/assets/audio/tip.wav differ diff --git a/im-ui/src/components/chat/ChatBox.vue b/im-ui/src/components/chat/ChatBox.vue index d53e1f3..98a881f 100644 --- a/im-ui/src/components/chat/ChatBox.vue +++ b/im-ui/src/components/chat/ChatBox.vue @@ -11,9 +11,9 @@
@@ -60,7 +60,7 @@ diff --git a/im-ui/src/components/chat/MessageItem.vue b/im-ui/src/components/chat/MessageItem.vue deleted file mode 100644 index 400bf24..0000000 --- a/im-ui/src/components/chat/MessageItem.vue +++ /dev/null @@ -1,369 +0,0 @@ - - - - - diff --git a/im-ui/src/components/chat/VideoAcceptor.vue b/im-ui/src/components/chat/VideoAcceptor.vue deleted file mode 100644 index 76ad470..0000000 --- a/im-ui/src/components/chat/VideoAcceptor.vue +++ /dev/null @@ -1,124 +0,0 @@ - - - - - diff --git a/im-ui/src/utils/directive/dialogDrag.js b/im-ui/src/utils/directive/dialogDrag.js new file mode 100644 index 0000000..5a35d2c --- /dev/null +++ b/im-ui/src/utils/directive/dialogDrag.js @@ -0,0 +1,72 @@ +import Vue from 'vue' +  +// v-dialogDrag: 弹窗拖拽 +Vue.directive('dialogDrag', { +  bind (el, binding, vnode, oldVnode) { +    const dialogHeaderEl = el.querySelector('.el-dialog__header') +    const dragDom = el.querySelector('.el-dialog') +    dialogHeaderEl.style.cursor = 'move' +  +    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); +    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null) +  +    dialogHeaderEl.onmousedown = (e) => { +      // 鼠标按下,计算当前元素距离可视区的距离 +      const disX = e.clientX - dialogHeaderEl.offsetLeft +      const disY = e.clientY - dialogHeaderEl.offsetTop +      const screenWidth = document.body.clientWidth; // body当前宽度 +      const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取) +      const dragDomWidth = dragDom.offsetWidth; // 对话框宽度 +      const dragDomheight = dragDom.offsetHeight; // 对话框高度 +      const minDragDomLeft = dragDom.offsetLeft; +      const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth; +      const minDragDomTop = dragDom.offsetTop; +      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight; +  +      // 获取到的值带px 正则匹配替换 +      let styL, styT +  +      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px +      if (sty.left.includes('%')) { +        styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100) +        styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100) +      } else { +        styL = +sty.left.replace(/\px/g, '') +        styT = +sty.top.replace(/\px/g, '') +      } +  +      document.onmousemove = function (e) { +        // 获取body的页面可视宽高 +        // var clientHeight = document.documentElement.clientHeight || document.body.clientHeight +        // var clientWidth = document.documentElement.clientWidth || document.body.clientWidth +  +        // 通过事件委托,计算移动的距离 +        var l = e.clientX - disX +        var t = e.clientY - disY +  +        // 边界处理 +        if (-l > minDragDomLeft) { +          l = -minDragDomLeft; +        } else if (l > maxDragDomLeft) { +          l = maxDragDomLeft; +        } +        if (-t > minDragDomTop) { +          t = -minDragDomTop; +        } else if (t > maxDragDomTop) { +          t = maxDragDomTop; +        } +        // 移动当前元素 +        dragDom.style.left = `${l + styL}px` +        dragDom.style.top = `${t + styT}px` +  +        // 将此时的位置传出去 +        // binding.value({x:e.pageX,y:e.pageY}) +      } +  +      document.onmouseup = function (e) { +        document.onmousemove = null +        document.onmouseup = null +      } +    } +  } +}) diff --git a/im-ui/src/view/Home.vue b/im-ui/src/view/Home.vue index 984dd87..a3b8b89 100644 --- a/im-ui/src/view/Home.vue +++ b/im-ui/src/view/Home.vue @@ -44,11 +44,11 @@ :offer="uiStore.chatPrivateVideo.offer" @close="$store.commit('closeChatPrivateVideoBox')" > - - + @@ -58,7 +58,7 @@ import UserInfo from '../components/common/UserInfo.vue'; import FullImage from '../components/common/FullImage.vue'; import ChatPrivateVideo from '../components/chat/ChatPrivateVideo.vue'; - import VideoAcceptor from '../components/chat/VideoAcceptor.vue'; + import ChatVideoAcceptor from '../components/chat/ChatVideoAcceptor.vue'; export default { @@ -68,7 +68,7 @@ UserInfo, FullImage, ChatPrivateVideo, - VideoAcceptor + ChatVideoAcceptor }, data() { return { @@ -156,6 +156,8 @@ this.$store.commit("openChat", chatInfo); // 插入消息 this.$store.commit("insertMessage", msg); + // 播放提示音 + this.playAudioTip(); }, handleGroupMessage(msg) { // 群聊缓存存在,直接插入群聊消息 @@ -184,6 +186,8 @@ this.$store.commit("openChat", chatInfo); // 插入消息 this.$store.commit("insertMessage", msg); + // 播放提示音 + this.playAudioTip(); }, handleExit() { this.$http({ @@ -194,6 +198,12 @@ location.href = "/"; }) }, + playAudioTip(){ + let audio = new Audio(); + let url = require(`@/assets/audio/tip.wav`); + audio.src = url; + audio.play(); + }, showSetting() { this.showSettingDialog = true; },