|
@@ -4,7 +4,8 @@ const SDP = require('./sdp/parser');
|
4
|
4
|
const Logger = require('./core/logger');
|
5
|
5
|
const context = require('./core/ctx');
|
6
|
6
|
const NtvAuthModule = require('./NtvAuthModule');
|
7
|
|
-
|
|
7
|
+const fs = require('fs');
|
|
8
|
+const cache_path = "/etc/noveltv/mserver/cache/";
|
8
|
9
|
class NodeSipSession {
|
9
|
10
|
constructor(config, userid, remote, uas) {
|
10
|
11
|
|
|
@@ -150,6 +151,7 @@ class NodeSipSession {
|
150
|
151
|
});
|
151
|
152
|
|
152
|
153
|
//ntv 尝试自动开启视频,只开启第一个通道。 TODO: 对于硬盘录像机,应可以开启多个通道
|
|
154
|
+ //如果要自动开启视频,把这个注释打开
|
153
|
155
|
await this.startRealPlay(firstChid,auto_play);
|
154
|
156
|
}
|
155
|
157
|
|
|
@@ -786,6 +788,50 @@ class NodeSipSession {
|
786
|
788
|
});
|
787
|
789
|
}
|
788
|
790
|
|
|
791
|
+//扩展函数////////////////////////////
|
|
792
|
+
|
|
793
|
+//ssrc生成规则
|
|
794
|
+genSSRC(id,chid){
|
|
795
|
+ let sub1 = 10000 + parseInt(id.substring(15));
|
|
796
|
+ let sub2 = chid.substring(15);
|
|
797
|
+ let ssrc = '' + sub1 + sub2;
|
|
798
|
+ return ssrc;
|
|
799
|
+}
|
|
800
|
+//设置关闭视频预览的指令缓存,如果要缓存更多指令,可以追加参数 NTV ADD
|
|
801
|
+setSessionData(key,json){
|
|
802
|
+ this.dialogs[key] = json;
|
|
803
|
+ var filename = cache_path + key;
|
|
804
|
+ fs.writeFile(filename, JSON.stringify(json), function (error) {
|
|
805
|
+ if (error) {
|
|
806
|
+ Logger.error('Failed to write cache file !');
|
|
807
|
+ }
|
|
808
|
+ });
|
|
809
|
+}
|
|
810
|
+//查询关闭视频预览的指令缓存 NTV ADD
|
|
811
|
+getSessionData(key){
|
|
812
|
+ var filename = cache_path + key;
|
|
813
|
+ if(this.dialogs[key]){
|
|
814
|
+ return this.dialogs[key];
|
|
815
|
+ }else if (fs.existsSync(filename)){
|
|
816
|
+ var data = fs.readFileSync(filename,'utf-8');
|
|
817
|
+ Logger.log('Get string from cache OK!');
|
|
818
|
+ return JSON.parse(data);
|
|
819
|
+ }
|
|
820
|
+
|
|
821
|
+ return null;
|
|
822
|
+}
|
|
823
|
+
|
|
824
|
+delSessionData(key){
|
|
825
|
+ var filename = cache_path + key;
|
|
826
|
+ delete this.dialogs[key];
|
|
827
|
+ fs.unlink(filename, (err) => {
|
|
828
|
+ if (err){
|
|
829
|
+ Logger.error('Failed to unlink file : ' + filename);
|
|
830
|
+ }
|
|
831
|
+ });
|
|
832
|
+}
|
|
833
|
+//扩展函数////////////////////////////
|
|
834
|
+
|
789
|
835
|
//预览 channelId 通道国标编码
|
790
|
836
|
sendRealPlayMessage(channelId, rhost, rport, mode) {
|
791
|
837
|
Logger.log("Start real play " + this.id + ":" + channelId + " " + rhost + ":" + rport + " mode:" + mode);
|
|
@@ -797,6 +843,7 @@ class NodeSipSession {
|
797
|
843
|
|
798
|
844
|
let findssrc = "";
|
799
|
845
|
|
|
846
|
+ /** 替换 NTV
|
800
|
847
|
for (var key in this.dialogs) {
|
801
|
848
|
let session = this.dialogs[key];
|
802
|
849
|
if (session.bye && session.port == rport && session.host == rhost && session.channelId == channelId && session.play == 'realplay') {
|
|
@@ -805,22 +852,26 @@ class NodeSipSession {
|
805
|
852
|
break;
|
806
|
853
|
}
|
807
|
854
|
}
|
|
855
|
+ */
|
|
856
|
+ let ssrc = this.genSSRC(this.id,channelId)
|
|
857
|
+ var key = ssrc + "p";
|
|
858
|
+ let session = this.dialogs[key] || this.getSessionData(key);
|
|
859
|
+ if(session){
|
|
860
|
+ isFinded = true;
|
|
861
|
+ findssrc = session.ssrc;
|
|
862
|
+ }
|
808
|
863
|
|
809
|
864
|
//己存在会话,同一个流媒体不需要重复请求
|
810
|
865
|
if (isFinded) {
|
|
866
|
+ this.playmode='realplay';
|
811
|
867
|
result.data = { ssrc: findssrc };
|
812
|
868
|
resolve(result);
|
|
869
|
+ Logger.log("Live stream is playing now, needn't send play cmd again!");
|
813
|
870
|
return;
|
814
|
871
|
}
|
815
|
872
|
//0: udp,1:tcp/passive ,2:tcp/active
|
816
|
873
|
let selectMode = mode || 0;
|
817
|
874
|
|
818
|
|
- //ssrc is here -- by ntv wangjian
|
819
|
|
- //let ssrc = "0" + channelId.substring(16, 20) + channelId.substring(3, 8);
|
820
|
|
- let sub1 = 10000 + parseInt(this.id.substring(15));
|
821
|
|
- let sub2 = channelId.substring(15);
|
822
|
|
- let ssrc = '' + sub1 + sub2;
|
823
|
|
-
|
824
|
875
|
let host = rhost || "127.0.0.1";
|
825
|
876
|
|
826
|
877
|
let port = rport || 9200;
|
|
@@ -912,10 +963,10 @@ class NodeSipSession {
|
912
|
963
|
});
|
913
|
964
|
|
914
|
965
|
//会话标识
|
915
|
|
- let key = [response.headers['call-id'], response.headers.from.params.tag, response.headers.to.params.tag].join(':');
|
|
966
|
+ //let key = [response.headers['call-id'], response.headers.from.params.tag, response.headers.to.params.tag].join(':');
|
916
|
967
|
|
917
|
968
|
//创建会话
|
918
|
|
- if (!that.dialogs[key]) {
|
|
969
|
+ //if (!that.dialogs[key]) {
|
919
|
970
|
// 断开会话请求
|
920
|
971
|
let byeRequest = {
|
921
|
972
|
method: 'BYE',
|
|
@@ -929,11 +980,12 @@ class NodeSipSession {
|
929
|
980
|
}
|
930
|
981
|
}
|
931
|
982
|
|
932
|
|
- that.dialogs[key] = { channelId: channelId, ssrc: ssrc, host: host, port: port, bye: byeRequest, play: 'realplay' };
|
933
|
|
-
|
|
983
|
+ //that.dialogs[key] = { channelId: channelId, ssrc: ssrc, host: host, port: port, bye: byeRequest, play: 'realplay' };
|
|
984
|
+ let bayCmd = { channelId: channelId, ssrc: ssrc, host: host, port: port, bye: byeRequest, play: 'realplay' };
|
|
985
|
+ that.setSessionData(key,bayCmd);
|
934
|
986
|
//console.log("BYE INFO:");
|
935
|
987
|
//console.log(that.dialogs[key]);
|
936
|
|
- }
|
|
988
|
+ //}
|
937
|
989
|
|
938
|
990
|
result.data = { ssrc: ssrc };
|
939
|
991
|
|
|
@@ -945,7 +997,6 @@ class NodeSipSession {
|
945
|
997
|
}else{
|
946
|
998
|
Logger.log("视频开启状态已上报失败!" + data.err_desc);
|
947
|
999
|
}
|
948
|
|
-
|
949
|
1000
|
});
|
950
|
1001
|
|
951
|
1002
|
resolve(result);
|
|
@@ -966,14 +1017,17 @@ class NodeSipSession {
|
966
|
1017
|
return new Promise((resolve, reject) => {
|
967
|
1018
|
let result = { result: false, message: '没有找到视频通道!' };
|
968
|
1019
|
|
969
|
|
- for (var key in this.dialogs) {
|
|
1020
|
+ //for (var key in this.dialogs) {
|
970
|
1021
|
//搜索满足条件的会话
|
971
|
|
- let session = this.dialogs[key];
|
|
1022
|
+ //let session = this.dialogs[key];
|
972
|
1023
|
//ntv 注释掉多余条件,因为数据类型不同导致找不到
|
973
|
|
- if (session.bye && session.port == rport && session.host == rhost && session.channelId == channelId && session.play == 'realplay') {
|
|
1024
|
+ //if (session.bye && session.port == rport && session.host == rhost && session.channelId == channelId && session.play == 'realplay') {
|
974
|
1025
|
//ntv 挪到回调中,TODO 这个指令发不成功!
|
975
|
1026
|
//context.nodeEvent.emit('stopPlayed', session.ssrc);
|
976
|
1027
|
|
|
1028
|
+ let key = this.genSSRC(this.id,channelId) + "p";
|
|
1029
|
+ let session= this.getSessionData(key);
|
|
1030
|
+ if(session){
|
977
|
1031
|
//add by ntv 强制更新uri地址,因为终端地址会变。
|
978
|
1032
|
session.bye.uri = 'sip:' + this.id + '@' + this.host + ':' + this.port;
|
979
|
1033
|
|
|
@@ -985,7 +1039,8 @@ class NodeSipSession {
|
985
|
1039
|
ntv remove rtp连接断开时再emit这条消息,放到了stream/session中执行
|
986
|
1040
|
*/
|
987
|
1041
|
//context.nodeEvent.emit('stopPlayed', session.ssrc);
|
988
|
|
- delete this.dialogs[key];
|
|
1042
|
+ //delete this.dialogs[key];
|
|
1043
|
+ this.delSessionData(key);
|
989
|
1044
|
this.authModule.play_status(this.id,0,(data)=>{
|
990
|
1045
|
if(data.code==0){
|
991
|
1046
|
Logger.log("视频关闭状态已上报!");
|
|
@@ -1002,8 +1057,9 @@ class NodeSipSession {
|
1002
|
1057
|
|
1003
|
1058
|
result.result = true;
|
1004
|
1059
|
result.message = 'OK';
|
|
1060
|
+
|
1005
|
1061
|
}
|
1006
|
|
- }
|
|
1062
|
+ //}
|
1007
|
1063
|
|
1008
|
1064
|
resolve(result);
|
1009
|
1065
|
});
|