123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- <template>
- <view class="calling" v-show="callingDialog">
-
- <view class="calling-waiting" v-if="dialling">
- <view class="calling-waiting-header">
- <u-avatar :src="defaultAvatar" size="240" mode="square"></u-avatar>
- </view>
- <view class="calling-waiting-status">
- <view>正在呼叫{{ toAccount }}</view>
- </view>
- <view class="calling-waiting-button">
- <view class="calling-waiting-button-passed" @click="handleDebounce(leave, 500)">
- <view class="iconfont icon-guaduan"></view>
- </view>
- <view class="calling-waiting-button-mute" @click="micHandler">
- <view class="iconfont icon-mic-on-full" :class="isMicOn ? 'on' : 'off'"></view>
- </view>
- </view>
- </view>
-
- <view class="calling-waiting" v-else-if="isDialled">
- <view class="calling-waiting-header">
- <u-avatar :src="defaultAvatar" size="240" mode="square"></u-avatar>
- </view>
- <view class="calling-waiting-status">
- <view>{{ sponsor }}来电</view>
- </view>
- <view class="calling-waiting-button">
- <view class="calling-waiting-button-mute" @click="handleDebounce(accept, 500)">
- <view class="iconfont icon-call"></view>
- </view>
- <view class="calling-waiting-button-passed" @click="handleDebounce(leave, 500)">
- <view class="iconfont icon-guaduan"></view>
- </view>
- </view>
- </view>
-
- <view class="calling-waiting" v-else-if="calling">
- <view class="calling-waiting-userList">
- <view class="calling-waiting-userList-item" v-for="(item, index) in invitedUserInfo" :key="index">
- <u-avatar :src="item.avatar || defaultAvatar" size="120"></u-avatar>
- <view style="text-align: center;margin-top: 30rpx;">
- <text class="nick-text">{{ item.nick || item.userID }}</text>
- <text v-if="item.isInvitedMicOn === true || item.isInvitedMicOn == undefined"
- class="iconfont icon-yuyin"
- style="color: #006FFF;font-size: 50rpx;margin-left: 10rpx;"></text>
- <text v-else class="iconfont icon-maikefeng-jingyin"
- style="color: #fff;font-size: 50rpx;margin-left: 10rpx;"></text>
- </view>
- </view>
- </view>
- <view class="calling-waiting-duration">
- {{ formatDurationStr }}
- </view>
- <view class="calling-waiting-button">
- <view class="calling-waiting-button-passed" @click="handleDebounce(leave, 500)">
- <view class="iconfont icon-guaduan"></view>
- </view>
- <view class="calling-waiting-button-mute" @click="micHandler">
- <view class="iconfont icon-mic-on-full" :class="isMicOn ? 'on' : 'off'"></view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- timeout: null,
- callType: 1,
- Trtc: undefined,
- isCamOn: true,
- isMicOn: true,
- isInvitedMicOn: true,
- maskShow: false,
- isLocalMain: true,
- start: 0,
- end: 0,
- duration: 0,
- hangUpTimer: 0,
- ready: false,
- dialling: true,
- calling: false,
- isDialled: false,
- inviteID: '',
- inviteData: {},
- sponsor: '',
- toAccount: '222',
- invitedUserID: [],
- invitedNick: '',
- invitedUserInfo: [],
- defaultAvatar: 'https://imgcache.qq.com/open/qcloud/video/act/webim-avatar/avatar-3.png',
- viewLocalDomID: '',
- callingUserList: [],
- callingType: 'C2C',
- isStartLocalView: false,
- callingTips: {
- callEnd: 1,
- callTimeout: 5
- },
- callingDialog: false,
- callingInfo: {
- type: 'C2C'
- }
- }
- },
-
-
-
- onHide() {
- this.removeListener();
- },
- watch: {
- callingUserList: {
- handler(newValue) {
- console.log(newValue)
- },
- deep: true,
- immediate: true
- }
- },
- computed: {
- formatDurationStr() {
- return this.$format.formatDuration(this.duration)
- }
- },
- methods: {
- handleDebounce(func, wait) {
- let context = this
- let args = arguments
- if (this.timeout) clearTimeout(this.timeout)
- this.timeout = setTimeout(() => {
- func.apply(context, args)
- }, wait)
- },
- accept() {
- this.trtcCalling.accept({
- inviteID: this.inviteID,
- roomID: this.inviteData.roomID,
- callType: this.inviteData.callType
- }).then((res) => {
- this.changeState('calling', true);
- this.dialling = false;
- this.calling = true;
- this.isDialled = false;
- console.log('接收信息res', res)
-
- })
- },
- leave() {
- this.isMicOn = true
- this.isCamOn = true
- this.maskShow = false
- this.isStartLocalView = false
- this.dialling = false;
- this.calling = false;
- this.isDialled = false;
- this.callingDialog = false
- if (!this.calling) {
- this.trtcCalling.hangup().then((res) => {
-
- this.changeState('dialling', false)
- clearTimeout(this.timer)
- })
- return
- }
- this.hangUp()
- },
- hangUp() {
- this.changeState('calling', false)
- this.trtcCalling.hangup();
- this.callingDialog = false
- uni.showToast({
- title: '已挂断',
- icon: 'none'
- })
- },
- openDialog() {
- this.callingDialog = true;
- this.dialling = true;
- this.calling = false;
- this.isDialled = false;
- },
- initListener() {
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.ERROR, this.handleError)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.INVITED, this.handleNewInvitationReceived)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.USER_ENTER, this.handleUserEnter)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.USER_LEAVE, this.handleUserLeave)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.REJECT, this.handleInviteeReject)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.LINE_BUSY, this.handleInviteeLineBusy)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.CALLING_CANCEL, this.handleInviterCancel)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.KICKED_OUT, this.handleKickedOut)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.CALLING_TIMEOUT, this.handleCallTimeout)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.NO_RESP, this.handleNoResponse)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.CALLING_END, this.handleCallEnd)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.USER_VIDEO_AVAILABLE, this.handleUserVideoChange)
-
- this.trtcCalling.on(this.TRTCCalling.EVENT.USER_AUDIO_AVAILABLE, this.handleUserAudioChange)
- },
- removeListener() {
- this.trtcCalling.off(this.TRTCCalling.EVENT.ERROR, this.handleError)
- this.trtcCalling.off(this.TRTCCalling.EVENT.INVITED, this.handleNewInvitationReceived)
- this.trtcCalling.off(this.TRTCCalling.EVENT.USER_ENTER, this.handleUserEnter)
- this.trtcCalling.off(this.TRTCCalling.EVENT.USER_LEAVE, this.handleUserLeave)
- this.trtcCalling.off(this.TRTCCalling.EVENT.REJECT, this.handleInviteeReject)
- this.trtcCalling.off(this.TRTCCalling.EVENT.LINE_BUSY, this.handleInviteeLineBusy)
- this.trtcCalling.off(this.TRTCCalling.EVENT.CALLING_CANCEL, this.handleInviterCancel)
- this.trtcCalling.off(this.TRTCCalling.EVENT.KICKED_OUT, this.handleKickedOut)
- this.trtcCalling.off(this.TRTCCalling.EVENT.CALLING_TIMEOUT, this.handleCallTimeout)
- this.trtcCalling.off(this.TRTCCalling.EVENT.NO_RESP, this.handleNoResponse)
- this.trtcCalling.off(this.TRTCCalling.EVENT.CALLING_END, this.handleCallEnd)
- this.trtcCalling.off(this.TRTCCalling.EVENT.USER_VIDEO_AVAILABLE, this.handleUserVideoChange)
- this.trtcCalling.off(this.TRTCCalling.EVENT.USER_AUDIO_AVAILABLE, this.handleUserAudioChange)
- },
- handleError() {
- console.log('Error')
- },
- handleUserVideoChange() {},
- handleUserAudioChange(payload) {
- const _index = this.invitedUserInfo.findIndex(item => item.userID === payload.userID)
- if (_index >= 0) {
- this.invitedUserInfo[_index].isInvitedMicOn = payload.isAudioAvailable
- }
- },
-
- handleCallEnd({
- userID,
- callEnd
- }) {
-
-
- if (userID === this.userID && this.invitedUserID.length === 0 || this.callingUserList === 0) {
- this.sendMessage(userID, callEnd, this.callingTips.callEnd)
- }
- this.changeState('dialling', false)
- this.isMicOn = true
- this.isCamOn = true
- this.maskShow = false
- this.isStartLocalView = false
- },
-
- handleNoResponse({
- sponsor,
- userIDList
- }) {
- if (sponsor === this.userID) {
- userIDList.forEach((userID) => {
- this.setCallingstatus(userID)
- })
- if (userIDList.indexOf(this.userID) === -1) {
- this.sendMessage(userIDList, '', this.callingTips.callTimeout)
- }
- }
- },
-
-
- handleCallTimeout({
- userIDList
- }) {
- if (this.calling) {
- return
- }
- if (this.userID === this.sponsor) {
- userIDList.forEach((userID) => {
- this.setCallingstatus(userID)
- })
- return
- }
-
- if (userIDList.indexOf(this.userID) > -1) {
-
- this.toAccount && this.sendMessage(this.userID, '', this.callingTips.callTimeout)
- }
- this.changeState('isDialled', false)
- },
- handleKickedOut() {
-
- },
-
- handleNoResponse({
- sponsor,
- userIDList
- }) {
- if (sponsor === this.userID) {
- userIDList.forEach((userID) => {
- this.setCallingstatus(userID)
- })
- if (userIDList.indexOf(this.userID) === -1) {
- this.sendMessage(userIDList, '', this.callingTips.callTimeout)
- }
- }
- },
-
-
- handleCallTimeout({
- userIDList
- }) {
- if (this.calling) {
- return
- }
- if (this.userID === this.sponsor) {
- userIDList.forEach((userID) => {
- this.setCallingstatus(userID)
- })
- return
- }
-
- if (userIDList.indexOf(this.userID) > -1) {
-
- this.toAccount && this.sendMessage(this.userID, '', this.callingTips.callTimeout)
- }
- this.changeState('isDialled', false)
- },
- handleKickedOut() {},
-
- handleInviterCancel() {
-
- this.changeState('isDialled', false)
- uni.showToast({
- title: '通话已取消',
- icon: 'none'
- })
- },
-
- handleInviteeLineBusy({
- sponsor,
- userID
- }) {
-
- if (sponsor === this.userID) {
- this.setCallingstatus(userID)
- uni.showToast({
- title: '对方忙线',
- icon: 'none'
- })
- }
- },
- setCallingstatus(userID) {
- const _index = this.invitedUserID.indexOf(userID)
- if (_index >= 0) {
- this.invitedUserID.splice(_index, 1)
- }
- if (this.invitedUserID.length === 0) {
- this.changeState('isDialled', false)
- this.changeState('dialling', false)
- }
- },
-
-
- handleInviteeReject({
- userID
- }) {
- if (this.userID === this.sponsor) {
-
- this.setCallingstatus(userID)
- uni.showToast({
- title: '用户拒绝通话',
- icon: 'none'
- })
- }
- },
-
- handleUserLeave({
- userID
- }) {
- console.log(this.callType)
- if (this.callType === this.TRTCCalling.CALL_TYPE.AUDIO_CALL) {
-
- const _index = this.invitedUserInfo.findIndex(item => item.userID === userID)
- if (_index >= 0) {
- this.invitedUserInfo.splice(_index, 1)
- }
- return
- }
- const index = this.callingUserList.findIndex(item => item === userID)
- if (index >= 0) {
- this.callingUserList.splice(index, 1)
- }
- this.dialling = true;
- this.calling = false;
- this.isDialled = false;
- this.callingDialog = false
- },
-
- async handleNewInvitationReceived(payload) {
- console.log('接听方', payload)
- this.inviteID = payload.inviteID
- this.callingDialog = true
- this.dialling = false;
- this.calling = false;
- this.isDialled = true;
- },
-
- handleUserEnter({
- userID
- }) {
- this.changeState('dialling', true)
- this.isAccept()
-
- if (this.callingUserList.length >= 2) {
- this.callingType = this.$TIM.TYPES.CONV_GROUP
- }
- if (this.callingUserList.indexOf(userID) === -1) {
- if (this.callType === this.TRTCCalling.CALL_TYPE.AUDIO_CALL) {
- this.getUserAvatar(userID)
- } else {
- this.callingUserList.push(userID)
- }
- }
- if (this.callType === this.TRTCCalling.CALL_TYPE.VIDEO_CALL) {
- this.$nextTick(() => {
- if (!this.isStartLocalView) {
- this.startLocalView()
- }
- this.startRemoteView(userID)
- })
- }
- },
-
- startLocalView() {
- this.trtcCalling.startLocalView({
- userID: this.userID,
- videoViewDomID: 'local'
- }).then(() => {
- this.isStartLocalView = true
- })
- },
- async sendMessage(userId, callEnd, callText) {
- let call_text = ''
- userId = Array.isArray(userId) ? userId.join(',') : userId
- let messageData = {
- to: this.toAccount,
- from: userId,
- conversationType: this.currentConversationType,
- payload: {
- data: '',
- description: '',
- extension: ''
- }
- }
- const message = await this.$TIM.createCustomMessage(messageData)
- },
-
- startRemoteView(userID) {
- this.trtcCalling.startRemoteView({
- userID: userID,
- videoViewDomID: `video-${userID}`
- }).then(() => {
- })
- },
-
- getUserAvatar(userID) {
- const _index = this.invitedUserInfo.findIndex(item => item.userID === userID)
- if (_index >= 0) {
- return
- }
- let _userIDList = [userID]
- let promise = this.tim.getUserProfile({
- userIDList: _userIDList
- })
- promise.then((imResponse) => {
- if (imResponse.data[0]) {
- this.invitedUserInfo.push(imResponse.data[0])
- }
- }).catch(() => {})
- },
-
- isAccept() {
- clearTimeout(this.timer)
- this.changeState('calling', true)
- clearTimeout(this.hangUpTimer)
- this.resetDuration(0)
- this.start = new Date()
- },
- resetDuration(duration) {
- this.duration = duration
- this.hangUpTimer = setTimeout(() => {
- let now = new Date()
- this.resetDuration(parseInt((now - this.start) / 1000))
- }, 1000)
- },
-
- changeState(state, boolean) {
- let stateList = ['dialling', 'isDialled', 'calling']
- stateList.forEach(item => {
- this[item] = item === state ? boolean : false
- })
- this.$store.commit('UPDATE_ISBUSY', stateList.some(item => this[
- item]))
-
- },
-
- micHandler() {
- if (this.isMicOn) {
- this.trtcCalling.setMicMute(true)
- this.isMicOn = false
- } else {
- this.trtcCalling.setMicMute(false)
- this.isMicOn = true
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- @import './index.scss';
- </style>
|