李勇

1.视频音频模块 获取播放地址增加录制回放的地址和发起人的nodeId

2.录制回放模块增加seek的逻辑
此 diff 太大无法显示。
... ... @@ -421,14 +421,14 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.MCUServerPort = _data.mcuList[0].port || "";
}
//视频推流播流地址
//上课中视频推流播流地址
if (_data.msList&&_data.msList.length>0) {
//MS地址默认使用第一个
GlobalConfig.MSServerIP = _data.msList[0].ip || "";
GlobalConfig.MSServerPort = _data.msList[0].port || "";
}
//m3u8播流地址
//录制回放时m3u8播流地址
if (_data.rsList&&_data.rsList.length>0) {
//RS地址默认使用第一个
GlobalConfig.RSServerIP = _data.rsList[0].ip || "";
... ...
... ... @@ -323,7 +323,7 @@ GlobalConfig.mcuList=[];//录制服务器地址集合
GlobalConfig.msList=[];//ms服务器地址集合
GlobalConfig.musicList=[];//music服务器地址集合
GlobalConfig.musicListPrepare=[];//提提前上传的music集合
GlobalConfig.rsList=[];
GlobalConfig.rsList=[];//录制回放中视频点播地址
GlobalConfig.country ="";//国家
... ...
... ... @@ -32,6 +32,7 @@ class RecordPlayBackParse extends Emiter {
console.log(parseBuffer);
this._recordPlaybackTimestamp = 0;//回放的时间
this._recordPlaybackMaxTime = 0;//录制回放的总时间
this._isReady=false;//录制回放是否已经准备完成
this._apes = {};
this._messages = {};
this._timerCounter = new TimerCounter();//计时器
... ... @@ -109,7 +110,7 @@ class RecordPlayBackParse extends Emiter {
this._recordPlaybackTimestamp = this._recordPlaybackTimestamp + 1;//计时
if(this._recordPlaybackTimestamp>=this._recordPlaybackMaxTime){
this._stopTimerCounter();
loger.log("录制结束...当前时间->", this._recordPlaybackTimestamp," 总时间->",this._recordPlaybackMaxTime);
loger.log("录制回放结束...当前时间->", this._recordPlaybackTimestamp," 总时间->",this._recordPlaybackMaxTime);
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":STOP});
return;
}
... ... @@ -123,6 +124,7 @@ class RecordPlayBackParse extends Emiter {
//加载录制文件
readyRecordPlay() {
this._isReady=false;
this._stopTimerCounter();
loger.log("读取回放数据");
//let url = `http://123.56.73.119:80/h5dev/20170306/1357644520_20170306.rec`;
... ... @@ -191,6 +193,7 @@ class RecordPlayBackParse extends Emiter {
this._recordPlaybackMaxTime=timestamp;
}
this._recordPlaybackTimestamp=0;
this._isReady=true;
this._stopTimerCounter();
GlobalConfig.recordPlaybackMaxTime=this._recordPlaybackMaxTime;
... ... @@ -204,7 +207,6 @@ class RecordPlayBackParse extends Emiter {
let msgDataArr=this._messages[_timestamp];
if(!msgDataArr){
//没有数据,需要查找当前时间点属于哪一个时间戳关键帧
}else {
//把时间点对应的数据发送,同一秒内有存在多个数据的情况
for(let i=0;i<msgDataArr.length;i++){
... ... @@ -214,31 +216,68 @@ class RecordPlayBackParse extends Emiter {
}
//method------------外部接口-------------------------------------
//开始播放
startRecordPlayback(_param) {
if(!this._isReady){
return {"code": ApeConsts.RETURN_FAILED,"data": "录制回放还未准备完成"};
}
this._startTimerCounter();
return {"code": ApeConsts.RETURN_SUCCESS,"data": "ok"};
//this._apes(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":});
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":PLAY});
}
//停止播放
stopRecordPlayback(_param) {
this._recordPlaybackTimestamp = 0;
this._stopTimerCounter();
return {"code": ApeConsts.RETURN_SUCCESS,"data": "ok"};
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":STOP});
}
//暂停播放
pauseRecordPlayback(_param) {
this._stopTimerCounter()
return {"code": ApeConsts.RETURN_SUCCESS,"data": "ok"};
this._stopTimerCounter();
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":PAUSE});
}
//跳转到指定时间点播放
seekRecordPlayback(_param) {
if(!this._isReady){
return {"code": ApeConsts.RETURN_FAILED,"data": "录制回放还未准备完成"};
}
if(!_param||!_param.time){
return {"code": ApeConsts.RETURN_FAILED,"data": "参数不正确"};
}
//先暂停,更改进行的时间
this._stopTimerCounter()
this._recordPlaybackTimestamp = _param.time || 0;
//查找关键帧
this._searchKeyFram();
}
_searchKeyFram(){
//查找关键帧,找到关键帧后再继续播放
let messageItem;
let keyFrameSeek=0;
for(let i=this._recordPlaybackTimestamp;i>0;i--){
messageItem=this._messages[i];
if(messageItem){
break;
}
}
if(messageItem){
keyFrameSeek=(this._recordPlaybackTimestamp-messageItem.timestamp)
loger.log("SEEK->",this._recordPlaybackTimestamp,"查找到相连的数据,seek和关键帧的位置偏移",keyFrameSeek,"秒");
//把时间点对应的数据发送,同一秒内有存在多个数据的情况
for(let i=0;i<messageItem.length;i++){
this._everSocketMsgReceivedHandler(messageItem[i].byteData);
}
}else {
loger.log("SEEK->",this._recordPlaybackTimestamp,"没有查找到相连的数据");
}
this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE,{"status":SEEK,"keyFrameSeek":keyFrameSeek});
//无论有没有找到关键帧数据,都继续播放
this._startTimerCounter();
return {"code": ApeConsts.RETURN_SUCCESS,"data": "ok"};
}
}
... ...
... ... @@ -51,14 +51,6 @@ export default class Ape extends Emiter {
//先收到onJoinSessionHandlerSuccess 后收到 onJoinChannelHandlerSuccess
loger.log('APE-->registerApe->',
'SessionId',
this._session_id,
'SessionName',
this._session_name,
'SessionTag',
this._session_tag);
// 监听底层MCU课堂
this.mcu = McuObj;
this.mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this));
... ...
... ... @@ -316,14 +316,17 @@ class AudioApe extends Ape {
if(unpackChannelInfo&&unpackChannelInfo.fromNodeId!=GlobalConfig.nodeId){
let receiveChannelInfo={};
receiveChannelInfo.mediaId=unpackChannelInfo.channelId;
receiveChannelInfo.fromNodeId=unpackChannelInfo.fromNodeId;
//消息不是自己同步的,需要处理
if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){
//正在推流
receiveChannelInfo.m3u8Url="";
receiveChannelInfo.rtmpUrl="";
receiveChannelInfo.replay="";
let m3u8Stream=this.mediaModule.getMediaPlayPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});
let rtmpStream=this.mediaModule.getMediaPlayPath({"type":"rtmp","streamId": unpackChannelInfo.streamId});
let replay=this.mediaModule.getMediaRecordPlaybackPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});
if(m3u8Stream.code==0){
receiveChannelInfo.m3u8Url=m3u8Stream.playUrl;
... ... @@ -331,6 +334,9 @@ class AudioApe extends Ape {
if(rtmpStream.code==0){
receiveChannelInfo.rtmpUrl=rtmpStream.playUrl;
}
if(replay.code==0){
receiveChannelInfo.replay=replay.playUrl;
}
loger.log("AUDIO_PLAY",receiveChannelInfo);
//广播播放视频的消息
this._emit(MessageTypes.AUDIO_PLAY, receiveChannelInfo);
... ...
... ... @@ -32,7 +32,7 @@ class MediaModule {
let port="";
if (_param.type == "m3u8") {
//M3U8
//http://123.56.73.119:6001/hls/h5dev_403074980_0_983041_1487663265/index.m3u8
//http://123.56.73.119:6001/live/h5dev_2106728010_8ab3b0ed5a3a9220015a3a958f0d0003_983041_1489113860/index.m3u8
port = (GlobalConfig.RSServerPort == "" || GlobalConfig.RSServerPort == null) ? "":":" + GlobalConfig.RSServerPort;
path = "http://" + GlobalConfig.RSServerIP
+ port + "/live/"
... ... @@ -47,6 +47,23 @@ class MediaModule {
return {"code": ApeConsts.RETURN_SUCCESS, "data": "","playUrl": path};
}
//获取录制回放时点播的地址,只有m3u8
getMediaRecordPlaybackPath(_param) {
loger.log('getMediaRecordPlaybackPath');
if (_param == null||_param.streamId == null)
{
loger.warn('getMediaRecordPlaybackPath,参数错误', _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.RSServerPort == "" || GlobalConfig.RSServerPort == null) ? "":":" + GlobalConfig.RSServerPort;
let path = "http://" + GlobalConfig.RSServerIP
+ port + "/live/"
+ _param.streamId
+ "/total.m3u8";
return {"code": ApeConsts.RETURN_SUCCESS, "data": "","playUrl": path};
}
//获取推流地址
getMediaPublishPath(_param) {
loger.log('getMediaPublishPath');
... ...
... ... @@ -319,14 +319,16 @@ class VideoApe extends Ape {
if(unpackChannelInfo&&unpackChannelInfo.fromNodeId!=GlobalConfig.nodeId){
let receiveChannelInfo={};
receiveChannelInfo.mediaId=unpackChannelInfo.channelId;
receiveChannelInfo.fromNodeId=unpackChannelInfo.fromNodeId;
//消息不是自己同步的,需要处理
if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){
//正在推流
receiveChannelInfo.m3u8Url="";
receiveChannelInfo.rtmpUrl="";
receiveChannelInfo.replay="";
let m3u8Stream=this.mediaModule.getMediaPlayPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});
let rtmpStream=this.mediaModule.getMediaPlayPath({"type":"rtmp","streamId": unpackChannelInfo.streamId});
let replay=this.mediaModule.getMediaRecordPlaybackPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});
if(m3u8Stream.code==0){
receiveChannelInfo.m3u8Url=m3u8Stream.playUrl;
... ... @@ -334,6 +336,9 @@ class VideoApe extends Ape {
if(rtmpStream.code==0){
receiveChannelInfo.rtmpUrl=rtmpStream.playUrl;
}
if(replay.code==0){
receiveChannelInfo.replay=replay.playUrl;
}
loger.log("VIDEO_PLAY",receiveChannelInfo);
//广播播放视频的消息
this._emit(MessageTypes.VIDEO_PLAY, receiveChannelInfo);
... ...