李勇

1.视频模块增加推流播流接口的逻辑判断;

2.用户退出会议的时候,如果当前自己正在推流,需要停止推流并且同步数据
... ... @@ -41,6 +41,7 @@ let _joinClassSuccessCallBackFun;
//监听mcu所有错误异常回调函数
let _mcuErrorCallBackFun;
let leaveDelay;
//MCUClient 外部实例化主类
export default class MessageEntrance extends Emiter {
... ... @@ -311,6 +312,14 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.MCUServerPort = server.split(":")[1];
}
//视频推流播流地址
if (_data.ms) {
//MS地址默认使用第一个
let server = _data.ms.split(";")[0];
GlobalConfig.MSServerIP = server.split(":")[0];
GlobalConfig.MSServerPort = server.split(":")[1];
}
GlobalConfig.docServer = _data.doc;
GlobalConfig.h5_mcu_list = _data.h5_mcu_list;
GlobalConfig.h5Module = _data.h5Module;
... ... @@ -606,6 +615,9 @@ export default class MessageEntrance extends Emiter {
}
// 离开会议
_leaveClass() {
if(_video_ape){
_video_ape.stopPublishVideo();
}
if(_confer_ape){
_confer_ape.leaveClass();
}
... ... @@ -637,7 +649,7 @@ export default class MessageEntrance extends Emiter {
sendVideoCommandMsg(_param){
if(_video_ape){
_video_ape.sendVideoCommandMsg(_param);
return _video_ape.sendVideoCommandMsg(_param);
}
}
... ...
... ... @@ -141,7 +141,9 @@ class EverSocket extends Emiter {
if (this._lastActiveTime &&
this._lastActiveTime >= pongTime - EverSocket.PONG_INTERVAL &&
this._lastActiveTime <= pongTime
) {} else {
) {
} else {
loger.warn('---服务器PINGPONG超时-----');
this._reConnection();
}
... ...
... ... @@ -244,7 +244,7 @@ GlobalConfig.statusCode_3={"code":3,message:"已经离开会议"};
GlobalConfig.statusCode_4={"code":4,message:"未知状态"};
GlobalConfig.md5="";
GlobalConfig.msType=1;
GlobalConfig.msType=1;//目前固定用这个
GlobalConfig.mcuDelay=3000;//默认的延迟时间
GlobalConfig.docDelay=1600;//文档模块加入成功之后延迟发送送成功的消息给主模块
GlobalConfig.portal="112.126.80.182:80";
... ... @@ -253,6 +253,10 @@ GlobalConfig.port="80";
GlobalConfig.MCUServerIP="114.215.195.70";
GlobalConfig.docServer="";//当前的文档地址加载的服务器地址
GlobalConfig.MCUServerPort=9003;
GlobalConfig.MSServerIP = "";//推流 播流的地址
GlobalConfig.MSServerPort ="";
GlobalConfig.maxVideoChannels=0;
GlobalConfig.maxAudioChannels=0;
GlobalConfig.maxMediaChannels=0;
... ...
... ... @@ -24,350 +24,344 @@ import EngineUtils from 'EngineUtils';
let loger = Loger.getLoger('VideoChat');
class VideoChat extends Ape {
constructor() {
super(
ApeConsts.VIDEO_SESSION_ID,
ApeConsts.VIDEO_SESSION_NAME,
ApeConsts.VIDEO_SESSION_TAG
);
//Attributes
this.videoChannels = {};
// Ape Models
this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.VIDEO_OBJ_TABLE_ID, ApeConsts.VIDEO_OBJ_TABLE_NAME, ApeConsts.VIDEO_OBJ_TABLE_TAG, 0, new ArrayBuffer);
// videoApe 监听视频控制消息,用户之间的消息传递
this.on(pdu.RCPDU_VIDEO_SEND_DATA_REQUEST, this.videoCommandHandler.bind(this));
}
/////////////发送数据操作//////////////////////////////////////////////////////
//获取播流地址
getPlayVideoPath(_param){
loger.log('getPlayVideoPath');
return {"code":0,"data":"播放流地址XXXXXXXXXXXXXXXXXXXXX"};
}
//获取推流地址
getPublishVideoPath(_param){
loger.log('getPublishVideoPath');
//判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
return {"code":0,"data":"推流地址XXXXXXXXXXXXXXXXXXXXXXX"};
}
//推流
publishVideo(_param){
loger.log('publishVideo -> maxVideoChannels',GlobalConfig.maxVideoChannels);
this.sendTableUpdateHandler();
/* protected function startPushMessageFlash():void
{
if((!Config.enableCDNServer && !Config.isH5Moudle) ||
Config.customer == Config.customerTaobao ||
Config.msType == Config.MS_TYPE_FMS
)
return;
var obj:Object = new Object;
obj.confID = Config.confID;
obj.streamType = RCNetStream.PRT_CAM_SOUND_FLASH;
obj.uriPush = "rtmp://" + Config.liveServerAddr + ":" + Config.liveServerPort + "/3m/" + streamName;
_streamPublished.send("startPush", obj);
log.info("startPushMessageFlash,startPush streamType:" + obj.streamType);
}*/
/* var rtmpUrl:String = "";
if(Config.msType == Config.MS_TYPE_DEFAULT)
{
rtmpUrl = "rtmp://" + mediaServerAddr + ":" + mediaServerPort;
constructor() {
super(
ApeConsts.VIDEO_SESSION_ID,
ApeConsts.VIDEO_SESSION_NAME,
ApeConsts.VIDEO_SESSION_TAG
);
//Attributes
this.videoChannels = {};
// Ape Models
this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.VIDEO_OBJ_TABLE_ID, ApeConsts.VIDEO_OBJ_TABLE_NAME, ApeConsts.VIDEO_OBJ_TABLE_TAG, 0, new ArrayBuffer);
// videoApe 监听视频控制消息,用户之间的消息传递
this.on(pdu.RCPDU_VIDEO_SEND_DATA_REQUEST, this.receiveVideoCommandHandler.bind(this));
}
else if(Config.msType == Config.MS_TYPE_FMS)//fms下链接地址 pzm+ 2016.4.12
{
if(Config.clientType == Config.CT_RECORDPLAYER)
{
rtmpUrl = "rtmp://" + mediaServerAddr + ":" + mediaServerPort + "/vod";
}
else
{
rtmpUrl = "rtmp://" + mediaServerAddr + ":" + mediaServerPort + "/live/" + Config.confID;
}
}*/
}
//停止推流
stopPublishVideo(_param){
loger.log('stopPublishVideo -> maxVideoChannels',GlobalConfig.maxVideoChannels);
this.sendTableUpdateHandler();
}
//
//aaaa(){
// if (event.cmd == ApplicationFacade.OPEN_MIC)
// {
// if (audioDeviceOpenedUsers() >= Config.maxAudioChannels)
// {
// item.closeAudioDevice();
// Alert.show(resourceManager.getString('meeting', 'CannotOpenDeviceAnyMore'),
// resourceManager.getString('meeting', 'AlertWarning'), Alert.OK, item);
// event.stopImmediatePropagation();
// }
// else
// {
// super.updateCamMicStatus(event.camOpened, event.micOpened, event.node_id);
// }
// }
// else if (event.cmd == ApplicationFacade.OPEN_CAMERA)
// {
// if (videoDeviceOpenedUsers() >= Config.maxVideoChannels)
// {
// item.closeVideoDevice();
// Alert.show(resourceManager.getString('meeting', 'CannotOpenDeviceAnyMore'),
// resourceManager.getString('meeting', 'AlertWarning'), Alert.OK, item);
// event.stopImmediatePropagation();
// }
// else
// {
// super.updateCamMicStatus(event.camOpened, event.micOpened, event.node_id);
// }
// }
//}
curAudioDeviceOpenedUsers()
{
//var openedUsers:int = 0;
//var index:int = 0;
//
//for(index = 0; index < _userArray.length; index++)
//{
// var tmpNode:RCNodeInfoRecordPdu = RCNodeInfoRecordPdu(_userArray.getItemAt(index));
// if(tmpNode.status & RCNodeStatus_E.NR_MIC_OPEN)
// {
// openedUsers++;
// }
//}
//
//return openedUsers;
}
curVideoDeviceOpenedUsers()
{
//var openedUsers:int = 0;
//var index:int = 0;
//
//for(index = 0; index < _userArray.length; index++)
//{
// var tmpNode:RCNodeInfoRecordPdu = RCNodeInfoRecordPdu(_userArray.getItemAt(index));
// if(tmpNode.status & RCNodeStatus_E.NR_CAMERA_OPEN)
// {
// openedUsers++;
// }
//}
//return openedUsers;
}
sendVideoCommandMsg(_param) {
if(this._classInfo===null||EngineUtils.isEmptyObject(this._classInfo)){
loger.log('不能发送Video消息.McuClient还未初始化数据!');
if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return ;
}
return 1;
}
if(_param==null){
loger.warn('sendVideoCommandMsg失败,参数错误',paramInfo);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return 1;
/////////////发送数据操作////////////////////////////////////////////
//获取播流地址
getPlayVideoPath(_param) {
loger.log('getPlayVideoPath');
if (_param == null||_param.classId == null||_param.channelId == null|| _param.timestamp==null) {
loger.warn('getPlayVideoPath,参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return {"code": 1, "data": "getPlayVideoPath,参数错误"};
}
let path = "";
if (_param.type == "m3u8") {
path = "http://" + GlobalConfig.MSServerIP + ":80" + "/hls/" + _param.classId + "_" + _param.channelId + "_" + _param.timestamp + ".m3u8";
} else {
let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "" : ":" + GlobalConfig.MSServerPort;
path = "rtmp://" + GlobalConfig.MSServerIP + port + "/live/" + _param.classId + "_" + _param.channelId + "_" + _param.timestamp;
}
return {"code": 0, "data": path};
}
// to, message
loger.log('发送Video消息.', _param);
//获取推流地址
getPublishVideoPath(_param) {
loger.log('getPublishVideoPath');
//if(_param==null){
// loger.warn('getPublishVideoPath,参数错误',_param);
// this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
// return {"code":1,"data":"getPublishVideoPath,参数错误"};;
//}
//判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
let freeChannel = this.getFreeVideoChannel();
if (freeChannel == 0) {
return {"code": 1, "data": "不能再打开更多的设备"};
}
let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "" : ":" + GlobalConfig.MSServerPort;
let timestamp = EngineUtils.creatTimestamp();
let publishUrl = "rtmp://" + GlobalConfig.MSServerIP + port + "/live/" + GlobalConfig.classId + "_" + freeChannel + "_" + timestamp;
return {"code": 0, "data": {"channelId": freeChannel, "timestamp": timestamp, "publishUrl": publishUrl}};
}
/* message RCVideoSendDataRequestPdu {
required uint32 from_node_id = 1;//发起人
optional uint32 to_node_id = 2;//接收人,如果是0就是所有人都接收
optional uint32 actionType = 3;//消息指令类型;
optional bytes data = 4;//其他数据,这个根据actionType来确定数据的结构
}*/
//推流
publishVideo(_param) {
loger.log('publishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
let videoSendPdu = new pdu['RCVideoSendDataRequestPdu'];
videoSendPdu.type = pdu.RCPDU_VIDEO_SEND_DATA_REQUEST;
videoSendPdu.isPublic = true;
//同一个nodeId只允许推一个流,如果已经推了就不能再推
if(this.getOpeningVideoChannel(GlobalConfig.nodeId)!=0){
loger.warn("publishVideo,已经存在一个流,不能再推");
return;
}
videoSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人
videoSendPdu.toNodeId = parseInt(_param.toNodeID)||0;//接收者,0就是所有人
videoSendPdu.actionType = parseInt(_param.actionType)||ApeConsts.MEDIA_ACTION_DEFAULT;
let freeChannel = this.getFreeVideoChannel();
if (freeChannel == 0) {
loger.warn("publishVideo,没有空闲的channel ");
return {"code": 1, "data": "不能再打开更多的设备"};
}
let channelInfo={};
channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;
channelInfo.fromNodeId=GlobalConfig.nodeId;
channelInfo.channelId=freeChannel;
channelInfo.timestamp=EngineUtils.creatTimestamp();
channelInfo.classId=GlobalConfig.classId;
channelInfo.toNodeId=0;
channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;
this.sendTableUpdateHandler(channelInfo);
}
videoSendPdu.data=this._rCArrayBufferUtil.strToUint8Array("h5" + _param.data);//开头两个字会乱码
//停止推流
stopPublishVideo(_param) {
loger.log('stopPublishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
let openingChannel = this.getOpeningVideoChannel(GlobalConfig.nodeId);
if (openingChannel == 0) {
loger.warn("stopPublishVideo,没有打开的channel");
return {"code": 1, "data": "没有打开的设备channel"};
}
if (!videoSendPdu.isPublic && 0!=videoSendPdu.toNodeId) {
//发送给制定的人
loger.log('发送私聊Video消息.');
this.send(videoSendPdu);
} else {
//发送给所有人
loger.log('发送公聊Video消息.');
this.sendChatUniform(videoSendPdu);
let channelInfo={};
channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;
channelInfo.fromNodeId=0;
channelInfo.channelId=openingChannel;
channelInfo.timestamp=0;
channelInfo.classId=GlobalConfig.classId;
channelInfo.toNodeId=0;
channelInfo.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT;
this.sendTableUpdateHandler(channelInfo);
}
return 0;
}
sendTableUpdateHandler(){
loger.log("video===sendTableUpdateHandler ");
/* //验证坐标点集合数组是否合法
if(_docDataModel==null||_itemIdx==null){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
}*/
loger.log("video===sendTableUpdateHandler ");
let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);
let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
tableItemPdu.itemIdx=ApeConsts.VIDEO_OBJ_TABLE_ID+2;//直接用时间戳作为id
tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
tableItemPdu.itemData =updateModelPdu.toArrayBuffer();
//insert
let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu'];
//optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
//repeated RCRegistryTableItemPdu items = 2;
tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//
tableInsertItemPdu.items.push(tableItemPdu);
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
updateObjPdu.objId = ApeConsts.VIDEO_OBJ_TABLE_ID;//
updateObjPdu.subType = tableInsertItemPdu.type;
updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer();
//同步
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
let adapterPdu = new pdu['RCAdapterPdu'];
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
loger.log("发送更新文档.itemIdx="+tableItemPdu.itemIdx);
this.sendUniform(adapterPdu,true);
}
/////收到消息处理/////////////////////////////////////////////////////////////////////////////////
// 视频消息处理,内部处理,不需要告诉应用层
videoCommandHandler(_data) {
let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(_data);
if(videoReceivePdu==null) {
loger.warn("视频消息处理,收到的消息为null,不做处理");
return;
sendVideoCommandMsg(_param) {
if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) {
loger.log('不能发送Video消息.McuClient还未初始化数据!');
if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"};
}
return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"};
}
if (_param == null) {
loger.warn('sendVideoCommandMsg失败,参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return {"code": 1, "data": "sendVideoCommandMsg失败,参数错误"};
;
}
// to, message
loger.log('发送Video消息.', _param);
if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) {
//判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
let freeChannel = this.getFreeVideoChannel();
if (freeChannel == 0) {
loger.warn('sendVideoCommandMsg,不能再打开更多的设备', _param);
return {"code": 1, "data": "不能再打开更多的设备"};
}
}
/* message RCVideoSendDataRequestPdu {
required uint32 from_node_id = 1;//发起人
optional uint32 to_node_id = 2;//接收人,如果是0就是所有人都接收
optional uint32 actionType = 3;//消息指令类型;
optional bytes data = 4;//其他数据,这个根据actionType来确定数据的结构
}*/
let videoSendPdu = new pdu['RCVideoSendDataRequestPdu'];
videoSendPdu.type = pdu.RCPDU_VIDEO_SEND_DATA_REQUEST;
videoSendPdu.isPublic = true;
videoSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人
videoSendPdu.toNodeId = parseInt(_param.toNodeID) || 0;//接收者,0就是所有人
videoSendPdu.actionType = parseInt(_param.actionType) || ApeConsts.MEDIA_ACTION_DEFAULT;
videoSendPdu.data = this._rCArrayBufferUtil.strToUint8Array("h5" + _param.data);//开头两个字会乱码
if (!videoSendPdu.isPublic && 0 != videoSendPdu.toNodeId) {
//发送给制定的人
loger.log('发送私聊Video消息.');
this.send(videoSendPdu);
} else {
//发送给所有人
loger.log('发送公聊Video消息.');
this.sendChatUniform(videoSendPdu);
}
return {"code": 0, "data": ""};
}
videoReceivePdu.data=this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data,2);//开头两个字会乱码
loger.log('视频消息处理 videoCommandHandler.', videoReceivePdu);
//判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理
if(videoReceivePdu.toNodeId!=0&&videoReceivePdu.toNodeId!=GlobalConfig.nodeId){
loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId,"my nodeId=",GlobalConfig.nodeId);
}else {
this._emit(MessageTypes.VIDEO_COMMAND,videoReceivePdu);
sendTableUpdateHandler(_channelInfo) {
loger.log("video===sendTableUpdateHandler ");
/* //验证坐标点集合数组是否合法
if(_docDataModel==null||_itemIdx==null){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
}*/
//let freeChannel=this.getFreeVideoChannel();
//if(freeChannel==0){
// loger.warn("sendTableUpdateHandler,没有空闲的channel ");
// return;
//}
let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);//let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);
let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
tableItemPdu.itemIdx = _channelInfo.channelId;//tableItemPdu.itemIdx=ApeConsts.VIDEO_OBJ_TABLE_ID+2;
tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
tableItemPdu.itemData = updateModelPdu.toArrayBuffer();
//insert
let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu'];
//optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
//repeated RCRegistryTableItemPdu items = 2;
tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//
tableInsertItemPdu.items.push(tableItemPdu);
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
updateObjPdu.objId = ApeConsts.VIDEO_OBJ_TABLE_ID;//
updateObjPdu.subType = tableInsertItemPdu.type;
updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer();
//同步
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
let adapterPdu = new pdu['RCAdapterPdu'];
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
loger.log("发送更新VIDEO.itemIdx=" + tableItemPdu.itemIdx);
this.sendUniform(adapterPdu, true);
}
}
tableUpdateHandler(owner, itemIdx, itemData) {
// debugger;
let videoChannelInfo =this.unPackPdu(owner, itemIdx, itemData);
//videoChannelInfo.owner = owner;
//videoChannelInfo.channelId = itemIdx;
//videoChannelInfo.status = owner === 0 ? ApeConsts.CHANNEL_STATUS_RELEASED : videoChannelInfo.status;
//loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo);
this.videoChannels[itemIdx] = videoChannelInfo;
this._emit(MessageTypes.VIDEO_UPDATE,videoChannelInfo);
/* switch (videoChannelInfo.status) {
case ApeConsts.CHANNEL_STATUS_RELEASED:
// 只能关闭自己的流
if (this.activeChannelId === videoChannelInfo.channelId) {
this.activeChannelId = 0;
this.activeURL = '';
this.emitVideoChange();
/////收到消息处理//////////////////////////////////////////////////
// 视频消息处理,内部处理,不需要告诉应用层
receiveVideoCommandHandler(_data) {
let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(_data);
if (videoReceivePdu == null) {
loger.warn("视频消息处理,收到的消息为null,不做处理");
return;
}
videoReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data, 2);//开头两个字会乱码
loger.log('视频消息处理 receiveVideoCommandHandler.', videoReceivePdu);
//判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理
if (videoReceivePdu.toNodeId != 0 && videoReceivePdu.toNodeId != GlobalConfig.nodeId) {
loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId);
} else {
this._emit(MessageTypes.VIDEO_COMMAND, videoReceivePdu);
}
break;
case ApeConsts.CHANNEL_STATUS_OPENING:
//_playUrl = "rtmfp://" + Config.mediaServerAddr + ":" + Config.mediaServerPort + "/message/" + _streamName;
//_cdnUrl = "rtmp://" + Config.mediaCDNServerAddr + ":" + Config.mediaCDNServerPort + "/message/" + _streamName;
//this.activeChannelId = videoChannelInfo.channelId;
//// AMS/FMS
//if (this._classInfo.msType ==ApeConsts.MS_TYPE_FMS) {
// this.activeURL = `http://dazhi.3mang.com/live/${this._classInfo.classId}/${this._classInfo.classId}_${videoChannelInfo.channelId}_flash_cam_mic_aac/playlist.m3u8`;
//}else {
// this.activeURL = `http://hls.3mang.com/live/${this._classInfo.classId}_${videoChannelInfo.channelId}_flash_cam_mic_aac/playlist.m3u8`;
//}
// 任何人都可以打开流
this.emitVideoChange();
break;
default:
break;
}*/
}
emitVideoChange() {
this._emit(MessageTypes.VIDEO_UPDATE, {
activeChannelId: this.activeChannelId,
HLSURL: this.activeURL,
});
};
///////数据的封包和解包/////////////////////////////////////////
packPdu(_param,_itemIdx){
loger.log("VIDEO===packPdu ");
//验证坐标点集合数组是否合法
if(_param==null||_itemIdx==null){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
}
/* message RCVideoChannelInfoPdu {
optional uint32 status = 1;//开启的状态
optional uint32 channel_id = 2;//唯一的频道id
optional uint32 timestamp = 3;//更新的时间戳
optional uint32 from_node_id = 4;//发起者的id
optional uint32 to_node_id = 5;//接收者的id,(如果是0,所有人都接收)
}*/
//判断type类型,根据type设置不同的参数
let packPduModel =new pdu['RCVideoChannelInfoPdu'];
packPduModel.status=ApeConsts.CHANNEL_STATUS_OPENING;
packPduModel.channelId=_itemIdx;
packPduModel.classId=parseInt(GlobalConfig.classId);
packPduModel.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;
packPduModel.timestamp=EngineUtils.creatTimestamp();
packPduModel.fromNodeId =GlobalConfig.nodeId;
packPduModel.toNodeId = 0;
console.log(packPduModel);
return packPduModel;
}
unPackPdu(owner, itemIdx,itemData){
loger.log("VIDEO==unPackPdu ");
if(owner==null||itemIdx==null||itemData==null){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
tableUpdateHandler(owner, itemIdx, itemData) {
// debugger;
let videoChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
//videoChannelInfo.owner = owner;
//videoChannelInfo.channelId = itemIdx;
//videoChannelInfo.status = owner === 0 ? ApeConsts.CHANNEL_STATUS_RELEASED : videoChannelInfo.status;
//loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo);
this.videoChannels[itemIdx] = videoChannelInfo;
this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo);
/* switch (videoChannelInfo.status) {
case ApeConsts.CHANNEL_STATUS_RELEASED:
// 只能关闭自己的流
if (this.activeChannelId === videoChannelInfo.channelId) {
this.activeChannelId = 0;
this.activeURL = '';
this.emitVideoChange();
}
break;
case ApeConsts.CHANNEL_STATUS_OPENING:
//_playUrl = "rtmfp://" + Config.mediaServerAddr + ":" + Config.mediaServerPort + "/message/" + _streamName;
//_cdnUrl = "rtmp://" + Config.mediaCDNServerAddr + ":" + Config.mediaCDNServerPort + "/message/" + _streamName;
//this.activeChannelId = videoChannelInfo.channelId;
//// AMS/FMS
//if (this._classInfo.msType ==ApeConsts.MS_TYPE_FMS) {
// this.activeURL = `http://dazhi.3mang.com/live/${this._classInfo.classId}/${this._classInfo.classId}_${videoChannelInfo.channelId}_flash_cam_mic_aac/playlist.m3u8`;
//}else {
// this.activeURL = `http://hls.3mang.com/live/${this._classInfo.classId}_${videoChannelInfo.channelId}_flash_cam_mic_aac/playlist.m3u8`;
//}
// 任何人都可以打开流
this.emitVideoChange();
break;
default:
break;
}*/
}
try{
let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData);
loger.log(videoChannelInfo);
return videoChannelInfo;
}catch (err){
loger.log("VIDEO收到数据 unPackPdu Pdu解析错误,itemIdx="+itemIdx+" err:"+err.message);
///////数据的封包和解包/////////////////////////////////////////
packPdu(_param, _itemIdx) {
loger.log("packPdu ");
//验证坐标点集合数组是否合法
if (_param == null || _itemIdx == null) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
}
/* message RCVideoChannelInfoPdu {
optional uint32 status = 1;//开启的状态
optional uint32 channel_id = 2;//唯一的频道id
optional uint32 timestamp = 3;//更新的时间戳
optional uint32 from_node_id = 4;//发起者的id
optional uint32 to_node_id = 5;//接收者的id,(如果是0,所有人都接收)
}*/
//判断type类型,根据type设置不同的参数
let packPduModel = new pdu['RCVideoChannelInfoPdu'];
packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED;
packPduModel.channelId = _itemIdx;
packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId);
packPduModel.mediaType =_param.mediaType|| ApeConsts.MEDIA_TYPE_VIDEO;
packPduModel.timestamp =_param.timestamp||EngineUtils.creatTimestamp();
packPduModel.fromNodeId = GlobalConfig.nodeId;
packPduModel.toNodeId = 0;
console.log(packPduModel);
return packPduModel;
}
return null;
}
unPackPdu(owner, itemIdx, itemData) {
loger.log("unPackPdu ");
if (owner == null || itemIdx == null || itemData == null) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
}
try {
let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData);
loger.log("unPackPdu",videoChannelInfo);
return videoChannelInfo;
} catch (err) {
loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message);
}
return null;
}
//获取当前空闲的channel,返回值为0代表没有空闲的,否则返回的就是空闲的channelId
getFreeVideoChannel() {
loger.log("getFreeVideoChannel");
console.log(this.videoChannels);
let counter = 0;
for (let key in this.videoChannels) {
let item = this.videoChannels[key];
if (item && item.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
return item.channelId;
}
counter++;
}
if (counter < GlobalConfig.maxVideoChannels) {
return ApeConsts.VIDEO_OBJ_TABLE_ID + (counter);
}
return 0;//没有空闲的
}
//获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId
getOpeningVideoChannel(_nodeId){
if(_nodeId==null||_nodeId==0){
return 0;
}
for (let key in this.videoChannels) {
let item = this.videoChannels[key];
if (item && item.status == ApeConsts.CHANNEL_STATUS_OPENING&&item.fromNodeId==_nodeId) {
return item.channelId;
}
}
return 0;
}
}
export default VideoChat;
... ...