import { Message } from 'element-ui'; import store from '@/store'; import { GetLiveRoomInfo } from '@/api/live'; /** * @description WebSDK 实例化对象 */ let rtc; /** * @method initSDK * @description 初始化SDK方法 * @param { object } data 初始化SDK所需参数 * @returns { object } */ export function initSDK(data) { rtc = new Rtc(data); return rtc; } /** * 推送本地流 * @method publishStream */ export function publishStream(streamName) { rtc.publish({ streamName, // 推流成功,更新上麦结果 success: function (stream) { console.log('推流成功', stream); rtc.updateMcResult({ pid: 1, stid: stream.id(), success: function (data) { console.log('更新上麦结果请求成功,此处可处理应用层逻辑', data); }, fail: function (data) { console.log('更新上麦结果请求失败:' + JSON.stringify(data)); } }); }, fail: function (str) { // 推流失败,更新上麦结果 console.log('推流失败,更新上麦结果', str); } }); } /** * @description 查询直播是否开启 */ export function getLiveStat(obj) { rtc.getLiveStat(obj); } /** * @method startLive * @description 开启直播 */ export function startLive() { rtc.startLive({ success(data) { console.log(data); publishStream('main'); // 如果需要立即推流,执行 publish 方法 Message({ message: '开启直播成功', type: 'success' }); }, fail(data) { Message({ message: `开启直播失败:${data}`, type: 'warning' }); } }); } /** * 创建本地流 * @method createLocalStram */ export function createLocalStream() { const createData = { video: true, audio: true }; rtc.createLocalStream({ streamName: 'main', createData, success: function (stream) { console.log('创建本地流成功', stream); // 创建本地流成功,将流展示到id为 live 的dom元素盒子中 stream.show('live'); publishStream('main'); // 如果需要立即推流,执行 publish 方法 // getLiveStat({ // success: function (data) { // console.log(data.started); // }, // fail: function (str) { // // startLive(); // } // }); }, fail: function (data) { // 创建本地流失败,应用层处理 Message({ type: 'error', message: '创建本地流失败:' + data }); } }); } /** * @method closeVideo * @description 结束本地流 */ export function closeVideo(streamName) { rtc.closeVideo({ streamName, success: function () { console.log('结束本地流成功'); }, fail: function (str) { console.log(str); } }); } /** * 初始化监听事件 * @method initListener */ export function initListener(vue) { rtc.on('login_success', data => { console.log('登录成功', data); Message({ message: '登录成功', type: 'success' }); vue.roomData = data; // 初始化画板需要的数据 let canvasInitData = { allowDraw: data.user.role === 'presenter', // 是否具有书写画笔权限(讲师权限) 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: '登录失败:' + JSON.stringify(data), type: 'warning' }); }); // 必须在加入房间成功的“conference_join”事件回调里创建本地流 rtc.on('conference_join', () => { console.log('加入房间成功'); // 有监听就是加入房间成功 if (store.state.user.user_type === 'TEACHER') { createLocalStream(); } }); rtc.on('conference_join_failed', err => { // 加入房间失败 err为错误原因 console.log('加入房间失败', err); }); // 新增订阅流事件 rtc.on('allow_sub', function (stream) { if (stream.isMixed()) { console.log('是混合流,不订阅'); } else { // 订阅远程流 rtc.trySubscribeStream({ tryStream: stream, success: function (stream) { // 订阅流成功 let streamType = stream.streamType(); console.log('订阅流成功', streamType); stream.show(store.state.user.user_type === 'STUDENT' ? 'live' : 'student', 'contain'); // 将流显示到id为 live 的盒子中 if (streamType === 10 || streamType === 1) { vue.connection = true; } }, fail: function (err) { console.log('订阅流失败', err); } }); } }); // 直播未开始,不能推流 rtc.on('not_live', function () { console.log('直播未开始,不能推流'); Message({ message: '直播未开始,不能推流', type: 'warning' }); }); // 推流前查询直播状态失败,导致没有推流 rtc.on('local_stream_publish_failed', function () { console.log('推流前查询直播状态失败,导致没有推流'); Message({ message: '推流前查询直播状态失败,导致没有推流', type: 'warning' }); }); // 房间全量信息事件(人员进出时广播) rtc.on('room_context', roomData => { vue.roomContext = JSON.parse(roomData); vue.getLiveRoomStudentList(); 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('publishStreamErr', data => { console.log('推流意外终止:' + data.streamName); // 直播开启状态下,尝试重推这条流 }); // 视频无法自动播放 rtc.on('playError', data => { console.log('视频无法自动播放', data); }); // 用户退出房间通知其他人员事件 rtc.on('exit_room_user', function (data) { console.log('用户退出房间通知其他人员事件', data); vue.studentExitLiveRoom(data.id); }); // 监听通知移除流事件 rtc.on('stream_removed', function (stream) { console.log('监听通知移除流事件'); if (stream.streamType() === 10 || stream.streamType() === 1) { vue.connection = false; } }); // 停止订阅流 rtc.on('unSub', function (stream) { console.log('停止订阅流'); rtc.unSubscribeStream({ unSubStream: stream, success: function (stream) { console.log('取消订阅流成功', stream.id()); }, fail: function (str) { console.log(str); } }); }); /** * 排麦监听事件 */ // 监听自己被邀请事件 rtc.on('inviteUp', uid => { console.log('监听自己被邀请事件', uid); rtc.inviteAccept({ success: function (str) { console.log('接受邀请成功', str); }, fail: function (data) { console.log('接受邀请失败', data); } }); }); rtc.on('mcDown', () => { closeVideo('main'); vue.connection = false; }); rtc.on('createLocalStream', () => { // 创建本地流推流 GetLiveRoomInfo({ task_id: vue.task_id }).then(({ video_mode }) => { console.log('创建本地流推流'); const createData = { video: video_mode === 1, audio: true }; rtc.createLocalStream({ streamName: 'main', createData, success: function (stream) { vue.connection = true; console.log('创建本地流成功', stream); // 创建本地流成功,将流展示到id为 student 的dom元素盒子中 stream.show('student'); publishStream('main'); // 如果需要立即推流,执行 publish 方法 }, fail: function (data) { console.log('创建本地流失败,应用层处理', data); // 创建本地流失败,应用层处理 Message({ type: 'error', message: '创建本地流失败:' + data }); } }); }); }); /** * 监听聊天事件 */ rtc.on('chat_message', data => { let 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', function (data) { let msg = data.settings.allow_chat ? '开言' : '禁言'; Message({ type: 'success', message: `全体${msg}成功` }); }); } /** * @method stopLive * @description 结束直播 */ export function stopLive() { rtc.stopLive({ success() { Message({ type: 'success', message: '直播已结束' }); }, fail(data) { Message({ type: 'error', message: '结束直播失败:' + JSON.stringify(data) }); } }); } /** * @method pauseAudio * @description 关闭本地流声音 */ export function pauseAudio() { rtc.pauseAudio({ streamName: 'main', success: function () { console.log('关闭本地流声音成功'); }, fail: function (str) { console.log(str); } }); } /** * @method playAudio * @description 开启本地流声音 */ export function playAudio() { rtc.playAudio({ streamName: 'main', success: function () { console.log('开启本地流声音成功'); }, fail: function (str) { console.log(str); } }); } /** * @method pauseVideo * @description 关闭本地流视频画面 */ export function pauseVideo() { rtc.pauseVideo({ streamName: 'main', success: function () { console.log('关闭本地流视频画面成功'); }, fail: function (str) { console.log(str); } }); } /** * @method playVideo * @description 开启本地流视频画面 */ export function playVideo() { rtc.playVideo({ streamName: 'main', success: function () { console.log('开启本地流视频画面成功'); }, fail: function (str) { console.log(str); } }); } /** * @description 推送桌面共享 */ export function publishShareStream() { rtc.publishShareStream({ success: function (stream) { console.log('推送桌面共享成功', stream); }, fail: function (str) { console.log(str); } }); } /** * 关闭桌面共享 */ export function unPubShareStream() { rtc.unPubShareStream(); } /** * @description 开启、结束、暂停、恢复录制 * @param { String } status: 'start' 开启, 'end' 结束, 'pause' 暂停, 'resume' 恢复 */ export function liveRecord(status) { rtc.liveRecord({ status: status, success: function (data) { console.log('成功', data); }, fail: function (str) { console.log(str); } }); } // 排麦 /** * @description 老师端发起邀请,邀请学生上麦。(举手模式) * @param {String} uid 被邀请用户id */ export function invite(uid) { rtc.invite({ uid: uid, success: function (str) { console.log('邀请上麦成功', str); }, fail: function (data) { console.log(data); Message({ type: 'error', message: `邀请上麦失败:${data.errorMsg}` }); } }); } /** * @method handsUp * @description 申请连麦 */ export function handsUp(data) { rtc.handsUp(data); } /** * 下麦操作 * @param { String } uid */ export function handsDown(uid) { rtc.handsDown({ uid, success: function (str) { console.log('下麦成功', str); }, fail: function (data) { console.log('下麦失败', data); } }); } /** * @description 学生端接受老师的上麦邀请,同意上麦 */ export function inviteAccept() { rtc.inviteAccept({ success: function (str) { console.log('接受邀请成功', str); }, fail: function (data) { console.log('接受邀请失败', data); } }); } // 聊天组件 /** * @descrption 发送聊天 * @param {String} msg length不能超过400 */ export function sendMsg(msg) { rtc.sendMsg(msg); } /** * @description 房间配置项更新 * @param {Object} option 房间配置项 (具体看2.0 https://doc.bokecc.com/class/developer/web/chat.html),以键值对的形式传 */ export function roomUpdate(option) { rtc.roomUpdate(option); } // 文档 export function drawChange(action, value) { rtc.drawChange({ action, value }); }