# rtcms-js-sdk-demo **Repository Path**: yabooo/rtcms-js-sdk-demo ## Basic Information - **Project Name**: rtcms-js-sdk-demo - **Description**: rtcms js demo 其中src为vue代码目录 public目录为sdk目录 - **Primary Language**: Java - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2021-01-27 - **Last Updated**: 2022-01-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # RTCMS JS SDK 说明文档 ## demo项目介绍 ``` demo项目基于VUE开发,clone到本地后,运行下面命令初始化开发环境 npm install ``` ### 配置rtcms服务端地址并运行 ``` 修改vue.config.js中的devServer代理traget,使其指向rtcms服务器提供的oam地址 修改main.js的BashUrl,使其指向rtcms服务器提供的ws地址 修改tvrtc.es.js中的iceServers配置,使其指向rtcms服务器提供的stun地址 运行npm run serve 注意:本机调试时,需要使用localhost地址,而不能使用IP地址,因为chrome等浏览器的webrtc功能只能在https或者http://localhost时生效。 ``` ### 编译并部署 ``` 修改上述地址为生产环境并 运行npm run build 拷贝生成的dist目录到生成环境 ``` ## sdk介绍 ### 简介 ``` rtcms是基于webrtc的多模式媒体服务器,其客户端可以是任何使用webrtc的软硬件终端, 为了简化客户端开发难度,提供js sdk供用户前台js调用。 sdk由一组js文件构成,在demo工程的public\js\sdk目录下。 ``` ### 使用方式 ``` 以VUE项目为例,为了使用sdk,请先在main.js中引入全局sdk实例,调用方式如下 ![Image text]https://gitee.com/yabooo/rtcms-js-sdk-demo/blob/master/flow.png ``` ```JS //引入RTCMS SDK import tvvssdk from "../public/js/sdk/tvvssdk.js"; Vue.prototype.$tvvssdk = tvvssdk; ``` ``` 此后,在其它VUE组件中就可以通过tvvssdk = this.$tvvssdk来获取tvvssdk对象, 对sdk的使用就是调用tvvssdk对象提供的各种方法。 ``` ### sdk提供方法列表 ``` 在tvvssdk.js中,找到module.exports,即可以看到sdk提供给用户js的方法。 方法描述如下: ``` #### init ``` 初始化,包括检查本地是否具备webrtc环境,设置服务器地址信息等操作: ``` ```JS let options = { websocketurl: "wss://meeting.zwan.com.cn:2337/websocket", //websocket信令服务URL oamurl: "https://meeting.zwan.com.cn:2337", //管理服务URL stunurl: "stun:stun.zwan.com.cn:2331", //stun服务器地址 }; tvvssdk.init(options, function (res) { if (res.success) { console.log(res.msg); } else { alert(res.msg); } }); ``` #### getAllDevices ``` 获得本机音视频输入设备信息: ``` ```JS let _this = this; tvvssdk.getAllDevices(function (devices) { _this.microphoneList.length=0; //microphoneList: [], _this.cameraList.length=0; //cameraList: [], devices.forEach(function (device, index, arr) { if(device.kind === "audioinput"){ _this.microphoneList.push(device); }else if(device.kind === "videoinput"){ _this.cameraList.push(device); } }); }); ``` #### createConnection ``` 创建服务器链接 ``` ```JS let _this = this; tvvssdk.createConnection(function (res) { if (res.success) { //服务器连接成功,可以进行加入房间操作,应用层应该保存res.sessionid,后续操作都需要携带sessionid //sdk支持同时建立多个链接 _this.joinRoom(res.sessionid, _this.roomId, _this.name); }else if (res === 'screen stop') { // 用户取消屏幕共享操作 } else if (res === 'screen denied') { // 用户共享屏幕时取消窗口选择 } else if (res === 'screen start') { // 开始屏幕共享 } else if (res.disconnected) { // ICE连接失败:需要停止当前推流,再重新推流,即执行streamStop和streamStart } else { alert(res.msg); } }); ``` #### joinRoom ``` 加入房间 ``` ```JS let _this = this; let callbacks = { onjoined: function (name) { //加入房间成功回调 console.log(TAG, name + " 已经加入房间"); }, onleave: function (name) { //被从房间中提出回调 console.log(TAG, name + " 已经离开房间"); }, ondata: function (sender, platform, data) { //接收到房间消息回调,其中data即服务器下发消息 console.log(TAG, "接收到文本消息:" + data); } }; //sessionid: createConnection返回的会话ID,roomId:房间名称字符串; name:用户名称字符串 tvvssdk.joinRoom(sessionid, room_name, name, callbacks); ``` #### streamStart ``` 开始推拉流,可以传入如下所示参数 在会中如需要推流时(没有设置推流参数),需要先停止推拉流,再重新传入推拉流信息 ``` ```JS let options = { audio: {}, //音频参数 video: {}, //视频参数 conf: {} //会议参数 }; //设置音频参数 options.audio.sendaudio = true; //是否发送音频流到媒体服务器 options.audio.recvaudio = true; //是否从媒体服务器接收音频流 options.audio.publishaudio = options.audio.sendaudio; //是否将音频流发布给其他会议成员,设置为true的前提是sendaudio也为true options.audio.subscribeaudio = options.audio.recvaudio; //是否从其他会议成员中接收音频流,设置为true的前提是recvaudio也是true options.audio.audioindeviceid = this.deviceInfo.microphone; //使用getAllDevices获得的麦克风id //设置视频参数 options.video.sendvideo = true; //是否发送视频流到媒体服务器 options.video.recvvideo = true; //是否从媒体服务器接收视频流 options.video.publishvideo = options.video.sendvideo; //是否将视频流发布给其他会议成员,设置为true的前提是sendvideo也为true options.video.subscribevideo = options.video.recvvideo; //是否从其他会议成员中接收视频流,设置为true的前提是recvvideo也是true options.video.deviceid = this.deviceInfo.camera; //使用getAllDevices获得的摄像头id options.video.type = "screen"; //设置是采集摄像头还是采集屏幕,"screen":屏幕;"camera":摄像头 //设置会场参数,仅对MCU会议有效 options.conf.size = "hdres"; //本地视频输出分辨率,其值参考sdk中tvvsdk_constants.js文件中的resList数组 options.conf.fps = 15; //本地视频帧率,其值参考sdk中tvvsdk_constants.js文件中的fpsList数组 options.conf.confsize = "hdres"; //其值参考sdk中tvvsdk_constants.js文件中的resList数组 options.conf.confminbr = 500*1024; //最小码率,其值参考sdk中tvvsdk_constants.js文件中的brList数组 options.conf.confmaxbr = 2*1024*1024; //最大码率,其值参考sdk中tvvsdk_constants.js文件中的brList数组 options.conf.confinitbr = 2*1024*1024; //初始码率,其值参考sdk中tvvsdk_constants.js文件中的brList数组 options.conf.conffps = 15; //会场帧率,其值参考sdk中tvvsdk_constants.js文件中的fpsList数组 options.conf.mode = 2; //会议模式,其值参考sdk中tvvsdk_constants.js文件中的confModeList数组 options.conf.picmode = 0; //对于多分屏会议(MCU会议),画面布局模式: 0:一大多小, 1:等大 let _this = this; let callbacks = { onlocalstream: function (stream, extra) { //本地媒体流状态发生改变时的回调,可保存stream信息供后续H5操作,extra包含当前流是否有音频和视频 console.log(TAG, "onlocalstream"); let index = 1; let localVideo = document.getElementById(_this.videoList[index].video) _this.videoList[index].stream = stream; _this.videoList[index].index = index; _this.videoList[index].name = _this.name; _this.videoList[index].show = true; _this.videoList[index].extra = { audio: extra.audio, video: extra.video, }; }, onremotestream: function (stream, extra) { //接收到媒体服务器下发媒体流后或者媒体流发生改变时的回调,可保存stream信息供后续H5操作,extra包含当前流是否有音频和视频 let index = 0; _this.videoList[index].stream = stream; _this.videoList[index].index = index; _this.videoList[index].name = "会场"; _this.videoList[index].show = true; _this.videoList[index].extra = extra; }, }; tvvssdk.streamStart(sessionId, options, room_name, callbacks); //room_name:房间名称字符串 ``` #### streamStop ``` 停止推拉流,此时音视频媒体终端,但仍然可以接收会场消息 ``` ```JS tvvssdk.streamStop(sessionId); ``` #### leaveRoom ``` 退出房间,此后无法接收会场消息。 ``` ```JS tvvssdk.leaveRoom(sessionId); ``` #### attachMediaStream ``` 一个帮助函数,将webrtc的stream与H5元素重新进行绑定,一般用于H5元素尺寸发生改变时进行画面重绘 ``` ```JS tvvssdk.attachMediaStream( document.getElementById(this.videoList[index].video), //H5元素 this.videoList[index].stream //webrtc 媒体流,从streamStart的onremotestream或者onlocalstream回调中返回 ); ``` #### sendGroupData ``` 获得当前媒体的参数动态信息,用于评估网络及音视频质量,可以放在定时器中定时执行 ``` ```JS tvvssdk.sendGroupData(sessionid, sender_name, receiver_name, content, function (res) { if (res.success) { // _this.$message.success("发送文字消息成功"); } }); ``` #### getQos ``` 获得当前媒体的参数动态信息,用于评估网络及音视频质量,可以放在定时器中定时执行 ``` ```JS let _this = this; tvvssdk.getQos(function (result) { if (result.success) { _this.qosData = result.report; } }); ``` #### queryRoomList ``` 获得当前媒体服务器上的所有房间信息 ``` ```JS tvvssdk.queryRoomList(res=>{ if (res.success) { //查询成功 console.log(TAG, res.msg); }else{ //查询失败 } }); ``` #### queryRoom ``` 获得房间内用户状态,包括用户id,用户的显示顺序,用户音视频收发属性等 显示顺序position属性说明:MCU会议,为1~9的是子画面编号,SFU会议,显示为1的是当前方,显示为0的未出现在画面中的推流方 ``` ```JS tvvssdk.queryRoom(sessionid, room_name, { success: function(result) { console.log(TAG, "queryRoom succ:"+result); }, error: function(msg) { console.log(TAG, "queryRoom error:"+msg); } }); ``` #### compositeRoom ``` 设置房间显示顺序,对于MCU会议,可控制每个用户的子画面显示位置,对于SFU会议,可控制画面显示哪一方用户 用户名和id可来自于queryRoom命令查询返回 ``` ```JS let user = {"userName": "用户1", "position": 1, "id": "11111111"}; let user = {"userName": "用户2", "position": 2, "id": "22222222"}; userList.push(user); tvvssdk.compositeRoom(userList); ``` ### electron用户使用方法 ``` 使用electron时需要在vue.config.js中pluginOptions添加配置: electronBuilder: { nodeIntegration: true } 在tvrtc.es.js中,desktopCapturer的创建方法改为: var { desktopCapturer } = require('electron'); 窗口共享时如何选择窗口: 创建服务器连接createConnection的回调函数中, res.isSources=true时: res.sources表示本机可选窗口列表; res.sourcesCallback为一个设置函数,用户选择窗口列表后获得窗口id,通过此函数设置到底层。 用户通过选择窗口id并传入返回的函数中 ``` ```JS tvvssdk.createConnection(function (res) { if(...) { ...... } else if (res.isSources) { // 如果使用的electron返回所有界面窗口 _this.sourceList = res.sources; // 窗口列表 res.sources => { appIcon: null display_id: "2528732444" id: "screen:0:0" name: "Entire Screen" thumbnail: 缩略图 } _this.sourceCallback = res.sourcesCallback; // 返回函数 传入窗口id进行传流同屏 // enable 是否推流=>boolean ,sourcesId 窗口id => id: "screen:0:0" res.sourcesCallback = function sourceCallback(enable, sourcesId) { } } ...... }); ```JS