本文介绍了使用标准集成(无UI)方式接入Web端的方法。适用于互动直播、互动课堂等场景产品。
引入SDK
SDK分两个版本,互动直播版本不支持RTC、白板、文档(gziped size 26kb),完全版全部支持(gziped size 300kb),注意引入合适的版本。
在script标签中引入SDK,并在URL中指定版本号,之后在JS中引入。
<!-- 完全版 --> <script src='https://g.alicdn.com/code/npm/@ali/room-paas-web-engine/1.8.1/RoomPaasSdk.web.min.js'></script> <!-- 互动直播版 --> <script src='https://g.alicdn.com/code/npm/@ali/room-paas-web-engine/1.8.1/RoomPaasInteractionSdk.web.min.js'></script>
// 按需解构赋值 const { RoomEngine, EventNameEnum } = window.RoomPaasSdk;
如需使用白板功能,请参照互动白板Web端集成与使用文档完成白板SDK接入(互动课堂场景建议接入)。白板的方法直接使用白板SDK的实例进行调用。白板的docKey通过roomChannel上的白板插件实例
wbService.getWhiteboardId().then(docKey => {})
获取,跟业务逻辑相关的白板录制功能也在白板插件实例上调用。
工程接入
RoomEngine鉴权
获取RoomEngine实例。
// 获取RoomEngine实例 const roomEngine = RoomEngine.getInstance();
为RoomEngine配置参数。
// 获取设备号deviceId,唯一标识当前设备 // 在web端,不同的tab页代表不同设备 const deviceId = roomEngine.getDeviceId(); // 如果场景确保一个设备只有一个页面,需要使用getSingleDeviceId const deviceId = roomEngine.getSingleDeviceId(); // 配置参数 const config = { appKey, // 创建应用时分配的appKey appId, // 创建应用时分配的appId deviceId, // 设备号 authTokenCallback, // 获取登录token的回调函数,需要返回Promise } // 传入配置 roomEngine.init(config);
重要获取deviceId时,如果是移动端设备这类,一个设备同一时间只会有一个页面的场景,请使用getSingleDeviceId,否则可能会出现数据不准确的情况。
其中
authTokenCallback
是一个返回Promise的函数,可以用以下的方式编写:可以使用任何能返回Promise的请求库或API(如axios或fetch等)。
可以自己构造Promise,在resolve里返回结果。
可以使用async函数,直接return结果。
下面使用fetch API举例:
const authTokenCallback = () => { const origin = 'xxx.xxx.com'; // 客户的域名 const path = 'api/getToken'; // 客户服务端接口 // fetch API返回一个Promise return fetch(`${origin}/${path}?userId=123&foo=bar`) // 您可以自己定义接口需要的数据 .then((res) => res.json()) .then((res) => { if (res) { // 需要保证数据结构符合AuthToken,其定义在下面 const authToken = res.result; // 这里需要根据您服务端返回的数据结构来决定返回什么属性 return authToken; } throw new Error('没有获取到Token'); }) .catch((err) => { console.error(err); }); }
resolve的值来源于客户服务端SDK的接入回调,数据结构为:
interface AuthToken { accessToken: string; refreshToken: string; accessTokenExpiredTime: number; }
RoomEngine鉴权,建立WebSocket长连接。
// uid即用户ID,标识用户身份,返回promise代表auth结果 // 需要在.then里进行或者使用await后进行房间操作,如进入房间等 roomEngine.auth(uid).then(() => { // 在这里获取RoomChannel实例进行房间操作 }); // 或者使用await await roomEngine.auth(uid); // 在这里获取RoomChannel实例进行房间操作
在退出登录时需要调用logout,确保一个auth对应一个logout。
await roomEngine.logout(); // 返回promise
服务部分
通过roomId获取或创建对应的roomChannel实例。
// roomId标识房间号,方法调用结果获取当前房间roomChannel实例 const roomChannel = roomEngine.getRoomChannel(roomId);
调用enterRoom进入房间。必须先进入房间才能进行后续操作。
// 必须保证enterRoom完成后才能进行后续操作,nick为用户名,例如示例为"jack" const nick = 'jack'; await roomChannel.enterRoom(nick); // enterRoom返回Promise
使用
getPluginService(PluginId)
来获取原子能力插件实例。// 获取Chat插件实例 const chatService = roomChannel.getPluginService('chat'); // 获取Live插件实例 const liveService = roomChannel.getPluginService('live'); // 获取Rtc插件实例 const rtcService = roomChannel.getPluginService('rtc'); // 获取Wb插件实例(白板) const wbService = roomChannel.getPluginService('wb'); // 获取Doc插件实例 const docService = roomChannel.getPluginService('doc');
事件绑定。
重要每个原子能力(包括roomChannel)都是通过插件实例来监听自身事件的,具体的事件列表可以查阅Web接口列表。
// 事件定义 const enterRoomEventHandler = (data) => { console.log(data); } // 绑定Room事件 roomChannel.on(EventNameEnum.PaaSRoomEnter, enterRoomEventHandler); // 解绑事件 // SDK的事件系统允许绑定多个回调函数,如果需要解绑,请传入之前绑定时定义的函数 roomChannel.remove(EventNameEnum.PaaSRoomEnter, enterRoomEventHandler); // 其他实例绑定方法是一样的 // 绑定Chat事件,匿名函数 chatService.on(EventNameEnum.PaaSChatReceiveComment, (data) => { console.log(data); }); // 解绑事件 // 如果在绑定时使用匿名函数,或者需要清空所有的绑定,可以不用传第二个参数 chatService.remove(EventNameEnum.PaaSChatReceiveComment);
退出房间。
// 退出房间时必须调leaveRoom,不然可能会导致状态不正常 roomChannel.leaveRoom();
API的使用
在这里仅列出部分API的使用方法,完整API列表请参见Web接口列表。
房间实例RoomChannel
在RoomChannel上可以调用房间的相关操作,比如进出房间、设置公告、查看房间内观众列表等。
// 进入房间
await roomChannel.enterRoom(nick);
// 异步获取房间信息
await roomChannel.getRoomDetailAsync();
// 分页获取房间用户在线列表
// pageIndex从1开始
await roomChannel.listUser(pageIndex, pageSize);
// 下面的方法需要房间所有者才可以调用
// 更新房间公告
await roomChannel.updateNotice(notice);
// 更新房间标题
await roomChannel.updateTitle(notice);
原子能力插件实例
在SDK中,各个原子能力是以插件(Plugin)的形式提供的服务(Service)。所以,需要使用getPluginService(PluginId)
获取到各个原子能力插件的实例,之后就可以使用实例上的方法了。根据原子能力的组合可以实现不同的业务场景。
互动Chat:
负责直播时的弹幕、点赞、自定义消息、禁言相关功能。
// 发送弹幕 // 第二个参数是extension字段,内容会透传给事件和弹幕列表 await chatService.sendComment(content, { avatar: 'xxx.xxx.png' }); // 异步获取房间信息 // sortType 排序方式,0-时间递增顺序,1-时间递减顺序 await chatService.listComment(sortType, pageIndex, pageSize); // 点赞,连续调用(用户连续点击)时在SDK内部合并请求 // 连续点赞场景一般实现:每次用户点击前端+1点赞数并调用sendLike // 收到点赞事件后用事件里的点赞数覆盖前端点赞数 chatService.sendLike(); // 下面的方法需要房间所有者才可以调用 // 禁言全体 await chatService.banAllComment(); // 禁言某个用户 muteSeconds 禁言时长(s) await chatService.banComment(userId, muteSeconds); // 取消禁言全体 await chatService.cancelBanAllComment();
直播Live:
负责直播拉流相关功能,并在Web端封装了AliPlayer播放器。
重要在liveService中,AliPlayer实例是单例的。
// 播放器配置,在创建播放器之前必须调用,否则会报错 liveService.setPlayerConfig({ container:'#player', // DOM容器id }); // 尝试播放直播流,会根据直播状态自动决定是否创建播放器 liveService.tryPlayLive(); // 切换播放源 liveService.switchPlaySource(url); // 结束播放(会同时销毁播放器) liveService.stopPlay(); // 销毁播放器 liveService.destroy(); // 获取m3u8里的录制时间戳 liveService.getCurrentPDT();
播放器的使用:
setPlayerConfig
中传入的参数列表是AliPlayer的参数和本SDK所需参数的并集,SDK所需参数如下:interface PlayerParams { protocal?: 'http' | 'https'; // 强制使用http或https协议的播放地址 useArtc?: boolean; // 是否使用连麦 // AliPlayer的参数可以任意添加到这里 }
重要如果需要开启连麦,应在控制台中为您的播流域名配置好HTTPS证书,之后在
setPlayerConfig
中增加useArtc: true即可。如果连麦出现播放失败,会自动降级到普通直播。
如果封装的播放器功能不足以支撑业务逻辑,可以直接获取到AliPlayer的实例:
// 在开始播放之后(创建播放器后)才能获取到 const playerInstance = liveService.playerInstance; // 直接调用AliPlayer的方法 playerInstance.play();
AliPlayer的属性和接口说明参阅属性和接口说明。
播放器事件:
播放器自身也会透出事件,这些事件被直播实例所捕获,可以按照下面的方法监听:
// 绑定播放器事件 liveService.on(EventNameEnum.PaaSPlayerEvent, (data) => { console.log(data.eventName); // 播放器事件名称 console.log(data.eventData); // 播放器事件返回数据 });
有关播放器事件列表,请参阅播放器事件。
音视频通信Rtc:
负责Rtc通信的入会、订阅、媒体操作(静音、屏幕分享等)、旁路推直播流等功能,封装了AliRtc。
// 获取设备信息 rtcService.getDeviceInfo(); // 开始摄像头预览 rtcService.startRtcPreview(videoDom); // 进入频道 await rtcService.joinChannel(); // 开始推流 await rtcService.startPublish(); // 开始旁路推流(开始直播) await rtcService.startRoadPublish(); // 发布屏幕流(必须在推流状态下设置) await rtcService.startPublishScreen(); // 获取会议成员列表 await rtcService.listConfUser(pageIndex, pageSize);
AliRtc实例:
如果封装的Rtc能力不足以支撑业务,可以通过以下方法获取AliRtc实例:
// 获取AliRtc的实例 const aliRtcInstance = rtcService.aliRtcInstance;
有关AliRtc的接口参阅AliRtcEngine接口。
AliRtc事件:
除了SDK事件以外,
rtcService
也透出了AliRtc自身的事件,事件名也直接并集成EventNameEnum
,可以直接在实例上监听:// 绑定onMedia事件 rtcService.on(EventNameEnum.onMedia, (data) => { console.log(data); });
AliRtc事件列表如下:
enum AliRTCSdkEventNames { onPublisher = 'onPublisher', onUnPublisher = 'onUnPublisher', onMediaStream = 'onMediaStream', onJoin = 'onJoin', onLeave = 'onLeave', onError = 'onError', onBye = 'onBye', onUpdateRole = 'onUpdateRole', onNotify = 'onNotify', onAudioLevel = 'onAudioLevel', onMedia = 'onMedia', onSubscribeResult = 'onSubscribeResult' }
说明可以发现
RtcService
和AliRtc的关系类似LiveService
和AliPlayer的关系,但绑定事件方式不同,是因为SDK内部对AliRtc的事件需要做特殊处理和封装,之后可能会根据需要作出改动。文档Doc
负责ppt/pdf/jpg/png等文档的操作,包括上传、下载、转码、查看等操作。
// 上传文档,返回值为文档Id const docId = await docService.upload(file); // 下载文档,返回值为文档下载地址,有效期30分钟 docService.download(docId); // 文档转码,targetType支持'jpg' await docService.convert(sourceDocId, targetType, targetName); // 获取文档链接 const data = await docService.getUrlList(docId);
白板Wb
负责白板服务与RoomChannel的关联,包括获取白板的dockey、白板的录制相关接口。
说明由于白板是一个较为完备的SDK,接入方式也有多种,所以本SDK只封装了白板与房间交互的部分,即获取白板的dockey、白板的录制,没有封装白板本身提供的方法。
// 获取白板id,如果存在则返回,不存在则创建一个 // 返回一个Promise,需要用await获取值或者在then里取值 const dockey = await wbService.getWhiteboardId(); // 开始白板录制,返回录制的recordId等信息 await wbService.startWhiteboardRecording(); // 根据recordId结束白板录制 await wbService.stopWhiteboardRecording(recordId); // 暂停白板录制 await wbService.pauseWhiteboardRecording(recordId); // 继续白板录制 await wbService.resumeWhiteboardRecording(recordId);