李勇

增加屏幕共享模块ShareApe

此 diff 太大无法显示。
... ... @@ -28,7 +28,7 @@ import MediaModule from 'apes/MediaModule';
import UTF8 from 'utf-8';
let loger = Loger.getLoger('McuClient');
let _sdkInfo = {"version": "v1.27.16.201705027", "author": "www.3mang.com"};
let _sdkInfo = {"version": "v1.27.17.201705031", "author": "www.3mang.com"};
//APE
let _sass;
... ... @@ -1530,6 +1530,9 @@ export default class MessageEntrance extends Emiter {
if (_whiteboard_ape) {
_whiteboard_ape.clearData();
}
if(_video_ape){
_video_ape.clearData();
}
}
//录制回放加入 课堂成功
... ...
... ... @@ -120,7 +120,7 @@ class RecordPlayBackParse extends Emiter {
//解析和储存,录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳
_parseSaveSocketMsgReceivedHandler(data, timestamp) {
loger.log('解析和储存录制回放数据-> ');
//loger.log('解析和储存录制回放数据-> ');
let pduMsg = pdu.decode_pdu(data);
let pduType = pduMsg.get("type");
let pduData = pduMsg.get("data");
... ... @@ -137,7 +137,7 @@ class RecordPlayBackParse extends Emiter {
//加入课堂请求返回数据处理
let joinConfPdu = pdu['RCConferenceJoinResponsePdu'].decode(pduData);
let pduResultCode = joinConfPdu.result;
loger.warn('RCPDU_CONNECT_PROVIDER_RESPONSE ->pduResultCode:' + pduResultCode);
//loger.warn('RCPDU_CONNECT_PROVIDER_RESPONSE ->pduResultCode:' + pduResultCode);
switch (pduResultCode) {
case PduConsts.RET_SUCCESS:
//加入成功
... ... @@ -186,6 +186,7 @@ class RecordPlayBackParse extends Emiter {
break;
default:
loger.warn('PDU-未知类型-等待处理.', pduType);
break;
}
}
... ... @@ -430,6 +431,7 @@ class RecordPlayBackParse extends Emiter {
//音视频模块seek的时候,查找当前seek点的关键帧数据,所有频道的数据都需要查一下,否则多路视频的时候会显示不全
searchMediaApeMessageKeyfram(_apeMessages){
loger.log("SEEK->查找音视频模块数据");
console.log('SEEK->查找音视频模块数据',_apeMessages)
if(_apeMessages) {
for (let k in _apeMessages) {
let channelInfos = _apeMessages[k];
... ...
... ... @@ -66,10 +66,10 @@ class MediaModule {
//获取录制回放时点播的地址,只有m3u8
getMediaRecordPlaybackPath(_param) {
loger.log('getMediaRecordPlaybackPath');
loger.log('获取录制回放时点播的地址->m3u8');
if (_param == null||_param.streamId == null)
{
loger.warn('getMediaRecordPlaybackPath,参数错误', _param);
loger.warn('获取录制回放时点播的地址->参数错误', _param);
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
//M3U8 http://123.56.73.119:6001/live/h5dev_2106728010_8ab3b0ed5a3a9220015a3a958f0d0003_983041_1489113860/total.m3u8
... ... @@ -85,7 +85,7 @@ class MediaModule {
//获取推流地址
getMediaPublishPath(_param) {
loger.log('getMediaPublishPath');
loger.log('获取推流地址->');
//判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
let freeChannel = this.getFreeMediaChannel();
if (freeChannel == 0) {
... ... @@ -128,7 +128,7 @@ class MediaModule {
}
//监课获取推流地址
getMediaPublishPathForInVisible(_param) {
let mediaLen=Object.keys(MediaModule.allMediaChannelsList={}).length;
let mediaLen=Object.keys(MediaModule.allMediaChannelsList).length;
let freeChannel=(this.MEDIA_OBJ_TABLE_ID-20-mediaLen)||GlobalConfig.nodeId;
loger.log('监课获取推流地址->'+freeChannel+" mediaLen:"+mediaLen);
//默认方式推流
... ... @@ -213,12 +213,13 @@ 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);
return item.channelId;
}
counter++;
}
loger.log("getFreeMediaChannel","maxMediaChannel",this.maxMediaChannel,"counter:",counter);
loger.log(this.mediaChannels);
loger.log("获取空闲的通道","mediaChannels",this.mediaChannels,"counter:",counter);
//loger.log(this.mediaChannels);
if (counter < this.maxMediaChannel) {
return this.MEDIA_OBJ_TABLE_ID + (counter);
}
... ... @@ -281,7 +282,7 @@ class MediaModule {
channelInfo.owner=0;//这个很重要,释放的时候必须设置为0,占用的时候设置为自己的nodeId
channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;
channelInfo.fromNodeId=GlobalConfig.nodeId;
channelInfo.channelId=0;
channelInfo.channelId=0;//channelId不能为0
channelInfo.streamId=""
channelInfo.classId=GlobalConfig.classId;
channelInfo.siteId=GlobalConfig.siteId;
... ...
// //////////////////////////////////////////////////////////////////////////////
//视频模块
// //////////////////////////////////////////////////////////////////////////////
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
import GlobalConfig from 'GlobalConfig';
import EngineUtils from 'EngineUtils';
import ShareScreen from 'ss'
import Emiter from 'Emiter';
import ApeConsts from './ApeConsts';
let loger = Loger.getLoger('ShareApe');
class ShareApe extends Emiter {
constructor() {
super();
this.channelId=ApeConsts.SCREENSHARING_OBJ_TABLE_ID;
this.streamId='';
this.publishUrl='';//rtmp://123.56.205.116/live/alexwang
this.isConnect=false;
//this.shareScreen=new ShareScreen();
this.shareScreen=ShareScreen;
this.ip='127.0.0.1';
this.port=8090;
this.init();
}
init(){
// // 版本信息
// ss.on(ss.VERSION_INFO_CHANGE, (d) => {
// console.log('VERSION_INFO_CHANGE->', d);
// })
// // 本地摄像头设备
// ss.on(ss.CAMERA_INFO_CHANGE, (d) => {
// console.log('CAMERA_INFO_CHANGE->', d);
// })
// // 本地麦克风设备
// ss.on(ss.MIC_INFO_CHANGE, (d) => {
// console.log('MIC_INFO_CHANGE->', d);
// })
// // 本地RTMP服务端口
// ss.on(ss.RTMP_PORT_CHANGE, (d) => {
// console.log('RTMP_PORT_CHANGE->', d);
// })
// // 麦克风音量
// ss.on(ss.MIC_VOL_CHANGE, (d) => {
// console.log('MIC_VOL_CHANGE->', d);
// })
// 媒体信息
this.shareScreen.on(ShareScreen.MOVIE_INFO_CHANGE, (d) => {
console.log('MOVIE_INFO_CHANGE->', d);
this._emit(MessageTypes.PUBLISH_SCREEN_MOVIE_INFO_CHANGE,d);
})
// 视频信息
this.shareScreen.on(ShareScreen.VIDEO_INFO_CHANGE, (d) => {
console.log('VIDEO_INFO_CHANGE->', d);
this._emit(MessageTypes.PUBLISH_SCREEN_VIDEO_INFO_CHANGE,d);
})
// 屏幕共享开始
this.shareScreen.on(ShareScreen.SS_START, () => {
//调用startShareScreen 成功
console.log('屏幕共享开始开启');
this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_SUCCESS);
})
// 屏幕共享关闭
this.shareScreen.on(ShareScreen.SS_STOP, () => {
//调用startShareScreen 失败
console.log('屏幕共享开启失败');
this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_FAILE);
})
// 发生错误 -- 无法连接本地服务
this.shareScreen.on(ShareScreen.ERROR, () => {
console.log('无法连接本地服务-ERROR');
/* this.isConnect=false;
this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_DISCONNECT);
this.reConnectTimer=setTimeout(()=>{
this.startConnectSocket();
},1400);*/
})
// 服务关闭 这个监听暂时不需要,使用ERROR监听即可
this.shareScreen.on(ShareScreen.CLOSE, () => {
console.log('屏幕共享服务-CLOSE->重连');
//1秒后继续重连
this.isConnect=false;
this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_DISCONNECT);
this.reConnectTimer=setTimeout(()=>{
this.startConnectSocket();
},1400);
})
// 服务开启
this.shareScreen.on(ShareScreen.OPEN, () => {
console.log('屏幕共享服务开启-OPEN');
this.isConnect=true;
this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_CONNECTED);
//连接成功
// 发起屏幕共享[推送地址可选]
this.sendPublishRequest();
})
}
// 连接本地流媒体服务
startConnectSocket(){
clearTimeout(this.reConnectTimer);
if(!this.isConnect){
console.log('开始连接本地流媒体服务->');
this.shareScreen.start(this.ip, this.port);
}
}
//屏幕共享推流,如果没有连接需要先建立连接
publish(_result){
/* return {"code": ApeConsts.RETURN_SUCCESS,
"data":"",
"mediaId":shareChannel,
"publishUrl": publishUrl,
"streamId":streamId
};*/
if(_result){
this.publishUrl=_result.publishUrl||'';
this.streamId=_result.streamId||''
}
clearTimeout(this.reConnectTimer);
if(!this.isConnect){
//还没有连接,需要先连接
this.startConnectSocket()
}else {
this.sendPublishRequest();
}
}
//发布推流
sendPublishRequest(){
if(this.publishUrl&& this.shareScreen){
// 发起屏幕共享[推送地址可选]
this.shareScreen.startShareScreen( this.publishUrl);
}
}
stopPublish(){
clearTimeout(this.reConnectTimer);
if( this.shareScreen){
// // 关闭屏幕共享
try{
this.shareScreen.stopShareScreen();
}catch (err){
console.log('关闭屏幕共享->失败',err.message);
}
}
this.publishUrl=''
}
//屏幕共享推流地址
getPublishChannelInfo(){
let channelInfo={};
channelInfo.owner=GlobalConfig.nodeId;//这个很重要,释放的时候必须设置为0,占用的时候设置为自己的nodeId
channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;
channelInfo.fromNodeId=GlobalConfig.nodeId;
channelInfo.channelId=this.channelId;
channelInfo.streamId=this.streamId;
channelInfo.classId=GlobalConfig.classId;
channelInfo.siteId=GlobalConfig.siteId;
channelInfo.toNodeId=0;
channelInfo.userId=GlobalConfig.userId;
channelInfo.mediaType=ApeConsts.MEDIA_TYPE_SHARE;
channelInfo.screenWidth=GlobalConfig.screenWidth;
channelInfo.screenHeight=GlobalConfig.screenHeight;
return channelInfo;
}
//默认的信息
getDefaultChannelInfo(){
let channelInfo={};
channelInfo.owner=0;//这个很重要,释放的时候必须设置为0,占用的时候设置为自己的nodeId
channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;
channelInfo.fromNodeId=GlobalConfig.nodeId;
channelInfo.channelId=this.channelId;
channelInfo.streamId=""
channelInfo.classId=GlobalConfig.classId;
channelInfo.siteId=GlobalConfig.siteId;
channelInfo.toNodeId=0;
channelInfo.userId=GlobalConfig.userId;
channelInfo.mediaType=ApeConsts.MEDIA_TYPE_SHARE;
channelInfo.screenWidth=GlobalConfig.screenWidth;
channelInfo.screenHeight=GlobalConfig.screenHeight;
return channelInfo;
}
}
export default ShareApe;
... ...
... ... @@ -540,6 +540,12 @@ class VideoApe extends Ape {
}
//清除当前模块的数据
clearData(){
loger.log("clearData->");
MediaModule.allMediaChannelsList={};
}
///////数据的封包和解包/////////////////////////////////////////
packPdu(_param, _itemIdx) {
loger.log("packPdu ");
... ...