|
@@ -153,8 +153,8 @@
|
|
<svg-icon class="tool-icon" name="ps" />
|
|
<svg-icon class="tool-icon" name="ps" />
|
|
<div>拍摄</div>
|
|
<div>拍摄</div>
|
|
</div>
|
|
</div>
|
|
- <div class="tool-btn" @click="startAudioOnline">
|
|
|
|
- <svg-icon class="tool-icon" name="yyth" />
|
|
|
|
|
|
+ <div class="tool-btn">
|
|
|
|
+ <svg-icon class="tool-icon" name="yyth" @click="startVoiceCall"/>
|
|
<div>语音通话</div>
|
|
<div>语音通话</div>
|
|
</div>
|
|
</div>
|
|
<div class="tool-btn">
|
|
<div class="tool-btn">
|
|
@@ -167,20 +167,8 @@
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
-
|
|
|
|
- <!-- 来电弹窗 -->
|
|
|
|
- <div v-if="imState.videoCallModal && !inCall" class="call-modal">
|
|
|
|
- <p>{{ imState.callName }} 正在呼叫你</p>
|
|
|
|
- <button @click="acceptCall">接听</button>
|
|
|
|
- <button @click="rejectCall">拒接</button>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <!-- 通话中显示挂断按钮 -->
|
|
|
|
- <div v-if="inCall" class="call-modal">
|
|
|
|
- <p>与 {{ imState.callName }} 通话中...</p>
|
|
|
|
- <button @click="hangupCall">挂断</button>
|
|
|
|
- </div>
|
|
|
|
|
|
+ <!-- 语音通话 -->
|
|
|
|
+ <CallController></CallController>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -195,6 +183,7 @@ import { MSG_TYPE, MESSAGE_TYPE_USER } from "@/common/constant/msgType";
|
|
import messageAudio from "@/views/im/components/messageAudio/index.vue";
|
|
import messageAudio from "@/views/im/components/messageAudio/index.vue";
|
|
import { showToast, showImagePreview } from "vant";
|
|
import { showToast, showImagePreview } from "vant";
|
|
import { useWebRTCStore } from "@/stores/modules/webrtcStore";
|
|
import { useWebRTCStore } from "@/stores/modules/webrtcStore";
|
|
|
|
+import CallController from "@/views/im/components/CallController/index.vue";
|
|
import * as Constant from "@/common/constant/Constant";
|
|
import * as Constant from "@/common/constant/Constant";
|
|
|
|
|
|
const IM_PATH = import.meta.env.VITE_IM_PATH_FIlE;
|
|
const IM_PATH = import.meta.env.VITE_IM_PATH_FIlE;
|
|
@@ -434,86 +423,12 @@ const beforeRead = (file) => {
|
|
};
|
|
};
|
|
|
|
|
|
// 创建呼叫:开启语音电话: 调试用,正式逻辑读src/views/im/hook/messagesHook.js
|
|
// 创建呼叫:开启语音电话: 调试用,正式逻辑读src/views/im/hook/messagesHook.js
|
|
-// ==== 1. 发起语音通话 ====
|
|
|
|
-const startAudioOnline = async () => {
|
|
|
|
- try {
|
|
|
|
- rtcStore.initConnection(true); // 主叫
|
|
|
|
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
|
|
|
|
- await rtcStore.addLocalStream(stream);
|
|
|
|
-
|
|
|
|
- const offer = await rtcStore.createOffer();
|
|
|
|
-
|
|
|
|
- wsStore.sendMessage({
|
|
|
|
- contentType: Constant.DIAL_AUDIO_ONLINE,
|
|
|
|
- content: JSON.stringify(offer),
|
|
|
|
- type: Constant.MESSAGE_TRANS_TYPE,
|
|
|
|
- to: imState.fromUserUuid || "对方用户ID", // 实际传对方ID
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- imState.videoCallModal = true;
|
|
|
|
- imState.callName = "对方昵称"; // 实际昵称
|
|
|
|
- inCall.value = true;
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error("发起语音通话失败", error);
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-// ==== 2. 接听来电 ====
|
|
|
|
-async function acceptCall() {
|
|
|
|
- try {
|
|
|
|
- rtcStore.initConnection(false); // 被叫
|
|
|
|
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
|
|
|
|
- await rtcStore.addLocalStream(stream);
|
|
|
|
-
|
|
|
|
- // 远端offer SDP,存在imState.offerContent,messagesHook里收到后需保存offerContent
|
|
|
|
- const offerSDP = JSON.parse(imState.offerContent);
|
|
|
|
- await rtcStore.setRemoteDescription(new RTCSessionDescription(offerSDP));
|
|
|
|
-
|
|
|
|
- const answer = await rtcStore.createAnswer();
|
|
|
|
-
|
|
|
|
- wsStore.sendMessage({
|
|
|
|
- contentType: Constant.ACCEPT_AUDIO_ONLINE,
|
|
|
|
- content: JSON.stringify(answer),
|
|
|
|
- type: Constant.MESSAGE_TRANS_TYPE,
|
|
|
|
- to: imState.fromUserUuid,
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- inCall.value = true;
|
|
|
|
- imState.videoCallModal = true;
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error("接听失败", error);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// ==== 3. 拒接来电 ====
|
|
|
|
-function rejectCall() {
|
|
|
|
- wsStore.sendMessage({
|
|
|
|
- contentType: Constant.REJECT_AUDIO_ONLINE,
|
|
|
|
- content: "",
|
|
|
|
- type: Constant.MESSAGE_TRANS_TYPE,
|
|
|
|
- to: imState.fromUserUuid,
|
|
|
|
|
|
+const startVoiceCall = () => {
|
|
|
|
+ rtcStore.startCall({
|
|
|
|
+ type: "audio",
|
|
|
|
+ toUserUuid: route.query.uuid, // 当前聊天对象的 uuid
|
|
});
|
|
});
|
|
-
|
|
|
|
- rtcStore.videoCallModal = false;
|
|
|
|
- inCall.value = false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// ==== 4. 挂断通话 ====
|
|
|
|
-function hangupCall() {
|
|
|
|
- rtcStore.cleanup();
|
|
|
|
- wsStore.sendMessage({
|
|
|
|
- contentType: Constant.CANCELL_AUDIO_ONLINE,
|
|
|
|
- content: "",
|
|
|
|
- type: Constant.MESSAGE_TRANS_TYPE,
|
|
|
|
- to: imState.fromUserUuid,
|
|
|
|
- });
|
|
|
|
- rtcStore.videoCallModal = false;
|
|
|
|
- inCall.value = false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// ==== 5. 监听信令消息 ====
|
|
|
|
-// 建议你在 useWebSocketStore 里实现 onMessage 订阅信令消息
|
|
|
|
-// 这里模拟简易监听,示范关键流程
|
|
|
|
-
|
|
|
|
|
|
+};
|
|
|
|
|
|
// 时间格式化
|
|
// 时间格式化
|
|
const formatTime = (timestamp) => {
|
|
const formatTime = (timestamp) => {
|