BiFace_Server_Config_API/node_modules/node-rtsp-stream/videoStream.js
2020-05-22 14:53:57 +07:00

134 lines
3.7 KiB
JavaScript

var Mpeg1Muxer, STREAM_MAGIC_BYTES, VideoStream, events, util, ws
ws = require('ws')
util = require('util')
events = require('events')
Mpeg1Muxer = require('./mpeg1muxer')
STREAM_MAGIC_BYTES = "jsmp" // Must be 4 bytes
VideoStream = function(options) {
this.options = options
this.name = options.name
this.streamUrl = options.streamUrl
this.width = options.width
this.height = options.height
this.wsPort = options.wsPort
this.inputStreamStarted = false
this.stream = undefined
this.startMpeg1Stream()
this.pipeStreamToSocketServer()
return this
}
util.inherits(VideoStream, events.EventEmitter)
VideoStream.prototype.stop = function() {
this.wsServer.close()
this.stream.kill()
this.inputStreamStarted = false
return this
}
VideoStream.prototype.startMpeg1Stream = function() {
var gettingInputData, gettingOutputData, inputData, outputData
this.mpeg1Muxer = new Mpeg1Muxer({
ffmpegOptions: this.options.ffmpegOptions,
url: this.streamUrl,
ffmpegPath: this.options.ffmpegPath == undefined ? "ffmpeg" : this.options.ffmpegPath
})
this.stream = this.mpeg1Muxer.stream
if (this.inputStreamStarted) {
return
}
this.mpeg1Muxer.on('mpeg1data', (data) => {
return this.emit('camdata', data)
})
gettingInputData = false
inputData = []
gettingOutputData = false
outputData = []
this.mpeg1Muxer.on('ffmpegStderr', (data) => {
var size
data = data.toString()
if (data.indexOf('Input #') !== -1) {
gettingInputData = true
}
if (data.indexOf('Output #') !== -1) {
gettingInputData = false
gettingOutputData = true
}
if (data.indexOf('frame') === 0) {
gettingOutputData = false
}
if (gettingInputData) {
inputData.push(data.toString())
size = data.match(/\d+x\d+/)
if (size != null) {
size = size[0].split('x')
if (this.width == null) {
this.width = parseInt(size[0], 10)
}
if (this.height == null) {
return this.height = parseInt(size[1], 10)
}
}
}
})
this.mpeg1Muxer.on('ffmpegStderr', function(data) {
return global.process.stderr.write(data)
})
this.mpeg1Muxer.on('exitWithError', () => {
return this.emit('exitWithError')
})
return this
}
VideoStream.prototype.pipeStreamToSocketServer = function() {
this.wsServer = new ws.Server({
port: this.wsPort
})
this.wsServer.on("connection", (socket, request) => {
return this.onSocketConnect(socket, request)
})
this.wsServer.broadcast = function(data, opts) {
var results
results = []
for (let client of this.clients) {
if (client.readyState === 1) {
results.push(client.send(data, opts))
} else {
results.push(console.log("Error: Client from remoteAddress " + client.remoteAddress + " not connected."))
}
}
return results
}
return this.on('camdata', (data) => {
return this.wsServer.broadcast(data)
})
}
VideoStream.prototype.onSocketConnect = function(socket, request) {
var streamHeader
// Send magic bytes and video size to the newly connected socket
// struct { char magic[4]; unsigned short width, height;}
streamHeader = new Buffer(8)
streamHeader.write(STREAM_MAGIC_BYTES)
streamHeader.writeUInt16BE(this.width, 4)
streamHeader.writeUInt16BE(this.height, 6)
socket.send(streamHeader, {
binary: true
})
console.log(`${this.name}: New WebSocket Connection (` + this.wsServer.clients.size + " total)")
socket.remoteAddress = request.connection.remoteAddress
return socket.on("close", (code, message) => {
return console.log(`${this.name}: Disconnected WebSocket (` + this.wsServer.clients.size + " total)")
})
}
module.exports = VideoStream