From a7a75ace3469c14b5f27898b5f3e650699c76fe9 Mon Sep 17 00:00:00 2001 From: liyong <liyong@3mang.com> Date: Mon, 25 Sep 2017 16:44:08 +0800 Subject: [PATCH] 1.修改FLASH推流拉流的规则-使用腾讯云 --- doc/nodeJs调用接口数据.txt | 38 ++++++++++++++++++++++++++++++++++++++ doc/录制.txt | 19 +++++++++++++++++++ doc/日志上传.txt | 11 +++++++++++ doc/腾讯云视频录制回调数据结构.txt | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/EngineEntrance.js | 35 +++++++++++++++++++++++------------ src/GlobalConfig.js | 15 ++++++++++++++- src/RecordPlayBackParse.js | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- src/SystemConfig.js | 24 +----------------------- src/apes/MediaModule.js | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 9 files changed, 325 insertions(+), 62 deletions(-) create mode 100644 doc/nodeJs调用接口数据.txt create mode 100644 doc/录制.txt create mode 100644 doc/日志上传.txt create mode 100644 doc/腾讯云视频录制回调数据结构.txt diff --git a/doc/nodeJs调用接口数据.txt b/doc/nodeJs调用接口数据.txt new file mode 100644 index 0000000..ca8e183 --- /dev/null +++ b/doc/nodeJs调用接口数据.txt @@ -0,0 +1,38 @@ +1.����¼��(��ʼ����)����һ���ӿ� +{ + "appId": "xxxxxxx", + "channel": "xxxxx_xxxx", + "channelKey": "xxxxxx", + "uid": 11111, + "userId": "xxx", + "userName": "xxx", + "userRole": "xxx", + "timestamp": "������Ϣ�ĵĿͻ���ʱ���", + "recordTimestamp": "��ǰ¼�ƽ��е�ʱ���(�ط�ʱʹ��)" +} + +2.ֹͣ���� +{ + "appId": "xxxxxxx", + "channel": "xxxxx_xxxx", + "channelKey": "xxxxxx", + "uid": 11111, + "userId": "xxx", + "userName": "xxx", + "userRole": "xxx", + "timestamp": "������Ϣ�ĵĿͻ���ʱ���", + "recordTimestamp": "��ǰ¼�ƽ��е�ʱ���(�ط�ʱʹ��)" +} + +3.ֹͣ¼�� +{ + "appId": "xxxxxxx", + "channel": "xxxxx_xxxx", + "channelKey": "xxxxxx", + "uid": 11111, + "userId": "xxx", + "userName": "xxx", + "userRole": "xxx", + "timestamp": "������Ϣ�ĵĿͻ���ʱ���", + "recordTimestamp": "��ǰ¼�ƽ��е�ʱ���(�ط�ʱʹ��)" +} \ No newline at end of file diff --git a/doc/录制.txt b/doc/录制.txt new file mode 100644 index 0000000..cb9fcff --- /dev/null +++ b/doc/录制.txt @@ -0,0 +1,19 @@ +1.时间戳 recordTimestamp +2.开始录制 startRecord +3.停止录制 stopRecord +4.录制权限 : + A.第一个进入课堂的人开启录制; + B.老师或最后一个离开课堂的人停止录制(课堂中没有人的时候10分钟后会停止录制) + C.课堂录制时间更新:老师->1个人->多个人且没有老师的时候,按nodeId值最小的人来更新(人员离开或更新的时候需要选择一个人) +5.课堂进行时间单独更新,和之前的逻辑一致,暂停和未开始的时候不记录; +6.录制的时间更新只要开启录制之后就更新,10秒一次发送到Saas和MCU同步; + +7.刚进入的人员的录制时间从Saas获取默认的,MCU同步更新的时候更改为最新时间; + +8.计时器: + updateTimer(){ + //1.更新课堂时间,课堂开始上课的情况下更新 + + //2.更新录制时间,开启录制的情况下更新 + + } \ No newline at end of file diff --git a/doc/日志上传.txt b/doc/日志上传.txt new file mode 100644 index 0000000..405dceb --- /dev/null +++ b/doc/日志上传.txt @@ -0,0 +1,11 @@ +type 1��error�� 2(warning) 3(info) +classId +userId +nodeId + +data:'aaa\nbbb' + + +//sdk�������Ϣ��ʽ�������Ϣ�û��з� \n���� + +20170729 16:42:00 INFO XX.js receive param name=lipeng diff --git a/doc/腾讯云视频录制回调数据结构.txt b/doc/腾讯云视频录制回调数据结构.txt new file mode 100644 index 0000000..9e101f1 --- /dev/null +++ b/doc/腾讯云视频录制回调数据结构.txt @@ -0,0 +1,60 @@ +[ + { + "app": "txlivepush.xuedianyun.com ", + "appid": 1251457656, + "appname": "live", + "channel_id": "marketflashtest_1966232762_user_627052_983041_1506308668", + "errcode": 0, + "errmsg": "Maybe Error return Data no record!", + "event_time": 1506308670, + "event_type": 1, + "idc_id": 34, + "node": "125.39.15.21", + "sequence": "7037777160241646428", + "set_id": 2, + "sign": "2eb0dcbd2ac7c3bade3089bb9aa999be", + "stream_id": "marketflashtest_1966232762_user_627052_983041_1506308668", + "stream_param": "bizid=11220&txSecret=339c4094afe1ae427e7bcd7f1f8d1128&txTime=59c91afc&record=hls&record_interval=5400", + "t": 1506309271, + "user_ip": "61.135.194.200" + }, + { + "appid": 1251457656, + "channel_id": "marketflashtest_1966232762_user_627052_983041_1506308688", + "duration": 63, + "end_time": 1506308756, + "event_type": 100, + "file_format": "hls", + "file_id": "9031868223267109922", + "file_size": 1349, + "media_start_time": 2931, + "record_file_id": "9031868223267109922", + "sign": "21f73f7e75f9e75196d1b16a536eaff2", + "start_time": 1506308695, + "stream_id": "marketflashtest_1966232762_user_627052_983041_1506308688", + "stream_param": "bizid=11220&txSecret=2a53a100442dbd5d660ff14edb4af853&txTime=59c91b10&record=hls&record_interval=5400", + "t": 1506309357, + "task_id": "479501701", + "video_id": "5158_e9a44513cce1471790f8b0c50c983ccc", + "video_url": "http://1251457656.vod2.myqcloud.com/9425a3e9vodgzp1251457656/6367ba459031868223267109922/playlist.m3u8 " + }, + { + "app": "txlivepush.xuedianyun.com", + "appid": 1251457656, + "appname": "live", + "channel_id": "marketflashtest_1966232762_user_627052_983041_1506308688", + "errcode": 2, + "errmsg": "recv rtmpcloseStream", + "event_time": 1506308756, + "event_type": 0, + "idc_id": 34, + "node": "125.39.15.21", + "sequence": "7037777160241957731", + "set_id": 2, + "sign": "21f73f7e75f9e75196d1b16a536eaff2", + "stream_id": "marketflashtest_1966232762_user_627052_983041_1506308688", + "stream_param": "bizid=11220&txSecret=2a53a100442dbd5d660ff14edb4af853&txTime=59c91b10&record=hls&record_interval=5400", + "t": 1506309357, + "user_ip": "61.135.194.200" + } +] \ No newline at end of file diff --git a/src/EngineEntrance.js b/src/EngineEntrance.js index 39993f1..9297462 100644 --- a/src/EngineEntrance.js +++ b/src/EngineEntrance.js @@ -62,7 +62,7 @@ export default class MessageEntrance extends Emiter { constructor() { super(); //sdk 信息 - GlobalConfig.sdkVersion = "v2.10.7.20170921"; + GlobalConfig.sdkVersion = "v2.11.13.20170925"; loger.warn("sdkVersion:" + GlobalConfig.sdkVersion); //设置 @@ -493,7 +493,7 @@ export default class MessageEntrance extends Emiter { if(!_data){ return; } - if(GlobalConfig.deviceType==1||GlobalConfig.deviceType==2||_data.nodeId==GlobalConfig.nodeId){ + if(GlobalConfig.deviceType==1||GlobalConfig.deviceType==2||GlobalConfig.deviceType==3||_data.nodeId==GlobalConfig.nodeId){ return; } if(_webRtc){ @@ -552,6 +552,7 @@ export default class MessageEntrance extends Emiter { GlobalConfig.isRecordPlayBack = false; //设置为非录制回放状态 GlobalConfig.classId = parseInt(_param.classId); GlobalConfig.portal = _param.portal||""; + GlobalConfig.openFlash=Boolean(_param.openFlash); if(GlobalConfig.isHttps==true){ //https的时候替换所有80端口 GlobalConfig.portal= GlobalConfig.replacePort(GlobalConfig.portal,":80",""); @@ -1292,10 +1293,12 @@ export default class MessageEntrance extends Emiter { //加入课堂成功,广播消息 this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData); - setTimeout(()=>{ - //加入音视频通话模块,延迟一秒处理,因为视频需要根据用户列表信息来判断放的位置,太早的话用户列表没有数据 - this._joinChannel({channelId:GlobalConfig.channelId,channelKey:GlobalConfig.channelKey ,uid:GlobalConfig.userUid,info:""+GlobalConfig.userRole}); - },1000); + if(GlobalConfig.appId&&!GlobalConfig.openFlash){ + setTimeout(()=>{ + //加入音视频通话模块,延迟一秒处理,因为视频需要根据用户列表信息来判断放的位置,太早的话用户列表没有数据 + this._joinChannel({channelId:GlobalConfig.channelId,channelKey:GlobalConfig.channelKey ,uid:GlobalConfig.userUid,info:""+GlobalConfig.userRole}); + },1000); + } } //切换MCU ->_param->{reConnect:false} //reConnect(是否立即替换当前的ip并且重新连接) @@ -1889,14 +1892,22 @@ export default class MessageEntrance extends Emiter { loger.warn("开启录制回放流程失败->还未创建模块"); } } else { - //初始化音视频通话sdk - this._initWebRtcSdk({ - appId:GlobalConfig.appId - },()=>{ - //音视频通话SDK初始化完成之后,根据用户的userIp获取信息,获取服务列表选点,选点测速完成后才加入MCU + if(GlobalConfig.appId&&!GlobalConfig.openFlash){ + loger.log("使用webRtc通话模式"); + //加入webRtc + this._initWebRtcSdk({ + appId:GlobalConfig.appId + },()=>{ + //音视频通话SDK初始化完成之后,根据用户的userIp获取信息,获取服务列表选点,选点测速完成后才加入MCU + this.loadServerJsonAndgetUserIpInfo(); + }); + }else { + //加入flash + loger.log("使用flash通话模式"); this.loadServerJsonAndgetUserIpInfo(); - }); + } + /* //根据用户的userIp获取信息,获取服务列表选点,选点测速完成后才加入MCU this.loadServerJsonAndgetUserIpInfo(); diff --git a/src/GlobalConfig.js b/src/GlobalConfig.js index e59e7ff..878d2d3 100644 --- a/src/GlobalConfig.js +++ b/src/GlobalConfig.js @@ -371,6 +371,19 @@ class GlobalConfig { } } + //通过IP查找IP对象 + static getIpItem(ip,ipList){ + if(!ip||!ipList) { + return null; + } + for(let i=0;i<ipList.length;i++){ + let item=ipList[i]; + if(item&&item.ip==ip){ + return item; + } + } + return null; + } } GlobalConfig.statusCode_0 = { "code": 0, message: "SDK 未初始化" }; @@ -578,7 +591,7 @@ GlobalConfig.locationProtocol="http://";//https;或http: GlobalConfig.websocketProtocol="ws://";//wss或ws GlobalConfig.isHttps=false;//是否是https - +GlobalConfig.openFlash=false;//使用flash通话模式。默认为false,使用的是webRtc //webRtc GlobalConfig.appId = ''; GlobalConfig.appCertificate = ""; diff --git a/src/RecordPlayBackParse.js b/src/RecordPlayBackParse.js index e5a7e5c..82d9c3c 100644 --- a/src/RecordPlayBackParse.js +++ b/src/RecordPlayBackParse.js @@ -123,7 +123,6 @@ class RecordPlayBackParse extends Emiter { //解析和储存,录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳 _parseSaveSocketMsgReceivedHandler(data, timestamp) { - let pduMsg = pdu.decode_pdu(data); let pduType = pduMsg.get("type"); let pduData = pduMsg.get("data"); @@ -135,7 +134,7 @@ class RecordPlayBackParse extends Emiter { pduMsg.type = PduType.RCPDU_SEND_DATA_REQUEST; pduType = PduType.RCPDU_SEND_DATA_REQUEST; } - loger.log('解析和储存->pduType', pduType); + //loger.log('解析和储存->pduType', pduType); switch (pduType) { case PduType.RCPDU_CONNECT_PROVIDER_RESPONSE: //加入课堂请求返回数据处理 @@ -161,7 +160,7 @@ class RecordPlayBackParse extends Emiter { let ape = this._apes[pduMsg.sessionId]; let sessionLabel = ApeConsts(pduMsg.sessionId); //只做解析存储,不对外发送 - loger.log('解析数据-timestamp->', timestamp, 'sessionId->', pduMsg.sessionId, 'sessionLabel->', sessionLabel,"subType:"+pduMsg.subType); + //loger.log('解析数据-timestamp->', timestamp, 'sessionId->', pduMsg.sessionId, 'sessionLabel->', sessionLabel,"subType:"+pduMsg.subType); switch (pduMsg.sessionId) { case ApeConsts.CONFERENCE_SESSION_ID: this.saveParseData(data, timestamp, this._conferApeMssages); @@ -183,11 +182,12 @@ class RecordPlayBackParse extends Emiter { break; case ApeConsts.VIDEO_SESSION_ID: this.saveParseData(data, timestamp, this._videoApeMssages); - this.unPackpduRegAdapterHandler(pduMsg.data,timestamp,data,ApeConsts.VIDEO_SESSION_ID) + this.unpackVideoBroadcastMessage(pduMsg,timestamp,data); + this.unPackpduRegAdapterHandler(pduMsg.data,timestamp,data,ApeConsts.VIDEO_SESSION_ID,pduMsg.subType) break; case ApeConsts.AUDIO_SESSION_ID: this.saveParseData(data, timestamp, this._audioApeMssages); - this.unPackpduRegAdapterHandler(pduMsg.data,timestamp,data,ApeConsts.AUDIO_SESSION_ID) + this.unPackpduRegAdapterHandler(pduMsg.data,timestamp,data,ApeConsts.AUDIO_SESSION_ID,pduMsg.subType) break; default: break; @@ -625,10 +625,62 @@ class RecordPlayBackParse extends Emiter { } } } + //解析视频模块的广播消息 + unpackVideoBroadcastMessage(pduMsg,timestamp,data){ + //console.log("VIDEO_SESSION_ID-pduMsg",pduMsg); + if(!pduMsg){ + return; + } + if(pduMsg.subType!=pdu.RCPDU_SEND_VIDEO_DATA_REQUEST){ + //视频广播消息,只处理501消息 + return; + } + try{ + let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(pduMsg.data); + if (videoReceivePdu == null) { + loger.warn("视频模块广播消息-decode->失败"); + return; + } + videoReceivePdu.data = ArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data, 2);//开头两个字会乱码 + let dataObj = {}; + try { + dataObj = JSON.parse(videoReceivePdu.data); + } catch (err) { + loger.warn('视频模块广播消息->JSON转换失败'); + dataObj = videoReceivePdu.data; + } + videoReceivePdu.data = dataObj; + //actionType:40 + //data :Object + //fromNodeId :902994631 + //toNodeId : 0 + if(videoReceivePdu.actionType==40){ + if(!this._videoApeBroadcastMssages[videoReceivePdu.fromNodeId]){ + this._videoApeBroadcastMssages[videoReceivePdu.fromNodeId]={}; + } + /* + //结构 + { + nodeId:{ + 时间戳:{数据} + }, + nodeId:{ + 时间戳:{数据} + },..... + }*/ + + this._videoApeBroadcastMssages[videoReceivePdu.fromNodeId][timestamp]={parseData:videoReceivePdu,byteData:data,timestamp: timestamp}; + //this._videoApeBroadcastMssages[timestamp]={parseData:videoReceivePdu,byteData:data,timestamp: timestamp}; + } + + }catch (err){ + console.log("视频模块广播消息->解析失败",err.message); + } + } //音视频的数据需要解析,然后按频道储存数据 // 解析pdu RCAdapterPdu的数据: regBuffer(RCAdapterPdu数据),timestamp(时间戳), data(mcu的原始数据) sessionId(类型) - unPackpduRegAdapterHandler(regBuffer, timestamp, data, sessionId) { + unPackpduRegAdapterHandler(regBuffer, timestamp, data, sessionId,subType) { let regPdu; let regItems ; let regItemSize ; @@ -639,13 +691,7 @@ class RecordPlayBackParse extends Emiter { regItemSize = regItems.length; }catch (err){ - console.warn('RCAdapterPdu->unpack-error->type类型不对'); - try { - let sendDataPdu = pdu['RCVideoSendDataRequestPdu'].decode(regBuffer); - console.log("RCVideoSendDataRequestPdu",sendDataPdu); - }catch (err){ - - } + console.warn('RCAdapterPdu->unpack-error->type类型不对',"subType:"+subType); return; } @@ -670,7 +716,8 @@ class RecordPlayBackParse extends Emiter { let sub_type = regUpdatedItem.subType; let object_id = regUpdatedItem.objId; let user_data = regUpdatedItem.userData; - //console.log('RCRegistryUpdateObjPdu',regUpdatedItem) + + console.log('RCRegistryUpdateObjPdu',regUpdatedItem) switch (sub_type) { case pdu.RCPDU_REG_ROSTER_INSERT_PDU: @@ -723,7 +770,7 @@ class RecordPlayBackParse extends Emiter { loger.warn("视频控制消息处理,收到的消息为null,不做处理"); return; } - videoReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data, 2);//开头两个字会乱码 + videoReceivePdu.data = ArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data, 2);//开头两个字会乱码 let dataObj = {}; try { dataObj = JSON.parse(videoReceivePdu.data); diff --git a/src/SystemConfig.js b/src/SystemConfig.js index ecc3035..aa972a0 100644 --- a/src/SystemConfig.js +++ b/src/SystemConfig.js @@ -52,28 +52,6 @@ class SystemConfig { } //获取浏览器和信息 - /* static getBrowserInfo() { - var Sys = {}; - var ua = navigator.userAgent.toLowerCase(); - var re = /(trident|msie|firefox|chrome|opera|version).*?([\d.]+)/; - var m = ua.match(re); - if (!m) m = ["version/1.0.0", "version", "1.0.0"]; - Sys.explorer = m[1].replace(/version/, "'safari"); - //判断是否是IE11 - if (Sys.explorer == "trident") { - Sys.explorer = "IE11" - Sys.explorerVersion = "11.0"; - } else if (Sys.explorer == "msie") { - //IE - Sys.explorer = "IE" - Sys.explorerVersion = m[2]; - } else { - //非IE - Sys.explorerVersion = m[2]; - } - return Sys; - }*/ - //获取浏览器和信息 static getBrowserInfo() { let Sys = {}; Sys.explorer = "unknow"; @@ -83,7 +61,7 @@ class SystemConfig { let re = /(trident|msie|firefox|chrome|version).*?([\d.]+)/; let m = ua.match(re); if (!m) m = ["version/1.0.0", "version", "1.0.0"]; - Sys.explorer = m[1].replace(/version/, "'safari"); + Sys.explorer = m[1].replace(/version/, "safari"); //判断是否是IE11 if (Sys.explorer == "trident") { Sys.explorer = "IE11" diff --git a/src/apes/MediaModule.js b/src/apes/MediaModule.js index c3c6def..9cf31ed 100644 --- a/src/apes/MediaModule.js +++ b/src/apes/MediaModule.js @@ -7,6 +7,7 @@ import Loger from 'Loger'; import MessageTypes from 'MessageTypes'; import GlobalConfig from 'GlobalConfig'; import EngineUtils from 'EngineUtils'; +import MD5 from "md5"; let loger = Loger.getLoger('MediaModule'); @@ -37,22 +38,36 @@ class MediaModule { if (!GlobalConfig.MS_PLAY_HLS_IP) { loger.error("HLS拉流地址地址无效"); } - //http://123.56.73.119:6001/live/h5dev_2106728010_8ab3b0ed5a3a9220015a3a958f0d0003_983041_1489113860/index.m3u8 + /* //http://123.56.73.119:6001/live/h5dev_2106728010_8ab3b0ed5a3a9220015a3a958f0d0003_983041_1489113860/index.m3u8 if (GlobalConfig.siteId == GlobalConfig.siteId_letv) { //乐视的hls地址规则 fileName = 'desc.m3u8'; } else { //fileName='index.m3u8'; fileName = 'playlist.m3u8'; - } + }*/ port = (GlobalConfig.MS_PLAY_HLS_PORT == "" || GlobalConfig.MS_PLAY_HLS_PORT == null) ? "" : ":" + GlobalConfig.MS_PLAY_HLS_PORT; //path = "http://" + GlobalConfig.MS_PLAY_HLS_IP + let ipItem=GlobalConfig.getIpItem(GlobalConfig.MS_PLAY_HLS_IP,GlobalConfig.hlsPullListFinal);//获取IP对象 + let type="live";//默认值 + let hlsSuffix="/playlist.m3u8"; + if(ipItem){ + type=ipItem.type||"live"; + hlsSuffix=ipItem.hlsSuffix||"/playlist.m3u8"; + } + path =GlobalConfig.locationProtocol + GlobalConfig.MS_PLAY_HLS_IP + + port + "/"+type+"/" + + _param.streamId + +hlsSuffix;// + //+ "/"+fileName;// + + /*path =GlobalConfig.locationProtocol + GlobalConfig.MS_PLAY_HLS_IP + port + "/live/" + _param.streamId + ".m3u8";// //+ "/"+fileName;// - + */ } else { //RTMP @@ -60,12 +75,20 @@ class MediaModule { loger.error("RTMP拉流地址地址无效"); } port = (GlobalConfig.MS_PLAY_RTMP_PORT == "" || GlobalConfig.MS_PLAY_RTMP_PORT == null) ? "" : ":" + GlobalConfig.MS_PLAY_RTMP_PORT; + + let ipItem=GlobalConfig.getIpItem(GlobalConfig.MS_PLAY_RTMP_IP,GlobalConfig.rtmpPullListFinal);//获取IP对象 + let type="live";//默认值 + if(ipItem){ + type=ipItem.type||"live"; + } path = "rtmp://" + GlobalConfig.MS_PLAY_RTMP_IP - + port + "/live/" + + port + "/"+type+"/" + _param.streamId; - } - + //path = "rtmp://" + GlobalConfig.MS_PLAY_RTMP_IP + // + port + "/live/" + // + _param.streamId; + } path = path.replace("::", ":");//如果ip和port之间有多的:需要去掉 return {"code": ApeConsts.RETURN_SUCCESS, "data": "", "playUrl": path}; } @@ -81,15 +104,41 @@ class MediaModule { //M3U8 http://123.56.73.119:6001/live/h5dev_2106728010_8ab3b0ed5a3a9220015a3a958f0d0003_983041_1489113860/total.m3u8 let port = (GlobalConfig.RS_RECORD_PLAY_PORT == "" || GlobalConfig.RS_RECORD_PLAY_PORT == null) ? "" : ":" + GlobalConfig.RS_RECORD_PLAY_PORT; //let path = "http://" + GlobalConfig.RS_RECORD_PLAY_IP + let ipItem=GlobalConfig.getIpItem(GlobalConfig.RS_RECORD_PLAY_IP,GlobalConfig.rsPullListFinal);//获取IP对象 + let type="live";//默认值 + let rHlsSuffix="/total.m3u8"; + if(ipItem){ + type=ipItem.type||"live"; + rHlsSuffix=ipItem.rHlsSuffix||"/total.m3u8"; + } + let path =GlobalConfig.locationProtocol + GlobalConfig.RS_RECORD_PLAY_IP - + port + "/live/" + + port + "/"+type+"/" + _param.streamId - + "/total.m3u8"; + +rHlsSuffix; path = path.replace("::", ":");//如果ip和port之间有多的:需要去掉 return {"code": ApeConsts.RETURN_SUCCESS, "data": "", "playUrl": path}; } + //推流地址后缀拼接参数 + setPublishSuffix(url,publishSuffix,streamId){ + let newUrl= url; + if(!url||!publishSuffix){ + return newUrl; + } + //publishSuffix就是外部传入的key + //txSecret = MD5(key + stream+txTime) + let txTime=new Date().getTime()/1000+(12*60*60); + //过去时间精确到分钟,转为16进制 + txTime=parseInt(txTime); + txTime=txTime.toString(16); + let txSecret= MD5(publishSuffix + streamId+txTime); + //rtmp://11220.livepush.myqcloud.com/live/11220_c5a1ea0bce?bizid=11220&txSecret=b1d8af72bf62366eef31cbb5dc5c8778&txTime=59C5337F + newUrl=url +"?bizid=11220&txSecret="+txSecret+"&txTime="+txTime+"&record=hls&record_interval=5400"; + loger.log("生成的推流地址->"+newUrl); + return newUrl; + } //获取推流地址 getMediaPublishPath(_param) { loger.log('获取推流地址->'); @@ -116,8 +165,21 @@ class MediaModule { + "_" + freeChannel + "_" + timestamp; //生成推流地址和推流数据(同步数据的时候用) + //let publishUrl = "rtmp://" + GlobalConfig.MS_PUBLISH_IP + // + port + "/" + pubType + "/" + streamId; + + let ipItem=GlobalConfig.getIpItem(GlobalConfig.MS_PUBLISH_IP,GlobalConfig.msListFinal);//获取IP对象 + let type="live";//默认值 + if(ipItem){ + type=ipItem.type||"live"; + } let publishUrl = "rtmp://" + GlobalConfig.MS_PUBLISH_IP - + port + "/" + pubType + "/" + streamId; + + port + "/"+ type + "/" + streamId; + + //设置推流地址的后缀,有的推流地址需要在地址后面加一些参数 + if(ipItem&&ipItem.publishSuffix){ + publishUrl=this.setPublishSuffix(publishUrl,ipItem.publishSuffix,streamId); + } publishUrl = publishUrl.replace("::", ":");//如果ip和port之间有多的:需要去掉 this.needPublishMediaChannel[publishUrl] = { @@ -169,9 +231,21 @@ class MediaModule { + "_" + freeChannel + "_" + timestamp; //生成推流地址和推流数据(同步数据的时候用) + //let publishUrl = "rtmp://" + GlobalConfig.MS_PUBLISH_IP + // + port + "/" + pubType + "/" + streamId; + + let ipItem=GlobalConfig.getIpItem(GlobalConfig.MS_PUBLISH_IP,GlobalConfig.msListFinal);//获取IP对象 + let type="live";//默认值 + if(ipItem){ + type=ipItem.type||"live"; + } let publishUrl = "rtmp://" + GlobalConfig.MS_PUBLISH_IP - + port + "/" + pubType + "/" + streamId; + + port + "/"+ type + "/" + streamId; + //设置推流地址的后缀,有的推流地址需要在地址后面加一些参数 + if(ipItem&&ipItem.publishSuffix){ + publishUrl=this.setPublishSuffix(publishUrl,ipItem.publishSuffix,streamId); + } publishUrl = publishUrl.replace("::", ":");//如果ip和port之间有多的:需要去掉 this.needPublishMediaChannel[publishUrl] = { "channelId": freeChannel, @@ -213,8 +287,20 @@ class MediaModule { + "_" + shareChannel + "_" + timestamp; //生成推流地址和推流数据(同步数据的时候用) + //let publishUrl = "rtmp://" + GlobalConfig.MS_PUBLISH_IP + // + port + "/" + pubType + "/" + streamId; + let ipItem=GlobalConfig.getIpItem(GlobalConfig.MS_PUBLISH_IP,GlobalConfig.msListFinal);//获取IP对象 + let type="live";//默认值 + if(ipItem){ + type=ipItem.type||"live"; + } let publishUrl = "rtmp://" + GlobalConfig.MS_PUBLISH_IP - + port + "/" + pubType + "/" + streamId; + + port + "/"+ type + "/" + streamId; + + //设置推流地址的后缀,有的推流地址需要在地址后面加一些参数 + if(ipItem&&ipItem.publishSuffix){ + publishUrl=this.setPublishSuffix(publishUrl,ipItem.publishSuffix,streamId); + } publishUrl = publishUrl.replace("::", ":");//如果ip和port之间有多的:需要去掉 /* this.needPublishMediaChannel[publishUrl]={ -- libgit2 0.24.0