优化音视频通话

This commit is contained in:
lmx
2026-02-06 23:56:01 +08:00
parent ea2ef96379
commit 62cde5bc5f
3 changed files with 151 additions and 112 deletions

View File

@@ -1,106 +1,102 @@
<script setup lang="ts"> <script setup lang="ts">
import ToolbarItemContainer from '../toolbar-item-container/index.vue' import ToolbarItemContainer from '../toolbar-item-container/index.vue'
import custom from '../../../../assets/icon/telephone-icon.svg' import custom from '../../../../assets/icon/telephone-icon.svg'
import videoIcon from '../../../../assets/icon/video-icon.svg' import videoIcon from '../../../../assets/icon/video-icon.svg'
import { isUniFrameWork } from '../../../../utils/env' import { isUniFrameWork } from '../../../../utils/env'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { type IConversationModel } from '@tencentcloud/chat-uikit-engine-lite' import { type IConversationModel } from '@tencentcloud/chat-uikit-engine-lite'
import { navigateTo } from '../../../../../utils/router' import { navigateTo } from '../../../../../utils/router'
import TUIChatEngine, { import TUIChatEngine, {
TUIConversationService, TUIConversationService,
TUIFriendService, TUIFriendService,
TUIChatService TUIChatService
} from '@tencentcloud/chat-uikit-engine-lite' } from '@tencentcloud/chat-uikit-engine-lite'
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
/** 通话状态: 0 语音 1 视频 */ /** 通话状态: 0 语音 1 视频 */
type?: '0' | '1' type ?: '0' | '1'
/** 信息数据 */ /** 信息数据 */
currentConversation?: IConversationModel currentConversation ?: IConversationModel
}>(), }>(),
{ {
type: '0', type: '0',
currentConversation: () => ({} as IConversationModel) currentConversation: () => ({} as IConversationModel)
}
)
/** 语音通话状态 */
const isType = computed(() => props.type === '0')
const evaluateIcon = isType.value ? custom : videoIcon
const emits = defineEmits(['onDialogPopupShowOrHide'])
const container = ref()
const closeDialog = () => {
container?.value?.toggleDialogDisplay(false)
}
const onDialogShow = () => {
console.log('弹出窗口', props.currentConversation)
const data = props.currentConversation.userProfile
emits('onDialogPopupShowOrHide', true)
if (isType.value) {
let params ={
to: props.currentConversation.conversationID,
conversationType: TUIChatEngine.TYPES.CONV_C2C,
payload: {
text: "拨打语音"
}
} }
console.log('params: ',params); )
// TUIChatService.sendTextMessage(params)
navigateTo('/pages/room/incom', { /** 语音通话状态 */
type: 'call', const isType = computed(() => props.type === '0')
userID: data.userID
}) const evaluateIcon = isType.value ? custom : videoIcon
} else {
let params ={ const emits = defineEmits(['onDialogPopupShowOrHide'])
to: props.currentConversation.conversationID,
conversationType: TUIChatEngine.TYPES.CONV_C2C, const container = ref()
payload: { const closeDialog = () => {
text: "拨打视频" container?.value?.toggleDialogDisplay(false)
}
const onDialogShow = () => {
console.log('弹出窗口', props.currentConversation)
const data = props.currentConversation.userProfile
emits('onDialogPopupShowOrHide', true)
if (isType.value) {
let params = {
to: props.currentConversation.conversationID,
conversationType: TUIChatEngine.TYPES.CONV_C2C,
payload: {
text: "拨打语音"
}
} }
console.log('params: ', params);
// TUIChatService.sendTextMessage(params)
navigateTo('/pages/room/incom', {
type: 'call',
userID: data.userID,
mediaType: 'audio',
callType: 'out',
})
} else {
let params = {
to: props.currentConversation.conversationID,
conversationType: TUIChatEngine.TYPES.CONV_C2C,
payload: {
text: "拨打视频"
}
}
// TUIChatService.sendTextMessage(params)
uni.setStorageSync('room-parameters', {
callType: 'out',
mediaType: 'video',
targetId: data.userID,
callSelect: 'single',
});
navigateTo('/pages/room/room')
} }
// TUIChatService.sendTextMessage(params) }
uni.setStorageSync('room-parameters', {
callType: 'out',
mediaType: 'video',
targetId: data.userID,
callSelect: 'single',
});
navigateTo('/pages/room/room')
}
}
const onDialogClose = () => { const onDialogClose = () => {
console.log('关闭窗口') console.log('关闭窗口')
emits('onDialogPopupShowOrHide', false) emits('onDialogPopupShowOrHide', false)
} }
const onDial = () => { const onDial = () => {
const data = props.currentConversation.userProfile const data = props.currentConversation.userProfile
// data.userID // data.userID
// CallLib.enableMicrophone(true) // CallLib.enableMicrophone(true)
// CallLib.startSingleCall(data.userID, 0, '邀请您进行语音通话') // CallLib.startSingleCall(data.userID, 0, '邀请您进行语音通话')
} }
</script> </script>
<template> <template>
<!-- needBottomPopup --> <!-- needBottomPopup -->
<ToolbarItemContainer <ToolbarItemContainer ref="container" :iconFile="evaluateIcon" :iconWidth="isUniFrameWork ? '34px' : '20px'"
ref="container" :iconHeight="isUniFrameWork ? '34px' : '20px'" :title="isType ? '语音通话' : '视频通话'" @onDialogShow="onDialogShow"
:iconFile="evaluateIcon" @onDialogClose="onDialogClose">
:iconWidth="isUniFrameWork ? '34px' : '20px'" <!-- <view class="box-index">
:iconHeight="isUniFrameWork ? '34px' : '20px'"
:title="isType ? '语音通话' : '视频通话'"
@onDialogShow="onDialogShow"
@onDialogClose="onDialogClose"
>
<!-- <view class="box-index">
<view class="top-icon"> <view class="top-icon">
<uni-icons <uni-icons
type="back" type="back"
@@ -134,7 +130,7 @@
挂点 挂点
</button> </button>
</view> --> </view> -->
</ToolbarItemContainer> </ToolbarItemContainer>
</template> </template>
<style scoped lang="scss" src="./style/index.scss"></style> <style scoped lang="scss" src="./style/index.scss"></style>

View File

@@ -444,14 +444,14 @@
{ {
"path": "pages/room/room", "path": "pages/room/room",
"style": { "style": {
"navigationBarTitleText": "拨打电话", "navigationBarTitleText": "拨打视频",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{ {
"path": "pages/room/incom", "path": "pages/room/incom",
"style": { "style": {
"navigationBarTitleText": "拨打视频", "navigationBarTitleText": "拨打电话",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },

View File

@@ -150,24 +150,16 @@
}, },
onUnload() { onUnload() {
call.hangup() call.hangup()
// this.removeAllListeners()
}, },
onHide() { onHide() {
const session = call.getCurrentCallSession() const session = call.getCurrentCallSession()
if (session) { if (session) {
call.hangup() call.hangup()
} }
// this.removeAllListeners() uni.$off('OnCallDisconnected')
uni.$off('OnCallConnected')
}, },
methods: { methods: {
removeAllListeners(){
//移除监听-接收到通话呼入
call.removeRemoteUserJoinedListener();
// 移除监听-通话已结束
call.removeCallDisconnectedListener();
// 移除监听-通话出现错误的回调
call.removeErrorListener();
},
changeMediaType() { changeMediaType() {
if (this.mediaTypeCur == 'video') { if (this.mediaTypeCur == 'video') {
this.mediaTypeCur = 'audio' this.mediaTypeCur = 'audio'
@@ -284,9 +276,9 @@
hangup() { hangup() {
this.isSelf = true this.isSelf = true
call.hangup() call.hangup()
uni.navigateBack({ // uni.navigateBack({
delta: 1 // delta: 1
}) // })
}, },
accept() { accept() {
call.accept() call.accept()
@@ -324,12 +316,61 @@
) )
} }
}, },
onCallConnected() { onCallConnected() {
let context = this let context = this
console.log('oncallconnected接收了') console.log('oncallconnected接收了')
console.log('call: ',call);
// 使用 Promise 确保 call 对象完全初始化
this.initializeCall(call)
.then(() => {
this.processCallSession()
})
.catch(error => {
console.error('初始化通话失败:', error)
})
},
async initializeCall(callObj) {
// 等待 call 对象就绪
await this.waitForCallReady(callObj)
// 设置扬声器
if (callObj.enableSpeaker && typeof callObj.enableSpeaker === 'function') {
try {
callObj.enableSpeaker(true)
} catch (error) {
console.warn('设置扬声器失败:', error)
}
}
return callObj
},
waitForCallReady(callObj, timeout = 2000) {
return new Promise((resolve, reject) => {
const startTime = Date.now()
const check = () => {
const now = Date.now()
if (callObj &&
callObj.enableSpeaker &&
callObj.getCurrentCallSession &&
typeof callObj.getCurrentCallSession === 'function') {
resolve(callObj)
} else if (now - startTime > timeout) {
reject(new Error('call 对象初始化超时'))
} else {
setTimeout(check, 50)
}
}
check()
})
},
processCallSession(){
// call.enableSpeaker(true)
this.mediaTypeCur = this.mediaType this.mediaTypeCur = this.mediaType
call.enableSpeaker(true)
this.currentCallSession = call.getCurrentCallSession() this.currentCallSession = call.getCurrentCallSession()
this.callWay = this.currentCallSession.callType this.callWay = this.currentCallSession.callType
this.users = this.currentCallSession.users this.users = this.currentCallSession.users
@@ -347,6 +388,7 @@
) { ) {
//视频是两个的时候 //视频是两个的时候
if (this.currentCallSession.users.length <= 2) { if (this.currentCallSession.users.length <= 2) {
console.log("视频是两个的时候");
setTimeout(() => { setTimeout(() => {
this.systemInfoSync( this.systemInfoSync(
this.currentCallSession.mine.userId, this.currentCallSession.mine.userId,
@@ -397,6 +439,7 @@
} }
} }
}, },
systemInfoSync(userId, ref, isZOrderOnTop) { systemInfoSync(userId, ref, isZOrderOnTop) {
switch (uni.getSystemInfoSync().platform) { switch (uni.getSystemInfoSync().platform) {
case 'android': case 'android':