715 lines
19 KiB
JavaScript
715 lines
19 KiB
JavaScript
// import { Notification } from '@arco-design/web-vue';
|
|
import { ElNotification, ElMessage } from 'element-plus'
|
|
import emitter from "@/utils/eventBus.js";
|
|
// import handleCallingNotification from '../hooks/callingNotification';
|
|
|
|
let call_id;
|
|
let hangup_event_cb_id;
|
|
let force_hangup_event_cb_id;
|
|
let answer_ack_cb_id;
|
|
let incoming_cb_id;
|
|
let floor_grant_cb_id;
|
|
|
|
// Whether it is a pushVideoFile call
|
|
// 是否为视频推送的呼叫
|
|
let pushing_video = false;
|
|
// monitor call list
|
|
// 值守呼叫列表
|
|
const monitor_call_list = [];
|
|
|
|
export default function useCallModule() {
|
|
// we allow only one call exist in demo.but actually,sdk supports more
|
|
|
|
/**
|
|
* make private vioce call,return nothing,receive result in callback
|
|
* This interface has been expanded to support makeGroupVoiceCall、makeDispatcherVoiceCall、makeConferenceVoiceCall、makeCrosspatchVoiceCall
|
|
* 这个接口已扩展,除了支持语音单呼外,还支持语音组呼、语音呼叫调度员、语音会议、群组呼叫。
|
|
* @param record who you wanna call
|
|
* @returns
|
|
*/
|
|
const makeVoiceCall = (record) => {
|
|
if (call_id) {
|
|
console.warn('we allow only one call exist,please hangup first');
|
|
return;
|
|
}
|
|
|
|
window.lemon.call
|
|
.makeVoiceCall({ basedata_id: record.basedata_id, hook_flag: 0 })
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
console.info('makeVoiceCall succ,registerCallEstablishEvent', call_id);
|
|
});
|
|
|
|
// test
|
|
// window.lemon.call.changeCamera({ call_id, target_camera: 0 });
|
|
|
|
// also can use this makecall method,the method provides the most comprehensive call capability
|
|
// For example, Voice private call, ensure that the basedata_id is a private
|
|
// window.lemon.call
|
|
// .makeCall({
|
|
// callee_guid: record.basedata_id,
|
|
// attribute: {
|
|
// call_type: 0,
|
|
// call_mode: 0,
|
|
// duplex_flag: 0,
|
|
// },
|
|
// })
|
|
// ?.then((resp) => {
|
|
// console.info('makeCall succ,resp', resp);
|
|
// call_id = resp.call_id;
|
|
// });
|
|
|
|
// For example, Voice group call,ensure that the basedata_id is a group
|
|
// window.lemon.call
|
|
// .makeCall({
|
|
// callee_guid: record.basedata_id,
|
|
// attribute: {
|
|
// call_type: 1,
|
|
// call_mode: 0,
|
|
// duplex_flag: 0, // group call ,the value must be 0
|
|
// },
|
|
// })
|
|
// ?.then((resp) => {
|
|
// console.info('makeCall succ,resp', resp);
|
|
// call_id = resp.call_id;
|
|
// });
|
|
};
|
|
/**
|
|
* make private video call,call with vioce and video,return nothing,receive result in callback
|
|
* This interface has been expanded to support makeGroupVideoCall、makeDispatcherVideoCall、makeConferenceVideoCall
|
|
* 这个接口已扩展,除了支持视频单呼外,还支持视频组呼、视频呼叫调度员、视频会议
|
|
* @param record who you wanna call
|
|
* @returns
|
|
*/
|
|
const makeVideoCall = (record) => {
|
|
if (call_id) {
|
|
console.warn('we allow only one call exist,please hangup first');
|
|
return;
|
|
}
|
|
window.lemon.call
|
|
.makeVideoCall({ basedata_id: record.basedata_id, video_frame_size: 3 })
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
|
|
console.warn('makeVideoCall succ,call_id=', call_id);
|
|
});
|
|
|
|
// also can use this makecall method,the method provides the most comprehensive call capability
|
|
// For example, Video private call (with voice), ensure that the basedata_id is a private
|
|
// window.lemon.call
|
|
// .makeCall({
|
|
// callee_guid: record.basedata_id,
|
|
// attribute: {
|
|
// call_type: 11,
|
|
// call_mode: 2,
|
|
// duplex_flag: 1,
|
|
// },
|
|
// video_frame_size: window.lemon.call.getMaxFrameSize(),
|
|
// })
|
|
// ?.then((resp) => {
|
|
// console.info('makeCall succ,resp', resp);
|
|
// call_id = resp.call_id;
|
|
// });
|
|
|
|
// For example, Video group call,ensure that the basedata_id is a group
|
|
// window.lemon.call
|
|
// .makeCall({
|
|
// callee_guid: record.basedata_id,
|
|
// attribute: {
|
|
// call_type: 13,
|
|
// call_mode: 2,
|
|
// duplex_flag: 0, // group call ,the value must be 0
|
|
// },
|
|
// video_frame_size: window.lemon.call.getMaxFrameSize(),
|
|
// })
|
|
// ?.then((resp) => {
|
|
// console.info('makeCall succ,resp', resp);
|
|
// call_id = resp.call_id;
|
|
// });
|
|
};
|
|
const makeGroupVideoCall = (record) => {
|
|
if (call_id) {
|
|
console.warn('we allow only one call exist,please hangup first');
|
|
return;
|
|
}
|
|
window.lemon.call
|
|
.makeGroupVideoCall({
|
|
basedata_id: record.basedata_id,
|
|
video_frame_size: 3,
|
|
})
|
|
?.then((resp) => {
|
|
console.log('makeGroupVideoCall call_id = ', call_id);
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
const makeGroupVoiceCall = (record) => {
|
|
if (call_id) {
|
|
console.warn('we allow only one call exist,please hangup first');
|
|
return;
|
|
}
|
|
window.lemon.call
|
|
.makeGroupVoiceCall({
|
|
basedata_id: record.basedata_id,
|
|
})
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
|
|
const makeCrosspatchVoiceCall = (record) => {
|
|
window.lemon.call
|
|
.makeCrosspatchVoiceCall({ basedata_id: record.basedata_id })
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* 视频上拉
|
|
* make pure video call,only video, no voice
|
|
* @param record who you wanna call
|
|
* @returns
|
|
*/
|
|
const pureVideoCall = (record) => {
|
|
if (call_id) {
|
|
console.warn('we allow only one call exist,please hangup first');
|
|
return;
|
|
}
|
|
window.lemon.call
|
|
.pullVideo({ basedata_id: record.basedata_id, hook_flag: 0 })
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
/**
|
|
* 环境监听
|
|
* @param record
|
|
*/
|
|
const voiceDetect = (record) => {
|
|
window.lemon.call
|
|
.makeCall({
|
|
callee_guid: record.basedata_id,
|
|
attribute: {
|
|
call_type: 0,
|
|
call_mode: 0,
|
|
duplex_flag: 0,
|
|
ambience_flag: 1,
|
|
},
|
|
})
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* 环境监视
|
|
* @param record
|
|
*/
|
|
const videoDetect = (record) => {
|
|
window.lemon.call
|
|
.makeCall({
|
|
callee_guid: record.basedata_id,
|
|
attribute: {
|
|
call_type: 11,
|
|
call_mode: 2,
|
|
duplex_flag: 0,
|
|
ambience_flag: 1,
|
|
},
|
|
})
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
/**
|
|
* 音频会议
|
|
* @param record
|
|
*/
|
|
const makeConferenceVoiceCall = (record) => {
|
|
window.lemon.call
|
|
.makeConferenceVoiceCall({
|
|
basedata_id: record.basedata_id,
|
|
})
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
/**
|
|
* 音视频会议
|
|
* @param record
|
|
*/
|
|
const makeConferenceVideoCall = (record) => {
|
|
window.lemon.call
|
|
.makeConferenceVideoCall({
|
|
basedata_id: record.basedata_id,
|
|
})
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
|
|
// 广播呼叫
|
|
// Broadcast Call
|
|
const makeBroadcastCall = (record) => {
|
|
window.lemon.call
|
|
.makeCall({
|
|
callee_guid: record.basedata_id,
|
|
attribute: {
|
|
call_type: 3,
|
|
call_mode: 0,
|
|
},
|
|
})
|
|
?.then((resp) => {
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* hangup call
|
|
*/
|
|
const hangup = (id) => {
|
|
console.info('try hangup,call_id=', call_id);
|
|
console.info('try hangup,id=', id);
|
|
|
|
window.lemon.call
|
|
.hangupCall({ call_id: id || call_id })
|
|
?.then(() => {
|
|
call_id = undefined;
|
|
window.calling_conference = undefined;
|
|
// console.log('22222registerCallEstablishEven');
|
|
})
|
|
.catch((err) => {
|
|
console.error('hangup call error,', err);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* 接听呼叫
|
|
* answer call
|
|
*/
|
|
const answerCall = () => {
|
|
ElNotification.close(call_id);
|
|
|
|
window.lemon.call
|
|
.answerCall({ call_id })
|
|
?.then(() => {
|
|
// display alert ui
|
|
ElNotification.close(call_id);
|
|
})
|
|
.catch((err) => {
|
|
console.error('answer call error,', err);
|
|
});
|
|
};
|
|
|
|
// 禁麦
|
|
// mute the microphone
|
|
const setMuteMic = (mute) => {
|
|
return window.lemon.call.muteMic({
|
|
call_id,
|
|
is_mute: mute,
|
|
});
|
|
};
|
|
|
|
// 禁摄像头
|
|
// disable the camera
|
|
const setMuteCamera = (mute) => {
|
|
return window.lemon.call.muteCamera({
|
|
call_id,
|
|
is_mute: mute,
|
|
});
|
|
};
|
|
// 静音
|
|
// mute call
|
|
const setMuteCall = (mute) => {
|
|
return window.lemon.call.muteCall({
|
|
call_id,
|
|
is_mute: mute,
|
|
});
|
|
};
|
|
|
|
const removeMonitorCall = (callId) => {
|
|
const index = monitor_call_list.findIndex(
|
|
(item) => item.call_id === callId
|
|
);
|
|
if (index >= 0) {
|
|
monitor_call_list.splice(index, 1);
|
|
emitter.emit('monitorUpdate');
|
|
}
|
|
};
|
|
|
|
const getMonitorCallList = () => {
|
|
return monitor_call_list;
|
|
};
|
|
|
|
// 添加 挂断 回调
|
|
// After hanging up the call, you can receive a notification and process the style of the current page based on the notification
|
|
const registerhangupEvent = () => {
|
|
if (hangup_event_cb_id !== undefined) {
|
|
return;
|
|
}
|
|
|
|
hangup_event_cb_id = window.lemon.call.addHangupEvt((data) => {
|
|
console.info('receive hangup event');
|
|
console.info(
|
|
'receive hangup event receive call id',
|
|
String(data.call_id)
|
|
);
|
|
console.info('receive hangup event local call id', String(call_id));
|
|
if (data.call_id === call_id) {
|
|
// remove display alert ui
|
|
ElNotification.close(call_id);
|
|
call_id = undefined;
|
|
window.calling_conference = undefined;
|
|
// console.log('2222211111registerCallEstablishEvent');
|
|
}
|
|
|
|
// pushVideoFile uninit
|
|
// 如果是视频推送的,挂断是反初始化一些东西。
|
|
if (pushing_video) {
|
|
window.video.src = undefined;
|
|
window.showVideo.value = false;
|
|
pushing_video = false;
|
|
window.videoViewRoot.style.display = 'none';
|
|
}
|
|
removeMonitorCall(data.call_id);
|
|
});
|
|
};
|
|
|
|
// 添加强拆事件
|
|
const registerForceHangupEvent = () => {
|
|
if (force_hangup_event_cb_id !== undefined) {
|
|
return;
|
|
}
|
|
force_hangup_event_cb_id = window.lemon.call.addForceHangupEvt((data) => {
|
|
// 目前强拆成功,都是走挂断通知事件。 当失败了,才走强拆事件通知。
|
|
if (data.result === 0) {
|
|
if (data.call_id === call_id) {
|
|
ElNotification.close(call_id);
|
|
call_id = undefined;
|
|
window.calling_conference = undefined;
|
|
}
|
|
removeMonitorCall(data.call_id);
|
|
} else {
|
|
// 强拆失败 fail
|
|
ElMessage.error("强拆失败");
|
|
}
|
|
});
|
|
};
|
|
|
|
// 添加接听回调通知 代表呼叫建立
|
|
// receive the answer acknowledgement asynchronously after the call is established
|
|
const registerCallEstablishEvent = () => {
|
|
if (answer_ack_cb_id !== undefined) {
|
|
return;
|
|
}
|
|
answer_ack_cb_id = window.lemon.call.addAnswerAckEvt((data) => {
|
|
// console.info('registerCallEstablishEvent0', call_id);
|
|
console.info('registerCallEstablishEvent', String(data.call_id));
|
|
console.info('registerCallEstablishEvent', JSON.stringify(data));
|
|
|
|
call_id = data.call_id;
|
|
// pushVideoFile init
|
|
// 接通后,视频推送的文件开始播放
|
|
if (pushing_video) {
|
|
window.videoViewRoot.style.display = 'unset';
|
|
window.showVideo.value = true;
|
|
window.video.play();
|
|
}
|
|
});
|
|
};
|
|
|
|
// 注册来电通知回调
|
|
// add the incoming call callback
|
|
const registerReceiveCallEvent = () => {
|
|
if (incoming_cb_id !== undefined) {
|
|
return;
|
|
}
|
|
incoming_cb_id = window.lemon.call.addIncomingEvt((session) => {
|
|
console.log('receive call------>', session);
|
|
call_id = session.call_id;
|
|
const callingReq = {
|
|
callInfo: session,
|
|
equipment: undefined,
|
|
text: {
|
|
calling: '队列',
|
|
answer: '接听',
|
|
hangUp: '挂断',
|
|
},
|
|
};
|
|
console.log('receive this------>', useCallModule());
|
|
if (session.listen_flag) {
|
|
// monitor call,auto answer call
|
|
// 值守的来电呼叫,自动接听
|
|
window.lemon.call.answerCall({ call_id: session.call_id });
|
|
monitor_call_list.push(session);
|
|
|
|
emitter.emit('monitorUpdate');
|
|
} else {
|
|
// normal call
|
|
// 正常来电,弹框询问接听
|
|
// handleCallingNotification(callingReq);
|
|
}
|
|
});
|
|
};
|
|
|
|
// 申请话权
|
|
// apply floor
|
|
const applyFloor = () => {
|
|
console.info('try applyFloor,call_id=', call_id);
|
|
if (!call_id) {
|
|
console.warn('no call exits');
|
|
return undefined;
|
|
}
|
|
return window.lemon.floor
|
|
.applySpeak({ call_id })
|
|
?.then((resp) => {
|
|
if (resp.result === 0) {
|
|
console.log('applyFloor request sucess');
|
|
} else {
|
|
ElMessage.error("申请话权失败");
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error('applyFloor error,', err);
|
|
});
|
|
};
|
|
|
|
// 释放话权
|
|
// release floor
|
|
const releaseFloor = () => {
|
|
console.info('try releaseFloor,call_id=', call_id);
|
|
return window.lemon.floor
|
|
.releaseSpeak({ call_id })
|
|
?.then((resp) => {
|
|
if (resp.result === 0) {
|
|
console.log('releaseSpeak request sucess');
|
|
} else {
|
|
ElMessage.error("释放话权失败");
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error('releaseSpeak error,', err);
|
|
});
|
|
};
|
|
|
|
// add floor event
|
|
// 添加话权通知事件
|
|
const registerFloorGrantEvent = () => {
|
|
if (floor_grant_cb_id !== undefined) {
|
|
return;
|
|
}
|
|
floor_grant_cb_id = window.lemon.floor.addGrantEvt((grantInfo) => {
|
|
console.log('registerFloorGrantEvent', grantInfo);
|
|
if (grantInfo.result !== 0) {
|
|
ElMessage.error("话权申请失败");
|
|
}
|
|
});
|
|
};
|
|
|
|
// 强拆
|
|
// override the call
|
|
const forceHangupCall = (callId) => {
|
|
return window.lemon.call
|
|
.forceHangupCall({ call_id: callId || call_id })
|
|
?.then((resp) => {
|
|
if (resp.result === 0) {
|
|
console.log('forceHangupCall request sucess');
|
|
} else {
|
|
ElMessage.error("强拆失败");
|
|
}
|
|
call_id = undefined;
|
|
window.calling_conference = undefined;
|
|
// console.log('2222233registerCallEstablishEven');
|
|
})
|
|
.catch((err) => {
|
|
console.error('forceHangupCall error,', err);
|
|
});
|
|
};
|
|
// 强插
|
|
// interrupt the call during monitoring
|
|
const forceApplySpeak = (callId) => {
|
|
return window.lemon.floor
|
|
.forceApplySpeak({ call_id: callId || call_id })
|
|
?.then((resp) => {
|
|
if (resp.result === 0) {
|
|
console.log('forceApplySpeak request sucess');
|
|
call_id = callId;
|
|
} else {
|
|
ElMessage.error("强插失败");
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error('forceApplySpeak error,', err);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* 会议成员禁言
|
|
* mute or unmute a conference member
|
|
* @param param
|
|
* @param param.conference_basedata_id
|
|
*/
|
|
const muteMemberInConference = (
|
|
conference_basedata_id,
|
|
member_basedata_id,
|
|
mute
|
|
) => {
|
|
return window.lemon.call.conferenceMemberSpeakSet({
|
|
conference_call_id: call_id,
|
|
conference_basedata_id,
|
|
member_setting: {
|
|
member_basedata_id,
|
|
forbid: mute ? 1 : 0,
|
|
},
|
|
});
|
|
};
|
|
|
|
/**
|
|
* 视频推送
|
|
* select a local video file and play then push the stream to remote
|
|
* @param record
|
|
* @param file
|
|
* @returns
|
|
*/
|
|
const pushVideoFile = (record, url) => {
|
|
console.info('try pushVideoFile,call_id=', call_id);
|
|
if (call_id) {
|
|
console.warn('call exits');
|
|
return;
|
|
}
|
|
console.warn('window.video', window.video);
|
|
// set the file to video tag
|
|
if (window.video) {
|
|
const canPlayListener = () => {
|
|
window.video.removeEventListener('canplay', canPlayListener);
|
|
// capture stream
|
|
const stream = (window.video)?.captureStream();
|
|
console.info('pushVideoFile,inited stream=', stream);
|
|
// register hook listner ,play the video when remote hooked
|
|
registerCallEstablishEvent();
|
|
// init the call
|
|
window.lemon.call
|
|
.pushVideoFile({
|
|
basedata_id: record?.basedata_id,
|
|
stream,
|
|
})
|
|
?.then((resp) => {
|
|
pushing_video = true;
|
|
call_id = resp.call_id;
|
|
});
|
|
};
|
|
|
|
const endListener = () => {
|
|
console.info('pushVideoFile,video play end');
|
|
window.video.removeEventListener('ended', endListener);
|
|
hangup();
|
|
};
|
|
// maybe did't finish the video,so that we has listener already,remove it
|
|
window.video.removeEventListener('ended', endListener);
|
|
console.info('pushVideoFile,add canplay Event Listener', canPlayListener);
|
|
window.video.addEventListener('canplay', canPlayListener);
|
|
// hangup the call when video finished
|
|
console.info('pushVideoFile,add ended Event Listener', endListener);
|
|
window.video.addEventListener('ended', endListener);
|
|
window.video.autoplay = false;
|
|
window.video.src = url;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 视频转发
|
|
* share a exist call to another device
|
|
* @param record
|
|
* @param stop
|
|
* @returns
|
|
*/
|
|
const forwardVideoCall = (record, stop) => {
|
|
console.info('try forwardVideoCall,call_id=', call_id);
|
|
if (!call_id) {
|
|
console.warn('no call exits,can not forward');
|
|
ElMessage.warning('no call exits');
|
|
return undefined;
|
|
}
|
|
return window.lemon.call
|
|
.forwardVideoCall({
|
|
basedata_id: record?.basedata_id,
|
|
call_id,
|
|
action: stop ? 1 : 0,
|
|
})
|
|
?.then((resp) => {
|
|
if (resp.result === 0) {
|
|
console.log('forwardVideoCall request sucess');
|
|
} else {
|
|
ElMessage.error("视频转发失败");
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error('forwardVideoCall error,', err);
|
|
});
|
|
};
|
|
|
|
const getEmitter = () => {
|
|
return emitter;
|
|
};
|
|
|
|
// call sdk unInit
|
|
const unInit = () => {
|
|
call_id = undefined;
|
|
|
|
if (hangup_event_cb_id) {
|
|
window.lemon.call.removeHangupEvt(hangup_event_cb_id);
|
|
hangup_event_cb_id = undefined;
|
|
}
|
|
if (force_hangup_event_cb_id) {
|
|
window.lemon.call.removeForceHangupEvt(force_hangup_event_cb_id);
|
|
force_hangup_event_cb_id = undefined;
|
|
}
|
|
if (answer_ack_cb_id) {
|
|
window.lemon.call.removeAnswerAckEvt(answer_ack_cb_id);
|
|
answer_ack_cb_id = undefined;
|
|
}
|
|
if (incoming_cb_id) {
|
|
window.lemon.call.removeIncomingEvt(incoming_cb_id);
|
|
incoming_cb_id = undefined;
|
|
}
|
|
if (floor_grant_cb_id) {
|
|
window.lemon.floor.removeGrantEvt(floor_grant_cb_id);
|
|
floor_grant_cb_id = undefined;
|
|
}
|
|
monitor_call_list.length = 0;
|
|
};
|
|
|
|
return {
|
|
makeVoiceCall,
|
|
makeVideoCall,
|
|
pureVideoCall,
|
|
registerhangupEvent,
|
|
registerReceiveCallEvent,
|
|
answerCall,
|
|
makeGroupVoiceCall,
|
|
makeGroupVideoCall,
|
|
makeBroadcastCall,
|
|
hangup,
|
|
voiceDetect,
|
|
videoDetect,
|
|
applyFloor,
|
|
releaseFloor,
|
|
setMuteCamera,
|
|
setMuteMic,
|
|
setMuteCall,
|
|
muteMemberInConference,
|
|
makeConferenceVoiceCall,
|
|
makeConferenceVideoCall,
|
|
makeCrosspatchVoiceCall,
|
|
registerCallEstablishEvent,
|
|
pushVideoFile,
|
|
forwardVideoCall,
|
|
forceHangupCall,
|
|
getMonitorCallList,
|
|
getEmitter,
|
|
forceApplySpeak,
|
|
registerFloorGrantEvent,
|
|
registerForceHangupEvent,
|
|
unInit,
|
|
};
|
|
}
|