李勇

增加MS地址无效时的判断

... ... @@ -35,7 +35,7 @@ import QuestionApe from 'apes/QuestionApe';
import UTF8 from 'utf-8';
let loger = Loger.getLoger('McuClient');
let _sdkInfo = {"version": "v1.59.0.20170729", "author": "www.3mang.com"};
let _sdkInfo = {"version": "v1.60.0.20170729", "author": "www.3mang.com"};
//APE
let _sass;
... ... @@ -907,6 +907,21 @@ export default class MessageEntrance extends Emiter {
loger.warn('HLS拉流地址->HLS->', GlobalConfig.MS_PLAY_HLS_IP, GlobalConfig.MS_PLAY_HLS_PORT);
loger.warn('HLS录制回放拉流地址->HLS->', GlobalConfig.RS_RECORD_PLAY_IP, GlobalConfig.RS_RECORD_PLAY_PORT);
if(!GlobalConfig.MS_PUBLISH_IP){
loger.error("推流MS地址地址无效");
}
if(!GlobalConfig.MS_PLAY_RTMP_IP){
loger.warn("RTMP拉流地址无效->使用推流地址作为RTMP拉流地址");
GlobalConfig.MS_PLAY_RTMP_IP=GlobalConfig.MS_PUBLISH_IP;
GlobalConfig.MS_PLAY_RTMP_PORT=GlobalConfig.MS_PUBLISH_PORT
}
if(!GlobalConfig.MS_PLAY_HLS_IP){
loger.warn("HLS拉流地址无效->使用HLS回放地址作为HLS拉流地址");
GlobalConfig.MS_PLAY_HLS_IP=GlobalConfig.MS_PLAY_HLS_PORT;
GlobalConfig.RS_RECORD_PLAY_IP=GlobalConfig.RS_RECORD_PLAY_PORT
}
if (_mcu) {
_mcu.joinMCU(GlobalConfig.getClassInfo());
}
... ...
... ... @@ -12,38 +12,40 @@ let loger = Loger.getLoger('MediaModule');
class MediaModule {
constructor() {
this.needPublishMediaChannel={};//记录准备推流的频道信息
this.needPublishMediaChannel = {};//记录准备推流的频道信息
this.mediaChannels = {};
this.maxMediaChannel=0;
this.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT;
this.MEDIA_OBJ_TABLE_ID=0;
this.SCREENSHARING_OBJ_TABLE_ID=ApeConsts.SCREENSHARING_OBJ_TABLE_ID;
this.maxMediaChannel = 0;
this.mediaType = ApeConsts.MEDIA_TYPE_DEFAULT;
this.MEDIA_OBJ_TABLE_ID = 0;
this.SCREENSHARING_OBJ_TABLE_ID = ApeConsts.SCREENSHARING_OBJ_TABLE_ID;
}
//获取播流地址
getMediaPlayPath(_param) {
loger.log('获取播放地址->');
if (_param == null||_param.streamId == null)
{
if (_param == null || _param.streamId == null) {
loger.warn('获取播放地址->参数错误', _param);
//this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
let path = "";
let port="";
let fileName='';
let port = "";
let fileName = '';
if (_param.type == "m3u8") {
//M3U8
if (!GlobalConfig.MS_PLAY_HLS_IP) {
loger.error("HLS拉流地址地址无效");
}
//http://123.56.73.119:6001/live/h5dev_2106728010_8ab3b0ed5a3a9220015a3a958f0d0003_983041_1489113860/index.m3u8
if(GlobalConfig.siteId==GlobalConfig.siteId_letv){
if (GlobalConfig.siteId == GlobalConfig.siteId_letv) {
//乐视的hls地址规则
fileName='desc.m3u8';
}else {
fileName = 'desc.m3u8';
} else {
//fileName='index.m3u8';
fileName='playlist.m3u8';
fileName = 'playlist.m3u8';
}
port = (GlobalConfig.MS_PLAY_HLS_PORT == "" || GlobalConfig.MS_PLAY_HLS_PORT == null) ? "":":" + GlobalConfig.MS_PLAY_HLS_PORT;
port = (GlobalConfig.MS_PLAY_HLS_PORT == "" || GlobalConfig.MS_PLAY_HLS_PORT == null) ? "" : ":" + GlobalConfig.MS_PLAY_HLS_PORT;
path = "http://" + GlobalConfig.MS_PLAY_HLS_IP
+ port + "/live/"
+ _param.streamId
... ... @@ -53,35 +55,37 @@ class MediaModule {
} else {
//RTMP
port = (GlobalConfig.MS_PLAY_RTMP_PORT == "" || GlobalConfig.MS_PLAY_RTMP_PORT == null) ? "":":" + GlobalConfig.MS_PLAY_RTMP_PORT;
if (!GlobalConfig.MS_PLAY_RTMP_IP) {
loger.error("RTMP拉流地址地址无效");
}
port = (GlobalConfig.MS_PLAY_RTMP_PORT == "" || GlobalConfig.MS_PLAY_RTMP_PORT == null) ? "" : ":" + GlobalConfig.MS_PLAY_RTMP_PORT;
path = "rtmp://" + GlobalConfig.MS_PLAY_RTMP_IP
+ port + "/live/"
+ _param.streamId;
}
path=path.replace("::",":");//如果ip和port之间有多的:需要去掉
return {"code": ApeConsts.RETURN_SUCCESS, "data": "","playUrl": path};
path = path.replace("::", ":");//如果ip和port之间有多的:需要去掉
return {"code": ApeConsts.RETURN_SUCCESS, "data": "", "playUrl": path};
}
//获取录制回放时点播的地址,只有m3u8
getMediaRecordPlaybackPath(_param) {
loger.log('获取录制回放时点播的地址->m3u8');
if (_param == null||_param.streamId == null)
{
if (_param == null || _param.streamId == null) {
loger.warn('获取录制回放时点播的地址->参数错误', _param);
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
//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 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
+ port + "/live/"
+ _param.streamId
+ "/total.m3u8";
path=path.replace("::",":");//如果ip和port之间有多的:需要去掉
return {"code": ApeConsts.RETURN_SUCCESS, "data": "","playUrl": path};
path = path.replace("::", ":");//如果ip和port之间有多的:需要去掉
return {"code": ApeConsts.RETURN_SUCCESS, "data": "", "playUrl": path};
}
//获取推流地址
... ... @@ -90,115 +94,118 @@ class MediaModule {
//判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
let freeChannel = this.getFreeMediaChannel();
if (freeChannel == 0) {
return {"code":ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaChannels":this.mediaChannels};
return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备", "mediaChannels": this.mediaChannels};
}
//默认方式推流
let pubType="live";
////flash推流
//if(_param&&_param.type=="flash"){
// pubType ="flash";
//}
let pubType = "live";
if (!GlobalConfig.MS_PUBLISH_IP) {
loger.error("MS推流地址地址无效");
}
//端口,有端口就显示 ":xxx",没有端口就是""
let port = (GlobalConfig.MS_PUBLISH_PORT == "" || GlobalConfig.MS_PUBLISH_PORT == null) ? "":":" + GlobalConfig.MS_PUBLISH_PORT;
let port = (GlobalConfig.MS_PUBLISH_PORT == "" || GlobalConfig.MS_PUBLISH_PORT == null) ? "" : ":" + GlobalConfig.MS_PUBLISH_PORT;
//时间戳
let timestamp = EngineUtils.creatTimestamp();
let streamId=GlobalConfig.siteId+"_"
+ GlobalConfig.classId + "_"+GlobalConfig.userId
+"_" + freeChannel + "_" + timestamp;
let streamId = GlobalConfig.siteId + "_"
+ GlobalConfig.classId + "_" + GlobalConfig.userId
+ "_" + freeChannel + "_" + timestamp;
//生成推流地址和推流数据(同步数据的时候用)
let publishUrl = "rtmp://" + GlobalConfig.MS_PUBLISH_IP
+ port + "/"+pubType+"/" +streamId;
+ port + "/" + pubType + "/" + streamId;
publishUrl=publishUrl.replace("::",":");//如果ip和port之间有多的:需要去掉
this.needPublishMediaChannel[publishUrl]={
"channelId":freeChannel,
"publishUrl":publishUrl,
"streamId":streamId,
"timestamp":timestamp,
"nodeId":GlobalConfig.nodeId
publishUrl = publishUrl.replace("::", ":");//如果ip和port之间有多的:需要去掉
this.needPublishMediaChannel[publishUrl] = {
"channelId": freeChannel,
"publishUrl": publishUrl,
"streamId": streamId,
"timestamp": timestamp,
"nodeId": GlobalConfig.nodeId
};
return {"code": ApeConsts.RETURN_SUCCESS,
"data":"",
"mediaId":freeChannel,
"userId":GlobalConfig.userId,
"userName":GlobalConfig.userName,
"userRole":GlobalConfig.userRole,
return {
"code": ApeConsts.RETURN_SUCCESS,
"data": "",
"mediaId": freeChannel,
"userId": GlobalConfig.userId,
"userName": GlobalConfig.userName,
"userRole": GlobalConfig.userRole,
"publishUrl": publishUrl
};
}
//监课获取推流地址
getMediaPublishPathForInVisible(_param) {
let mediaLen=Object.keys(MediaModule.allMediaChannelsList).length;
let freeChannel=(this.MEDIA_OBJ_TABLE_ID-20-mediaLen)||GlobalConfig.nodeId;
loger.log('监课获取推流地址->'+freeChannel+" mediaLen:"+mediaLen);
let mediaLen = Object.keys(MediaModule.allMediaChannelsList).length;
let freeChannel = (this.MEDIA_OBJ_TABLE_ID - 20 - mediaLen) || GlobalConfig.nodeId;
loger.log('监课获取推流地址->' + freeChannel + " mediaLen:" + mediaLen);
//默认方式推流
let pubType="live";
let pubType = "live";
////flash推流
//if(_param&&_param.type=="flash"){
// pubType ="flash";
//}
//端口,有端口就显示 ":xxx",没有端口就是""
let port = (GlobalConfig.MS_PUBLISH_PORT == "" || GlobalConfig.MS_PUBLISH_PORT == null) ? "":":" + GlobalConfig.MS_PUBLISH_PORT;
let port = (GlobalConfig.MS_PUBLISH_PORT == "" || GlobalConfig.MS_PUBLISH_PORT == null) ? "" : ":" + GlobalConfig.MS_PUBLISH_PORT;
//时间戳
let timestamp = EngineUtils.creatTimestamp();
let streamId=GlobalConfig.siteId+"_"
+ GlobalConfig.classId + "_"+GlobalConfig.userId
+"_" + freeChannel + "_" + timestamp;
let streamId = GlobalConfig.siteId + "_"
+ GlobalConfig.classId + "_" + GlobalConfig.userId
+ "_" + freeChannel + "_" + timestamp;
//生成推流地址和推流数据(同步数据的时候用)
let publishUrl = "rtmp://" + GlobalConfig.MS_PUBLISH_IP
+ port + "/"+pubType+"/" +streamId;
+ port + "/" + pubType + "/" + streamId;
publishUrl=publishUrl.replace("::",":");//如果ip和port之间有多的:需要去掉
this.needPublishMediaChannel[publishUrl]={
"channelId":freeChannel,
"publishUrl":publishUrl,
"streamId":streamId,
"timestamp":timestamp,
"nodeId":GlobalConfig.nodeId
publishUrl = publishUrl.replace("::", ":");//如果ip和port之间有多的:需要去掉
this.needPublishMediaChannel[publishUrl] = {
"channelId": freeChannel,
"publishUrl": publishUrl,
"streamId": streamId,
"timestamp": timestamp,
"nodeId": GlobalConfig.nodeId
};
return {"code": ApeConsts.RETURN_SUCCESS,
"data":"",
"userId":GlobalConfig.userId,
"userName":GlobalConfig.userName,
"userRole":GlobalConfig.userRole,
"mediaId":freeChannel,
return {
"code": ApeConsts.RETURN_SUCCESS,
"data": "",
"userId": GlobalConfig.userId,
"userName": GlobalConfig.userName,
"userRole": GlobalConfig.userRole,
"mediaId": freeChannel,
"publishUrl": publishUrl
};
}
//桌面共享获取推流地址,频道号由外部传入
getMediaPublishPathForScreenShare(_shareChannel,_publishType) {
getMediaPublishPathForScreenShare(_shareChannel, _publishType) {
let shareChannel=_shareChannel||this.SCREENSHARING_OBJ_TABLE_ID;
loger.log('桌面共享获取推流地址->'+shareChannel);
let shareChannel = _shareChannel || this.SCREENSHARING_OBJ_TABLE_ID;
loger.log('桌面共享获取推流地址->' + shareChannel);
//默认方式推流
let pubType="live";//统一使用live 20170615
let pubType = "live";//统一使用live 20170615
/*//flash推流
if(_publishType=="live"){
pubType ="live";
}*/
//端口,有端口就显示 ":xxx",没有端口就是""
let port = (GlobalConfig.MS_PUBLISH_PORT == "" || GlobalConfig.MS_PUBLISH_PORT == null) ? "":":" + GlobalConfig.MS_PUBLISH_PORT;
let port = (GlobalConfig.MS_PUBLISH_PORT == "" || GlobalConfig.MS_PUBLISH_PORT == null) ? "" : ":" + GlobalConfig.MS_PUBLISH_PORT;
//时间戳
let timestamp = EngineUtils.creatTimestamp();
let streamId=GlobalConfig.siteId+"_"
+ GlobalConfig.classId + "_"+GlobalConfig.userId
+"_" + shareChannel + "_" + timestamp;
let streamId = GlobalConfig.siteId + "_"
+ GlobalConfig.classId + "_" + GlobalConfig.userId
+ "_" + shareChannel + "_" + timestamp;
//生成推流地址和推流数据(同步数据的时候用)
let publishUrl = "rtmp://" + GlobalConfig.MS_PUBLISH_IP
+ port + "/"+pubType+"/" +streamId;
+ port + "/" + pubType + "/" + streamId;
publishUrl=publishUrl.replace("::",":");//如果ip和port之间有多的:需要去掉
publishUrl = publishUrl.replace("::", ":");//如果ip和port之间有多的:需要去掉
/* this.needPublishMediaChannel[publishUrl]={
"channelId":shareChannel,
"publishUrl":publishUrl,
... ... @@ -206,14 +213,15 @@ class MediaModule {
"timestamp":timestamp,
"nodeId":GlobalConfig.nodeId
};*/
return {"code": ApeConsts.RETURN_SUCCESS,
"data":"",
"mediaId":shareChannel,
"userId":GlobalConfig.userId,
"userName":GlobalConfig.userName,
"userRole":GlobalConfig.userRole,
return {
"code": ApeConsts.RETURN_SUCCESS,
"data": "",
"mediaId": shareChannel,
"userId": GlobalConfig.userId,
"userName": GlobalConfig.userName,
"userRole": GlobalConfig.userRole,
"publishUrl": publishUrl,
"streamId":streamId
"streamId": streamId
};
}
... ... @@ -223,12 +231,12 @@ class MediaModule {
for (let key in this.mediaChannels) {
let item = this.mediaChannels[key];
if (item && item.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
loger.log("已获取空闲的通道->channelId:"+item.channelId);
loger.log("已获取空闲的通道->channelId:" + item.channelId);
return item.channelId;
}
counter++;
}
loger.log("获取空闲的通道","mediaChannels",this.mediaChannels,"counter:",counter);
loger.log("获取空闲的通道", "mediaChannels", this.mediaChannels, "counter:", counter);
//loger.log(this.mediaChannels);
if (counter < this.maxMediaChannel) {
return this.MEDIA_OBJ_TABLE_ID + (counter);
... ... @@ -237,21 +245,21 @@ class MediaModule {
}
//获取准备推流的频道信息
getNeedPublishMediaChannel(_publishUrl){
getNeedPublishMediaChannel(_publishUrl) {
return this.needPublishMediaChannel[_publishUrl];
}
//获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId
getOpeningMediaChannelForNodeId(_nodeId){
loger.log("getOpeningMediaChannel","nodeId",_nodeId,"mediaChannels:",this.mediaChannels);
let channelInfo={};
channelInfo.channelId=0;
if(_nodeId==null||_nodeId==0){
getOpeningMediaChannelForNodeId(_nodeId) {
loger.log("getOpeningMediaChannel", "nodeId", _nodeId, "mediaChannels:", this.mediaChannels);
let channelInfo = {};
channelInfo.channelId = 0;
if (_nodeId == null || _nodeId == 0) {
return channelInfo;
}
for (let key in this.mediaChannels) {
let item = this.mediaChannels[key];
if (item && item.status == ApeConsts.CHANNEL_STATUS_OPENING&&item.fromNodeId==_nodeId) {
if (item && item.status == ApeConsts.CHANNEL_STATUS_OPENING && item.fromNodeId == _nodeId) {
return item;
}
}
... ... @@ -259,51 +267,52 @@ class MediaModule {
}
//检查频道是否已经被占用
checkChannelIsOpening(_channelId){
if(_channelId==null){
loger.warn("checkChannelIsOpening error,channel=",_channelId);
checkChannelIsOpening(_channelId) {
if (_channelId == null) {
loger.warn("checkChannelIsOpening error,channel=", _channelId);
return true;
}
let channelInfo=this.mediaChannels[_channelId];
if(channelInfo==null||channelInfo.status==ApeConsts.CHANNEL_STATUS_RELEASED){
let channelInfo = this.mediaChannels[_channelId];
if (channelInfo == null || channelInfo.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
return false;
}
return true;
}
//获取当前所有频道的信息
getAllMediaChannelInfo(){
let channels=[];
for (let key in this.mediaChannels){
let channel=this.mediaChannels[key];
if(channel){
channels.push({"mediaId":channel.channelId,"status":channel.status,"fromNodeId":channel.fromNodeId});
getAllMediaChannelInfo() {
let channels = [];
for (let key in this.mediaChannels) {
let channel = this.mediaChannels[key];
if (channel) {
channels.push({"mediaId": channel.channelId, "status": channel.status, "fromNodeId": channel.fromNodeId});
}
}
if(channels.length<this.maxMediaChannel){
for (let i=channels.length;i<this.maxMediaChannel;i++){
let channelId=this.MEDIA_OBJ_TABLE_ID + (i);
channels.push({"mediaId":channelId,"status":ApeConsts.CHANNEL_STATUS_RELEASED,"fromNodeId":0});
if (channels.length < this.maxMediaChannel) {
for (let i = channels.length; i < this.maxMediaChannel; i++) {
let channelId = this.MEDIA_OBJ_TABLE_ID + (i);
channels.push({"mediaId": channelId, "status": ApeConsts.CHANNEL_STATUS_RELEASED, "fromNodeId": 0});
}
}
return channels;
}
//获取默认的频道信息
getDefaultChannelInfo(){
let channelInfo={};
channelInfo.owner=0;//这个很重要,释放的时候必须设置为0,占用的时候设置为自己的nodeId
channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;
channelInfo.fromNodeId=GlobalConfig.nodeId;
channelInfo.channelId=0;//channelId不能为0
channelInfo.streamId="";
channelInfo.classId=GlobalConfig.classId;
channelInfo.siteId=GlobalConfig.siteId;
channelInfo.toNodeId=0;
channelInfo.userId=GlobalConfig.userId;
channelInfo.mediaType=this.mediaType||ApeConsts.MEDIA_TYPE_DEFAULT;
getDefaultChannelInfo() {
let channelInfo = {};
channelInfo.owner = 0;//这个很重要,释放的时候必须设置为0,占用的时候设置为自己的nodeId
channelInfo.status = ApeConsts.CHANNEL_STATUS_RELEASED;
channelInfo.fromNodeId = GlobalConfig.nodeId;
channelInfo.channelId = 0;//channelId不能为0
channelInfo.streamId = "";
channelInfo.classId = GlobalConfig.classId;
channelInfo.siteId = GlobalConfig.siteId;
channelInfo.toNodeId = 0;
channelInfo.userId = GlobalConfig.userId;
channelInfo.mediaType = this.mediaType || ApeConsts.MEDIA_TYPE_DEFAULT;
return channelInfo;
}
}
MediaModule.allMediaChannelsList={};//当前已经创建的所有音视频通道(包含释放或未未释放的)
MediaModule.allMediaChannelsList = {};//当前已经创建的所有音视频通道(包含释放或未未释放的)
export default MediaModule;
... ...