import { Message } from 'element-ui'; import store from '@/store'; import { rtc, updateMcResult, getDevice, createData, getHistory } from '@/views/live/common'; export { initSDK, downloadWebSDK, createScript, getLiveStat, roomUpdate, sendMsg, drawChange, publishStream, handsDown, sendPublishMessage, closeVideo, chatRoll, updateMcResult, reconnection, getNetPoint, pauseAudio, playAudio, pauseVideo, playVideo } from '@/views/live/common'; import i18n from '@/locales/i18n'; /** * 推送本地流 */ function publishStream(streamName) { rtc.publish({ streamName, // 推流成功,更新上麦结果 success: stream => { console.log('推流成功', stream); updateMcResult(stream.id(), 1); }, fail: str => { // 推流失败,更新上麦结果 console.log('推流失败,更新上麦结果', str); updateMcResult('', 0); } }); } /** * 创建本地流 */ export function createLocalStream(vue) { rtc.createLocalStream({ streamName: 'main', createData: createData(), success(stream) { console.log('创建本地流成功', stream); vue.hasAudio = stream.hasAudio(); vue.hasVideo = stream.hasVideo(); // 创建本地流成功,将流展示到id为 live 的 dom 元素盒子中 stream.show('live'); publishStream('main'); // 如果需要立即推流,执行 publish 方法 }, fail(data) { console.log('创建本地流失败:', data); // 创建本地流失败,应用层处理 Message({ type: 'error', message: `${i18n.t('Key441')}:${data.err}` }); } }); } /** * 结束本地流 */ export function closeVideoTeacher(options) { rtc.closeVideo(options); } /** * 初始化监听事件 */ export function initListener(vue) { rtc.on('login_success', data => { console.log('登录成功', data); vue.roomData = data; // 初始化画板需要的数据 const canvasInitData = { allowDraw: true, // 是否具有书写画笔权限(讲师权限) true / false id: 'draw-parent', pptDisplay: 1, // 文档展示方式。默认0,按窗口 1,按宽度 liveId: data.live.status === 1 ? data.live.id : '' // 如果直播已经开始,需将直播 id 传入 sdk 中 }; // 初始化画板 rtc.canvasInit(canvasInitData); }); rtc.on('login_failed', data => { console.log('登录失败', data); Message({ message: `${i18n.t('Key443')}:${JSON.stringify(data)}`, type: 'warning' }); }); // 教师 必须在加入房间成功的事件回调里创建本地流 rtc.on('conference_join', () => { console.log('加入房间成功'); getHistory({ success(data) { const chatLog = data.datas.meta.chatLog.map(({ content, userName }) => { return { msg: content, username: userName }; }); vue.chatList = chatLog; }, fail(str) { console.log(str); } }); getDevice({ success(data) { console.log('获取音视频设备成功', data); const device = store.state.app.liveDevice; vue.device = data; if (data.video.length === 0 && data.audio.length === 0) { Message({ type: 'warning', message: i18n.t('Key444') }); } const isVideo = device.video.length > 0 && data.video.some(item => item.deviceId === device.video); const isAudio = device.audio.length > 0 && data.audio.some(item => item.deviceId === device.audio); if (!isVideo && !isAudio) { vue.setDevice(false); } else { createLocalStream(vue); } }, fail(str) { console.log('直播关闭状态或查询直播失败: ', str); Message({ type: 'error', message: `${i18n.t('Key445')}: ${str}` }); } }); }); rtc.on('conference_join_failed', err => { // 加入房间失败 err为错误原因 console.log('加入房间失败', err); Message({ message: `${i18n.t('Key446')}:${err}`, type: 'warning' }); }); // 新增订阅流事件 rtc.on('allow_sub', tryStream => { if (tryStream.isMixed()) { console.log('是混合流,不订阅'); } else { // 订阅远程流 rtc.trySubscribeStream({ tryStream, success(stream) { // 订阅流成功 const streamType = stream.streamType(); vue.remoteStreamType = streamType; console.log('订阅流成功', streamType); stream.show('student', 'contain'); // 将流显示到指定 id 的盒子中 if (streamType === 1 || streamType === 10) { vue.connect = true; vue.callLoading = false; } if (streamType === 10) { vue.dealStudentConnection(vue.connectUid, 2, vue.roomInfo.video_mode); } }, fail(err) { console.log('订阅流失败', err); } }); } }); // 直播未开始,不能推流 rtc.on('not_live', () => { console.log('直播未开始,不能推流'); Message({ message: i18n.t('Key402'), type: 'warning' }); }); // 推流前查询直播状态失败,导致没有推流 rtc.on('local_stream_publish_failed', () => { console.log('推流前查询直播状态失败,导致没有推流'); Message({ message: i18n.t('Key403'), type: 'warning' }); }); // 房间全量信息事件(人员进出时广播) rtc.on('room_context', roomData => { vue.roomContext = JSON.parse(roomData); vue.getLiveRoomData_DRTD(); console.log('房间全量信息事件(人员进出时广播)', JSON.parse(roomData)); }); rtc.on('publish_stream', str => { console.log('直播已开启', str); vue.liveStat = true; }); rtc.on('end_stream', str => { console.log('直播已关闭', str); vue.liveStat = false; }); rtc.on('switch_user_settings', settingData => { // 单个用户配置监听 console.log(settingData); }); // 人员列表事件(人员麦序变化时广播) rtc.on('speak_context', speakData => { vue.speakData = JSON.parse(speakData); console.log('人员列表事件(人员麦序变化时广播)', JSON.parse(speakData)); }); rtc.on('switch_settings', data => { console.log('房间设置事件', data); // 房间设置事件 }); // 网络整体状态事件 rtc.on('netStatus', data => { vue.netStatus = data.netStatus; }); // 单条流状态通知事件 rtc.on('streamStatus', data => { console.log(data); }); // 推流异常断开事件 rtc.on('publishStreamErr', data => { // 直播开启状态下,尝试重推这条流 console.log(`推流意外终止:${data.streamName}`); publishStream('main'); }); // 视频无法自动播放 rtc.on('playError', data => { console.log('视频无法自动播放', data); }); // 监听通知移除流事件 rtc.on('stream_removed', stream => { console.log('监听通知移除流事件', stream); if ('room_user_id' in vue.connectStudent && stream.streamType() === 10 && vue.connect) { vue.handsDown(); } vue.connect = false; vue.remoteStreamType = -1; }); // 停止订阅流 rtc.on('unSub', unSubStream => { console.log('停止订阅流', unSubStream); rtc.unSubscribeStream({ unSubStream, success(stream) { console.log('取消订阅流成功', stream.id()); }, fail(str) { console.log(str); } }); }); // 用户退出房间通知其他人员事件 rtc.on('exit_room_user', data => { console.log('用户退出房间通知其他人员事件', data); vue.studentExitLiveRoom(data.id, false); }); /** * 排麦监听事件 */ // 监听自己被邀请事件 rtc.on('inviteUp', uid => { console.log('监听自己被邀请事件', uid); rtc.inviteAccept({ success(str) { console.log('接受邀请成功', str); }, fail(data) { console.log('接受邀请失败', data); } }); }); /** * 监听聊天事件 */ rtc.on('chat_message', data => { const dat = JSON.parse(data); console.log(dat); // 敏感词过滤:如果发送的聊天消息被系统判定包含敏感词,则只有发送者能收到本条消息,房间内其他人都不会收到这条聊天消息。 // 如果返回消息中有 isFilterChat 字段(消息不包含敏感词返回数据中无isFilterChat字段),且isFilterChat的值为1,则说明该消息包含敏感字,除发送者外其他人不会收到这条消息。 if (dat.isFilterChat && dat.isFilterChat === 1) { return; } vue.chatList.push(dat); }); rtc.on('allowChatChange', ({ settings }) => { Message({ type: 'success', message: settings.allow_chat ? i18n.t('Key633') : i18n.t('Key632') }); }); // 接收自定义消息 rtc.on('publish_message', data => { // 连接中途下麦 if (data.type === 'handsDown-load-student' && data.uid === vue.connectUid) { vue.callLoading = false; Message({ type: 'warning', message: i18n.t('Key449') }); } // 无对应设备 if (data.type === 'no-device') { vue.callLoading = false; Message({ type: 'warning', message: data.video_mode === 1 ? i18n.t('Key451') : i18n.t('Key450') }); } }); } /** * 开启直播 */ export function startLive() { rtc.startLive({ success(data) { console.log(data); publishStream('main'); // 如果需要立即推流,执行 publish 方法 Message({ message: i18n.t('Key452'), type: 'success' }); }, fail(data) { Message({ message: `${i18n.t('Key453')}:${data}`, type: 'warning' }); } }); } /** * 结束直播 */ export function stopLive() { rtc.stopLive({ success() { Message({ type: 'success', message: i18n.t('Key454') }); }, fail(data) { Message({ type: 'error', message: `${i18n.t('Key455')}:${JSON.stringify(data)}` }); } }); } /** * 推送桌面共享 */ export function publishShareStream() { rtc.publishShareStream({ success: stream => { console.log('推送桌面共享成功', stream); }, fail: str => { console.log(str); } }); } /** * 关闭桌面共享 */ export function unPubShareStream() { rtc.unPubShareStream(); } /** * 开启、结束、暂停、恢复录制 * @param { String } status: 'start' 开启, 'end' 结束, 'pause' 暂停, 'resume' 恢复 */ export function liveRecord(status) { rtc.liveRecord({ status, success(data) { console.log('成功', data); }, fail(str) { console.log(str); } }); } // 连麦 /** * 老师端发起邀请,邀请学生上麦。(举手模式) * @param {Object} object */ export function invite(object) { rtc.invite(object); }