李勇

增加屏幕共享模块ShareApe

此 diff 太大无法显示。
@@ -28,7 +28,7 @@ import MediaModule from 'apes/MediaModule'; @@ -28,7 +28,7 @@ import MediaModule from 'apes/MediaModule';
28 import UTF8 from 'utf-8'; 28 import UTF8 from 'utf-8';
29 29
30 let loger = Loger.getLoger('McuClient'); 30 let loger = Loger.getLoger('McuClient');
31 -let _sdkInfo = {"version": "v1.27.16.201705027", "author": "www.3mang.com"}; 31 +let _sdkInfo = {"version": "v1.27.17.201705031", "author": "www.3mang.com"};
32 32
33 //APE 33 //APE
34 let _sass; 34 let _sass;
@@ -1530,6 +1530,9 @@ export default class MessageEntrance extends Emiter { @@ -1530,6 +1530,9 @@ export default class MessageEntrance extends Emiter {
1530 if (_whiteboard_ape) { 1530 if (_whiteboard_ape) {
1531 _whiteboard_ape.clearData(); 1531 _whiteboard_ape.clearData();
1532 } 1532 }
  1533 + if(_video_ape){
  1534 + _video_ape.clearData();
  1535 + }
1533 } 1536 }
1534 1537
1535 //录制回放加入 课堂成功 1538 //录制回放加入 课堂成功
@@ -120,7 +120,7 @@ class RecordPlayBackParse extends Emiter { @@ -120,7 +120,7 @@ class RecordPlayBackParse extends Emiter {
120 120
121 //解析和储存,录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳 121 //解析和储存,录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳
122 _parseSaveSocketMsgReceivedHandler(data, timestamp) { 122 _parseSaveSocketMsgReceivedHandler(data, timestamp) {
123 - loger.log('解析和储存录制回放数据-> '); 123 + //loger.log('解析和储存录制回放数据-> ');
124 let pduMsg = pdu.decode_pdu(data); 124 let pduMsg = pdu.decode_pdu(data);
125 let pduType = pduMsg.get("type"); 125 let pduType = pduMsg.get("type");
126 let pduData = pduMsg.get("data"); 126 let pduData = pduMsg.get("data");
@@ -137,7 +137,7 @@ class RecordPlayBackParse extends Emiter { @@ -137,7 +137,7 @@ class RecordPlayBackParse extends Emiter {
137 //加入课堂请求返回数据处理 137 //加入课堂请求返回数据处理
138 let joinConfPdu = pdu['RCConferenceJoinResponsePdu'].decode(pduData); 138 let joinConfPdu = pdu['RCConferenceJoinResponsePdu'].decode(pduData);
139 let pduResultCode = joinConfPdu.result; 139 let pduResultCode = joinConfPdu.result;
140 - loger.warn('RCPDU_CONNECT_PROVIDER_RESPONSE ->pduResultCode:' + pduResultCode); 140 + //loger.warn('RCPDU_CONNECT_PROVIDER_RESPONSE ->pduResultCode:' + pduResultCode);
141 switch (pduResultCode) { 141 switch (pduResultCode) {
142 case PduConsts.RET_SUCCESS: 142 case PduConsts.RET_SUCCESS:
143 //加入成功 143 //加入成功
@@ -186,6 +186,7 @@ class RecordPlayBackParse extends Emiter { @@ -186,6 +186,7 @@ class RecordPlayBackParse extends Emiter {
186 break; 186 break;
187 default: 187 default:
188 loger.warn('PDU-未知类型-等待处理.', pduType); 188 loger.warn('PDU-未知类型-等待处理.', pduType);
  189 + break;
189 } 190 }
190 } 191 }
191 192
@@ -430,6 +431,7 @@ class RecordPlayBackParse extends Emiter { @@ -430,6 +431,7 @@ class RecordPlayBackParse extends Emiter {
430 //音视频模块seek的时候,查找当前seek点的关键帧数据,所有频道的数据都需要查一下,否则多路视频的时候会显示不全 431 //音视频模块seek的时候,查找当前seek点的关键帧数据,所有频道的数据都需要查一下,否则多路视频的时候会显示不全
431 searchMediaApeMessageKeyfram(_apeMessages){ 432 searchMediaApeMessageKeyfram(_apeMessages){
432 loger.log("SEEK->查找音视频模块数据"); 433 loger.log("SEEK->查找音视频模块数据");
  434 + console.log('SEEK->查找音视频模块数据',_apeMessages)
433 if(_apeMessages) { 435 if(_apeMessages) {
434 for (let k in _apeMessages) { 436 for (let k in _apeMessages) {
435 let channelInfos = _apeMessages[k]; 437 let channelInfos = _apeMessages[k];
@@ -66,10 +66,10 @@ class MediaModule { @@ -66,10 +66,10 @@ class MediaModule {
66 66
67 //获取录制回放时点播的地址,只有m3u8 67 //获取录制回放时点播的地址,只有m3u8
68 getMediaRecordPlaybackPath(_param) { 68 getMediaRecordPlaybackPath(_param) {
69 - loger.log('getMediaRecordPlaybackPath'); 69 + loger.log('获取录制回放时点播的地址->m3u8');
70 if (_param == null||_param.streamId == null) 70 if (_param == null||_param.streamId == null)
71 { 71 {
72 - loger.warn('getMediaRecordPlaybackPath,参数错误', _param); 72 + loger.warn('获取录制回放时点播的地址->参数错误', _param);
73 return {"code": ApeConsts.RETURN_FAILED, "data": ""}; 73 return {"code": ApeConsts.RETURN_FAILED, "data": ""};
74 } 74 }
75 //M3U8 http://123.56.73.119:6001/live/h5dev_2106728010_8ab3b0ed5a3a9220015a3a958f0d0003_983041_1489113860/total.m3u8 75 //M3U8 http://123.56.73.119:6001/live/h5dev_2106728010_8ab3b0ed5a3a9220015a3a958f0d0003_983041_1489113860/total.m3u8
@@ -85,7 +85,7 @@ class MediaModule { @@ -85,7 +85,7 @@ class MediaModule {
85 85
86 //获取推流地址 86 //获取推流地址
87 getMediaPublishPath(_param) { 87 getMediaPublishPath(_param) {
88 - loger.log('getMediaPublishPath'); 88 + loger.log('获取推流地址->');
89 //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 89 //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
90 let freeChannel = this.getFreeMediaChannel(); 90 let freeChannel = this.getFreeMediaChannel();
91 if (freeChannel == 0) { 91 if (freeChannel == 0) {
@@ -128,7 +128,7 @@ class MediaModule { @@ -128,7 +128,7 @@ class MediaModule {
128 } 128 }
129 //监课获取推流地址 129 //监课获取推流地址
130 getMediaPublishPathForInVisible(_param) { 130 getMediaPublishPathForInVisible(_param) {
131 - let mediaLen=Object.keys(MediaModule.allMediaChannelsList={}).length; 131 + let mediaLen=Object.keys(MediaModule.allMediaChannelsList).length;
132 let freeChannel=(this.MEDIA_OBJ_TABLE_ID-20-mediaLen)||GlobalConfig.nodeId; 132 let freeChannel=(this.MEDIA_OBJ_TABLE_ID-20-mediaLen)||GlobalConfig.nodeId;
133 loger.log('监课获取推流地址->'+freeChannel+" mediaLen:"+mediaLen); 133 loger.log('监课获取推流地址->'+freeChannel+" mediaLen:"+mediaLen);
134 //默认方式推流 134 //默认方式推流
@@ -213,12 +213,13 @@ class MediaModule { @@ -213,12 +213,13 @@ class MediaModule {
213 for (let key in this.mediaChannels) { 213 for (let key in this.mediaChannels) {
214 let item = this.mediaChannels[key]; 214 let item = this.mediaChannels[key];
215 if (item && item.status == ApeConsts.CHANNEL_STATUS_RELEASED) { 215 if (item && item.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
  216 + loger.log("已获取空闲的通道->channelId:"+item.channelId);
216 return item.channelId; 217 return item.channelId;
217 } 218 }
218 counter++; 219 counter++;
219 } 220 }
220 - loger.log("getFreeMediaChannel","maxMediaChannel",this.maxMediaChannel,"counter:",counter);  
221 - loger.log(this.mediaChannels); 221 + loger.log("获取空闲的通道","mediaChannels",this.mediaChannels,"counter:",counter);
  222 + //loger.log(this.mediaChannels);
222 if (counter < this.maxMediaChannel) { 223 if (counter < this.maxMediaChannel) {
223 return this.MEDIA_OBJ_TABLE_ID + (counter); 224 return this.MEDIA_OBJ_TABLE_ID + (counter);
224 } 225 }
@@ -281,7 +282,7 @@ class MediaModule { @@ -281,7 +282,7 @@ class MediaModule {
281 channelInfo.owner=0;//这个很重要,释放的时候必须设置为0,占用的时候设置为自己的nodeId 282 channelInfo.owner=0;//这个很重要,释放的时候必须设置为0,占用的时候设置为自己的nodeId
282 channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED; 283 channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;
283 channelInfo.fromNodeId=GlobalConfig.nodeId; 284 channelInfo.fromNodeId=GlobalConfig.nodeId;
284 - channelInfo.channelId=0; 285 + channelInfo.channelId=0;//channelId不能为0
285 channelInfo.streamId="" 286 channelInfo.streamId=""
286 channelInfo.classId=GlobalConfig.classId; 287 channelInfo.classId=GlobalConfig.classId;
287 channelInfo.siteId=GlobalConfig.siteId; 288 channelInfo.siteId=GlobalConfig.siteId;
  1 +// //////////////////////////////////////////////////////////////////////////////
  2 +//视频模块
  3 +// //////////////////////////////////////////////////////////////////////////////
  4 +import Loger from 'Loger';
  5 +import MessageTypes from 'MessageTypes';
  6 +import GlobalConfig from 'GlobalConfig';
  7 +import EngineUtils from 'EngineUtils';
  8 +import ShareScreen from 'ss'
  9 +import Emiter from 'Emiter';
  10 +import ApeConsts from './ApeConsts';
  11 +let loger = Loger.getLoger('ShareApe');
  12 +
  13 +class ShareApe extends Emiter {
  14 + constructor() {
  15 + super();
  16 + this.channelId=ApeConsts.SCREENSHARING_OBJ_TABLE_ID;
  17 + this.streamId='';
  18 + this.publishUrl='';//rtmp://123.56.205.116/live/alexwang
  19 + this.isConnect=false;
  20 + //this.shareScreen=new ShareScreen();
  21 + this.shareScreen=ShareScreen;
  22 + this.ip='127.0.0.1';
  23 + this.port=8090;
  24 + this.init();
  25 + }
  26 + init(){
  27 +
  28 + // // 版本信息
  29 + // ss.on(ss.VERSION_INFO_CHANGE, (d) => {
  30 + // console.log('VERSION_INFO_CHANGE->', d);
  31 + // })
  32 +
  33 + // // 本地摄像头设备
  34 + // ss.on(ss.CAMERA_INFO_CHANGE, (d) => {
  35 + // console.log('CAMERA_INFO_CHANGE->', d);
  36 + // })
  37 +
  38 + // // 本地麦克风设备
  39 + // ss.on(ss.MIC_INFO_CHANGE, (d) => {
  40 + // console.log('MIC_INFO_CHANGE->', d);
  41 + // })
  42 +
  43 + // // 本地RTMP服务端口
  44 + // ss.on(ss.RTMP_PORT_CHANGE, (d) => {
  45 + // console.log('RTMP_PORT_CHANGE->', d);
  46 + // })
  47 +
  48 + // // 麦克风音量
  49 + // ss.on(ss.MIC_VOL_CHANGE, (d) => {
  50 + // console.log('MIC_VOL_CHANGE->', d);
  51 + // })
  52 +
  53 + // 媒体信息
  54 + this.shareScreen.on(ShareScreen.MOVIE_INFO_CHANGE, (d) => {
  55 + console.log('MOVIE_INFO_CHANGE->', d);
  56 + this._emit(MessageTypes.PUBLISH_SCREEN_MOVIE_INFO_CHANGE,d);
  57 + })
  58 +
  59 + // 视频信息
  60 + this.shareScreen.on(ShareScreen.VIDEO_INFO_CHANGE, (d) => {
  61 + console.log('VIDEO_INFO_CHANGE->', d);
  62 + this._emit(MessageTypes.PUBLISH_SCREEN_VIDEO_INFO_CHANGE,d);
  63 + })
  64 +
  65 + // 屏幕共享开始
  66 + this.shareScreen.on(ShareScreen.SS_START, () => {
  67 + //调用startShareScreen 成功
  68 + console.log('屏幕共享开始开启');
  69 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_SUCCESS);
  70 + })
  71 + // 屏幕共享关闭
  72 + this.shareScreen.on(ShareScreen.SS_STOP, () => {
  73 + //调用startShareScreen 失败
  74 + console.log('屏幕共享开启失败');
  75 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_FAILE);
  76 + })
  77 +
  78 + // 发生错误 -- 无法连接本地服务
  79 + this.shareScreen.on(ShareScreen.ERROR, () => {
  80 + console.log('无法连接本地服务-ERROR');
  81 + /* this.isConnect=false;
  82 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_DISCONNECT);
  83 + this.reConnectTimer=setTimeout(()=>{
  84 + this.startConnectSocket();
  85 + },1400);*/
  86 +
  87 + })
  88 +
  89 + // 服务关闭 这个监听暂时不需要,使用ERROR监听即可
  90 + this.shareScreen.on(ShareScreen.CLOSE, () => {
  91 + console.log('屏幕共享服务-CLOSE->重连');
  92 + //1秒后继续重连
  93 + this.isConnect=false;
  94 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_DISCONNECT);
  95 + this.reConnectTimer=setTimeout(()=>{
  96 + this.startConnectSocket();
  97 + },1400);
  98 + })
  99 +
  100 + // 服务开启
  101 + this.shareScreen.on(ShareScreen.OPEN, () => {
  102 + console.log('屏幕共享服务开启-OPEN');
  103 + this.isConnect=true;
  104 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_CONNECTED);
  105 + //连接成功
  106 + // 发起屏幕共享[推送地址可选]
  107 + this.sendPublishRequest();
  108 + })
  109 + }
  110 + // 连接本地流媒体服务
  111 + startConnectSocket(){
  112 + clearTimeout(this.reConnectTimer);
  113 + if(!this.isConnect){
  114 + console.log('开始连接本地流媒体服务->');
  115 + this.shareScreen.start(this.ip, this.port);
  116 + }
  117 + }
  118 +
  119 + //屏幕共享推流,如果没有连接需要先建立连接
  120 + publish(_result){
  121 + /* return {"code": ApeConsts.RETURN_SUCCESS,
  122 + "data":"",
  123 + "mediaId":shareChannel,
  124 + "publishUrl": publishUrl,
  125 + "streamId":streamId
  126 + };*/
  127 + if(_result){
  128 + this.publishUrl=_result.publishUrl||'';
  129 + this.streamId=_result.streamId||''
  130 + }
  131 + clearTimeout(this.reConnectTimer);
  132 + if(!this.isConnect){
  133 + //还没有连接,需要先连接
  134 + this.startConnectSocket()
  135 + }else {
  136 + this.sendPublishRequest();
  137 + }
  138 + }
  139 + //发布推流
  140 + sendPublishRequest(){
  141 + if(this.publishUrl&& this.shareScreen){
  142 + // 发起屏幕共享[推送地址可选]
  143 + this.shareScreen.startShareScreen( this.publishUrl);
  144 + }
  145 + }
  146 + stopPublish(){
  147 + clearTimeout(this.reConnectTimer);
  148 + if( this.shareScreen){
  149 + // // 关闭屏幕共享
  150 + try{
  151 + this.shareScreen.stopShareScreen();
  152 + }catch (err){
  153 + console.log('关闭屏幕共享->失败',err.message);
  154 +
  155 + }
  156 + }
  157 + this.publishUrl=''
  158 + }
  159 +
  160 + //屏幕共享推流地址
  161 + getPublishChannelInfo(){
  162 + let channelInfo={};
  163 + channelInfo.owner=GlobalConfig.nodeId;//这个很重要,释放的时候必须设置为0,占用的时候设置为自己的nodeId
  164 + channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;
  165 + channelInfo.fromNodeId=GlobalConfig.nodeId;
  166 + channelInfo.channelId=this.channelId;
  167 + channelInfo.streamId=this.streamId;
  168 + channelInfo.classId=GlobalConfig.classId;
  169 + channelInfo.siteId=GlobalConfig.siteId;
  170 + channelInfo.toNodeId=0;
  171 + channelInfo.userId=GlobalConfig.userId;
  172 + channelInfo.mediaType=ApeConsts.MEDIA_TYPE_SHARE;
  173 + channelInfo.screenWidth=GlobalConfig.screenWidth;
  174 + channelInfo.screenHeight=GlobalConfig.screenHeight;
  175 + return channelInfo;
  176 + }
  177 + //默认的信息
  178 + getDefaultChannelInfo(){
  179 + let channelInfo={};
  180 + channelInfo.owner=0;//这个很重要,释放的时候必须设置为0,占用的时候设置为自己的nodeId
  181 + channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;
  182 + channelInfo.fromNodeId=GlobalConfig.nodeId;
  183 + channelInfo.channelId=this.channelId;
  184 + channelInfo.streamId=""
  185 + channelInfo.classId=GlobalConfig.classId;
  186 + channelInfo.siteId=GlobalConfig.siteId;
  187 + channelInfo.toNodeId=0;
  188 + channelInfo.userId=GlobalConfig.userId;
  189 + channelInfo.mediaType=ApeConsts.MEDIA_TYPE_SHARE;
  190 + channelInfo.screenWidth=GlobalConfig.screenWidth;
  191 + channelInfo.screenHeight=GlobalConfig.screenHeight;
  192 + return channelInfo;
  193 + }
  194 +}
  195 +
  196 +export default ShareApe;
  197 +
@@ -540,6 +540,12 @@ class VideoApe extends Ape { @@ -540,6 +540,12 @@ class VideoApe extends Ape {
540 540
541 } 541 }
542 542
  543 + //清除当前模块的数据
  544 + clearData(){
  545 + loger.log("clearData->");
  546 + MediaModule.allMediaChannelsList={};
  547 + }
  548 +
543 ///////数据的封包和解包///////////////////////////////////////// 549 ///////数据的封包和解包/////////////////////////////////////////
544 packPdu(_param, _itemIdx) { 550 packPdu(_param, _itemIdx) {
545 loger.log("packPdu "); 551 loger.log("packPdu ");