338 lines
12 KiB
Plaintext
338 lines
12 KiB
Plaintext
<template>
|
|
<view class="call">
|
|
<view class="video">
|
|
<RongCloud-Call-RCUniCallView ref="bigVideoView" :style="bigVideoStyle" class="bigVideoView">
|
|
</RongCloud-Call-RCUniCallView>
|
|
|
|
<movable-area class="movableArea" :style="movableAreaStyle">
|
|
<movable-view class="movableView" direction="all" :x="50" :y="50" v-if="mediaType == 1 && connected">
|
|
<RongCloud-Call-RCUniCallView ref="smallVideoView" class="smallVideoView" @click="changeMine">
|
|
</RongCloud-Call-RCUniCallView>
|
|
</movable-view>
|
|
</movable-area>
|
|
</view>
|
|
|
|
<view class="status" v-if="!connected">
|
|
<view class="remote">
|
|
<u-avatar :src="contact(targetId).portraitUrl" shape="square" :size="avatarSize" bgColor="#fff" />
|
|
<view><text class="nickname">{{ contact(targetId).name }}</text></view>
|
|
<view v-if="remoteRinging"><text class="mediaType">等待对方接听</text></view>
|
|
<view v-if="connected"><text class="mediaType">已接通</text></view>
|
|
</view>
|
|
</view>
|
|
<view class="buttons">
|
|
<view class="btn" v-if="connected" @click="changeMicrophone">
|
|
<view class="icon">
|
|
<u-icon name="mic-off" color="#ffffff" size="30" v-if="micOff" />
|
|
<u-icon name="mic" color="#ffffff" size="30" v-else />
|
|
</view>
|
|
<text class="text">麦克风</text>
|
|
</view>
|
|
<view class="btn" @click="hangup">
|
|
<view class="icon hangup">
|
|
<u-icon name="close" color="#ffffff" size="25" />
|
|
</view>
|
|
<text class="text">挂断</text>
|
|
</view>
|
|
<view class="btn" v-if="!connected && this.isCall == false" @click="accept">
|
|
<view class="icon">
|
|
<u-icon name="checkmark" color="#ffffff" size="30" />
|
|
</view>
|
|
<text class="text">接听</text>
|
|
</view>
|
|
<view class="btn" v-if="connected" @click="changeSpeaker">
|
|
<view class="icon">
|
|
<u-icon name="volume-off-fill" color="#ffffff" size="27" v-if="volumeOff" />
|
|
<u-icon name="volume-fill" color="#ffffff" size="27" v-else />
|
|
</view>
|
|
<text class="text">扬声器</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
|
import * as IMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
import utils from '@/utils/index.js'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
targetId: '',
|
|
mediaType: 0, // 0 语音 1 视频
|
|
connected: false,
|
|
micStatus: false,
|
|
speStatus: false,
|
|
remoteRinging: false,
|
|
ring: null,
|
|
isCall: false,
|
|
avatarSize: 96,
|
|
bigVideoStyle: {},
|
|
movableAreaStyle: {},
|
|
// 关闭麦克风
|
|
micOff: false,
|
|
// 关闭扬声器
|
|
volumeOff: false
|
|
}
|
|
},
|
|
onLoad(e) {
|
|
this.avatarSize = utils.rpx2px(200)
|
|
this.targetId = e.targetId
|
|
this.mediaType = e.mediaType
|
|
this.isCall = Boolean(e.isCall)
|
|
// 进入页面开启外呼
|
|
if (this.isCall) {
|
|
CallLib.startSingleCall(this.targetId, this.mediaType, '');
|
|
if (this.mediaType == 1) {
|
|
const session = CallLib.getCurrentCallSession()
|
|
setTimeout(() => {
|
|
CallLib.setVideoView(session.mine.userId, this.$refs.bigVideoView.ref, 0, false)
|
|
}, 200)
|
|
}
|
|
}
|
|
// 响铃
|
|
this.startRing()
|
|
// 监听通话链接状态
|
|
uni.$once('onCallConnected', this.onCallConnected)
|
|
uni.$once('onCallDisconnected', this.hangup)
|
|
uni.$once('onRemoteUserRinging', () => {
|
|
this.remoteRinging = true
|
|
})
|
|
uni.$once('onRemoteUserJoined', () => {
|
|
this.remoteRinging = false
|
|
})
|
|
this.bigVideoStyle = {
|
|
width: this.windowWidth + 'px',
|
|
height: this.windowHeight + 'px',
|
|
// backgroundImage: `url("${this.contact(this.targetId).portraitUrl}")`
|
|
}
|
|
this.movableAreaStyle = {
|
|
width: this.windowWidth + 'px',
|
|
height: this.windowHeight + 'px',
|
|
}
|
|
},
|
|
beforeDestroy() {
|
|
|
|
},
|
|
computed: {
|
|
windowWidth() {
|
|
return uni.getSystemInfoSync().windowWidth
|
|
},
|
|
windowHeight() {
|
|
return uni.getSystemInfoSync().windowHeight
|
|
},
|
|
contact() {
|
|
return function(targetId) {
|
|
return this.$store.getters.contactInfo(targetId)
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
afterHangup() {
|
|
const conversationType = IMLib.ConversationType.PRIVATE // 会话类型
|
|
const targetId = this.targetId
|
|
const sentStatus = 30
|
|
const messageContent = {
|
|
objectName: 'RC:InfoNtf',
|
|
userInfo: this.$store.getters.sender,
|
|
message: String(this.mediaType),
|
|
extra: '这里传接通和时长信息',
|
|
}
|
|
const sentTime = 0 // 消息的发送时间
|
|
IMLib.insertOutgoingMessage(conversationType, targetId, sentStatus, messageContent, sentTime,
|
|
({
|
|
code,
|
|
message
|
|
}) => {
|
|
console.log(code);
|
|
// 插入消息成功
|
|
if (code === 0) {
|
|
console.log(message)
|
|
}
|
|
}
|
|
)
|
|
uni.$emit('onReceiveMessage', {
|
|
targetId: this.targetId
|
|
})
|
|
},
|
|
changeMicrophone() {
|
|
this.micOff = !this.micOff
|
|
CallLib.enableMicrophone(this.micStatus)
|
|
this.micStatus = !this.micStatus
|
|
},
|
|
changeSpeaker() {
|
|
this.volumeOff = !this.volumeOff
|
|
CallLib.enableSpeaker(this.speStatus)
|
|
this.speStatus = !this.speStatus
|
|
},
|
|
accept() {
|
|
CallLib.accept()
|
|
},
|
|
onCallConnected() {
|
|
// 关掉铃声
|
|
this.stopRing()
|
|
// 设置链接状态
|
|
this.connected = true
|
|
// 视频通话,才开摄像头
|
|
if (this.mediaType == 1) {
|
|
const session = CallLib.getCurrentCallSession()
|
|
setTimeout(() => {
|
|
CallLib.setVideoView(session.targetId, this.$refs.bigVideoView.ref, 0, false)
|
|
CallLib.setVideoView(session.mine.userId, this.$refs.smallVideoView.ref, 0, true)
|
|
}, 200)
|
|
}
|
|
},
|
|
// 切换主屏显示人
|
|
changeMine() {
|
|
if (this.isCall) {
|
|
const session = CallLib.getCurrentCallSession()
|
|
setTimeout(() => {
|
|
CallLib.setVideoView(session.targetId, this.$refs.bigVideoView.ref, 0, false)
|
|
CallLib.setVideoView(session.mine.userId, this.$refs.smallVideoView.ref, 0, true)
|
|
}, 200)
|
|
} else {
|
|
const session = CallLib.getCurrentCallSession()
|
|
setTimeout(() => {
|
|
CallLib.setVideoView(session.targetId, this.$refs.smallVideoView.ref, 0, true)
|
|
CallLib.setVideoView(session.mine.userId, this.$refs.bigVideoView.ref, 0, false)
|
|
}, 200)
|
|
}
|
|
this.isCall = !this.isCall
|
|
},
|
|
hangup() {
|
|
this.afterHangup()
|
|
CallLib.hangup()
|
|
this.stopRing()
|
|
|
|
setTimeout(() => {
|
|
this.downRing()
|
|
uni.navigateBack()
|
|
}, 200);
|
|
},
|
|
toHome() {
|
|
uni.switchTab({
|
|
url: '/pages/im/index'
|
|
})
|
|
},
|
|
startRing() {
|
|
const ring = uni.createInnerAudioContext()
|
|
this.ring = ring
|
|
ring.autoplay = true
|
|
ring.loop = true
|
|
ring.src = '/static/im/sounds/call-ring.mp3'
|
|
ring.onEnded(() => {
|
|
ring.destroy()
|
|
})
|
|
},
|
|
stopRing() {
|
|
this.ring.stop()
|
|
},
|
|
downRing() {
|
|
const ding = uni.createInnerAudioContext()
|
|
ding.autoplay = true
|
|
ding.src = '/static/im/sounds/call-down.mp3'
|
|
ding.onEnded(() => {
|
|
ding.destroy()
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.call {
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
position: relative;
|
|
|
|
.video {
|
|
.movableArea {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
|
|
.movableView {
|
|
width: 180rpx;
|
|
height: 320rpx;
|
|
position: relative;
|
|
|
|
.smallVideoView {
|
|
width: 180rpx;
|
|
height: 320rpx;
|
|
background-color: #666;
|
|
}
|
|
}
|
|
}
|
|
|
|
.bigVideoView {
|
|
background-color: #666;
|
|
}
|
|
}
|
|
|
|
.status {
|
|
flex: 1;
|
|
width: 750rpx;
|
|
position: fixed;
|
|
bottom: 0;
|
|
top: 0;
|
|
|
|
.remote {
|
|
flex: 1;
|
|
width: 750rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
top: 300rpx;
|
|
|
|
.mediaType {
|
|
font-size: 32rpx;
|
|
color: #aaa;
|
|
}
|
|
|
|
.nickname {
|
|
margin: 30rpx;
|
|
font-size: 44rpx;
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.buttons {
|
|
position: fixed;
|
|
bottom: 100rpx;
|
|
width: 750rpx;
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-around;
|
|
}
|
|
|
|
|
|
.btn {
|
|
align-items: center;
|
|
|
|
.icon {
|
|
background: $main-color;
|
|
width: 132rpx;
|
|
height: 132rpx;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
&.hangup {
|
|
background-color: $text-price;
|
|
}
|
|
}
|
|
|
|
.text {
|
|
margin-top: 16rpx;
|
|
color: #FFFFFF;
|
|
font-size: 32rpx;
|
|
}
|
|
}
|
|
}
|
|
</style>
|