-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathserver.js
188 lines (164 loc) · 5.79 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
思路说明
1. 通过post请求激活->新建视频源组[客户端连接socket 地址为 ip:port?username:password:ip:port]
2. 当有新的socket连接并且是视频组的第一次连接则开始转码
3. 当视频组最后一个用户断开则停止解码
*/
//项目依赖
const express = require('express');
const rtsp = require('rtsp-ffmpeg');
const bodyParser = require('body-parser');
//启动 socket服务
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
server.listen(3000, function() {
console.log('server is runing');
});
//解析post参数
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({extended: true})); // for parsing application/x-www-form-urlencoded
//资源目录
app.use('/src', express.static('src'));
//所有正在激活的视频组 [{token:'ip:port',count:0}]
let liveRtspStream = [];
//解析socket的登录参数判断是否合法
const getToken = (url) => {
let theRequest = {};
if (url.indexOf("?") != -1) {
let str = url.substr(url.indexOf("?") + 1);
let strs = str.split("&");
for (let i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
}
}
return theRequest;
};
//新建视频组
let createNewRtsp = (rtspUrl, socketName, loginInfo) => {
//rtspUrl = "rtsp://admin:[email protected]:554/h264/ch1/main/av_stream"
//转码配置
let stream = new rtsp.FFMpeg({input: rtspUrl, rate: 10, resolution: '48x27', quality: 50});
stream.on('start', function() {
console.log(socketName + ' 开始转码');
});
stream.on('stop', function() {
console.log(socketName + ' 结束转码');
});
//新建socket组
let ns = io.of('/' + socketName);
ns.on('connection', function(wsocket) {
//判断登录信息是否合法 不合法退出 合法发送实时的图片流
let token = getToken(wsocket.request.url).token;
let [un,
pw,
ip,
pt] = token.split(':');
const verifyParams = {
username: un,
password: pw,
ip: ip,
port: pt
};
for (let item in verifyParams) {
if (loginInfo[item] != verifyParams[item]) {
wsocket.emit('login_error', `${item}参数错误`);
return console.log(`${item}参数错误`);
}
}
console.log(socketName + ' 新增用户连接');
//初始化当前视频组的索引值
let liveRtspStreamIndex = NaN;
for ([i, item]of liveRtspStream.entries()) {
if (item.token === socketName) {
//更新当前视频组的索引值
liveRtspStreamIndex = i;
}
}
//更新视频组的用户数量
liveRtspStream[liveRtspStreamIndex].count++;
console.log(liveRtspStream);
//实时转码通过socket传输数据
let pipeStream = function(data) {
wsocket.emit('data', data);
};
stream.on('data', pipeStream);
//用户断开连接
wsocket.on('disconnect', function() {
console.log(socketName + ' 断开用户连接');
//更新视频组的连接数
liveRtspStream[liveRtspStreamIndex].count--;
console.log(liveRtspStream);
//每当用户断开连接 就注销对应的回调函数 当绑定的回调函数数量为0 rtsp-ffmpeg内部会停止转码
stream.removeListener('data', pipeStream);
});
});
}
//当有新用户连接 判断售票员是否在转码 通过socket连接触发
// io.on('connection', function(socket) {
// //获取前端传递的参数
// let params = getToken(socket.request.url).token.split('-');
// let [username,
// password,
// ip,
// port,
// channel = 1] = params;
//
// let rtspUrl = `rtsp://${username}:${password}@${ip}:${port}/h264/ch${channel}/main/av_stream`,
// socketName = ip + ':' + port;
//
// //如果当前视频组已激活 则返回
// for ([i, item]of liveRtspStream.entries()) {
// if (item.token == socketName && item.count > 0) {
// console.log(liveRtspStream);
// return console.log(socketName + ' 正在转码中');
// }
// }
//
// //转码视频流
// return createNewRtsp(rtspUrl, socketName);
// });
//激活rtsp转码 通过post请求手动激活视频源
app.post('/rtsp', function(req, res) {
let {
username,
password,
ip,
port,
channel = 1
} = req.body;
if (!username || !password || !ip || !port) {
return res.json({Status: 0, Message: '请完成填写登录信息', Data: req.body});
}
const rtspUrl = `rtsp://${username}:${password}@${ip}:${port}/h264/ch${channel}/main/av_stream`;
const socketName = ip + ':' + port;
//如果当前视频组已激活 则返回
for ([i, item]of liveRtspStream.entries()) {
if (item.token == socketName) {
console.log(socketName + ' 正在转码中');
res.json({Status: 1, Message: '此视频流已激活'});
return;
}
}
//转码视频流
liveRtspStream.push({token: socketName, count: 0});
res.json({Status: 1, Message: '激活成功'});
return createNewRtsp(rtspUrl, socketName, req.body);
});
//访问吐出页面
app.get('/rtsp', function(req, res) {
var options = {
root: __dirname,
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
};
res.sendFile('index.html', options, function(err) {
if (err) {
console.log(err);
res.status(err.status).end();
}
});
});