diff --git a/.gitignore b/.gitignore index 57a1574c..cde092c3 100644 --- a/.gitignore +++ b/.gitignore @@ -194,3 +194,7 @@ FakesAssemblies/ # Visual Studio 6 workspace options file *.opt + +v4l2ctl.json +release/ +release.zip \ No newline at end of file diff --git a/.settings/launch.json b/.settings/launch.json new file mode 100644 index 00000000..ea5d9abc --- /dev/null +++ b/.settings/launch.json @@ -0,0 +1,33 @@ +{ + "version": "0.1.0", + // List of configurations. Add new configurations or edit existing ones. + // ONLY "node" and "mono" are supported, change "type" to switch. + "configurations": [ + { + // Name of configuration; appears in the launch configuration drop down menu. + "name": "Launch rpos", + // Type of configuration. Possible values: "node", "mono". + "type": "node", + // Workspace relative or absolute path to the program. + "program": "rpos.js", + // Automatically stop program after launch. + "stopOnEntry": false, + // Command line arguments passed to the program. + "args": [], + // Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace. + "cwd": ".", + // Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH. + "runtimeExecutable": null, + // Environment variables passed to the program. + "env": { } + }, + { + "name": "Attach", + "type": "node", + // TCP/IP address. Default is "localhost". + "address": "localhost", + // Port to attach to. + "port": 5858 + } + ] +} diff --git a/.settings/tasks.json b/.settings/tasks.json new file mode 100644 index 00000000..0038ead0 --- /dev/null +++ b/.settings/tasks.json @@ -0,0 +1,196 @@ +// Available variables which can be used inside of strings. +// ${workspaceRoot}: the root folder of the team +// ${file}: the current opened file +// ${fileBasename}: the current opened file's basename +// ${fileDirname}: the current opened file's dirname +// ${fileExtname}: the current opened file's extension +// ${cwd}: the current working directory of the spawned process + +// A task runner that calls the Typescipt compiler (tsc) and +// Compiles a HelloWorld.ts program +{ + "version": "0.1.0", + + // The command is tsc. + "command": "tsc", + + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + + // Under windows use tsc.exe. This ensures we don't need a shell. + "windows": { + "command": "tsc.exe" + }, + + // use the standard tsc problem matcher to find compile problems + // in the output. + "problemMatcher": "$tsc" +} + +// A task runner configuration for gulp. Gulp provides a less task +// which compiles less to css. +/* +{ + "version": "0.1.0", + "command": "gulp", + "isShellCommand": true, + "tasks": [ + { + "taskName": "less", + // Make this the default build command. + "isBuildCommand": true, + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Use the standard less compilation problem matcher. + "problemMatcher": "$lessCompile" + } + ] +} +*/ + +// Uncomment the following section to use gulp in a watching mode that compiles a +// less file. The gulp task prints "[hh:mm:ss] Starting 'clean-styles'" to the console +// when existing css files get deleted and "[hh:mm:ss] Finished 'styles'" when the +// overall less compilation has finished. When the clean pattern is detect internal less +// problems are cleaned. When the finshed pattern is detected in the output less +// problems are published. +/* +{ + "version": "0.1.0", + "command": "gulp", + "isShellCommand": true, + "tasks": [ + { + "taskName": "watch-less", + // Make this the default build command. + "isBuildCommand": true, + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Task is running in watching mode. + "isWatching": true, + "problemMatcher": { + // Use the standard less compilation problem matcher as the base. + "base": "$lessCompile", + // A regular expression signalling that a watched task begins executing (usually triggered through file watching). + "watchedTaskBeginsRegExp": "^\\[\\d+:\\d+:\\d+\\] Starting 'clean-styles'\\.\\.\\.$", + // A regular expression signalling that a watched tasks ends executing. + "watchedTaskEndsRegExp": "^\\[\\d+:\\d+:\\d+\\] Finished 'styles' after \\d+" + } + } + ] +} +*/ + +// Uncomment the following section to use jake to build a workspace +// cloned from https://github.com/Microsoft/TypeScript.git +/* +{ + "version": "0.1.0", + // Task runner is jake + "command": "jake", + // Need to be executed in shell / cmd + "isShellCommand": true, + "showOutput": "silent", + "tasks": [ + { + // TS build command is local. + "taskName": "local", + // Make this the default build command. + "isBuildCommand": true, + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Use the redefined Typescript output problem matcher. + "problemMatcher": [ + "$tsc" + ] + } + ] +} +*/ + +// Uncomment the section below to use msbuild and generate problems +// for csc, cpp, tsc and vb. The configuration assumes that msbuild +// is available on the path and a solution file exists in the +// workspace folder root. +/* +{ + "version": "0.1.0", + "command": "msbuild", + "args": [ + // Ask msbuild to generate full paths for file names. + "/property:GenerateFullPaths=true" + ], + "taskSelector": "/t:", + "showOutput": "silent", + "tasks": [ + { + "taskName": "build", + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Use the standard MS compiler pattern to detect errors, warnings + // and infos in the output. + "problemMatcher": "$msCompile" + } + ] +} +*/ + +// Uncomment the following section to use msbuild which compiles Typescript +// and less files. +/* +{ + "version": "0.1.0", + "command": "msbuild", + "args": [ + // Ask msbuild to generate full paths for file names. + "/property:GenerateFullPaths=true" + ], + "taskSelector": "/t:", + "showOutput": "silent", + "tasks": [ + { + "taskName": "build", + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Use the standard MS compiler pattern to detect errors, warnings + // and infos in the output. + "problemMatcher": [ + "$msCompile", + "$lessCompile" + ] + } + ] +} +*/ +// A task runner example that defines a problemMatcher inline instead of using +// a predfined one. +/* +{ + "version": "0.1.0", + "command": "tsc.exe", + "args": ["HelloWorld.ts"], + "showOutput": "silent", + "problemMatcher": { + // The problem is owned by the typescript language service. Ensure that the problems + // are merged with problems produced by Visual Studio's language service. + "owner": "typescript", + // The file name for reported problems is relative to the current working directory. + "fileLocation": ["relative", "${cwd}"], + // The actual pattern to match problems in the output. + "pattern": { + // The regular expression. Matches HelloWorld.ts(2,10): error TS2339: Property 'logg' does not exist on type 'Console'. + "regexp": "^([^\\s].*)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(error|warning|info)\\s+(TS\\d+)\\s*:\\s*(.*)$", + // The match group that denotes the file containing the problem. + "file": 1, + // The match group that denotes the problem location. + "location": 2, + // The match group that denotes the problem's severity. Can be omitted. + "severity": 3, + // The match group that denotes the problem code. Can be omitted. + "code": 4, + // The match group that denotes the problem's message. + "message": 5 + } + } +} +*/ \ No newline at end of file diff --git a/README.md b/README.md index d965d701..b7f8eef1 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ This version uses a patched version of the "node-soap" v0.80 library (https://gi - Streams H264 video over rtsp - Camera control (resolution and framerate) through Onvif +- Set other camera options through a web interface. #How to: @@ -34,32 +35,19 @@ Install nodejs on your pi (http://weworkweplay.com/play/raspberry-pi-nodejs/): wget http://node-arm.herokuapp.com/node_latest_armhf.deb sudo dpkg -i node_latest_armhf.deb -Download rpos master from github to your pi +Download rpos release from github to your pi - wget https://github.com/BreeeZe/rpos/archive/master.zip - unzip master.zip - cd rpos-master - npm install - sudo chmod -R a+rwx ./bin/rtspServer - -Be sure to configure the ipaddress, service port, rtsp stream name and rtsp port in "config.js" ("nano config.js") -For now you can set V-flip or H-flip in the file "./lib/camera.js" - - Camera.prototype.settings = { - hf : false, //horizontal flip - vf : true, //vertical flip - drc : 2, //0=OFF, 1=LOW, 2=MEDIUM, 3=HIGH - gop : 2, //keyframe every X sec. - forceGop : true, - resolution : { Width : 1280, Height: 720 }, - framerate : 30, - bitrate : 7500, - profile : "Baseline", - quality : null, - exposure : "auto" - }; - -Then you start rpos by running "sudo node server.js" + wget https://github.com/BreeeZe/rpos/[release] + unzip [release].zip + cd rpos-[release] + +Optionaly set the service port or other options in rposConfig.json + +Then you start rpos by running "sudo node rpos.js" + +#Camera settings +You can set camera settings by browsing to : http://CameraIP:Port/ +These settings are then saved in a file called v4l2ctl.json and are persisted on rpos restart. #Known Issues - 1920x1080 can cause hangs and crashes. diff --git a/RPOS.njsproj b/RPOS.njsproj index a4ea6c84..feb1f39d 100644 --- a/RPOS.njsproj +++ b/RPOS.njsproj @@ -46,6 +46,7 @@ + @@ -67,6 +68,7 @@ + diff --git a/bin/rtspServer b/bin/rtspServer old mode 100644 new mode 100755 diff --git a/config.js b/config.js deleted file mode 100644 index fee9d06d..00000000 --- a/config.js +++ /dev/null @@ -1,16 +0,0 @@ -var exports = module.exports = { - NetworkAdapter : "eth0", //if not found, IpAddress will be used - IpAddress : "192.168.1.15", - ServicePort : 81, - RTSPPort : 8554, - RTSPName : "h264", - DeviceInformation : { - Manufacturer : "Raspberry Pi", - Model : "2 B", - FirmwareVersion : "", - SerialNumber : "", - HardwareId : "" - }, - logLevel : 4, // 0 : none, 1 : Error, 2 : Warn, 3 : Info, 4 : Debug - logSoapCalls : false -}; \ No newline at end of file diff --git a/lib/SoapService.js b/lib/SoapService.js new file mode 100644 index 00000000..7c2d66d4 --- /dev/null +++ b/lib/SoapService.js @@ -0,0 +1,64 @@ +/// +/// +var utils_1 = require('./utils'); +var soap = require('soap'); +var utils = utils_1.Utils.utils; +var SoapService = (function () { + function SoapService(config, server) { + this.webserver = server; + this.config = config; + this.serviceInstance = null; + this.startedCallbacks = []; + this.isStarted = false; + this.serviceOptions = { + path: '', + services: null, + xml: null, + wsdlPath: '', + onReady: function () { } + }; + } + SoapService.prototype.starting = function () { }; + ; + SoapService.prototype.started = function () { }; + ; + SoapService.prototype.start = function () { + var _this = this; + this.starting(); + utils.log.info("Binding %s to http://%s:%s%s", this.constructor.name, utils.getIpAddress(), this.config.ServicePort, this.serviceOptions.path); + this.webserver.listen(this.config.ServicePort); + var onReady = this.serviceOptions.onReady; + this.serviceOptions.onReady = function () { + _this._started(); + onReady(); + }; + this.serviceInstance = soap.listen(this.webserver, this.serviceOptions); + this.serviceInstance.on("request", function (request, methodName) { + utils.log.debug('%s received request %s', _this.constructor.name, methodName); + }); + this.serviceInstance.log = function (type, data) { + if (_this.config.logSoapCalls) + utils.log.debug('%s - Calltype : %s, Data : %s', _this.constructor.name, type, data); + }; + }; + SoapService.prototype.onStarted = function (callback) { + if (this.isStarted) + callback(); + else + this.startedCallbacks.push(callback); + }; + ; + SoapService.prototype._started = function () { + this.isStarted = true; + for (var _i = 0, _a = this.startedCallbacks; _i < _a.length; _i++) { + var callback = _a[_i]; + callback(); + } + this.startedCallbacks = []; + this.started(); + }; + ; + return SoapService; +})(); +module.exports = SoapService; +//# sourceMappingURL=SoapService.js.map \ No newline at end of file diff --git a/lib/SoapService.js.map b/lib/SoapService.js.map new file mode 100644 index 00000000..bca6f6d4 --- /dev/null +++ b/lib/SoapService.js.map @@ -0,0 +1 @@ +{"version":3,"file":"SoapService.js","sourceRoot":"","sources":["SoapService.ts"],"names":["SoapService","SoapService.constructor","SoapService.starting","SoapService.started","SoapService.start","SoapService.onStarted","SoapService._started"],"mappings":"AAAA,0CAA0C;AAC1C,gDAAgD;AAGhD,sBAAuB,SAAS,CAAC,CAAA;AAEjC,IAAI,IAAI,GAAQ,OAAO,CAAC,MAAM,CAAC,CAAC;AAChC,IAAI,KAAK,GAAG,aAAK,CAAC,KAAK,CAAC;AAExB;IAQEA,qBAAYA,MAAkBA,EAAEA,MAAcA;QAC5CC,IAAIA,CAACA,SAASA,GAAGA,MAAMA,CAACA;QACxBA,IAAIA,CAACA,MAAMA,GAAGA,MAAMA,CAACA;QACrBA,IAAIA,CAACA,eAAeA,GAAGA,IAAIA,CAACA;QAC5BA,IAAIA,CAACA,gBAAgBA,GAAGA,EAAEA,CAACA;QAC3BA,IAAIA,CAACA,SAASA,GAAGA,KAAKA,CAACA;QAEvBA,IAAIA,CAACA,cAAcA,GAAGA;YACpBA,IAAIA,EAAEA,EAAEA;YACRA,QAAQA,EAAEA,IAAIA;YACdA,GAAGA,EAAEA,IAAIA;YACTA,QAAQA,EAAEA,EAAEA;YACZA,OAAOA,EAAEA,cAAQA,CAACA;SACnBA,CAACA;IAEJA,CAACA;IAEDD,8BAAQA,GAARA,cAAaE,CAACA;;IAEdF,6BAAOA,GAAPA,cAAYG,CAACA;;IAEbH,2BAAKA,GAALA;QAAAI,iBAqBCA;QApBCA,IAAIA,CAACA,QAAQA,EAAEA,CAACA;QAEhBA,KAAKA,CAACA,GAAGA,CAACA,IAAIA,CAACA,8BAA8BA,EAAoBA,IAAIA,CAACA,WAAYA,CAACA,IAAIA,EAAEA,KAAKA,CAACA,YAAYA,EAAEA,EAAEA,IAAIA,CAACA,MAAMA,CAACA,WAAWA,EAAEA,IAAIA,CAACA,cAAcA,CAACA,IAAIA,CAACA,CAACA;QAClKA,IAAIA,CAACA,SAASA,CAACA,MAAMA,CAACA,IAAIA,CAACA,MAAMA,CAACA,WAAWA,CAACA,CAACA;QAC/CA,IAAIA,OAAOA,GAAGA,IAAIA,CAACA,cAAcA,CAACA,OAAOA,CAACA;QAC1CA,IAAIA,CAACA,cAAcA,CAACA,OAAOA,GAAGA;YAC5BA,KAAIA,CAACA,QAAQA,EAAEA,CAACA;YAChBA,OAAOA,EAAEA,CAACA;QACZA,CAACA,CAACA;QACFA,IAAIA,CAACA,eAAeA,GAAGA,IAAIA,CAACA,MAAMA,CAACA,IAAIA,CAACA,SAASA,EAAEA,IAAIA,CAACA,cAAcA,CAACA,CAACA;QAGxEA,IAAIA,CAACA,eAAeA,CAACA,EAAEA,CAACA,SAASA,EAAEA,UAACA,OAAYA,EAAEA,UAAkBA;YAClEA,KAAKA,CAACA,GAAGA,CAACA,KAAKA,CAACA,wBAAwBA,EAAoBA,KAAIA,CAACA,WAAYA,CAACA,IAAIA,EAAEA,UAAUA,CAACA,CAACA;QAClGA,CAACA,CAACA,CAACA;QAEHA,IAAIA,CAACA,eAAeA,CAACA,GAAGA,GAAGA,UAACA,IAAYA,EAAEA,IAASA;YACjDA,EAAEA,CAACA,CAACA,KAAIA,CAACA,MAAMA,CAACA,YAAYA,CAACA;gBAC3BA,KAAKA,CAACA,GAAGA,CAACA,KAAKA,CAACA,+BAA+BA,EAAoBA,KAAIA,CAACA,WAAYA,CAACA,IAAIA,EAAEA,IAAIA,EAAEA,IAAIA,CAACA,CAACA;QAC3GA,CAACA,CAACA;IACJA,CAACA;IAEDJ,+BAASA,GAATA,UAAUA,QAAkBA;QAC1BK,EAAEA,CAACA,CAACA,IAAIA,CAACA,SAASA,CAACA;YACjBA,QAAQA,EAAEA,CAACA;QACbA,IAAIA;YACFA,IAAIA,CAACA,gBAAgBA,CAACA,IAAIA,CAACA,QAAQA,CAACA,CAACA;IACzCA,CAACA;;IAEDL,8BAAQA,GAARA;QACEM,IAAIA,CAACA,SAASA,GAAGA,IAAIA,CAACA;QACtBA,GAAGA,CAACA,CAAiBA,UAAqBA,EAArBA,KAAAA,IAAIA,CAACA,gBAAgBA,EAArCA,cAAYA,EAAZA,IAAqCA,CAACA;YAAtCA,IAAIA,QAAQA,SAAAA;YACfA,QAAQA,EAAEA,CAACA;SAAAA;QACbA,IAAIA,CAACA,gBAAgBA,GAAGA,EAAEA,CAACA;QAC3BA,IAAIA,CAACA,OAAOA,EAAEA,CAACA;IACjBA,CAACA;;IACHN,kBAACA;AAADA,CAACA,AAlED,IAkEC;AACoB,AAArB,iBAAS,WAAW,CAAC"} \ No newline at end of file diff --git a/lib/SoapService.ts b/lib/SoapService.ts new file mode 100644 index 00000000..97dac851 --- /dev/null +++ b/lib/SoapService.ts @@ -0,0 +1,77 @@ +/// +/// + +import fs = require("fs"); +import { Utils } from './utils'; +import { Server } from 'http'; +var soap = require('soap'); +var utils = Utils.utils; + +class SoapService { + webserver: Server; + config: rposConfig; + serviceInstance: any; + serviceOptions: SoapServiceOptions; + startedCallbacks: (() => void)[]; + isStarted: boolean; + + constructor(config: rposConfig, server: Server) { + this.webserver = server; + this.config = config; + this.serviceInstance = null; + this.startedCallbacks = []; + this.isStarted = false; + + this.serviceOptions = { + path: '', + services: null, + xml: null, + wsdlPath: '', + onReady: () => { } + }; + + } + + starting() { }; + + started() { }; + + start() { + this.starting(); + + utils.log.info("Binding %s to http://%s:%s%s", (this.constructor).name, utils.getIpAddress(), this.config.ServicePort, this.serviceOptions.path); + this.webserver.listen(this.config.ServicePort); + var onReady = this.serviceOptions.onReady; + this.serviceOptions.onReady = () => { + this._started(); + onReady(); + }; + this.serviceInstance = soap.listen(this.webserver, this.serviceOptions); + + + this.serviceInstance.on("request", (request: any, methodName: string) => { + utils.log.debug('%s received request %s', (this.constructor).name, methodName); + }); + + this.serviceInstance.log = (type: string, data: any) => { + if (this.config.logSoapCalls) + utils.log.debug('%s - Calltype : %s, Data : %s', (this.constructor).name, type, data); + }; + } + + onStarted(callback: () => {}) { + if (this.isStarted) + callback(); + else + this.startedCallbacks.push(callback); + }; + + _started() { + this.isStarted = true; + for (var callback of this.startedCallbacks) + callback(); + this.startedCallbacks = []; + this.started(); + }; +} +export = SoapService; \ No newline at end of file diff --git a/lib/camera.js b/lib/camera.js index 17f3d29c..26fb93a1 100644 --- a/lib/camera.js +++ b/lib/camera.js @@ -1,126 +1,171 @@ -var spawn = require('child_process').spawn; -var execSync = require('child_process').execSync; -var utils = require('./utils'); - -function Camera(config) { - this.config = config; - this.rtspServer = null; - this.load(); - $this = this; - utils.cleanup(function () { - if (!utils.isWin()) { - utils.log.debug(execSync("sudo modprobe -r bcm2835-v4l2")); - $this.stopRtsp(); +/// +/// +var utils_1 = require('./utils'); +var fs = require('fs'); +var parser = require('body-parser'); +var v4l2ctl_1 = require('./v4l2ctl'); +var utils = utils_1.Utils.utils; +var Camera = (function () { + function Camera(config, webserver) { + var _this = this; + this.options = { + resolutions: [ + { Width: 640, Height: 480 }, + { Width: 800, Height: 600 }, + { Width: 1024, Height: 768 }, + { Width: 1280, Height: 1024 }, + { Width: 1280, Height: 720 }, + { Width: 1920, Height: 1080 } + ], + framerates: [2, 5, 10, 15, 25, 30], + bitrates: [ + 250, + 500, + 1000, + 2500, + 5000, + 7500, + 10000, + 12500, + 15000, + 17500 + ] + }; + this.settings = { + forceGop: true, + resolution: { Width: 1280, Height: 720 }, + framerate: 25, + }; + this.config = config; + this.rtspServer = null; + this.loadDriver(); + this.webserver = webserver; + this.setupWebserver(); + this.setupCamera(); + v4l2ctl_1.v4l2ctl.ReadControls(); + utils.cleanup(function () { + _this.stopRtsp(); + var stop = new Date().getTime() + 2000; + while (new Date().getTime() < stop) { + ; + } + utils.execSync("sudo modprobe -r bcm2835-v4l2"); + }); + fs.chmodSync("./bin/rtspServer", "0755"); } - }); -}; - -Camera.prototype.load = function () { - if (!utils.isWin()) { - utils.log.debug(execSync("sudo modprobe bcm2835-v4l2")); - } else { - utils.log.debug("Would load driver"); - } -} - -Camera.prototype.options = { - resolutions : [ - { Width : 640, Height : 480 }, - { Width : 800, Height : 600 }, - { Width : 1024, Height : 768 }, - { Width : 1280, Height : 1024 }, - { Width : 1280, Height : 720 }, - { Width : 1920, Height : 1080 } - ], - framerates : [2, 5, 10, 15, 25, 30], - bitrates : [ - 250, - 500, - 1000, - 2500, - 5000, - 7500, - 10000, - 12500, - 15000, - 17500 - ], - quality : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - profiles : ["Baseline", "Main", "High"] -}; - -Camera.prototype.settings = { - hf : false, //horizontal flip - vf : true, //vertical flip - drc : 2, //0=OFF, 1=LOW, 2=MEDIUM, 3=HIGH - gop : 2, //keyframe every X sec. - forceGop : true, - resolution : { Width : 1280, Height: 720 }, - framerate : 30, - bitrate : 7500, - profile : "Baseline", - quality : null, - exposure : "auto" -}; - -Camera.prototype.setSettings = function (newsettings) { - if (!utils.isWin()) { - - utils.log.debug(execSync("sudo v4l2-ctl --set-fmt-video=width=" + newsettings.resolution.Width + ",height=" + newsettings.resolution.Height + ",pixelformat=4")); - utils.log.debug(execSync("sudo v4l2-ctl --set-ctrl " + - "video_bitrate=" + (newsettings.bitrate * 1000) + - ",video_bitrate_mode=" + (newsettings.quality > 0 ? 0 : 1) + - ",h264_i_frame_period=" + (this.settings.forceGop ? this.settings.gop : newsettings.gop) + - ",horizontal_flip=" + (this.settings.hf ? 1 : 0) + - ",vertical_flip=" + (this.settings.vf ? 1 : 0) - )); - utils.log.debug(execSync("sudo v4l2-ctl --set-parm=" + newsettings.frameRate)); - } else { - for (var s in newsettings) - utils.log.debug("Would set %s to %s", s, newsettings[s]); - } - -//settings.frameRate; -//settings.profile; -//settings.quality; -//settings.resolution; -}; - -Camera.prototype.startRtsp = function (input) { - if (this.rtspServer) { - utils.log.warn("Cannot start rtspServer, already running"); - return; - } - utils.log.info("Starting Live555 rtsp server"); - - this.rtspServer = spawn("./bin/rtspServer", [ - input, - "1024000", - this.config.RTSPPort, - 0, - this.config.RTSPName]); - - this.rtspServer.stdout.on('data', function (data) { - utils.log.debug("rtspServer: %s", data); - }); - this.rtspServer.stderr.on('data', function (data) { - utils.log.error("rtspServer: %s", data); - }); - this.rtspServer.on('error', function (err) { - utils.log.error("rtspServer error: %s", err); - }); - this.rtspServer.on('exit', function (code, signal) { - if (code) - utils.log.error("rtspServer exited with code: %s", code); - }); -} - -Camera.prototype.stopRtsp = function () { - if (this.rtspServer) { - utils.log.info("Stopping Live555 rtsp server"); - this.rtspServer.kill(); - this.rtspServer = null; - } -} - -module.exports = Camera; \ No newline at end of file + Camera.prototype.setupWebserver = function () { + var _this = this; + utils.log.info("Starting camera settings webserver on http://%s:%s/", utils.getIpAddress(), this.config.ServicePort); + this.webserver.use(parser.urlencoded({ extended: true })); + this.webserver.engine('ntl', function (filePath, options, callback) { + _this.getSettingsPage(filePath, callback); + }); + this.webserver.set('views', './views'); + this.webserver.set('view engine', 'ntl'); + this.webserver.get('/', function (req, res) { + res.render('camera', {}); + }); + this.webserver.post('/', function (req, res) { + for (var par in req.body) { + var g = par.split('.')[0]; + var p = par.split('.')[1]; + if (p && g) { + var prop = v4l2ctl_1.v4l2ctl.Controls[g][p]; + var val = req.body[par]; + if (val instanceof Array) + val = val.pop(); + prop.value = val; + if (prop.isDirty) { + utils.log.debug("Property %s changed to %s", par, prop.value); + } + } + } + v4l2ctl_1.v4l2ctl.ApplyControls(); + res.render('camera', {}); + }); + }; + Camera.prototype.getSettingsPage = function (filePath, callback) { + v4l2ctl_1.v4l2ctl.ReadControls(); + fs.readFile(filePath, function (err, content) { + if (err) + return callback(new Error(err.message)); + var parseControls = function (html, displayname, propname, controls) { + html += "" + displayname + ""; + for (var uc in controls) { + var p = controls[uc]; + if (p.hasSet) { + var set = p.getLookupSet(); + html += "" + uc + ""; + for (var _i = 0; _i < set.length; _i++) { + var o = set[_i]; + html += "" + o.desc + ""; + } + html += ''; + } + else if (p.type == "Boolean") { + html += "" + uc + "\n \n "; + } + else { + html += "" + uc + "\n "; + if (p.hasRange) + html += "( min: " + p.getRange().min + " max: " + p.getRange().max + " )"; + html += ""; + } + } + return html; + }; + var html = parseControls("", 'User Controls', 'UserControls', v4l2ctl_1.v4l2ctl.Controls.UserControls); + html = parseControls(html, 'Codec Controls', 'CodecControls', v4l2ctl_1.v4l2ctl.Controls.CodecControls); + html = parseControls(html, 'Camera Controls', 'CameraControls', v4l2ctl_1.v4l2ctl.Controls.CameraControls); + html = parseControls(html, 'JPG Compression Controls', 'JPEGCompressionControls', v4l2ctl_1.v4l2ctl.Controls.JPEGCompressionControls); + var rendered = content.toString().replace('{{row}}', html); + return callback(null, rendered); + }); + }; + Camera.prototype.loadDriver = function () { + utils.execSync("sudo modprobe bcm2835-v4l2"); + }; + Camera.prototype.setupCamera = function () { + v4l2ctl_1.v4l2ctl.SetPixelFormat(v4l2ctl_1.v4l2ctl.Pixelformat.H264); + v4l2ctl_1.v4l2ctl.SetResolution(this.settings.resolution); + v4l2ctl_1.v4l2ctl.SetFrameRate(this.settings.framerate); + v4l2ctl_1.v4l2ctl.SetPriority(v4l2ctl_1.v4l2ctl.ProcessPriority.record); + v4l2ctl_1.v4l2ctl.ReadFromFile(); + v4l2ctl_1.v4l2ctl.ApplyControls(); + }; + Camera.prototype.setSettings = function (newsettings) { + v4l2ctl_1.v4l2ctl.SetResolution(newsettings.resolution); + v4l2ctl_1.v4l2ctl.SetFrameRate(newsettings.framerate); + v4l2ctl_1.v4l2ctl.Controls.CodecControls.video_bitrate.value = newsettings.bitrate * 1000; + v4l2ctl_1.v4l2ctl.Controls.CodecControls.video_bitrate_mode.value = newsettings.quality > 0 ? 0 : 1; + v4l2ctl_1.v4l2ctl.Controls.CodecControls.h264_i_frame_period.value = this.settings.forceGop ? v4l2ctl_1.v4l2ctl.Controls.CodecControls.h264_i_frame_period.value : newsettings.gop; + v4l2ctl_1.v4l2ctl.ApplyControls(); + }; + Camera.prototype.startRtsp = function () { + if (this.rtspServer) { + utils.log.warn("Cannot start rtspServer, already running"); + return; + } + utils.log.info("Starting Live555 rtsp server"); + this.rtspServer = utils.spawn("./bin/rtspServer", ["/dev/video0", "2088960", this.config.RTSPPort.toString(), "0", this.config.RTSPName.toString()]); + this.rtspServer.stdout.on('data', function (data) { return utils.log.debug("rtspServer: %s", data); }); + this.rtspServer.stderr.on('data', function (data) { return utils.log.error("rtspServer: %s", data); }); + this.rtspServer.on('error', function (err) { return utils.log.error("rtspServer error: %s", err); }); + this.rtspServer.on('exit', function (code, signal) { + if (code) + utils.log.error("rtspServer exited with code: %s", code); + else + utils.log.debug("rtspServer exited"); + }); + }; + Camera.prototype.stopRtsp = function () { + if (this.rtspServer) { + utils.log.info("Stopping Live555 rtsp server"); + this.rtspServer.kill(); + this.rtspServer = null; + } + }; + return Camera; +})(); +module.exports = Camera; +//# sourceMappingURL=camera.js.map \ No newline at end of file diff --git a/lib/camera.js.map b/lib/camera.js.map new file mode 100644 index 00000000..463143a4 --- /dev/null +++ b/lib/camera.js.map @@ -0,0 +1 @@ +{"version":3,"file":"camera.js","sourceRoot":"","sources":["camera.ts"],"names":["Camera","Camera.constructor","Camera.setupWebserver","Camera.getSettingsPage","Camera.loadDriver","Camera.setupCamera","Camera.setSettings","Camera.startRtsp","Camera.stopRtsp"],"mappings":"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"} \ No newline at end of file diff --git a/lib/camera.ts b/lib/camera.ts new file mode 100644 index 00000000..01628000 --- /dev/null +++ b/lib/camera.ts @@ -0,0 +1,195 @@ +/// +/// +import { Utils } from './utils'; +import fs = require('fs'); +import parser = require('body-parser'); +import { ChildProcess } from 'child_process'; +import { v4l2ctl } from './v4l2ctl'; + +var utils = Utils.utils; + +class Camera { + options = { + resolutions: [ + { Width: 640, Height: 480 }, + { Width: 800, Height: 600 }, + { Width: 1024, Height: 768 }, + { Width: 1280, Height: 1024 }, + { Width: 1280, Height: 720 }, + { Width: 1920, Height: 1080 } + ], + framerates: [2, 5, 10, 15, 25, 30], + bitrates: [ + 250, + 500, + 1000, + 2500, + 5000, + 7500, + 10000, + 12500, + 15000, + 17500 + ] + }; + + settings: CameraSettingsBase = { + forceGop: true, + resolution: { Width: 1280, Height: 720 }, + framerate: 25, + }; + + config: rposConfig; + rtspServer: ChildProcess; + webserver: any; + + constructor(config: rposConfig, webserver: any) { + this.config = config; + this.rtspServer = null; + this.loadDriver(); + this.webserver = webserver; + + this.setupWebserver(); + this.setupCamera(); + + v4l2ctl.ReadControls(); + + utils.cleanup(() => { + this.stopRtsp(); + var stop = new Date().getTime() + 2000; + while (new Date().getTime() < stop) { + //wait for rtsp server to stop + ; + } + utils.execSync("sudo modprobe -r bcm2835-v4l2"); + }); + + fs.chmodSync("./bin/rtspServer", "0755"); + } + setupWebserver() { + utils.log.info("Starting camera settings webserver on http://%s:%s/", utils.getIpAddress(), this.config.ServicePort); + this.webserver.use(parser.urlencoded({ extended: true })); + this.webserver.engine('ntl', (filePath, options, callback) => { + this.getSettingsPage(filePath, callback); + }); + this.webserver.set('views', './views'); // specify the views directory + this.webserver.set('view engine', 'ntl'); // register the template engine + this.webserver.get('/', (req, res) => { + res.render('camera', {}); + }); + this.webserver.post('/', (req, res) => { + for (var par in req.body) { + var g = par.split('.')[0]; + var p = par.split('.')[1]; + if (p && g) { + var prop = >v4l2ctl.Controls[g][p]; + var val = req.body[par]; + if (val instanceof Array) + val = (val).pop(); + prop.value = val; + if (prop.isDirty) { + utils.log.debug("Property %s changed to %s", par, prop.value); + } + } + } + v4l2ctl.ApplyControls(); + res.render('camera', {}); + }); + } + + getSettingsPage(filePath, callback) { + v4l2ctl.ReadControls(); + fs.readFile(filePath, (err, content) => { + if (err) + return callback(new Error(err.message)); + + var parseControls = (html: string, displayname: string, propname: string, controls: Object) => { + html += `${displayname}`; + for (var uc in controls) { + var p = >controls[uc]; + if (p.hasSet) { + var set = p.getLookupSet(); + html += `${uc}`; + for (let o of set) { + html += `${o.desc}`; + } + html += ''; + + } else if (p.type == "Boolean") { + html += `${uc} + + `; + } else { + html += `${uc} + ` + if (p.hasRange) + html += `( min: ${p.getRange().min} max: ${p.getRange().max} )` + html += ``; + } + } + return html; + } + + var html = parseControls("", 'User Controls', 'UserControls', v4l2ctl.Controls.UserControls); + html = parseControls(html, 'Codec Controls', 'CodecControls', v4l2ctl.Controls.CodecControls); + html = parseControls(html, 'Camera Controls', 'CameraControls', v4l2ctl.Controls.CameraControls); + html = parseControls(html, 'JPG Compression Controls', 'JPEGCompressionControls', v4l2ctl.Controls.JPEGCompressionControls); + + var rendered = content.toString().replace('{{row}}', html); + return callback(null, rendered); + }) + } + + loadDriver() { + utils.execSync("sudo modprobe bcm2835-v4l2"); + } + + setupCamera() { + v4l2ctl.SetPixelFormat(v4l2ctl.Pixelformat.H264) + v4l2ctl.SetResolution(this.settings.resolution); + v4l2ctl.SetFrameRate(this.settings.framerate); + v4l2ctl.SetPriority(v4l2ctl.ProcessPriority.record); + v4l2ctl.ReadFromFile(); + v4l2ctl.ApplyControls(); + } + + setSettings(newsettings: CameraSettingsParameter) { + v4l2ctl.SetResolution(newsettings.resolution); + v4l2ctl.SetFrameRate(newsettings.framerate); + + v4l2ctl.Controls.CodecControls.video_bitrate.value = newsettings.bitrate * 1000; + v4l2ctl.Controls.CodecControls.video_bitrate_mode.value = newsettings.quality > 0 ? 0 : 1; + v4l2ctl.Controls.CodecControls.h264_i_frame_period.value = this.settings.forceGop ? v4l2ctl.Controls.CodecControls.h264_i_frame_period.value : newsettings.gop; + v4l2ctl.ApplyControls(); + } + + startRtsp() { + if (this.rtspServer) { + utils.log.warn("Cannot start rtspServer, already running"); + return; + } + utils.log.info("Starting Live555 rtsp server"); + + this.rtspServer = utils.spawn("./bin/rtspServer", ["/dev/video0", "2088960", this.config.RTSPPort.toString(), "0", this.config.RTSPName.toString()]); + + this.rtspServer.stdout.on('data', data => utils.log.debug("rtspServer: %s", data)); + this.rtspServer.stderr.on('data', data => utils.log.error("rtspServer: %s", data)); + this.rtspServer.on('error', err=> utils.log.error("rtspServer error: %s", err)); + this.rtspServer.on('exit', (code, signal) => { + if (code) + utils.log.error("rtspServer exited with code: %s", code); + else + utils.log.debug("rtspServer exited") + }); + } + + stopRtsp() { + if (this.rtspServer) { + utils.log.info("Stopping Live555 rtsp server"); + this.rtspServer.kill(); + this.rtspServer = null; + } + } +} + +export = Camera; \ No newline at end of file diff --git a/lib/extension.js b/lib/extension.js new file mode 100644 index 00000000..313326f4 --- /dev/null +++ b/lib/extension.js @@ -0,0 +1,10 @@ +/// +Date.prototype.stdTimezoneOffset = function () { + var jan = new Date(this.getFullYear(), 0, 1); + var jul = new Date(this.getFullYear(), 6, 1); + return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); +}; +Date.prototype.dst = function () { + return this.getTimezoneOffset() < this.stdTimezoneOffset(); +}; +//# sourceMappingURL=extension.js.map \ No newline at end of file diff --git a/lib/extension.js.map b/lib/extension.js.map new file mode 100644 index 00000000..ce6a0224 --- /dev/null +++ b/lib/extension.js.map @@ -0,0 +1 @@ +{"version":3,"file":"extension.js","sourceRoot":"","sources":["extension.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAEhD,IAAI,CAAC,SAAS,CAAC,iBAAiB,GAAG;IAClC,IAAI,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7C,IAAI,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,EAAE,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACnE,CAAC,CAAC;AAEF,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG;IACpB,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;AAC5D,CAAC,CAAC"} \ No newline at end of file diff --git a/lib/extension.ts b/lib/extension.ts new file mode 100644 index 00000000..d957caf5 --- /dev/null +++ b/lib/extension.ts @@ -0,0 +1,11 @@ +/// + +Date.prototype.stdTimezoneOffset = function() { + var jan = new Date(this.getFullYear(), 0, 1); + var jul = new Date(this.getFullYear(), 6, 1); + return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); +}; + +Date.prototype.dst = function() { + return this.getTimezoneOffset() < this.stdTimezoneOffset(); +}; \ No newline at end of file diff --git a/lib/service.js b/lib/service.js deleted file mode 100644 index 4beb3b26..00000000 --- a/lib/service.js +++ /dev/null @@ -1,67 +0,0 @@ -var fs = require("fs"); -var soap = require('soap'); -var utils = require('./utils'); - -function Service(config, server) { - var $this = this; - this.webserver = server; - this.config = config; - this.serviceInstance = null; - this.serviceOptions = { - path : '', - services : null, - xml : null, - wsdlPath : '', - onReady : function () { - } - }; - this.startedCallbacks = []; - this.isStarted = false; -} - -Service.prototype.starting = function () { }; - -Service.prototype.started = function () { }; - -Service.prototype.start = function () { - var $this = this; - - this.starting(); - - utils.log.info("Starting webserver on port: %s", this.config.ServicePort); - this.webserver.listen(this.config.ServicePort); - - utils.log.info("Binding %s to %s", $this.constructor.name, this.serviceOptions.path); - var onReady = this.serviceOptions.onReady; - this.serviceOptions.onReady = function () { - $this._started(); - onReady(); - }; - this.service = soap.listen(this.webserver, this.serviceOptions); - - - this.service.on("request", function (request, methodName) { - utils.log.debug('%s received request %s', $this.constructor.name, methodName); - }); - - this.service.log = function (type, data) { - if ($this.config.logSoapCalls) - utils.log.debug('%s - Calltype : %s, Data : %s', $this.constructor.name, type, data); - }; -} - -Service.prototype.onStarted = function (callback) { - if (this.isStarted) - callback(); - else - this.startedCallbacks.push(callback); -}; - -Service.prototype._started = function () { - this.isStarted = true; - for (var c = 0; c < this.startedCallbacks.length ; c++) - this.startedCallbacks[c](); - this.startedCallbacks = []; - this.started(); -}; -module.exports = Service; \ No newline at end of file diff --git a/lib/utils.js b/lib/utils.js index 6def065e..1614d97b 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,95 +1,176 @@ -var os = require('os'); -var clc = require('cli-color'); - -Date.prototype.stdTimezoneOffset = function () { - var jan = new Date(this.getFullYear(), 0, 1); - var jul = new Date(this.getFullYear(), 6, 1); - return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); -}; - -Date.prototype.dst = function () { - return this.getTimezoneOffset() < this.stdTimezoneOffset(); +var __extends = this.__extends || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); }; - -var utils = { - - getSerial : function () { - // Extract serial from cpuinfo file - cpuserial = "0000000000000000" - try { - var f = require('child_process').execSync('sudo cat /proc/cpuinfo').toString(); - cpuserial = f.match(/Serial[\t]*: ([0-9a-f]{16})/)[1]; - } catch (ex) { - this.log.error("Failed to read serial : %s", ex.message); - cpuserial = "ERROR000000000"; - } - return cpuserial - }, - - getIpAddress : function (interfaceName, type) { - var address = null; - type = type || "IPv4"; - var ni = os.networkInterfaces()[interfaceName] || []; - for (var i = 0; i < ni.length ; i++) { - var nif = ni[i]; - if (nif.family == type) - address = nif.address; - } - return address; - }, - isWin : function () { - return /^win/.test(process.platform); - }, - log : { - level : 0, - error : function () { - if (this.level > 0) { - arguments[0] = clc.red(arguments[0]); - console.log.apply(this, arguments); - } - }, - warn: function () { - if (this.level > 1) { - arguments[0] = clc.yellow(arguments[0]); - console.log.apply(this, arguments); - } - }, - info : function () { - if (this.level > 2) - console.log.apply(this, arguments); - }, - debug : function () { - if (this.level > 3) { - arguments[0] = clc.green(arguments[0]); - console.log.apply(this, arguments); - } - }, - }, - cleanup : function(callback) { - - // attach user callback to the process event emitter - // if no callback, it will still exit gracefully on Ctrl-C - callback = callback || function () { }; - process.on('cleanup', callback); - - // do app specific cleaning before exiting - process.on('exit', function () { - process.emit('cleanup'); - }); - - // catch ctrl+c event and exit normally - process.on('SIGINT', function () { - console.log('Ctrl-C...'); - process.exit(2); - }); - - //catch uncaught exceptions, trace, then exit normally - process.on('uncaughtException', function (e) { - console.log('Uncaught Exception...'); - console.log(e.stack); - process.exit(99); - }); - } -}; - -module.exports = utils; \ No newline at end of file +/// +var os_1 = require('os'); +var child_process_1 = require('child_process'); +var events_1 = require("events"); +var stream_1 = require("stream"); +var clc = require('cli-color'); +var Utils; +(function (Utils) { + (function (logLevel) { + logLevel[logLevel["None"] = 0] = "None"; + logLevel[logLevel["Error"] = 1] = "Error"; + logLevel[logLevel["Warn"] = 2] = "Warn"; + logLevel[logLevel["Info"] = 3] = "Info"; + logLevel[logLevel["Debug"] = 4] = "Debug"; + })(Utils.logLevel || (Utils.logLevel = {})); + var logLevel = Utils.logLevel; + var DummyProcess = (function (_super) { + __extends(DummyProcess, _super); + function DummyProcess() { + this.stdin = new stream_1.Writable(); + this.stderr = this.stdout = new DummyReadable(); + _super.call(this); + } + DummyProcess.prototype.kill = function (signal) { }; + ; + DummyProcess.prototype.send = function (message, sendHandle) { }; + ; + DummyProcess.prototype.disconnect = function () { }; + ; + return DummyProcess; + })(events_1.EventEmitter); + var DummyReadable = (function (_super) { + __extends(DummyReadable, _super); + function DummyReadable() { + _super.apply(this, arguments); + } + DummyReadable.prototype.read = function () { return null; }; + return DummyReadable; + })(stream_1.Readable); + var utils = (function () { + function utils() { + } + utils.setConfig = function (config) { + this.config = config; + }; + utils.getSerial = function () { + var cpuserial = "0000000000000000"; + try { + var f = utils.execSync('sudo cat /proc/cpuinfo').toString(); + cpuserial = f.match(/Serial[\t]*: ([0-9a-f]{16})/)[1]; + } + catch (ex) { + this.log.error("Failed to read serial : %s", ex.message); + cpuserial = "ERROR000000000"; + } + return cpuserial; + }; + utils.testIpAddress = function () { + var ip, interfaces = os_1.networkInterfaces(); + for (var _i = 0, _a = this.config.NetworkAdapters; _i < _a.length; _i++) { + var inf = _a[_i]; + ip = this.getAddress(interfaces[inf], "IPv4"); + if (!ip) + utils.log.debug("Read IP address from %s failed", inf); + else { + utils.log.info("Read IP address %s from %s", ip, inf); + return; + } + } + utils.log.info("Using IP address from config: %s", this.config.IpAddress); + }; + utils.getIpAddress = function (type) { + type = type || "IPv4"; + var interfaces = os_1.networkInterfaces(); + for (var _i = 0, _a = this.config.NetworkAdapters; _i < _a.length; _i++) { + var inf = _a[_i]; + var ip = this.getAddress(interfaces[inf], type); + if (ip) + return ip; + } + return this.config.IpAddress; + }; + utils.notPi = function () { + return /^win/.test(process.platform) || /^darwin/.test(process.platform); + }; + utils.execSync = function (cmd) { + utils.log.debug(["execSync('", cmd, "')"].join('')); + return utils.notPi() ? "" : require('child_process').execSync(cmd); + }; + utils.spawn = function (cmd, args, options) { + utils.log.debug("spawn('" + cmd + "', [" + args.join() + "], " + options + ")"); + if (utils.notPi()) { + return new DummyProcess(); + } + else { + return child_process_1.spawn(cmd, args, options); + } + }; + utils.cleanup = function (callback) { + callback = callback || (function () { }); + process.on('cleanup', callback); + process.on('exit', function () { + process.emit('cleanup'); + }); + process.on('SIGINT', function () { + console.log('Ctrl-C...'); + process.exit(2); + }); + process.on('uncaughtException', function (e) { + utils.log.error('Uncaught Exception... : %s', e.stack); + process.exit(99); + }); + }; + utils.getAddress = function (ni, type) { + ni = ni || []; + var address = ""; + for (var _i = 0; _i < ni.length; _i++) { + var nif = ni[_i]; + if (nif.family == type) + address = nif.address; + } + return address; + }; + utils.log = { + level: logLevel.Error, + error: function (message) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + if (utils.log.level > logLevel.None) { + message = clc.red(message); + console.log.apply(this, [message].concat(args)); + } + }, + warn: function (message) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + if (utils.log.level > logLevel.Error) { + message = clc.yellow(message); + console.log.apply(this, [message].concat(args)); + } + }, + info: function (message) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + if (utils.log.level > logLevel.Warn) + console.log.apply(this, [message].concat(args)); + }, + debug: function (message) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + if (utils.log.level > logLevel.Info) { + message = clc.green(message); + console.log.apply(this, [message].concat(args)); + } + } + }; + return utils; + })(); + Utils.utils = utils; + ; +})(Utils = exports.Utils || (exports.Utils = {})); +//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/lib/utils.js.map b/lib/utils.js.map new file mode 100644 index 00000000..bb67bfa5 --- /dev/null +++ b/lib/utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":["Utils","Utils.logLevel","Utils.DummyProcess","Utils.DummyProcess.constructor","Utils.DummyProcess.kill","Utils.DummyProcess.send","Utils.DummyProcess.disconnect","Utils.DummyReadable","Utils.DummyReadable.constructor","Utils.DummyReadable.read","Utils.utils","Utils.utils.constructor","Utils.utils.setConfig","Utils.utils.getSerial","Utils.utils.testIpAddress","Utils.utils.getIpAddress","Utils.utils.notPi","Utils.utils.execSync","Utils.utils.spawn","Utils.utils.cleanup","Utils.utils.error","Utils.utils.warn","Utils.utils.info","Utils.utils.debug"],"mappings":"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"} \ No newline at end of file diff --git a/lib/utils.ts b/lib/utils.ts new file mode 100644 index 00000000..03552fba --- /dev/null +++ b/lib/utils.ts @@ -0,0 +1,158 @@ +/// +import { networkInterfaces } from 'os'; +import { spawn, ChildProcess } from 'child_process'; +import { EventEmitter} from "events"; +import { Writable, Readable } from "stream"; + +var clc = require('cli-color'); + +export module Utils { + export enum logLevel { + None = 0, + Error = 1, + Warn = 2, + Info = 3, + Debug = 4 + } + + class DummyProcess extends EventEmitter implements ChildProcess { + stdin: Writable; + stdout: Readable; + stderr: Readable; + pid: number; + constructor() { + this.stdin = new Writable(); + this.stderr = this.stdout = new DummyReadable(); + super(); + } + kill(signal?: string) { }; + send(message: any, sendHandle?: any) { }; + disconnect() { }; + } + + class DummyReadable extends Readable { + read() { return null; } + } + + export class utils { + private static config: rposConfig; + static setConfig(config: rposConfig) { + this.config = config; + } + + static getSerial() { + // Extract serial from cpuinfo file + var cpuserial = "0000000000000000"; + try { + var f = utils.execSync('sudo cat /proc/cpuinfo').toString(); + cpuserial = f.match(/Serial[\t]*: ([0-9a-f]{16})/)[1]; + } catch (ex) { + this.log.error("Failed to read serial : %s", ex.message); + cpuserial = "ERROR000000000"; + } + return cpuserial; + } + + static testIpAddress() { + var ip, interfaces = networkInterfaces(); + for (var inf of this.config.NetworkAdapters) { + ip = this.getAddress(interfaces[inf], "IPv4"); + if (!ip) + utils.log.debug("Read IP address from %s failed", inf); + else { + utils.log.info("Read IP address %s from %s", ip, inf); + return; + } + } + utils.log.info("Using IP address from config: %s", this.config.IpAddress); + } + private static getAddress = (ni: any[], type) => { + ni = ni || []; + var address = ""; + for (var nif of ni) { + if (nif.family == type) + address = nif.address; + } + return address; + }; + + static getIpAddress(type?: string) { + type = type || "IPv4"; + var interfaces = networkInterfaces(); + for (var inf of this.config.NetworkAdapters) { + var ip = this.getAddress(interfaces[inf], type); + if (ip) + return ip; + } + return this.config.IpAddress; + } + + static notPi() { + return /^win/.test(process.platform) || /^darwin/.test(process.platform); + } + + static log = { + level: logLevel.Error, + error(message: string, ...args) { + if (utils.log.level > logLevel.None) { + message = clc.red(message); + console.log.apply(this, [message, ...args]); + } + }, + warn(message: string, ...args) { + if (utils.log.level > logLevel.Error) { + message = clc.yellow(message); + console.log.apply(this, [message, ...args]); + } + }, + info(message: string, ...args) { + if (utils.log.level > logLevel.Warn) + console.log.apply(this, [message, ...args]); + }, + debug(message: string, ...args) { + if (utils.log.level > logLevel.Info) { + message = clc.green(message); + console.log.apply(this, [message, ...args]); + } + } + } + static execSync(cmd: string) { + utils.log.debug(["execSync('", cmd, "')"].join('')); + return utils.notPi() ? "" : require('child_process').execSync(cmd); + } + static spawn(cmd: string, args?: string[], options?: {}): ChildProcess { + utils.log.debug(`spawn('${ cmd }', [${ args.join() }], ${ options })`); + if (utils.notPi()) { + return new DummyProcess(); + } + else { + return spawn(cmd, args, options); + } + } + + static cleanup(callback: () => void) { + + // attach user callback to the process event emitter + // if no callback, it will still exit gracefully on Ctrl-C + callback = callback || (() => { }); + process.on('cleanup', callback); + + // do app specific cleaning before exiting + process.on('exit', () => { + process.emit('cleanup'); + }); + + // catch ctrl+c event and exit normally + process.on('SIGINT', () => { + console.log('Ctrl-C...'); + process.exit(2); + }); + + //catch uncaught exceptions, trace, then exit normally + process.on('uncaughtException', (e) => { + utils.log.error('Uncaught Exception... : %s', e.stack); + process.exit(99); + }); + } + }; +} \ No newline at end of file diff --git a/lib/v4l2ctl.js b/lib/v4l2ctl.js index 6ea8111d..ad556018 100644 --- a/lib/v4l2ctl.js +++ b/lib/v4l2ctl.js @@ -1,44 +1,285 @@ -var v4l2ctl = { - Controls : { - UserControls : { - brightness: 50, // min=0 max=100 step=1 default=50 value=50 flags=slider - contrast: 0, // min=-100 max=100 step=1 default=0 value=0 flags=slider - saturation: 0, // min=-100 max=100 step=1 default=0 value=0 flags=slider - red_balance: 1000, // min=1 max=7999 step=1 default=1000 value=1000 flags=slider - blue_balance: 1000, // min=1 max=7999 step=1 default=1000 value=1000 flags=slider - horizontal_flip: false, // default=0 value=0 - vertical_flip: false, // default=0 value=0 - power_line_frequency: 1, // min=0 max=3 default=1 value=1 | 0: Disabled,1: 50 Hz,2: 60 Hz,3: Auto - sharpness: 0, // min=-100 max=100 step=1 default=0 value=0 flags=slider - color_effects: 0, // min=0 max=15 default=0 value=0 | 0: None,1: Black & White,2: Sepia,3: Negative,4: Emboss,5: Sketch,6: Sky Blue,7: Grass Green,8: Skin Whiten,9: Vivid,10: Aqua,11: Art Freeze,12: Silhouette,13: Solarization,14: Antique,15: Set Cb/Cr - rotate: 0, // min=0 max=360 step=90 default=0 value=0 - color_effects_cbcr: 32896, // min=0 max=65535 step=1 default=32896 value=32896 - }, - CodecControls : { - video_bitrate_mode: 0, // min=0 max=1 default=0 value=0 flags=update | 0: Variable Bitrate,1: Constant Bitrate - video_bitrate: 10000000, // min=25000 max=25000000 step=25000 default=10000000 value=10000000 - repeat_sequence_header: false, // default=0 value=0 - h264_i_frame_period: 60, // min=0 max=2147483647 step=1 default=60 value=60 - h264_level: 11, // min=0 max=11 default=11 value=11 | 0:1,1:1b,2:1.1,3:1.2,4:1.3,5:2,6:2.1,7:2.2,8:3,9:3.1,10:3.2,11:4 - h264_profile: 4 // min=0 max=4 default=4 value=4 | 0:Baseline,1:Constrained Baseline,2:Main,4:High - }, - CameraControls : { - auto_exposur: 0, // min=0 max=3 default=0 value=0 - exposure_time_absolute: 1000, // min=1 max=10000 step=1 default=1000 value=1000 - exposure_dynamic_framerate: false, // default=0 value=0 - auto_exposure_bias: 12, // min=0 max=24 default=12 value=12 - white_balance_auto_preset: 1, // min=0 max=9 default=1 value=1 | 0:Manual,1:Auto,2:Incandescent,3:Fluorescent,4:Fluorescent,5:Horizon,6:Daylight,7:Flash,8:Cloudy,9:Shade - image_stabilization: false, // default=0 value=0 - iso_sensitivity: 0, // min=0 max=4 default=0 value=0 | 0: 0,1: 100,2: 200,3: 400,4: 800, - exposure_metering_mode: 0, // min=0 max=2 default=0 value=0 | 0: Average,1: Center Weighted,2: Spot, - scene_mode: 0 // min=0 max=13 default=0 value=0 | 0: None,8: Night,11: Sports - }, - JPEGCompressionControls : { - compression_quality: 30 // min=1 max=100 step=1 default=30 value=30 - } - }, - - //v4l2-ctl --get-ctrl -}; - -module.exports = v4l2ctl; \ No newline at end of file +/// +/// +var utils_1 = require('./utils'); +var fs_1 = require('fs'); +var stringifyBool = function (v) { return v ? "1" : "0"; }; +var utils = utils_1.Utils.utils; +var v4l2ctl; +(function (v4l2ctl) { + (function (Pixelformat) { + Pixelformat[Pixelformat["YU12"] = 0] = "YU12"; + Pixelformat[Pixelformat["YUYV"] = 1] = "YUYV"; + Pixelformat[Pixelformat["RGB3"] = 2] = "RGB3"; + Pixelformat[Pixelformat["JPEG"] = 3] = "JPEG"; + Pixelformat[Pixelformat["H264"] = 4] = "H264"; + Pixelformat[Pixelformat["MJPG"] = 5] = "MJPG"; + Pixelformat[Pixelformat["YVYU"] = 6] = "YVYU"; + Pixelformat[Pixelformat["VYUY"] = 7] = "VYUY"; + Pixelformat[Pixelformat["UYVY"] = 8] = "UYVY"; + Pixelformat[Pixelformat["NV12"] = 9] = "NV12"; + Pixelformat[Pixelformat["BGR3"] = 10] = "BGR3"; + Pixelformat[Pixelformat["YV12"] = 11] = "YV12"; + Pixelformat[Pixelformat["NV21"] = 12] = "NV21"; + Pixelformat[Pixelformat["BGR4"] = 13] = "BGR4"; + })(v4l2ctl.Pixelformat || (v4l2ctl.Pixelformat = {})); + var Pixelformat = v4l2ctl.Pixelformat; + (function (ProcessPriority) { + ProcessPriority[ProcessPriority["background"] = 1] = "background"; + ProcessPriority[ProcessPriority["interactive"] = 2] = "interactive"; + ProcessPriority[ProcessPriority["record"] = 3] = "record"; + })(v4l2ctl.ProcessPriority || (v4l2ctl.ProcessPriority = {})); + var ProcessPriority = v4l2ctl.ProcessPriority; + var UserControl = (function () { + function UserControl(value, options) { + if (value === undefined || value === null) + throw "'value' is required"; + this.typeConstructor = value.constructor; + this.dirty = false; + this._value = value === undefined ? null : value; + this.options = options || {}; + this.options.stringify = this.options.stringify || (function (value) { return value.toString(); }); + } + Object.defineProperty(UserControl.prototype, "value", { + get: function () { return this._value; }, + set: function (value) { + var val = value; + if (this.typeConstructor.name == "Boolean") { + val = (val === true || val === 1 || val + "".toLowerCase() === "true" || val === "1"); + } + else if (this.typeConstructor.name != "Object") + val = this.typeConstructor(val); + if (val !== null && val !== undefined) { + if (this.hasRange && (val < this.options.range.min || val > this.options.range.max) && (val !== 0 || !this.options.range.allowZero)) + throw ("value: " + val + " not in range: " + this.options.range.min + " - " + this.options.range.max); + if (this.hasSet && this.options.lookupSet.map(function (ls) { return ls.value; }).indexOf(val) == -1) + throw ("value: " + val + " not in set: " + this.options.lookupSet.map(function (ls) { return ("{ value:" + ls.value + " desc:" + ls.desc + " }"); }).join()); + } + if (this.hasRange && this.options.range.step && (val) % this.options.range.step !== 0) + val = Math.round(val / this.options.range.step) * this.options.range.step; + if (val !== this._value) + this.dirty = true; + this._value = val; + }, + enumerable: true, + configurable: true + }); + ; + Object.defineProperty(UserControl.prototype, "desc", { + get: function () { + if (this.hasSet) + return this.getLookupSet().map(function (ls) { return ls.desc; })[this.value]; + return this.toString(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UserControl.prototype, "type", { + get: function () { + return this.typeConstructor.name; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UserControl.prototype, "hasSet", { + get: function () { + return (this.options.lookupSet || []).length > 0; + }, + enumerable: true, + configurable: true + }); + ; + UserControl.prototype.getLookupSet = function () { + var result = new Array(0); + for (var _i = 0, _a = this.options.lookupSet; _i < _a.length; _i++) { + var l = _a[_i]; + result.push({ + value: l.value, + desc: l.desc + }); + } + return result; + }; + ; + Object.defineProperty(UserControl.prototype, "hasRange", { + get: function () { + return !!this.options.range; + }, + enumerable: true, + configurable: true + }); + ; + UserControl.prototype.getRange = function () { + if (this.hasRange) + return { min: this.options.range.min, max: this.options.range.max }; + return null; + }; + Object.defineProperty(UserControl.prototype, "isDirty", { + get: function () { + return this.dirty; + }, + enumerable: true, + configurable: true + }); + ; + UserControl.prototype.reset = function () { + this.dirty = false; + }; + ; + UserControl.prototype.toString = function () { + return this.options.stringify(this._value); + }; + return UserControl; + })(); + v4l2ctl.UserControl = UserControl; + v4l2ctl.Controls = { + UserControls: { + brightness: new UserControl(50, { range: { min: 0, max: 100 } }), + contrast: new UserControl(0, { range: { min: -100, max: 100 } }), + saturation: new UserControl(0, { range: { min: -100, max: 100 } }), + red_balance: new UserControl(1000, { range: { min: 1, max: 7999 } }), + blue_balance: new UserControl(1000, { range: { min: 1, max: 7999 } }), + horizontal_flip: new UserControl(false, { stringify: stringifyBool }), + vertical_flip: new UserControl(false, { stringify: stringifyBool }), + power_line_frequency: new UserControl(1, { lookupSet: [{ value: 0, desc: 'Disabled' }, { value: 1, desc: '50 Hz' }, { value: 2, desc: '60 Hz' }, { value: 3, desc: 'Auto' }] }), + sharpness: new UserControl(0, { range: { min: -100, max: 100 } }), + color_effects: new UserControl(0, { lookupSet: [{ value: 0, desc: 'None' }, { value: 1, desc: 'Black & White' }, { value: 2, desc: 'Sepia' }, { value: 3, desc: 'Negative' }, { value: 4, desc: 'Emboss' }, { value: 5, desc: 'Sketch' }, { value: 6, desc: 'Sky Blue' }, { value: 7, desc: 'Grass Green' }, { value: 8, desc: 'Skin Whiten' }, { value: 9, desc: 'Vivid' }, { value: 10, desc: 'Aqua' }, { value: 11, desc: 'Art Freeze' }, { value: 12, desc: 'Silhouette' }, { value: 13, desc: 'Solarization' }, { value: 14, desc: 'Antique' }, { value: 15, desc: 'Set Cb/Cr' }] }), + rotate: new UserControl(0, { range: { min: 0, max: 360 } }), + color_effects_cbcr: new UserControl(32896, { range: { min: 0, max: 65535 } }), + }, + CodecControls: { + video_bitrate_mode: new UserControl(0, { lookupSet: [{ value: 0, desc: 'Variable Bitrate' }, { value: 1, desc: 'Constant Bitrate' }] }), + video_bitrate: new UserControl(10000000, { range: { min: 25000, max: 25000000, step: 25000, allowZero: true } }), + repeat_sequence_header: new UserControl(false, { stringify: stringifyBool }), + h264_i_frame_period: new UserControl(60, { range: { min: 0, max: 2147483647 } }), + h264_level: new UserControl(11, { lookupSet: [{ value: 0, desc: '1' }, { value: 1, desc: '1b' }, { value: 2, desc: '1.1' }, { value: 3, desc: '1.2' }, { value: 4, desc: '1.3' }, { value: 5, desc: '2' }, { value: 6, desc: '2.1' }, { value: 7, desc: '2.2' }, { value: 8, desc: '3' }, { value: 9, desc: '3.1' }, { value: 10, desc: '3.2' }, { value: 11, desc: '4' }] }), + h264_profile: new UserControl(4, { lookupSet: [{ value: 0, desc: 'Baseline' }, { value: 1, desc: 'Constrained Baseline' }, { value: 2, desc: 'Main' }, { value: 4, desc: 'High' }] }) + }, + CameraControls: { + auto_exposure: new UserControl(false, { stringify: stringifyBool }), + exposure_time_absolute: new UserControl(1000, { range: { min: 0, max: 10000 } }), + exposure_dynamic_framerate: new UserControl(false, { stringify: stringifyBool }), + auto_exposure_bias: new UserControl(12, { range: { min: 0, max: 24 } }), + white_balance_auto_preset: new UserControl(1, { lookupSet: [{ value: 0, desc: 'Manual' }, { value: 1, desc: 'Auto' }, { value: 2, desc: 'Incandescent' }, { value: 3, desc: 'Fluorescent' }, { value: 4, desc: 'Fluorescent' }, { value: 5, desc: 'Horizon' }, { value: 6, desc: 'Daylight' }, { value: 7, desc: 'Flash' }, { value: 8, desc: 'Cloudy' }, { value: 9, desc: 'Shade' }] }), + image_stabilization: new UserControl(false, { stringify: stringifyBool }), + iso_sensitivity: new UserControl(0, { lookupSet: [{ value: 0, desc: '0' }, { value: 1, desc: '100' }, { value: 2, desc: '200' }, { value: 3, desc: '400' }, { value: 4, desc: '800' }] }), + exposure_metering_mode: new UserControl(0, { lookupSet: [{ value: 0, desc: 'Average' }, { value: 1, desc: 'Center Weighted' }, { value: 2, desc: 'Spot' }] }), + scene_mode: new UserControl(0, { lookupSet: [{ value: 0, desc: 'None' }, { value: 8, desc: 'Night' }, { value: 11, desc: 'Sport' }] }) + }, + JPEGCompressionControls: { + compression_quality: new UserControl(30, { range: { min: 1, max: 100 } }) + } + }; + function execV4l2(cmd) { + return utils.execSync("sudo v4l2-ctl " + cmd).toString(); + ; + } + function ApplyControls() { + var usercontrols = v4l2ctl.Controls.UserControls; + var codeccontrols = v4l2ctl.Controls.CodecControls; + var cameracontrols = v4l2ctl.Controls.CameraControls; + var jpgcontrols = v4l2ctl.Controls.JPEGCompressionControls; + var getChanges = function (controls) { + var changes = []; + for (var c in controls) { + var control = controls[c]; + if (!control.isDirty) + continue; + changes.push([c, "=", control].join('')); + control.reset(); + } + return changes; + }; + var changedcontrols = getChanges(usercontrols) + .concat(getChanges(codeccontrols)) + .concat(getChanges(cameracontrols)) + .concat(getChanges(jpgcontrols)); + if (changedcontrols.length > 0) { + execV4l2("--set-ctrl " + changedcontrols.join(',')); + WriteToFile(); + } + } + v4l2ctl.ApplyControls = ApplyControls; + ; + function WriteToFile() { + var data = {}; + for (var ct in v4l2ctl.Controls) { + data[ct] = {}; + for (var k in v4l2ctl.Controls[ct]) { + var uc = v4l2ctl.Controls[ct][k]; + data[ct][k] = uc.value; + } + } + var json = JSON.stringify(data); + json = json.replace(/{"/g, "{\n\"").replace(/:{/g, ":\n{").replace(/,"/g, ",\n\"").replace(/}/g, "}\n"); + fs_1.writeFileSync("v4l2ctl.json", json); + } + v4l2ctl.WriteToFile = WriteToFile; + function ReadFromFile() { + try { + var data = JSON.parse(fs_1.readFileSync("v4l2ctl.json").toString()); + for (var ct in data) { + for (var k in data[ct]) { + var uc = v4l2ctl.Controls[ct][k]; + uc.value = data[ct][k]; + } + } + } + catch (ex) { + utils.log.error("v4l2ctl.json does not exist yet or invalid."); + } + } + v4l2ctl.ReadFromFile = ReadFromFile; + function ReadControls() { + var settings = execV4l2("-l"); + var regexPart = ".*value=([0-9]*)"; + var getControls = function (controls) { + for (var c in controls) { + var control = controls[c]; + var value = settings.match(new RegExp([c, regexPart].join(''))); + if (!value || (value.length > 1 && value[1] === "" && c == "auto_exposure")) + value = settings.match(new RegExp([c.substr(0, c.length - 1), regexPart].join(''))); + if (value && value.length > 1) { + utils.log.debug("Controlvalue '%s' : %s", c, value[1]); + try { + control.value = value[1]; + control.reset(); + } + catch (ex) { + utils.log.error(ex); + } + } + else { + utils.log.error("Could not retrieve Controlvalue '%s'", c); + } + } + }; + var usercontrols = v4l2ctl.Controls.UserControls; + var codeccontrols = v4l2ctl.Controls.CodecControls; + var cameracontrols = v4l2ctl.Controls.CameraControls; + var jpgcontrols = v4l2ctl.Controls.JPEGCompressionControls; + getControls(usercontrols); + getControls(codeccontrols); + getControls(cameracontrols); + getControls(jpgcontrols); + WriteToFile(); + } + v4l2ctl.ReadControls = ReadControls; + ; + function SetFrameRate(framerate) { + execV4l2("--set-parm=" + framerate); + } + v4l2ctl.SetFrameRate = SetFrameRate; + function SetResolution(resolution) { + execV4l2("--set-fmt-video=width=" + resolution.Width + ",height=" + resolution.Height); + } + v4l2ctl.SetResolution = SetResolution; + function SetPixelFormat(pixelformat) { + execV4l2("--set-fmt-video=pixelformat=" + pixelformat); + } + v4l2ctl.SetPixelFormat = SetPixelFormat; + function SetPriority(priority) { + execV4l2("--set-priority=" + priority); + } + v4l2ctl.SetPriority = SetPriority; +})(v4l2ctl = exports.v4l2ctl || (exports.v4l2ctl = {})); +//# sourceMappingURL=v4l2ctl.js.map \ No newline at end of file diff --git a/lib/v4l2ctl.js.map b/lib/v4l2ctl.js.map new file mode 100644 index 00000000..ae2ed5d6 --- /dev/null +++ b/lib/v4l2ctl.js.map @@ -0,0 +1 @@ +{"version":3,"file":"v4l2ctl.js","sourceRoot":"","sources":["v4l2ctl.ts"],"names":["v4l2ctl","v4l2ctl.Pixelformat","v4l2ctl.ProcessPriority","v4l2ctl.UserControl","v4l2ctl.UserControl.constructor","v4l2ctl.UserControl.value","v4l2ctl.UserControl.desc","v4l2ctl.UserControl.type","v4l2ctl.UserControl.hasSet","v4l2ctl.UserControl.getLookupSet","v4l2ctl.UserControl.hasRange","v4l2ctl.UserControl.getRange","v4l2ctl.UserControl.isDirty","v4l2ctl.UserControl.reset","v4l2ctl.UserControl.toString","v4l2ctl.execV4l2","v4l2ctl.ApplyControls","v4l2ctl.WriteToFile","v4l2ctl.ReadFromFile","v4l2ctl.ReadControls","v4l2ctl.SetFrameRate","v4l2ctl.SetResolution","v4l2ctl.SetPixelFormat","v4l2ctl.SetPriority"],"mappings":"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"} \ No newline at end of file diff --git a/lib/v4l2ctl.ts b/lib/v4l2ctl.ts new file mode 100644 index 00000000..1f51cabb --- /dev/null +++ b/lib/v4l2ctl.ts @@ -0,0 +1,311 @@ +/// +/// +import { Utils } from './utils'; +import { writeFileSync, readFileSync } from 'fs'; +var stringifyBool = (v: boolean) => { return v ? "1" : "0"; } +var utils = Utils.utils; + +export module v4l2ctl { + export enum Pixelformat { + YU12 = 0, // 4:2:0, packed YUV + YUYV = 1, // 4:2:2, packed, YUYV + RGB3 = 2, // RGB24 (LE) + JPEG = 3, // JPEG + H264 = 4, // H264 + MJPG = 5, // MJPEG + YVYU = 6, // 4:2:2, packed, YVYU + VYUY = 7, // 4:2:2, packed, VYUY + UYVY = 8, // 4:2:2, packed, UYVY + NV12 = 9, // 4:2:0, packed, NV12 + BGR3 = 10,// RGB24 (BE) + YV12 = 11,// 4:2:0, packed YVU + NV21 = 12,// 4:2:0, packed, NV21 + BGR4 = 13,// RGB32 (BE) + } + + export enum ProcessPriority { + background = 1, + interactive = 2, + record = 3 + } + + export class UserControl { + private typeConstructor: TypeConstructor; + private dirty: boolean; + private _value: T; + private options: UserControlOptions; + + constructor(value: T, options: UserControlOptions) { + if (value === undefined || value === null) + throw "'value' is required"; + + this.typeConstructor = value.constructor; + this.dirty = false; + this._value = value === undefined ? null : value; + this.options = options || {}; + this.options.stringify = this.options.stringify || (value => value.toString()); + } + + get value(): T { return this._value; }; + + set value(value: T) { + var val: any = value; + if (this.typeConstructor.name == "Boolean") { + val = (val === true || val === 1 || (val) + "".toLowerCase() === "true" || val === "1"); + } else if (this.typeConstructor.name != "Object") + val = this.typeConstructor(val); + + if (val !== null && val !== undefined) { + if (this.hasRange && (val < this.options.range.min || val > this.options.range.max) && (val !== 0 || !this.options.range.allowZero)) + throw (`value: ${val} not in range: ${this.options.range.min} - ${this.options.range.max}`); + if (this.hasSet && this.options.lookupSet.map(ls=> ls.value).indexOf(val) == -1) + throw (`value: ${val} not in set: ${this.options.lookupSet.map(ls=> `{ value:${ls.value} desc:${ls.desc} }`).join() }`); + } + + if (this.hasRange && this.options.range.step && (val) % (this.options.range.step) !== 0) + val = Math.round(val / (this.options.range.step)) * (this.options.range.step); + + if (val !== this._value) + this.dirty = true; + + this._value = val; + } + + get desc():string{ + if(this.hasSet) + return this.getLookupSet().map(ls=>ls.desc)[(this.value)]; + return this.toString(); + } + + get type(): string { + return this.typeConstructor.name; + } + + get hasSet(): boolean { + return (this.options.lookupSet || []).length > 0; + }; + + getLookupSet(): UserControlsLookupSet { + var result = new Array>(0); + for (var l of this.options.lookupSet) { + result.push({ + value: l.value, + desc: l.desc + }) + } + return result; + }; + get hasRange(): boolean { + return !!this.options.range; + }; + + getRange() { + if (this.hasRange) + return { min: this.options.range.min, max: this.options.range.max }; + + return null; + } + + get isDirty(): boolean { + return this.dirty; + }; + + reset() { + this.dirty = false; + }; + + toString(): string { + return this.options.stringify(this._value); + } + } + + export var Controls = { + UserControls: { + // min=0 max=100 step=1 default=50 value=50 flags=slider + brightness: new UserControl(50, { range: { min: 0, max: 100 } }), + + // min=-100 max=100 step=1 default=0 value=0 flags=slider + contrast: new UserControl(0, { range: { min: -100, max: 100 } }), + + // min=-100 max=100 step=1 default=0 value=0 flags=slider + saturation: new UserControl(0, { range: { min: -100, max: 100 } }), + + // min=1 max=7999 step=1 default=1000 value=1000 flags=slider + red_balance: new UserControl(1000, { range: { min: 1, max: 7999 } }), + + // min=1 max=7999 step=1 default=1000 value=1000 flags=slider + blue_balance: new UserControl(1000, { range: { min: 1, max: 7999 } }), + + // default=0 value=0 + horizontal_flip: new UserControl(false, { stringify: stringifyBool }), + + // default=0 value=0 + vertical_flip: new UserControl(false, { stringify: stringifyBool }), + + // min=0 max=3 default=1 value=1 | 0: Disabled,1: 50 Hz,2: 60 Hz,3: Auto + power_line_frequency: new UserControl(1, { lookupSet: [{ value: 0, desc: 'Disabled' }, { value: 1, desc: '50 Hz' }, { value: 2, desc: '60 Hz' }, { value: 3, desc: 'Auto' }] }), + + // min=-100 max=100 step=1 default=0 value=0 flags=slider + sharpness: new UserControl(0, { range: { min: -100, max: 100 } }), + + // min=0 max=15 default=0 value=0 | 0: None,1: Black & White,2: Sepia,3: Negative,4: Emboss,5: Sketch,6: Sky Blue,7: Grass Green,8: Skin Whiten,9: Vivid,10: Aqua,11: Art Freeze,12: Silhouette,13: Solarization,14: Antique,15: Set Cb/Cr + color_effects: new UserControl(0, { lookupSet: [{ value: 0, desc: 'None' }, { value: 1, desc: 'Black & White' }, { value: 2, desc: 'Sepia' }, { value: 3, desc: 'Negative' }, { value: 4, desc: 'Emboss' }, { value: 5, desc: 'Sketch' }, { value: 6, desc: 'Sky Blue' }, { value: 7, desc: 'Grass Green' }, { value: 8, desc: 'Skin Whiten' }, { value: 9, desc: 'Vivid' }, { value: 10, desc: 'Aqua' }, { value: 11, desc: 'Art Freeze' }, { value: 12, desc: 'Silhouette' }, { value: 13, desc: 'Solarization' }, { value: 14, desc: 'Antique' }, { value: 15, desc: 'Set Cb/Cr' }] }), + // min=0 max=360 step=90 default=0 value=0 + rotate: new UserControl(0, { range: { min: 0, max: 360 } }), + // min=0 max=65535 step=1 default=32896 value=32896 + color_effects_cbcr: new UserControl(32896, { range: { min: 0, max: 65535 } }), + }, + CodecControls: { + // min=0 max=1 default=0 value=0 flags=update | 0: Variable Bitrate,1: Constant Bitrate + video_bitrate_mode: new UserControl(0, { lookupSet: [{ value: 0, desc: 'Variable Bitrate' }, { value: 1, desc: 'Constant Bitrate' }] }), + // min=25000 max=25000000 step=25000 default=10000000 value=10000000 + video_bitrate: new UserControl(10000000, { range: { min: 25000, max: 25000000, step: 25000, allowZero: true } }), + // default=0 value=0 + repeat_sequence_header: new UserControl(false, { stringify: stringifyBool }), + // min=0 max=2147483647 step=1 default=60 value=60 + h264_i_frame_period: new UserControl(60, { range: { min: 0, max: 2147483647 } }), + // min=0 max=11 default=11 value=11 | 0:1,1:1b,2:1.1,3:1.2,4:1.3,5:2,6:2.1,7:2.2,8:3,9:3.1,10:3.2,11:4 + h264_level: new UserControl(11, { lookupSet: [{ value: 0, desc: '1' }, { value: 1, desc: '1b' }, { value: 2, desc: '1.1' }, { value: 3, desc: '1.2' }, { value: 4, desc: '1.3' }, { value: 5, desc: '2' }, { value: 6, desc: '2.1' }, { value: 7, desc: '2.2' }, { value: 8, desc: '3' }, { value: 9, desc: '3.1' }, { value: 10, desc: '3.2' }, { value: 11, desc: '4' }] }), + // min=0 max=4 default=4 value=4 | 0:Baseline,1:Constrained Baseline,2:Main,4:High + h264_profile: new UserControl(4, { lookupSet: [{ value: 0, desc: 'Baseline' }, { value: 1, desc: 'Constrained Baseline' }, { value: 2, desc: 'Main' }, { value: 4, desc: 'High' }] }) + }, + CameraControls: { + // min=0 max=3 default=0 value=0 + auto_exposure: new UserControl(false, { stringify: stringifyBool }), + // min=1 max=10000 step=1 default=1000 value=1000 + exposure_time_absolute: new UserControl(1000, { range: { min: 0, max: 10000 } }), + // default=0 value=0 + exposure_dynamic_framerate: new UserControl(false, { stringify: stringifyBool }), + // min=0 max=24 default=12 value=12 + auto_exposure_bias: new UserControl(12, { range: { min: 0, max: 24 } }), + // min=0 max=9 default=1 value=1 | 0:Manual,1:Auto,2:Incandescent,3:Fluorescent,4:Fluorescent,5:Horizon,6:Daylight,7:Flash,8:Cloudy,9:Shade + white_balance_auto_preset: new UserControl(1, { lookupSet: [{ value: 0, desc: 'Manual' }, { value: 1, desc: 'Auto' }, { value: 2, desc: 'Incandescent' }, { value: 3, desc: 'Fluorescent' }, { value: 4, desc: 'Fluorescent' }, { value: 5, desc: 'Horizon' }, { value: 6, desc: 'Daylight' }, { value: 7, desc: 'Flash' }, { value: 8, desc: 'Cloudy' }, { value: 9, desc: 'Shade' }] }), + // default=0 value=0 + image_stabilization: new UserControl(false, { stringify: stringifyBool }), + // min=0 max=4 default=0 value=0 | 0: 0,1: 100,2: 200,3: 400,4: 800, + iso_sensitivity: new UserControl(0, { lookupSet: [{ value: 0, desc: '0' }, { value: 1, desc: '100' }, { value: 2, desc: '200' }, { value: 3, desc: '400' }, { value: 4, desc: '800' }] }), + // min=0 max=2 default=0 value=0 | 0: Average,1: Center Weighted,2: Spot, + exposure_metering_mode: new UserControl(0, { lookupSet: [{ value: 0, desc: 'Average' }, { value: 1, desc: 'Center Weighted' }, { value: 2, desc: 'Spot' }] }), + // min=0 max=13 default=0 value=0 | 0: None,8: Night,11: Sports + scene_mode: new UserControl(0, { lookupSet: [{ value: 0, desc: 'None' }, { value: 8, desc: 'Night' }, { value: 11, desc: 'Sport' }] }) + }, + JPEGCompressionControls: { + // min=1 max=100 step=1 default=30 value=30 + compression_quality: new UserControl(30, { range: { min: 1, max: 100 } }) + } + }; + + function execV4l2(cmd: string): string { + return utils.execSync(`sudo v4l2-ctl ${cmd}`).toString();; + } + + export function ApplyControls() { + var usercontrols = Controls.UserControls; + var codeccontrols = Controls.CodecControls; + var cameracontrols = Controls.CameraControls; + var jpgcontrols = Controls.JPEGCompressionControls; + + var getChanges = function(controls: {}) { + var changes = []; + for (var c in controls) { + var control = >controls[c]; + if (!control.isDirty) + continue; + + changes.push([c, "=", control].join('')); + control.reset(); + } + return changes; + }; + + var changedcontrols = getChanges(usercontrols) + .concat(getChanges(codeccontrols)) + .concat(getChanges(cameracontrols)) + .concat(getChanges(jpgcontrols)); + + if (changedcontrols.length > 0) { + execV4l2(`--set-ctrl ${changedcontrols.join(',') }`); + WriteToFile(); + } + }; + + export function WriteToFile() { + var data = {}; + for (var ct in Controls) { + data[ct] = {}; + for (var k in Controls[ct]) { + var uc = >Controls[ct][k]; + data[ct][k] = uc.value; + } + } + var json = JSON.stringify(data); + json = json.replace(/{"/g,"{\n\"").replace(/:{/g, ":\n{").replace(/,"/g, ",\n\"").replace(/}/g,"}\n"); + writeFileSync("v4l2ctl.json", json); + } + + export function ReadFromFile() { + try { + var data = JSON.parse(readFileSync("v4l2ctl.json").toString()); + for (var ct in data) { + for (var k in data[ct]) { + var uc = >Controls[ct][k]; + uc.value = data[ct][k]; + } + } + } catch (ex) { + utils.log.error("v4l2ctl.json does not exist yet or invalid.") + } + } + + export function ReadControls() { + var settings = execV4l2("-l"); + var regexPart = ".*value=([0-9]*)"; + + var getControls = function(controls) { + for (var c in controls) { + var control = controls[c]; + var value = settings.match(new RegExp([c, regexPart].join(''))); + if (!value || (value.length > 1 && value[1] === "" && c == "auto_exposure")) //-- fix for typo in camera driver! + value = settings.match(new RegExp([c.substr(0, c.length - 1), regexPart].join(''))); + if (value && value.length > 1) { + utils.log.debug("Controlvalue '%s' : %s", c, value[1]); + try { + control.value = value[1]; + control.reset(); + } catch (ex) { + utils.log.error(ex); + } + } else { + utils.log.error("Could not retrieve Controlvalue '%s'", c); + } + } + }; + + var usercontrols = Controls.UserControls; + var codeccontrols = Controls.CodecControls; + var cameracontrols = Controls.CameraControls; + var jpgcontrols = Controls.JPEGCompressionControls; + getControls(usercontrols); + getControls(codeccontrols); + getControls(cameracontrols); + getControls(jpgcontrols); + + WriteToFile(); + }; + + export function SetFrameRate(framerate: number) { + execV4l2(`--set-parm=${framerate}`); + } + + export function SetResolution(resolution: Resolution) { + execV4l2(`--set-fmt-video=width=${resolution.Width},height=${resolution.Height}`); + } + + export function SetPixelFormat(pixelformat: Pixelformat) { + execV4l2(`--set-fmt-video=pixelformat=${pixelformat}`); + } + + export function SetPriority(priority: ProcessPriority) { + execV4l2(`--set-priority=${priority}`); + } +} \ No newline at end of file diff --git a/package.json b/package.json index 5e6c953f..6202f03c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rpos", - "version": "0.0.1", + "version": "0.1.0", "description": "rpos", "main": "server.js", "author": { @@ -13,6 +13,8 @@ }, "dependencies": { "soap": "git://github.com/BreeeZe/node-soap.git", - "cli-color" : "" + "cli-color": "1.0.0", + "express": "4.12.3", + "body-parser": "1.12.3" } } diff --git a/rpos.js b/rpos.js new file mode 100644 index 00000000..a32872f3 --- /dev/null +++ b/rpos.js @@ -0,0 +1,28 @@ +/// +/// +require("./lib/extension"); +var http = require("http"); +var express = require("express"); +var utils_1 = require("./lib/utils"); +var Camera = require("./lib/camera"); +var DeviceService = require("./services/device_service"); +var MediaService = require("./services/media_service"); +var utils = utils_1.Utils.utils; +var pjson = require("./package.json"); +var config = require("./rposConfig.json"); +utils.log.level = config.logLevel; +config.DeviceInformation.SerialNumber = utils.getSerial(); +config.DeviceInformation.FirmwareVersion = pjson.version; +utils.setConfig(config); +utils.testIpAddress(); +for (var i in config.DeviceInformation) { + utils.log.info("%s : %s", i, config.DeviceInformation[i]); +} +var webserver = express(); +var httpserver = http.createServer(webserver); +var camera = new Camera(config, webserver); +var device_service = new DeviceService(config, httpserver); +var media_service = new MediaService(config, httpserver, camera); +device_service.start(); +media_service.start(); +//# sourceMappingURL=rpos.js.map \ No newline at end of file diff --git a/rpos.js.map b/rpos.js.map new file mode 100644 index 00000000..939ce7ad --- /dev/null +++ b/rpos.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rpos.js","sourceRoot":"","sources":["rpos.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,wCAAwC;AAyBxC,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE3B,IAAO,IAAI,WAAW,MAAM,CAAC,CAAC;AAC9B,IAAO,OAAO,WAAW,SAAS,CAAC,CAAC;AACpC,sBAAsB,aAAa,CAAC,CAAA;AACpC,IAAO,MAAM,WAAW,cAAc,CAAC,CAAC;AACxC,IAAO,aAAa,WAAW,2BAA2B,CAAC,CAAC;AAC5D,IAAO,YAAY,WAAW,0BAA0B,CAAC,CAAC;AAC1D,IAAI,KAAK,GAAG,aAAK,CAAC,KAAK,CAAC;AACxB,IAAI,KAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AACtC,IAAI,MAAM,GAAe,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEtD,KAAK,CAAC,GAAG,CAAC,KAAK,GAAmB,MAAM,CAAC,QAAQ,CAAC;AAElD,MAAM,CAAC,iBAAiB,CAAC,YAAY,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;AAC1D,MAAM,CAAC,iBAAiB,CAAC,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC;AACzD,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AACxB,KAAK,CAAC,aAAa,EAAE,CAAC;AAEtB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACvC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC;AAC1B,IAAI,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AAE9C,IAAI,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAC3C,IAAI,cAAc,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC3D,IAAI,aAAa,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AAEjE,cAAc,CAAC,KAAK,EAAE,CAAC;AACvB,aAAa,CAAC,KAAK,EAAE,CAAC"} \ No newline at end of file diff --git a/server.js b/rpos.ts similarity index 58% rename from server.js rename to rpos.ts index 0cc4e8bc..f1690055 100644 --- a/server.js +++ b/rpos.ts @@ -1,4 +1,7 @@ -/* +/// +/// + +/* The MIT License(MIT) Copyright(c) 2015 Jeroen Versteege @@ -21,28 +24,35 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +require("./lib/extension"); -var utils = require('./lib/utils'); -var pjson = require('./package.json'); -var config = require('./config'); -var http = require('http'); +import http = require("http"); +import express = require("express"); +import { Utils } from "./lib/utils"; +import Camera = require("./lib/camera"); +import DeviceService = require("./services/device_service"); +import MediaService = require("./services/media_service"); +var utils = Utils.utils; +let pjson = require("./package.json"); +let config = require("./rposConfig.json"); -utils.log.level = config.logLevel; +utils.log.level = config.logLevel; config.DeviceInformation.SerialNumber = utils.getSerial(); config.DeviceInformation.FirmwareVersion = pjson.version; +utils.setConfig(config); +utils.testIpAddress(); for (var i in config.DeviceInformation) { - utils.log.info("%s : %s", i , config.DeviceInformation[i]); + utils.log.info("%s : %s", i, config.DeviceInformation[i]); } -var webserver = http.createServer(function (request, response) { - response.end("404: Not Found: " + request); -}); +let webserver = express(); +let httpserver = http.createServer(webserver); -var camera = new (require('./lib/camera'))(config); -var device_service = new (require('./services/device_service.js'))(config, webserver); -var media_service = new (require('./services/media_service.js'))(config, webserver, camera); +let camera = new Camera(config, webserver); +let device_service = new DeviceService(config, httpserver); +let media_service = new MediaService(config, httpserver, camera); device_service.start(); media_service.start(); \ No newline at end of file diff --git a/rposConfig.json b/rposConfig.json new file mode 100644 index 00000000..c71081dc --- /dev/null +++ b/rposConfig.json @@ -0,0 +1,14 @@ +{ + "NetworkAdapters" : ["awdl0","eth0", "en0"], + "IpAddress" : "192.168.1.15", + "ServicePort" : 8081, + "RTSPPort" : 8554, + "RTSPName" : "h264", + "DeviceInformation" : { + "Manufacturer" : "Raspberry Pi", + "Model" : "2 B", + "HardwareId" : "" + }, + "logLevel" : 4, "logLevelComment": "## LogLevels are > 1:Error 2:Warning 3:Info 4:Debug", + "logSoapCalls" : false +} \ No newline at end of file diff --git a/services/device_service.js b/services/device_service.js index 8cca6646..9194b8c1 100644 --- a/services/device_service.js +++ b/services/device_service.js @@ -1,282 +1,267 @@ +/// +/// +var __extends = this.__extends || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; var fs = require("fs"); -var util = require("util"); var os = require('os'); -var config = require('../config'); -var Service = require('../lib/service'); - -var DeviceService = function (config, server) { - Service.apply(this, [config, server]); - - this.device_service = require('./stubs/device_service.js').DeviceService; - - this.serviceOptions = { - path : '/onvif/device_service', - services : this.device_service, - xml : fs.readFileSync('./wsdl/device_service.wsdl', 'utf8'), - wsdlPath : 'wsdl/device_service.wsdl', - onReady : function () { - console.log('device_service started'); - } - }; - - this.extendService(); -}; -util.inherits(DeviceService, Service); - -DeviceService.prototype.extendService = function () { - var port = this.device_service.DeviceService.Device; - - port.GetDeviceInformation = function (args /*, cb, headers*/) { - var GetDeviceInformationResponse = { - Manufacturer : config.DeviceInformation.Manufacturer, - Model : config.DeviceInformation.Manufacturer, - FirmwareVersion : config.DeviceInformation.FirmwareVersion, - SerialNumber : config.DeviceInformation.SerialNumber, - HardwareId : config.DeviceInformation.HardwareId - }; - return GetDeviceInformationResponse; - }; - - port.GetSystemDateAndTime = function (args /*, cb, headers*/) { - var now = new Date(); - var GetSystemDateAndTimeResponse = { - SystemDateAndTime : { - DateTimeType : "NTP", - DaylightSavings : now.dst(), - TimeZone : { - TZ : "CET-1CEST,M3.5.0,M10.5.0/3" - }, - UTCDateTime : { - Date : { Day : now.getUTCDate() , Month : now.getUTCMonth() + 1, Year : now.getUTCFullYear() }, - Time : { Hour : now.getUTCHours(), Minute : now.getUTCMinutes() , Second : now.getUTCSeconds() } - }, - LocalDateTime : { - Date : { Day : now.getDate() , Month : now.getMonth() + 1 , Year : now.getFullYear() }, - Time : { Hour : now.getHours(), Minute : now.getMinutes() , Second : now.getSeconds() } - }, - Extension : {} - } - }; - return GetSystemDateAndTimeResponse; - }; - - port.SystemReboot = function (args /*, cb, headers*/) { - var SystemRebootResponse = { - Message : require('child_process').execSync("sudo reboot") - }; - return SystemRebootResponse; - }; - - port.GetCapabilities = function (args /*, cb, headers*/) { - var category = args.Category; - //{ 'All', 'Analytics', 'Device', 'Events', 'Imaging', 'Media', 'PTZ' } - var GetCapabilitiesResponse = { - Capabilities : {} - }; - - if (category == "All" || category == "Device") { - GetCapabilitiesResponse.Capabilities.Device = { - XAddr : "http://" + config.IpAddress + ":" + config.ServicePort + "/onvif/device_service", - Network : { - IPFilter : false, - ZeroConfiguration : false, - IPVersion6 : false, - DynDNS : false, - Extension : { - Dot11Configuration : false, - Extension : {} - } - }, - System : { - DiscoveryResolve : false, - DiscoveryBye : false, - RemoteDiscovery : false, - SystemBackup : false, - SystemLogging : false, - FirmwareUpgrade : false, - SupportedVersions : { - Major : 2, - Minor : 5 - }, - Extension : { - HttpFirmwareUpgrade : false, - HttpSystemBackup : false, - HttpSystemLogging : false, - HttpSupportInformation : false, - Extension : {} - } - }, - IO : { - InputConnectors : 0, - RelayOutputs : 0, - Extension : { - Auxiliary : false, - AuxiliaryCommands : "", - Extension : {} - } - }, - Security : { - "TLS1.1" : false, - "TLS1.2" : false, - OnboardKeyGeneration : false, - AccessPolicyConfig : false, - "X.509Token" : false, - SAMLToken : false, - KerberosToken : false, - RELToken : false, - Extension : { - "TLS1.0" : false, - Extension : {} - } - }, - Extension : {} - }; +var SoapService = require('../lib/SoapService'); +var utils_1 = require('../lib/utils'); +var utils = utils_1.Utils.utils; +var DeviceService = (function (_super) { + __extends(DeviceService, _super); + function DeviceService(config, server) { + _super.call(this, config, server); + this.device_service = require('./stubs/device_service.js').DeviceService; + this.serviceOptions = { + path: '/onvif/device_service', + services: this.device_service, + xml: fs.readFileSync('./wsdl/device_service.wsdl', 'utf8'), + wsdlPath: 'wsdl/device_service.wsdl', + onReady: function () { return console.log('device_service started'); } + }; + this.extendService(); } - if (category == "All" || category == "Device") { - GetCapabilitiesResponse.Capabilities.Media = { - XAddr : "http://" + config.IpAddress + ":" + config.ServicePort + "/onvif/media_service", - StreamingCapabilities : { - RTPMulticast : false, - RTP_TCP : true, - RTP_RTSP_TCP : true, - Extension : {} - }, - Extension : { - ProfileCapabilities : { - MaximumNumberOfProfiles : 1 - } - } - } - } - return GetCapabilitiesResponse; - }; - - port.GetHostname = function (args /*, cb, headers*/) { - var GetHostnameResponse = { - HostnameInformation : { - FromDHCP : false, - Name : os.hostname(), - Extension : {} - } - }; - return GetHostnameResponse; - }; - - port.SetHostname = function (args /*, cb, headers*/) { - var SetHostnameResponse = {}; - return SetHostnameResponse; - }; - - port.SetHostnameFromDHCP = function (args /*, cb, headers*/) { - var SetHostnameFromDHCPResponse = { - RebootNeeded : false - }; - return SetHostnameFromDHCPResponse; - }; - - port.GetServiceCapabilities = function (args /*, cb, headers*/) { - var GetServiceCapabilitiesResponse = { - Capabilities : { - Network : { - attributes : { - IPFilter : false, - ZeroConfiguration : false, - IPVersion6 : false, - DynDNS : false, - Dot11Configuration : false, - Dot1XConfigurations : 0, - HostnameFromDHCP : false, - NTP : 0, - DHCPv6 : false - } - }, - Security : { - attributes : { - "TLS1.0" : false, - "TLS1.1" : false, - "TLS1.2" : false, - OnboardKeyGeneration : false, - AccessPolicyConfig : false, - DefaultAccessPolicy : false, - Dot1X : false, - RemoteUserHandling : false, - "X.509Token" : false, - SAMLToken : false, - KerberosToken : false, - UsernameToken : false, - HttpDigest : false, - RELToken : false, - SupportedEAPMethods : 0, - MaxUsers : 1, - MaxUserNameLength : 10, - MaxPasswordLength : 256 - } - }, - System : { - attributes : { - DiscoveryResolve : false, - DiscoveryBye : false, - RemoteDiscovery : false, - SystemBackup : false, - SystemLogging : false, - FirmwareUpgrade : false, - HttpFirmwareUpgrade : false, - HttpSystemBackup : false, - HttpSystemLogging : false, - HttpSupportInformation : false, - StorageConfiguration : false - } - }, - //Misc : { - // attributes : { - // AuxiliaryCommands : {tt:StringAttrList} - // } - //} - } - }; - return GetServiceCapabilitiesResponse; - }; - - port.GetNTP = function (args /*, cb, headers*/) { - var GetNTPResponse = {}; - return GetNTPResponse; - }; - - port.SetNTP = function (args /*, cb, headers*/) { - var SetNTPResponse = {}; - return SetNTPResponse; - }; - - port.GetNetworkInterfaces = function (args /*, cb, headers*/) { - var GetNetworkInterfacesResponse = { - NetworkInterfaces : [] + DeviceService.prototype.extendService = function () { + var _this = this; + var port = this.device_service.DeviceService.Device; + port.GetDeviceInformation = function (args) { + var GetDeviceInformationResponse = { + Manufacturer: _this.config.DeviceInformation.Manufacturer, + Model: _this.config.DeviceInformation.Manufacturer, + FirmwareVersion: _this.config.DeviceInformation.FirmwareVersion, + SerialNumber: _this.config.DeviceInformation.SerialNumber, + HardwareId: _this.config.DeviceInformation.HardwareId + }; + return GetDeviceInformationResponse; + }; + port.GetSystemDateAndTime = function (args) { + var now = new Date(); + var GetSystemDateAndTimeResponse = { + SystemDateAndTime: { + DateTimeType: "NTP", + DaylightSavings: now.dst(), + TimeZone: { + TZ: "CET-1CEST,M3.5.0,M10.5.0/3" + }, + UTCDateTime: { + Date: { Day: now.getUTCDate(), Month: now.getUTCMonth() + 1, Year: now.getUTCFullYear() }, + Time: { Hour: now.getUTCHours(), Minute: now.getUTCMinutes(), Second: now.getUTCSeconds() } + }, + LocalDateTime: { + Date: { Day: now.getDate(), Month: now.getMonth() + 1, Year: now.getFullYear() }, + Time: { Hour: now.getHours(), Minute: now.getMinutes(), Second: now.getSeconds() } + }, + Extension: {} + } + }; + return GetSystemDateAndTimeResponse; + }; + port.SystemReboot = function (args) { + var SystemRebootResponse = { + Message: utils.execSync("sudo reboot") + }; + return SystemRebootResponse; + }; + port.GetCapabilities = function (args) { + var category = args.Category; + var GetCapabilitiesResponse = { + Capabilities: {} + }; + if (category == "All" || category == "Device") { + GetCapabilitiesResponse.Capabilities["Device"] = { + XAddr: "http://" + utils.getIpAddress() + ":" + _this.config.ServicePort + "/onvif/device_service", + Network: { + IPFilter: false, + ZeroConfiguration: false, + IPVersion6: false, + DynDNS: false, + Extension: { + Dot11Configuration: false, + Extension: {} + } + }, + System: { + DiscoveryResolve: false, + DiscoveryBye: false, + RemoteDiscovery: false, + SystemBackup: false, + SystemLogging: false, + FirmwareUpgrade: false, + SupportedVersions: { + Major: 2, + Minor: 5 + }, + Extension: { + HttpFirmwareUpgrade: false, + HttpSystemBackup: false, + HttpSystemLogging: false, + HttpSupportInformation: false, + Extension: {} + } + }, + IO: { + InputConnectors: 0, + RelayOutputs: 0, + Extension: { + Auxiliary: false, + AuxiliaryCommands: "", + Extension: {} + } + }, + Security: { + "TLS1.1": false, + "TLS1.2": false, + OnboardKeyGeneration: false, + AccessPolicyConfig: false, + "X.509Token": false, + SAMLToken: false, + KerberosToken: false, + RELToken: false, + Extension: { + "TLS1.0": false, + Extension: {} + } + }, + Extension: {} + }; + } + if (category == "All" || category == "Media") { + GetCapabilitiesResponse.Capabilities["Media"] = { + XAddr: "http://" + utils.getIpAddress() + ":" + _this.config.ServicePort + "/onvif/media_service", + StreamingCapabilities: { + RTPMulticast: false, + RTP_TCP: true, + RTP_RTSP_TCP: true, + Extension: {} + }, + Extension: { + ProfileCapabilities: { + MaximumNumberOfProfiles: 1 + } + } + }; + } + return GetCapabilitiesResponse; + }; + port.GetHostname = function (args) { + var GetHostnameResponse = { + HostnameInformation: { + FromDHCP: false, + Name: os.hostname(), + Extension: {} + } + }; + return GetHostnameResponse; + }; + port.SetHostname = function (args) { + var SetHostnameResponse = {}; + return SetHostnameResponse; + }; + port.SetHostnameFromDHCP = function (args) { + var SetHostnameFromDHCPResponse = { + RebootNeeded: false + }; + return SetHostnameFromDHCPResponse; + }; + port.GetServiceCapabilities = function (args) { + var GetServiceCapabilitiesResponse = { + Capabilities: { + Network: { + attributes: { + IPFilter: false, + ZeroConfiguration: false, + IPVersion6: false, + DynDNS: false, + Dot11Configuration: false, + Dot1XConfigurations: 0, + HostnameFromDHCP: false, + NTP: 0, + DHCPv6: false + } + }, + Security: { + attributes: { + "TLS1.0": false, + "TLS1.1": false, + "TLS1.2": false, + OnboardKeyGeneration: false, + AccessPolicyConfig: false, + DefaultAccessPolicy: false, + Dot1X: false, + RemoteUserHandling: false, + "X.509Token": false, + SAMLToken: false, + KerberosToken: false, + UsernameToken: false, + HttpDigest: false, + RELToken: false, + SupportedEAPMethods: 0, + MaxUsers: 1, + MaxUserNameLength: 10, + MaxPasswordLength: 256 + } + }, + System: { + attributes: { + DiscoveryResolve: false, + DiscoveryBye: false, + RemoteDiscovery: false, + SystemBackup: false, + SystemLogging: false, + FirmwareUpgrade: false, + HttpFirmwareUpgrade: false, + HttpSystemBackup: false, + HttpSystemLogging: false, + HttpSupportInformation: false, + StorageConfiguration: false + } + }, + } + }; + return GetServiceCapabilitiesResponse; + }; + port.GetNTP = function (args) { + var GetNTPResponse = {}; + return GetNTPResponse; + }; + port.SetNTP = function (args) { + var SetNTPResponse = {}; + return SetNTPResponse; + }; + port.GetNetworkInterfaces = function (args) { + var GetNetworkInterfacesResponse = { + NetworkInterfaces: [] + }; + var nwifs = os.networkInterfaces(); + for (var nwif in nwifs) { + GetNetworkInterfacesResponse.NetworkInterfaces.push({ + attributes: { + token: nwif + } + }); + } + return GetNetworkInterfacesResponse; + }; + port.GetNetworkProtocols = function (args) { + var GetNetworkProtocolsResponse = { + NetworkProtocols: [{ + Name: "RTSP", + Enabled: true, + Port: _this.config.RTSPPort + }] + }; + return GetNetworkProtocolsResponse; + }; + port.GetRelayOutputs = function (args) { + var GetRelayOutputsResponse = {}; + return GetRelayOutputsResponse; + }; }; - var nwifs = os.networkInterfaces(); - for (var nwif in nwifs) { - GetNetworkInterfacesResponse.NetworkInterfaces.push({ - attributes : { - token : nwif - } - }); - } - return GetNetworkInterfacesResponse; - }; - - port.GetNetworkProtocols = function (args /*, cb, headers*/) { - var GetNetworkProtocolsResponse = { - NetworkProtocols : [{ - Name : "RTSP", - Enabled : true, - Port : config.RTSPPort - }] - }; - return GetNetworkProtocolsResponse; - }; - - port.GetRelayOutputs = function (args /*, cb, headers*/) { - var GetRelayOutputsResponse = {}; - return GetRelayOutputsResponse; - }; - -}; -module.exports = DeviceService; \ No newline at end of file + return DeviceService; +})(SoapService); +module.exports = DeviceService; +//# sourceMappingURL=device_service.js.map \ No newline at end of file diff --git a/services/device_service.js.map b/services/device_service.js.map new file mode 100644 index 00000000..8a1355b3 --- /dev/null +++ b/services/device_service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"device_service.js","sourceRoot":"","sources":["device_service.ts"],"names":["DeviceService","DeviceService.constructor","DeviceService.extendService"],"mappings":"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"} \ No newline at end of file diff --git a/services/device_service.ts b/services/device_service.ts new file mode 100644 index 00000000..8f1069e9 --- /dev/null +++ b/services/device_service.ts @@ -0,0 +1,286 @@ +/// +/// + +import fs = require("fs"); +import util = require("util"); +import os = require('os'); +import SoapService = require('../lib/SoapService'); +import { Utils } from '../lib/utils'; +import { Server } from 'http'; +var utils = Utils.utils; + +class DeviceService extends SoapService { + device_service: any; + constructor(config: rposConfig, server: Server) { + super(config, server); + + this.device_service = require('./stubs/device_service.js').DeviceService; + + this.serviceOptions = { + path: '/onvif/device_service', + services: this.device_service, + xml: fs.readFileSync('./wsdl/device_service.wsdl', 'utf8'), + wsdlPath: 'wsdl/device_service.wsdl', + onReady: () => console.log('device_service started') + }; + + this.extendService(); + } + + extendService() { + var port = this.device_service.DeviceService.Device; + + port.GetDeviceInformation = (args /*, cb, headers*/) => { + var GetDeviceInformationResponse = { + Manufacturer: this.config.DeviceInformation.Manufacturer, + Model: this.config.DeviceInformation.Manufacturer, + FirmwareVersion: this.config.DeviceInformation.FirmwareVersion, + SerialNumber: this.config.DeviceInformation.SerialNumber, + HardwareId: this.config.DeviceInformation.HardwareId + }; + return GetDeviceInformationResponse; + }; + + port.GetSystemDateAndTime = (args /*, cb, headers*/) => { + var now = new Date(); + var GetSystemDateAndTimeResponse = { + SystemDateAndTime: { + DateTimeType: "NTP", + DaylightSavings: now.dst(), + TimeZone: { + TZ: "CET-1CEST,M3.5.0,M10.5.0/3" + }, + UTCDateTime: { + Date: { Day: now.getUTCDate(), Month: now.getUTCMonth() + 1, Year: now.getUTCFullYear() }, + Time: { Hour: now.getUTCHours(), Minute: now.getUTCMinutes(), Second: now.getUTCSeconds() } + }, + LocalDateTime: { + Date: { Day: now.getDate(), Month: now.getMonth() + 1, Year: now.getFullYear() }, + Time: { Hour: now.getHours(), Minute: now.getMinutes(), Second: now.getSeconds() } + }, + Extension: {} + } + }; + return GetSystemDateAndTimeResponse; + }; + + port.SystemReboot = (args /*, cb, headers*/) => { + var SystemRebootResponse = { + Message: utils.execSync("sudo reboot") + }; + return SystemRebootResponse; + }; + + port.GetCapabilities = (args /*, cb, headers*/) => { + var category = args.Category; + //{ 'All', 'Analytics', 'Device', 'Events', 'Imaging', 'Media', 'PTZ' } + var GetCapabilitiesResponse = { + Capabilities: {} + }; + + if (category == "All" || category == "Device") { + GetCapabilitiesResponse.Capabilities["Device"] = { + XAddr: `http://${utils.getIpAddress() }:${this.config.ServicePort}/onvif/device_service`, + Network: { + IPFilter: false, + ZeroConfiguration: false, + IPVersion6: false, + DynDNS: false, + Extension: { + Dot11Configuration: false, + Extension: {} + } + }, + System: { + DiscoveryResolve: false, + DiscoveryBye: false, + RemoteDiscovery: false, + SystemBackup: false, + SystemLogging: false, + FirmwareUpgrade: false, + SupportedVersions: { + Major: 2, + Minor: 5 + }, + Extension: { + HttpFirmwareUpgrade: false, + HttpSystemBackup: false, + HttpSystemLogging: false, + HttpSupportInformation: false, + Extension: {} + } + }, + IO: { + InputConnectors: 0, + RelayOutputs: 0, + Extension: { + Auxiliary: false, + AuxiliaryCommands: "", + Extension: {} + } + }, + Security: { + "TLS1.1": false, + "TLS1.2": false, + OnboardKeyGeneration: false, + AccessPolicyConfig: false, + "X.509Token": false, + SAMLToken: false, + KerberosToken: false, + RELToken: false, + Extension: { + "TLS1.0": false, + Extension: {} + } + }, + Extension: {} + }; + } + if (category == "All" || category == "Media") { + GetCapabilitiesResponse.Capabilities["Media"] = { + XAddr: `http://${utils.getIpAddress() }:${this.config.ServicePort}/onvif/media_service`, + StreamingCapabilities: { + RTPMulticast: false, + RTP_TCP: true, + RTP_RTSP_TCP: true, + Extension: {} + }, + Extension: { + ProfileCapabilities: { + MaximumNumberOfProfiles: 1 + } + } + } + } + return GetCapabilitiesResponse; + }; + + port.GetHostname = (args /*, cb, headers*/) => { + var GetHostnameResponse = { + HostnameInformation: { + FromDHCP: false, + Name: os.hostname(), + Extension: {} + } + }; + return GetHostnameResponse; + }; + + port.SetHostname = (args /*, cb, headers*/) => { + var SetHostnameResponse = {}; + return SetHostnameResponse; + }; + + port.SetHostnameFromDHCP = (args /*, cb, headers*/) => { + var SetHostnameFromDHCPResponse = { + RebootNeeded: false + }; + return SetHostnameFromDHCPResponse; + }; + + port.GetServiceCapabilities = (args /*, cb, headers*/) => { + var GetServiceCapabilitiesResponse = { + Capabilities: { + Network: { + attributes: { + IPFilter: false, + ZeroConfiguration: false, + IPVersion6: false, + DynDNS: false, + Dot11Configuration: false, + Dot1XConfigurations: 0, + HostnameFromDHCP: false, + NTP: 0, + DHCPv6: false + } + }, + Security: { + attributes: { + "TLS1.0": false, + "TLS1.1": false, + "TLS1.2": false, + OnboardKeyGeneration: false, + AccessPolicyConfig: false, + DefaultAccessPolicy: false, + Dot1X: false, + RemoteUserHandling: false, + "X.509Token": false, + SAMLToken: false, + KerberosToken: false, + UsernameToken: false, + HttpDigest: false, + RELToken: false, + SupportedEAPMethods: 0, + MaxUsers: 1, + MaxUserNameLength: 10, + MaxPasswordLength: 256 + } + }, + System: { + attributes: { + DiscoveryResolve: false, + DiscoveryBye: false, + RemoteDiscovery: false, + SystemBackup: false, + SystemLogging: false, + FirmwareUpgrade: false, + HttpFirmwareUpgrade: false, + HttpSystemBackup: false, + HttpSystemLogging: false, + HttpSupportInformation: false, + StorageConfiguration: false + } + }, + //Misc : { + // attributes : { + // AuxiliaryCommands : {tt:StringAttrList} + // } + //} + } + }; + return GetServiceCapabilitiesResponse; + }; + + port.GetNTP = (args /*, cb, headers*/) => { + var GetNTPResponse = {}; + return GetNTPResponse; + }; + + port.SetNTP = (args /*, cb, headers*/) => { + var SetNTPResponse = {}; + return SetNTPResponse; + }; + + port.GetNetworkInterfaces = (args /*, cb, headers*/) => { + var GetNetworkInterfacesResponse = { + NetworkInterfaces: [] + }; + var nwifs = os.networkInterfaces(); + for (var nwif in nwifs) { + GetNetworkInterfacesResponse.NetworkInterfaces.push({ + attributes: { + token: nwif + } + }); + } + return GetNetworkInterfacesResponse; + }; + + port.GetNetworkProtocols = (args /*, cb, headers*/) => { + var GetNetworkProtocolsResponse = { + NetworkProtocols: [{ + Name: "RTSP", + Enabled: true, + Port: this.config.RTSPPort + }] + }; + return GetNetworkProtocolsResponse; + }; + + port.GetRelayOutputs = (args /*, cb, headers*/) => { + var GetRelayOutputsResponse = {}; + return GetRelayOutputsResponse; + }; + } +} +export = DeviceService; \ No newline at end of file diff --git a/services/media_service.js b/services/media_service.js index f3628d8b..c5736cdd 100644 --- a/services/media_service.js +++ b/services/media_service.js @@ -1,276 +1,254 @@ +var __extends = this.__extends || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +/// +/// var fs = require("fs"); -var util = require("util"); -var config = require('../config'); -var Service = require('../lib/service'); -var utils = require('../lib/utils'); +var SoapService = require('../lib/SoapService'); +var utils_1 = require('../lib/utils'); var url = require('url'); - -var MediaService = function (config, server, camera) { - Service.apply(this, [config, server]); - - this.media_service = require('./stubs/media_service.js').MediaService; - - this.camera = camera; - this.serviceOptions = { - path : '/onvif/media_service', - services : this.media_service, - xml : fs.readFileSync('./wsdl/media_service.wsdl', 'utf8'), - wsdlPath : 'wsdl/media_service.wsdl', - onReady : function () { - console.log('media_service started'); - } - }; - - this.extendService(); -}; -util.inherits(MediaService, Service); - -MediaService.prototype.starting = function () { - var listeners = this.webserver.listeners('request').slice(); - this.webserver.removeAllListeners('request'); - this.webserver.addListener('request', function (request, response) { - utils.log.debug('web request received : %s', request.url); - - var request = url.parse(request.url, true); - var action = request.pathname; - if (action == '/web/snapshot.jpg') { - try { - var img = fs.readFileSync('/dev/shm/snapshot.jpg'); - response.writeHead(200, { 'Content-Type': 'image/jpg' }); - response.end(img, 'binary'); - } catch (err) { - utils.log.error("Error opening snapshot : %s", err); - response.end("404: Not Found: " + request); - } - } else { - for (var i = 0, len = listeners.length; i < len; i++) { - listeners[i].call(this, request, response); - } - } - }); -}; - -MediaService.prototype.started = function () { - if (!utils.isWin()) { - this.camera.startRtsp("/dev/video0"); - } else { - utils.log.debug("Would start rtsp server"); - } -}; - -MediaService.prototype.extendService = function () { - var port = this.media_service.MediaService.Media; - - var cameraOptions = this.camera.options; - var cameraSettings = this.camera.settings; - var camera = this.camera; - - var videoConfigurationOptions = { - QualityRange : { - Min : cameraOptions.quality[0], - Max : cameraOptions.quality[cameraOptions.quality.length - 1] - }, - H264 : { - ResolutionsAvailable : cameraOptions.resolutions, - GovLengthRange : { Min : 1, Max : 10 }, - FrameRateRange : { - Min : cameraOptions.framerates[0], - Max : cameraOptions.framerates[cameraOptions.framerates.length - 1] - }, - EncodingIntervalRange : { Min : 1, Max : 1 }, - H264ProfilesSupported : cameraOptions.profiles - }, - Extension : { - H264 : { - ResolutionsAvailable : cameraOptions.resolutions, - GovLengthRange : { Min : 1, Max : 10 }, - FrameRateRange : { - Min : cameraOptions.framerates[0], - Max : cameraOptions.framerates[cameraOptions.framerates.length - 1] - }, - EncodingIntervalRange : { Min : 1, Max : 1 }, - H264ProfilesSupported : cameraOptions.profiles, - BitrateRange : { - Min : cameraOptions.bitrates[0], - Max : cameraOptions.bitrates[cameraOptions.bitrates.length - 1] - } - } +var v4l2ctl_1 = require('../lib/v4l2ctl'); +var utils = utils_1.Utils.utils; +var MediaService = (function (_super) { + __extends(MediaService, _super); + function MediaService(config, server, camera) { + _super.call(this, config, server); + this.media_service = require('./stubs/media_service.js').MediaService; + this.camera = camera; + this.serviceOptions = { + path: '/onvif/media_service', + services: this.media_service, + xml: fs.readFileSync('./wsdl/media_service.wsdl', 'utf8'), + wsdlPath: 'wsdl/media_service.wsdl', + onReady: function () { + utils.log.info('media_service started'); + } + }; + this.extendService(); } - }; - - var videoEncoderConfiguration = { - attributes : { - token : "token" - }, - Name : "PiCameraConfiguration", - UseCount : 0, - Encoding : "H264", - Resolution : { - Width : cameraSettings.resolution.Width, - Height : cameraSettings.resolution.Height - }, - Quality : cameraSettings.bitrate ? null : cameraSettings.quality, - RateControl : { - FrameRateLimit : cameraSettings.framerate, - EncodingInterval : 1, - BitrateLimit : cameraSettings.bitrate - }, - H264 : { - GovLength : cameraSettings.gop, - H264Profile : cameraSettings.profile - }, - SessionTimeout : "1000" - }; - - var videoSourceConfiguration = { - Name : "Primary Source", - UseCount : 0, - attributes : { - token : "token" - }, - SourceToken : [], - Bounds : { attributes : { x : 0, y : 0, width : 1920, height : 1080 } } - }; - - var audioEncoderConfigurationOptions = { - Options : [] - }; - - var profile = { - Name : "CurrentProfile", - attributes : { - token : "token" - }, - VideoSourceConfiguration : videoSourceConfiguration, - VideoEncoderConfiguration : videoEncoderConfiguration - }; - - port.GetServiceCapabilities = function (args /*, cb, headers*/) { - var GetServiceCapabilitiesResponse = { - Capabilities : { - attributes : { - SnapshotUri : false, - Rotation : false, - VideoSourceMode : true, - OSD : false - }, - ProfileCapabilities : { - attributes : { - MaximumNumberOfProfiles : 1 - } - }, - StreamingCapabilities : { - attributes : { - RTPMulticast : false, - RTP_TCP : true, - RTP_RTSP_TCP : true, - NonAggregateControl : false, - NoRTSPStreaming : false - } - } - } + MediaService.prototype.starting = function () { + var _this = this; + var listeners = this.webserver.listeners('request').slice(); + this.webserver.removeAllListeners('request'); + this.webserver.addListener('request', function (request, response, next) { + utils.log.debug('web request received : %s', request.url); + var uri = url.parse(request.url, true); + var action = uri.pathname; + if (action == '/web/snapshot.jpg') { + try { + var img = fs.readFileSync('/dev/shm/snapshot.jpg'); + response.writeHead(200, { 'Content-Type': 'image/jpg' }); + response.end(img, 'binary'); + } + catch (err) { + utils.log.error("Error opening snapshot : %s", err); + response.end("404: Not Found: " + request); + } + } + else { + for (var i = 0, len = listeners.length; i < len; i++) { + listeners[i].call(_this, request, response, next); + } + } + }); }; - return GetServiceCapabilitiesResponse; - }; - - //var GetStreamUri = { - //StreamSetup : { - //Stream : { xs:string} - //}, - //ProfileToken : { xs:string} - // - //}; - port.GetStreamUri = function (args /*, cb, headers*/) { - var GetStreamUriResponse = { - MediaUri : { - Uri : "rtsp://" + config.IpAddress + ":" + config.RTSPPort + "/" + config.RTSPName, - InvalidAfterConnect : false, - InvalidAfterReboot : false, - Timeout : "PT30S" - } + ; + MediaService.prototype.started = function () { + this.camera.startRtsp(); }; - return GetStreamUriResponse; - }; - - port.GetProfile = function (args) { - var GetProfileResponse = { Profile : profile }; - return GetProfileResponse; - }; - - port.GetProfiles = function (args) { - var GetProfilesResponse = { Profiles : [profile] }; - return GetProfilesResponse; - }; - - port.CreateProfile = function (args) { - var CreateProfileResponse = { Profile : profile }; - return CreateProfileResponse; - }; - - port.DeleteProfile = function (args) { - var DeleteProfileResponse = {}; - return DeleteProfileResponse; - }; - - port.GetVideoSourceConfigurations = function (args) { - var GetVideoSourceConfigurationsResponse = { Configurations : [videoSourceConfiguration] }; - return GetVideoSourceConfigurationsResponse; - }; - - port.GetVideoEncoderConfigurations = function (args) { - var GetVideoEncoderConfigurationsResponse = { Configurations : [videoEncoderConfiguration] }; - return GetVideoEncoderConfigurationsResponse; - }; - - port.GetVideoEncoderConfiguration = function (args) { - var GetVideoEncoderConfigurationResponse = { Configuration : videoEncoderConfiguration }; - return GetVideoEncoderConfigurationResponse; - }; - - port.SetVideoEncoderConfiguration = function (args) { - var settings = { - bitrate : args.Configuration.RateControl.BitrateLimit, - frameRate : args.Configuration.RateControl.FrameRateLimit, - gop : args.Configuration.H264.GovLength, - profile : args.Configuration.H264.H264Profile, - quality : args.Configuration.Quality instanceof Object ? null : args.Configuration.Quality, - resolution : args.Configuration.Resolution + ; + MediaService.prototype.extendService = function () { + var _this = this; + var port = this.media_service.MediaService.Media; + var cameraOptions = this.camera.options; + var cameraSettings = this.camera.settings; + var camera = this.camera; + var h264Profiles = v4l2ctl_1.v4l2ctl.Controls.CodecControls.h264_profile.getLookupSet().map(function (ls) { return ls.desc; }); + h264Profiles.splice(1, 1); + var videoConfigurationOptions = { + QualityRange: { + Min: 1, + Max: 1 + }, + H264: { + ResolutionsAvailable: cameraOptions.resolutions, + GovLengthRange: { + Min: v4l2ctl_1.v4l2ctl.Controls.CodecControls.h264_i_frame_period.getRange().min, + Max: v4l2ctl_1.v4l2ctl.Controls.CodecControls.h264_i_frame_period.getRange().max + }, + FrameRateRange: { + Min: cameraOptions.framerates[0], + Max: cameraOptions.framerates[cameraOptions.framerates.length - 1] + }, + EncodingIntervalRange: { Min: 1, Max: 1 }, + H264ProfilesSupported: h264Profiles + }, + Extension: { + H264: { + ResolutionsAvailable: cameraOptions.resolutions, + GovLengthRange: { + Min: v4l2ctl_1.v4l2ctl.Controls.CodecControls.h264_i_frame_period.getRange().min, + Max: v4l2ctl_1.v4l2ctl.Controls.CodecControls.h264_i_frame_period.getRange().max + }, + FrameRateRange: { + Min: cameraOptions.framerates[0], + Max: cameraOptions.framerates[cameraOptions.framerates.length - 1] + }, + EncodingIntervalRange: { Min: 1, Max: 1 }, + H264ProfilesSupported: h264Profiles, + BitrateRange: { + Min: cameraOptions.bitrates[0], + Max: cameraOptions.bitrates[cameraOptions.bitrates.length - 1] + } + } + } + }; + var videoEncoderConfiguration = { + attributes: { + token: "token" + }, + Name: "PiCameraConfiguration", + UseCount: 0, + Encoding: "H264", + Resolution: { + Width: cameraSettings.resolution.Width, + Height: cameraSettings.resolution.Height + }, + Quality: v4l2ctl_1.v4l2ctl.Controls.CodecControls.video_bitrate.value ? null : 1, + RateControl: { + FrameRateLimit: cameraSettings.framerate, + EncodingInterval: 1, + BitrateLimit: v4l2ctl_1.v4l2ctl.Controls.CodecControls.video_bitrate.value / 1000 + }, + H264: { + GovLength: v4l2ctl_1.v4l2ctl.Controls.CodecControls.h264_i_frame_period.value, + H264Profile: v4l2ctl_1.v4l2ctl.Controls.CodecControls.h264_profile.desc + }, + SessionTimeout: "1000" + }; + var videoSourceConfiguration = { + Name: "Primary Source", + UseCount: 0, + attributes: { + token: "token" + }, + SourceToken: [], + Bounds: { attributes: { x: 0, y: 0, width: 1920, height: 1080 } } + }; + var audioEncoderConfigurationOptions = { + Options: [] + }; + var profile = { + Name: "CurrentProfile", + attributes: { + token: "token" + }, + VideoSourceConfiguration: videoSourceConfiguration, + VideoEncoderConfiguration: videoEncoderConfiguration + }; + port.GetServiceCapabilities = function (args) { + var GetServiceCapabilitiesResponse = { + Capabilities: { + attributes: { + SnapshotUri: false, + Rotation: false, + VideoSourceMode: true, + OSD: false + }, + ProfileCapabilities: { + attributes: { + MaximumNumberOfProfiles: 1 + } + }, + StreamingCapabilities: { + attributes: { + RTPMulticast: false, + RTP_TCP: true, + RTP_RTSP_TCP: true, + NonAggregateControl: false, + NoRTSPStreaming: false + } + } + } + }; + return GetServiceCapabilitiesResponse; + }; + port.GetStreamUri = function (args) { + var GetStreamUriResponse = { + MediaUri: { + Uri: "rtsp://" + utils.getIpAddress() + ":" + _this.config.RTSPPort + "/" + _this.config.RTSPName, + InvalidAfterConnect: false, + InvalidAfterReboot: false, + Timeout: "PT30S" + } + }; + return GetStreamUriResponse; + }; + port.GetProfile = function (args) { + var GetProfileResponse = { Profile: profile }; + return GetProfileResponse; + }; + port.GetProfiles = function (args) { + var GetProfilesResponse = { Profiles: [profile] }; + return GetProfilesResponse; + }; + port.CreateProfile = function (args) { + var CreateProfileResponse = { Profile: profile }; + return CreateProfileResponse; + }; + port.DeleteProfile = function (args) { + var DeleteProfileResponse = {}; + return DeleteProfileResponse; + }; + port.GetVideoSourceConfigurations = function (args) { + var GetVideoSourceConfigurationsResponse = { Configurations: [videoSourceConfiguration] }; + return GetVideoSourceConfigurationsResponse; + }; + port.GetVideoEncoderConfigurations = function (args) { + var GetVideoEncoderConfigurationsResponse = { Configurations: [videoEncoderConfiguration] }; + return GetVideoEncoderConfigurationsResponse; + }; + port.GetVideoEncoderConfiguration = function (args) { + var GetVideoEncoderConfigurationResponse = { Configuration: videoEncoderConfiguration }; + return GetVideoEncoderConfigurationResponse; + }; + port.SetVideoEncoderConfiguration = function (args) { + var settings = { + bitrate: args.Configuration.RateControl.BitrateLimit, + framerate: args.Configuration.RateControl.FrameRateLimit, + gop: args.Configuration.H264.GovLength, + profile: args.Configuration.H264.H264Profile, + quality: args.Configuration.Quality instanceof Object ? null : args.Configuration.Quality, + resolution: args.Configuration.Resolution + }; + camera.setSettings(settings); + var SetVideoEncoderConfigurationResponse = {}; + return SetVideoEncoderConfigurationResponse; + }; + port.GetVideoEncoderConfigurationOptions = function (args) { + var GetVideoEncoderConfigurationOptionsResponse = { Options: videoConfigurationOptions }; + return GetVideoEncoderConfigurationOptionsResponse; + }; + port.GetGuaranteedNumberOfVideoEncoderInstances = function (args) { + var GetGuaranteedNumberOfVideoEncoderInstancesResponse = { + TotalNumber: 1, + H264: 1 + }; + return GetGuaranteedNumberOfVideoEncoderInstancesResponse; + }; + port.GetSnapshotUri = function (args) { + var GetSnapshotUriResponse = {}; + return GetSnapshotUriResponse; + }; + port.GetAudioEncoderConfigurationOptions = function (args) { + var GetAudioEncoderConfigurationOptionsResponse = { Options: [{}] }; + return GetAudioEncoderConfigurationOptionsResponse; + }; }; - camera.setSettings(settings); - - var SetVideoEncoderConfigurationResponse = {}; - return SetVideoEncoderConfigurationResponse; - }; - - port.GetVideoEncoderConfigurationOptions = function (args) { - var GetVideoEncoderConfigurationOptionsResponse = { Options : videoConfigurationOptions }; - return GetVideoEncoderConfigurationOptionsResponse; - }; - - port.GetGuaranteedNumberOfVideoEncoderInstances = function (args) { - var GetGuaranteedNumberOfVideoEncoderInstancesResponse = { - TotalNumber : 1, - H264 : 1 - } - return GetGuaranteedNumberOfVideoEncoderInstancesResponse; - }; - - port.GetSnapshotUri = function (args) { - var GetSnapshotUriResponse = {}; - // MediaUri : { - // Uri : "http://" + config.IpAddress + ":" + config.ServicePort + "/web/snapshot.jpg", - // Timeout : "PT30S", - // InvalidAfterConnect : false, - // InvalidAfterReboot : false - // } - //}; - return GetSnapshotUriResponse; - }; - - port.GetAudioEncoderConfigurationOptions = function (args) { - var GetAudioEncoderConfigurationOptionsResponse = { Options : [{}] }; - return GetAudioEncoderConfigurationOptionsResponse; - }; -}; - -module.exports = MediaService; \ No newline at end of file + return MediaService; +})(SoapService); +module.exports = MediaService; +//# sourceMappingURL=media_service.js.map \ No newline at end of file diff --git a/services/media_service.js.map b/services/media_service.js.map new file mode 100644 index 00000000..81cdbf7e --- /dev/null +++ b/services/media_service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"media_service.js","sourceRoot":"","sources":["media_service.ts"],"names":["MediaService","MediaService.constructor","MediaService.starting","MediaService.started","MediaService.extendService"],"mappings":"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"} \ No newline at end of file diff --git a/services/media_service.ts b/services/media_service.ts new file mode 100644 index 00000000..663bf138 --- /dev/null +++ b/services/media_service.ts @@ -0,0 +1,288 @@ +/// +/// +import fs = require("fs"); +import util = require("util"); +import SoapService = require('../lib/SoapService'); +import { Utils } from '../lib/utils'; +import url = require('url'); +import { Server } from 'http'; +import Camera = require('../lib/camera'); +import { v4l2ctl } from '../lib/v4l2ctl'; +var utils = Utils.utils; + +class MediaService extends SoapService { + media_service: any; + camera: Camera; + + constructor(config: rposConfig, server: Server, camera: Camera) { + super(config, server); + this.media_service = require('./stubs/media_service.js').MediaService; + + this.camera = camera; + this.serviceOptions = { + path: '/onvif/media_service', + services: this.media_service, + xml: fs.readFileSync('./wsdl/media_service.wsdl', 'utf8'), + wsdlPath: 'wsdl/media_service.wsdl', + onReady: function() { + utils.log.info('media_service started'); + } + }; + + this.extendService(); + } + + starting() { + var listeners = this.webserver.listeners('request').slice(); + this.webserver.removeAllListeners('request'); + this.webserver.addListener('request', (request, response, next) => { + utils.log.debug('web request received : %s', request.url); + + var uri = url.parse(request.url, true); + var action = uri.pathname; + if (action == '/web/snapshot.jpg') { + try { + var img = fs.readFileSync('/dev/shm/snapshot.jpg'); + response.writeHead(200, { 'Content-Type': 'image/jpg' }); + response.end(img, 'binary'); + } catch (err) { + utils.log.error("Error opening snapshot : %s", err); + response.end("404: Not Found: " + request); + } + } else { + for (var i = 0, len = listeners.length; i < len; i++) { + listeners[i].call(this, request, response, next); + } + } + }); + }; + + started() { + this.camera.startRtsp(); + }; + + extendService() { + var port = this.media_service.MediaService.Media; + + var cameraOptions = this.camera.options; + var cameraSettings = this.camera.settings; + var camera = this.camera; + + var h264Profiles = v4l2ctl.Controls.CodecControls.h264_profile.getLookupSet().map(ls=> ls.desc); + h264Profiles.splice(1, 1); + + var videoConfigurationOptions = { + QualityRange: { + Min: 1, + Max: 1 + }, + H264: { + ResolutionsAvailable: cameraOptions.resolutions, + GovLengthRange: { + Min: v4l2ctl.Controls.CodecControls.h264_i_frame_period.getRange().min, + Max: v4l2ctl.Controls.CodecControls.h264_i_frame_period.getRange().max + }, + FrameRateRange: { + Min: cameraOptions.framerates[0], + Max: cameraOptions.framerates[cameraOptions.framerates.length - 1] + }, + EncodingIntervalRange: { Min: 1, Max: 1 }, + H264ProfilesSupported: h264Profiles + }, + Extension: { + H264: { + ResolutionsAvailable: cameraOptions.resolutions, + GovLengthRange: { + Min: v4l2ctl.Controls.CodecControls.h264_i_frame_period.getRange().min, + Max: v4l2ctl.Controls.CodecControls.h264_i_frame_period.getRange().max + }, + FrameRateRange: { + Min: cameraOptions.framerates[0], + Max: cameraOptions.framerates[cameraOptions.framerates.length - 1] + }, + EncodingIntervalRange: { Min: 1, Max: 1 }, + H264ProfilesSupported: h264Profiles, + BitrateRange: { + Min: cameraOptions.bitrates[0], + Max: cameraOptions.bitrates[cameraOptions.bitrates.length - 1] + } + } + } + }; + + var videoEncoderConfiguration = { + attributes: { + token: "token" + }, + Name: "PiCameraConfiguration", + UseCount: 0, + Encoding: "H264", + Resolution: { + Width: cameraSettings.resolution.Width, + Height: cameraSettings.resolution.Height + }, + Quality: v4l2ctl.Controls.CodecControls.video_bitrate.value ? null : 1, + RateControl: { + FrameRateLimit: cameraSettings.framerate, + EncodingInterval: 1, + BitrateLimit: v4l2ctl.Controls.CodecControls.video_bitrate.value / 1000 + }, + H264: { + GovLength: v4l2ctl.Controls.CodecControls.h264_i_frame_period.value, + H264Profile: v4l2ctl.Controls.CodecControls.h264_profile.desc + }, + SessionTimeout: "1000" + }; + + var videoSourceConfiguration = { + Name: "Primary Source", + UseCount: 0, + attributes: { + token: "token" + }, + SourceToken: [], + Bounds: { attributes: { x: 0, y: 0, width: 1920, height: 1080 } } + }; + + var audioEncoderConfigurationOptions = { + Options: [] + }; + + var profile = { + Name: "CurrentProfile", + attributes: { + token: "token" + }, + VideoSourceConfiguration: videoSourceConfiguration, + VideoEncoderConfiguration: videoEncoderConfiguration + }; + + port.GetServiceCapabilities = (args /*, cb, headers*/) => { + var GetServiceCapabilitiesResponse = { + Capabilities: { + attributes: { + SnapshotUri: false, + Rotation: false, + VideoSourceMode: true, + OSD: false + }, + ProfileCapabilities: { + attributes: { + MaximumNumberOfProfiles: 1 + } + }, + StreamingCapabilities: { + attributes: { + RTPMulticast: false, + RTP_TCP: true, + RTP_RTSP_TCP: true, + NonAggregateControl: false, + NoRTSPStreaming: false + } + } + } + }; + return GetServiceCapabilitiesResponse; + }; + + //var GetStreamUri = { + //StreamSetup : { + //Stream : { xs:string} + //}, + //ProfileToken : { xs:string} + // + //}; + port.GetStreamUri = (args /*, cb, headers*/) => { + var GetStreamUriResponse = { + MediaUri: { + Uri: `rtsp://${utils.getIpAddress() }:${this.config.RTSPPort}/${this.config.RTSPName}`, + InvalidAfterConnect: false, + InvalidAfterReboot: false, + Timeout: "PT30S" + } + }; + return GetStreamUriResponse; + }; + + port.GetProfile = (args) => { + var GetProfileResponse = { Profile: profile }; + return GetProfileResponse; + }; + + port.GetProfiles = (args) => { + var GetProfilesResponse = { Profiles: [profile] }; + return GetProfilesResponse; + }; + + port.CreateProfile = (args) => { + var CreateProfileResponse = { Profile: profile }; + return CreateProfileResponse; + }; + + port.DeleteProfile = (args) => { + var DeleteProfileResponse = {}; + return DeleteProfileResponse; + }; + + port.GetVideoSourceConfigurations = (args) => { + var GetVideoSourceConfigurationsResponse = { Configurations: [videoSourceConfiguration] }; + return GetVideoSourceConfigurationsResponse; + }; + + port.GetVideoEncoderConfigurations = (args) => { + var GetVideoEncoderConfigurationsResponse = { Configurations: [videoEncoderConfiguration] }; + return GetVideoEncoderConfigurationsResponse; + }; + + port.GetVideoEncoderConfiguration = (args) => { + var GetVideoEncoderConfigurationResponse = { Configuration: videoEncoderConfiguration }; + return GetVideoEncoderConfigurationResponse; + }; + + port.SetVideoEncoderConfiguration = (args) => { + var settings = { + bitrate: args.Configuration.RateControl.BitrateLimit, + framerate: args.Configuration.RateControl.FrameRateLimit, + gop: args.Configuration.H264.GovLength, + profile: args.Configuration.H264.H264Profile, + quality: args.Configuration.Quality instanceof Object ? null : args.Configuration.Quality, + resolution: args.Configuration.Resolution + }; + camera.setSettings(settings); + + var SetVideoEncoderConfigurationResponse = {}; + return SetVideoEncoderConfigurationResponse; + }; + + port.GetVideoEncoderConfigurationOptions = (args) => { + var GetVideoEncoderConfigurationOptionsResponse = { Options: videoConfigurationOptions }; + return GetVideoEncoderConfigurationOptionsResponse; + }; + + port.GetGuaranteedNumberOfVideoEncoderInstances = (args) => { + var GetGuaranteedNumberOfVideoEncoderInstancesResponse = { + TotalNumber: 1, + H264: 1 + } + return GetGuaranteedNumberOfVideoEncoderInstancesResponse; + }; + + port.GetSnapshotUri = (args) => { + var GetSnapshotUriResponse = {}; + // MediaUri : { + // Uri : "http://" + config.IpAddress + ":" + config.ServicePort + "/web/snapshot.jpg", + // Timeout : "PT30S", + // InvalidAfterConnect : false, + // InvalidAfterReboot : false + // } + //}; + return GetSnapshotUriResponse; + }; + + port.GetAudioEncoderConfigurationOptions = (args) => { + var GetAudioEncoderConfigurationOptionsResponse = { Options: [{}] }; + return GetAudioEncoderConfigurationOptionsResponse; + }; + } +} +export = MediaService; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..d4c75bb6 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ES5", + "module": "commonjs", + "noImplicitAny": false, + "removeComments": true, + "preserveConstEnums": false, + "sourceMap": true, + "watch": true + } +} \ No newline at end of file diff --git a/tsd.json b/tsd.json new file mode 100644 index 00000000..d4bb7c37 --- /dev/null +++ b/tsd.json @@ -0,0 +1,18 @@ +{ + "version": "v4", + "repo": "borisyankov/DefinitelyTyped", + "ref": "master", + "path": "typings", + "bundle": "typings/tsd.d.ts", + "installed": { + "body-parser/body-parser.d.ts": { + "commit": "1400e07731048ae841bcebed658cb68539cbfb99" + }, + "node/node.d.ts": { + "commit": "1400e07731048ae841bcebed658cb68539cbfb99" + }, + "express/express.d.ts": { + "commit": "1400e07731048ae841bcebed658cb68539cbfb99" + } + } +} diff --git a/typings/body-parser/body-parser.d.ts b/typings/body-parser/body-parser.d.ts new file mode 100644 index 00000000..994aa4e1 --- /dev/null +++ b/typings/body-parser/body-parser.d.ts @@ -0,0 +1,138 @@ +// Type definitions for body-parser +// Project: http://expressjs.com +// Definitions by: Santi Albo , VILIC VANE , Jonathan Häberle +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module "body-parser" { + import express = require('express'); + + /** + * bodyParser: use individual json/urlencoded middlewares + * @deprecated + */ + + function bodyParser(options?: { + /** + * if deflated bodies will be inflated. (default: true) + */ + inflate?: boolean; + /** + * maximum request body size. (default: '100kb') + */ + limit?: any; + /** + * function to verify body content, the parsing can be aborted by throwing an error. + */ + verify?: (req: express.Request, res: express.Response, buf: Buffer, encoding: string) => void; + /** + * only parse objects and arrays. (default: true) + */ + strict?: boolean; + /** + * passed to JSON.parse(). + */ + receiver?: (key: string, value: any) => any; + /** + * parse extended syntax with the qs module. (default: true) + */ + extended?: boolean; + }): express.RequestHandler; + + module bodyParser { + export function json(options?: { + /** + * if deflated bodies will be inflated. (default: true) + */ + inflate?: boolean; + /** + * maximum request body size. (default: '100kb') + */ + limit?: any; + /** + * request content-type to parse, passed directly to the type-is library. (default: 'json') + */ + type?: any; + /** + * function to verify body content, the parsing can be aborted by throwing an error. + */ + verify?: (req: express.Request, res: express.Response, buf: Buffer, encoding: string) => void; + /** + * only parse objects and arrays. (default: true) + */ + strict?: boolean; + /** + * passed to JSON.parse(). + */ + receiver?: (key: string, value: any) => any; + }): express.RequestHandler; + + export function raw(options?: { + /** + * if deflated bodies will be inflated. (default: true) + */ + inflate?: boolean; + /** + * maximum request body size. (default: '100kb') + */ + limit?: any; + /** + * request content-type to parse, passed directly to the type-is library. (default: 'application/octet-stream') + */ + type?: any; + /** + * function to verify body content, the parsing can be aborted by throwing an error. + */ + verify?: (req: express.Request, res: express.Response, buf: Buffer, encoding: string) => void; + }): express.RequestHandler; + + export function text(options?: { + /** + * if deflated bodies will be inflated. (default: true) + */ + inflate?: boolean; + /** + * maximum request body size. (default: '100kb') + */ + limit?: any; + /** + * request content-type to parse, passed directly to the type-is library. (default: 'text/plain') + */ + type?: any; + /** + * function to verify body content, the parsing can be aborted by throwing an error. + */ + verify?: (req: express.Request, res: express.Response, buf: Buffer, encoding: string) => void; + /** + * the default charset to parse as, if not specified in content-type. (default: 'utf-8') + */ + defaultCharset?: string; + }): express.RequestHandler; + + export function urlencoded(options?: { + /** + * if deflated bodies will be inflated. (default: true) + */ + inflate?: boolean; + /** + * maximum request body size. (default: '100kb') + */ + limit?: any; + /** + * request content-type to parse, passed directly to the type-is library. (default: 'urlencoded') + */ + type?: any; + /** + * function to verify body content, the parsing can be aborted by throwing an error. + */ + verify?: (req: express.Request, res: express.Response, buf: Buffer, encoding: string) => void; + /** + * parse extended syntax with the qs module. (default: true) + */ + extended?: boolean; + }): express.RequestHandler; + } + + export = bodyParser; +} \ No newline at end of file diff --git a/typings/node/node.d.ts b/typings/node/node.d.ts new file mode 100644 index 00000000..b0a7b77e --- /dev/null +++ b/typings/node/node.d.ts @@ -0,0 +1,1519 @@ +// Type definitions for Node.js v0.12.0 +// Project: http://nodejs.org/ +// Definitions by: Microsoft TypeScript , DefinitelyTyped +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/************************************************ +* * +* Node.js v0.12.0 API * +* * +************************************************/ + +/************************************************ +* * +* GLOBAL * +* * +************************************************/ +declare var process: NodeJS.Process; +declare var global: NodeJS.Global; + +declare var __filename: string; +declare var __dirname: string; + +declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearTimeout(timeoutId: NodeJS.Timer): void; +declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearInterval(intervalId: NodeJS.Timer): void; +declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; +declare function clearImmediate(immediateId: any): void; + +declare var require: { + (id: string): any; + resolve(id:string): string; + cache: any; + extensions: any; + main: any; +}; + +declare var module: { + exports: any; + require(id: string): any; + id: string; + filename: string; + loaded: boolean; + parent: any; + children: any[]; +}; + +// Same as module.exports +declare var exports: any; +declare var SlowBuffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (size: Uint8Array): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + + +// Buffer class +interface Buffer extends NodeBuffer {} +declare var Buffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (size: Uint8Array): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + +/************************************************ +* * +* GLOBAL INTERFACES * +* * +************************************************/ +declare module NodeJS { + export interface ErrnoException extends Error { + errno?: number; + code?: string; + path?: string; + syscall?: string; + } + + export interface EventEmitter { + addListener(event: string, listener: Function): EventEmitter; + on(event: string, listener: Function): EventEmitter; + once(event: string, listener: Function): EventEmitter; + removeListener(event: string, listener: Function): EventEmitter; + removeAllListeners(event?: string): EventEmitter; + setMaxListeners(n: number): void; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + } + + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): string|Buffer; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): ReadableStream; + } + + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface ReadWriteStream extends ReadableStream, WritableStream {} + + export interface Process extends EventEmitter { + stdout: WritableStream; + stderr: WritableStream; + stdin: ReadableStream; + argv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + env: any; + exit(code?: number): void; + getgid(): number; + setgid(id: number): void; + setgid(id: string): void; + getuid(): number; + setuid(id: number): void; + setuid(id: string): void; + version: string; + versions: { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + openssl: string; + }; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid: number, signal?: string): void; + pid: number; + title: string; + arch: string; + platform: string; + memoryUsage(): { rss: number; heapTotal: number; heapUsed: number; }; + nextTick(callback: Function): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?:number[]): number[]; + + // Worker + send?(message: any, sendHandle?: any): void; + } + + export interface Global { + Array: typeof Array; + ArrayBuffer: typeof ArrayBuffer; + Boolean: typeof Boolean; + Buffer: typeof Buffer; + DataView: typeof DataView; + Date: typeof Date; + Error: typeof Error; + EvalError: typeof EvalError; + Float32Array: typeof Float32Array; + Float64Array: typeof Float64Array; + Function: typeof Function; + GLOBAL: Global; + Infinity: typeof Infinity; + Int16Array: typeof Int16Array; + Int32Array: typeof Int32Array; + Int8Array: typeof Int8Array; + Intl: typeof Intl; + JSON: typeof JSON; + Map: typeof Map; + Math: typeof Math; + NaN: typeof NaN; + Number: typeof Number; + Object: typeof Object; + Promise: Function; + RangeError: typeof RangeError; + ReferenceError: typeof ReferenceError; + RegExp: typeof RegExp; + Set: typeof Set; + String: typeof String; + Symbol: Function; + SyntaxError: typeof SyntaxError; + TypeError: typeof TypeError; + URIError: typeof URIError; + Uint16Array: typeof Uint16Array; + Uint32Array: typeof Uint32Array; + Uint8Array: typeof Uint8Array; + Uint8ClampedArray: Function; + WeakMap: typeof WeakMap; + WeakSet: Function; + clearImmediate: (immediateId: any) => void; + clearInterval: (intervalId: NodeJS.Timer) => void; + clearTimeout: (timeoutId: NodeJS.Timer) => void; + console: typeof console; + decodeURI: typeof decodeURI; + decodeURIComponent: typeof decodeURIComponent; + encodeURI: typeof encodeURI; + encodeURIComponent: typeof encodeURIComponent; + escape: (str: string) => string; + eval: typeof eval; + global: Global; + isFinite: typeof isFinite; + isNaN: typeof isNaN; + parseFloat: typeof parseFloat; + parseInt: typeof parseInt; + process: Process; + root: Global; + setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; + setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + undefined: typeof undefined; + unescape: (str: string) => string; + } + + export interface Timer { + ref() : void; + unref() : void; + } +} + +/** + * @deprecated + */ +interface NodeBuffer { + [index: number]: number; + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): any; + length: number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + readUInt8(offset: number, noAsset?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + writeUInt8(value: number, offset: number, noAssert?: boolean): void; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): void; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): void; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): void; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): void; + writeInt8(value: number, offset: number, noAssert?: boolean): void; + writeInt16LE(value: number, offset: number, noAssert?: boolean): void; + writeInt16BE(value: number, offset: number, noAssert?: boolean): void; + writeInt32LE(value: number, offset: number, noAssert?: boolean): void; + writeInt32BE(value: number, offset: number, noAssert?: boolean): void; + writeFloatLE(value: number, offset: number, noAssert?: boolean): void; + writeFloatBE(value: number, offset: number, noAssert?: boolean): void; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): void; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): void; + fill(value: any, offset?: number, end?: number): void; +} + +/************************************************ +* * +* MODULES * +* * +************************************************/ +declare module "buffer" { + export var INSPECT_MAX_BYTES: number; +} + +declare module "querystring" { + export function stringify(obj: any, sep?: string, eq?: string): string; + export function parse(str: string, sep?: string, eq?: string, options?: { maxKeys?: number; }): any; + export function escape(str: string): string; + export function unescape(str: string): string; +} + +declare module "events" { + export class EventEmitter implements NodeJS.EventEmitter { + static listenerCount(emitter: EventEmitter, event: string): number; + + addListener(event: string, listener: Function): EventEmitter; + on(event: string, listener: Function): EventEmitter; + once(event: string, listener: Function): EventEmitter; + removeListener(event: string, listener: Function): EventEmitter; + removeAllListeners(event?: string): EventEmitter; + setMaxListeners(n: number): void; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + } +} + +declare module "http" { + import events = require("events"); + import net = require("net"); + import stream = require("stream"); + + export interface Server extends events.EventEmitter { + listen(port: number, hostname?: string, backlog?: number, callback?: Function): Server; + listen(port: number, hostname?: string, callback?: Function): Server; + listen(path: string, callback?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + close(cb?: any): Server; + address(): { port: number; family: string; address: string; }; + maxHeadersCount: number; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ServerRequest extends IncomingMessage { + connection: net.Socket; + } + export interface ServerResponse extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + writeContinue(): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; + writeHead(statusCode: number, headers?: any): void; + statusCode: number; + setHeader(name: string, value: string): void; + sendDate: boolean; + getHeader(name: string): string; + removeHeader(name: string): void; + write(chunk: any, encoding?: string): any; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientRequest extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + write(chunk: any, encoding?: string): void; + abort(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface IncomingMessage extends events.EventEmitter, stream.Readable { + httpVersion: string; + headers: any; + rawHeaders: string[]; + trailers: any; + rawTrailers: any; + setTimeout(msecs: number, callback: Function): NodeJS.Timer; + /** + * Only valid for request obtained from http.Server. + */ + method?: string; + /** + * Only valid for request obtained from http.Server. + */ + url?: string; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusCode?: number; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusMessage?: string; + socket: net.Socket; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ClientResponse extends IncomingMessage { } + + export interface AgentOptions { + /** + * Keep sockets around in a pool to be used by other requests in the future. Default = false + */ + keepAlive?: boolean; + /** + * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. + * Only relevant if keepAlive is set to true. + */ + keepAliveMsecs?: number; + /** + * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity + */ + maxSockets?: number; + /** + * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. + */ + maxFreeSockets?: number; + } + + export class Agent { + maxSockets: number; + sockets: any; + requests: any; + + constructor(opts?: AgentOptions); + + /** + * Destroy any sockets that are currently in use by the agent. + * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, + * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, + * sockets may hang open for quite a long time before the server terminates them. + */ + destroy(): void; + } + + export var STATUS_CODES: { + [errorCode: number]: string; + [errorCode: string]: string; + }; + export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) =>void ): Server; + export function createClient(port?: number, host?: string): any; + export function request(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; + export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; + export var globalAgent: Agent; +} + +declare module "cluster" { + import child = require("child_process"); + import events = require("events"); + + export interface ClusterSettings { + exec?: string; + args?: string[]; + silent?: boolean; + } + + export class Worker extends events.EventEmitter { + id: string; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any): void; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + } + + export var settings: ClusterSettings; + export var isMaster: boolean; + export var isWorker: boolean; + export function setupMaster(settings?: ClusterSettings): void; + export function fork(env?: any): Worker; + export function disconnect(callback?: Function): void; + export var worker: Worker; + export var workers: Worker[]; + + // Event emitter + export function addListener(event: string, listener: Function): void; + export function on(event: string, listener: Function): any; + export function once(event: string, listener: Function): void; + export function removeListener(event: string, listener: Function): void; + export function removeAllListeners(event?: string): void; + export function setMaxListeners(n: number): void; + export function listeners(event: string): Function[]; + export function emit(event: string, ...args: any[]): boolean; +} + +declare module "zlib" { + import stream = require("stream"); + export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } + + export interface Gzip extends stream.Transform { } + export interface Gunzip extends stream.Transform { } + export interface Deflate extends stream.Transform { } + export interface Inflate extends stream.Transform { } + export interface DeflateRaw extends stream.Transform { } + export interface InflateRaw extends stream.Transform { } + export interface Unzip extends stream.Transform { } + + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; + + export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; + export var Z_NULL: number; +} + +declare module "os" { + export function tmpdir(): string; + export function hostname(): string; + export function type(): string; + export function platform(): string; + export function arch(): string; + export function release(): string; + export function uptime(): number; + export function loadavg(): number[]; + export function totalmem(): number; + export function freemem(): number; + export function cpus(): { model: string; speed: number; times: { user: number; nice: number; sys: number; idle: number; irq: number; }; }[]; + export function networkInterfaces(): any; + export var EOL: string; +} + +declare module "https" { + import tls = require("tls"); + import events = require("events"); + import http = require("http"); + + export interface ServerOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + crl?: any; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; + SNICallback?: (servername: string) => any; + } + + export interface RequestOptions { + host?: string; + hostname?: string; + port?: number; + path?: string; + method?: string; + headers?: any; + auth?: string; + agent?: any; + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + } + + export interface Agent { + maxSockets: number; + sockets: any; + requests: any; + } + export var Agent: { + new (options?: RequestOptions): Agent; + }; + export interface Server extends tls.Server { } + export function createServer(options: ServerOptions, requestListener?: Function): Server; + export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; + export var globalAgent: Agent; +} + +declare module "punycode" { + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): string; + encode(codePoints: number[]): string; + } + export var version: any; +} + +declare module "repl" { + import stream = require("stream"); + import events = require("events"); + + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + } + export function start(options: ReplOptions): events.EventEmitter; +} + +declare module "readline" { + import events = require("events"); + import stream = require("stream"); + + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string, length: number): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: Function): void; + pause(): void; + resume(): void; + close(): void; + write(data: any, key?: any): void; + } + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output: NodeJS.WritableStream; + completer?: Function; + terminal?: boolean; + } + export function createInterface(options: ReadLineOptions): ReadLine; +} + +declare module "vm" { + export interface Context { } + export interface Script { + runInThisContext(): void; + runInNewContext(sandbox?: Context): void; + } + export function runInThisContext(code: string, filename?: string): void; + export function runInNewContext(code: string, sandbox?: Context, filename?: string): void; + export function runInContext(code: string, context: Context, filename?: string): void; + export function createContext(initSandbox?: Context): Context; + export function createScript(code: string, filename?: string): Script; +} + +declare module "child_process" { + import events = require("events"); + import stream = require("stream"); + + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + pid: number; + kill(signal?: string): void; + send(message: any, sendHandle?: any): void; + disconnect(): void; + } + + export function spawn(command: string, args?: string[], options?: { + cwd?: string; + stdio?: any; + custom?: any; + env?: any; + detached?: boolean; + }): ChildProcess; + export function exec(command: string, options: { + cwd?: string; + stdio?: any; + customFds?: any; + env?: any; + encoding?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function exec(command: string, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, + callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, args?: string[], + callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, args?: string[], options?: { + cwd?: string; + stdio?: any; + customFds?: any; + env?: any; + encoding?: string; + timeout?: number; + maxBuffer?: string; + killSignal?: string; + }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function fork(modulePath: string, args?: string[], options?: { + cwd?: string; + env?: any; + encoding?: string; + }): ChildProcess; + export function execSync(command: string, options?: { + cwd?: string; + input?: string|Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + encoding?: string; + }): ChildProcess; + export function execFileSync(command: string, args?: string[], options?: { + cwd?: string; + input?: string|Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + encoding?: string; + }): ChildProcess; +} + +declare module "url" { + export interface Url { + href: string; + protocol: string; + auth: string; + hostname: string; + port: string; + host: string; + pathname: string; + search: string; + query: any; // string | Object + slashes: boolean; + hash?: string; + path?: string; + } + + export interface UrlOptions { + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: any; + hash?: string; + path?: string; + } + + export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url; + export function format(url: UrlOptions): string; + export function resolve(from: string, to: string): string; +} + +declare module "dns" { + export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) =>void ): string; + export function lookup(domain: string, callback: (err: Error, address: string, family: number) =>void ): string; + export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve4(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve6(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function reverse(ip: string, callback: (err: Error, domains: string[]) =>void ): string[]; +} + +declare module "net" { + import stream = require("stream"); + + export interface Socket extends stream.Duplex { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + connect(port: number, host?: string, connectionListener?: Function): void; + connect(path: string, connectionListener?: Function): void; + bufferSize: number; + setEncoding(encoding?: string): void; + write(data: any, encoding?: string, callback?: Function): void; + destroy(): void; + pause(): void; + resume(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setKeepAlive(enable?: boolean, initialDelay?: number): void; + address(): { port: number; family: string; address: string; }; + unref(): void; + ref(): void; + + remoteAddress: string; + remoteFamily: string; + remotePort: number; + localAddress: string; + localPort: number; + bytesRead: number; + bytesWritten: number; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + + export var Socket: { + new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; + }; + + export interface Server extends Socket { + listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + maxConnections: number; + connections: number; + } + export function createServer(connectionListener?: (socket: Socket) =>void ): Server; + export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server; + export function connect(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; +} + +declare module "dgram" { + import events = require("events"); + + interface RemoteInfo { + address: string; + port: number; + size: number; + } + + interface AddressInfo { + address: string; + family: string; + port: number; + } + + export function createSocket(type: string, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + + interface Socket extends events.EventEmitter { + send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + bind(port: number, address?: string, callback?: () => void): void; + close(): void; + address(): AddressInfo; + setBroadcast(flag: boolean): void; + setMulticastTTL(ttl: number): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + } +} + +declare module "fs" { + import stream = require("stream"); + import events = require("events"); + + interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atime: Date; + mtime: Date; + ctime: Date; + } + + interface FSWatcher extends events.EventEmitter { + close(): void; + } + + export interface ReadStream extends stream.Readable { + close(): void; + } + export interface WriteStream extends stream.Writable { + close(): void; + } + + export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function renameSync(oldPath: string, newPath: string): void; + export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: string, len?: number): void; + export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number): void; + export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chownSync(path: string, uid: number, gid: number): void; + export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchownSync(path: string, uid: number, gid: number): void; + export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmodSync(path: string, mode: number): void; + export function chmodSync(path: string, mode: string): void; + export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmodSync(fd: number, mode: number): void; + export function fchmodSync(fd: number, mode: string): void; + export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmodSync(path: string, mode: number): void; + export function lchmodSync(path: string, mode: string): void; + export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function statSync(path: string): Stats; + export function lstatSync(path: string): Stats; + export function fstatSync(fd: number): Stats; + export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function linkSync(srcpath: string, dstpath: string): void; + export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; + export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; + export function readlinkSync(path: string): string; + export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void; + export function realpathSync(path: string, cache?: {[path: string]: string}): string; + export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function unlinkSync(path: string): void; + export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function rmdirSync(path: string): void; + export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function mkdirSync(path: string, mode?: number): void; + export function mkdirSync(path: string, mode?: string): void; + export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdirSync(path: string): string[]; + export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function closeSync(fd: number): void; + export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function openSync(path: string, flags: string, mode?: number): number; + export function openSync(path: string, flags: string, mode?: string): number; + export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimesSync(path: string, atime: number, mtime: number): void; + export function utimesSync(path: string, atime: Date, mtime: Date): void; + export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimesSync(fd: number, atime: number, mtime: number): void; + export function futimesSync(fd: number, atime: Date, mtime: Date): void; + export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fsyncSync(fd: number): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; + export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void ): void; + export function readFileSync(filename: string, encoding: string): string; + export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; + export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; + export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; + export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; + export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; + export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; + export function exists(path: string, callback?: (exists: boolean) => void): void; + export function existsSync(path: string): boolean; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: string; + mode?: number; + bufferSize?: number; + }): ReadStream; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: string; + mode?: string; + bufferSize?: number; + }): ReadStream; + export function createWriteStream(path: string, options?: { + flags?: string; + encoding?: string; + string?: string; + }): WriteStream; +} + +declare module "path" { + + export interface ParsedPath { + root: string; + dir: string; + base: string; + ext: string; + name: string; + } + + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + + export module posix { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } + + export module win32 { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } +} + +declare module "string_decoder" { + export interface NodeStringDecoder { + write(buffer: Buffer): string; + detectIncompleteChar(buffer: Buffer): number; + } + export var StringDecoder: { + new (encoding: string): NodeStringDecoder; + }; +} + +declare module "tls" { + import crypto = require("crypto"); + import net = require("net"); + import stream = require("stream"); + + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; + + export interface TlsOptions { + pfx?: any; //string or buffer + key?: any; //string or buffer + passphrase?: string; + cert?: any; + ca?: any; //string or buffer + crl?: any; //string or string array + ciphers?: string; + honorCipherOrder?: any; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; //array or Buffer; + SNICallback?: (servername: string) => any; + } + + export interface ConnectionOptions { + host?: string; + port?: number; + socket?: net.Socket; + pfx?: any; //string | Buffer + key?: any; //string | Buffer + passphrase?: string; + cert?: any; //string | Buffer + ca?: any; //Array of string | Buffer + rejectUnauthorized?: boolean; + NPNProtocols?: any; //Array of string | Buffer + servername?: string; + } + + export interface Server extends net.Server { + // Extended base methods + listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + + listen(port: number, host?: string, callback?: Function): Server; + close(): Server; + address(): { port: number; family: string; address: string; }; + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; + maxConnections: number; + connections: number; + } + + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } + + export interface SecurePair { + encrypted: any; + cleartext: any; + } + + export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server; + export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; +} + +declare module "crypto" { + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: any; //string | string array + crl: any; //string | string array + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string): Hmac; + export function createHmac(algorithm: string, key: Buffer): Hmac; + interface Hash { + update(data: any, input_encoding?: string): Hash; + digest(encoding: 'buffer'): Buffer; + digest(encoding: string): any; + digest(): Buffer; + } + interface Hmac { + update(data: any, input_encoding?: string): Hmac; + digest(encoding: 'buffer'): Buffer; + digest(encoding: string): any; + digest(): Buffer; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + interface Cipher { + update(data: Buffer): Buffer; + update(data: string, input_encoding?: string, output_encoding?: string): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding: boolean): void; + } + export function createDecipher(algorithm: string, password: any): Decipher; + export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + interface Decipher { + update(data: Buffer): Buffer; + update(data: string, input_encoding?: string, output_encoding?: string): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding: boolean): void; + } + export function createSign(algorithm: string): Signer; + interface Signer { + update(data: any): void; + sign(private_key: string, output_format: string): string; + } + export function createVerify(algorith: string): Verify; + interface Verify { + update(data: any): void; + verify(object: string, signature: string, signature_format?: string): boolean; + } + export function createDiffieHellman(prime_length: number): DiffieHellman; + export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; + interface DiffieHellman { + generateKeys(encoding?: string): string; + computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; + getPrime(encoding?: string): string; + getGenerator(encoding: string): string; + getPublicKey(encoding?: string): string; + getPrivateKey(encoding?: string): string; + setPublicKey(public_key: string, encoding?: string): void; + setPrivateKey(public_key: string, encoding?: string): void; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number) : Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; +} + +declare module "stream" { + import events = require("events"); + + export interface Stream extends events.EventEmitter { + pipe(destination: T, options?: { end?: boolean; }): T; + } + + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + } + + export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { + readable: boolean; + constructor(opts?: ReadableOptions); + _read(size: number): void; + read(size?: number): string|Buffer; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + } + + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + } + + export class Writable extends events.EventEmitter implements NodeJS.WritableStream { + writable: boolean; + constructor(opts?: WritableOptions); + _write(data: Buffer, encoding: string, callback: Function): void; + _write(data: string, encoding: string, callback: Function): void; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + } + + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements NodeJS.ReadWriteStream { + writable: boolean; + constructor(opts?: DuplexOptions); + _write(data: Buffer, encoding: string, callback: Function): void; + _write(data: string, encoding: string, callback: Function): void; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface TransformOptions extends ReadableOptions, WritableOptions {} + + // Note: Transform lacks the _read and _write methods of Readable/Writable. + export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { + readable: boolean; + writable: boolean; + constructor(opts?: TransformOptions); + _transform(chunk: Buffer, encoding: string, callback: Function): void; + _transform(chunk: string, encoding: string, callback: Function): void; + _flush(callback: Function): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export class PassThrough extends Transform {} +} + +declare module "util" { + export interface InspectOptions { + showHidden?: boolean; + depth?: number; + colors?: boolean; + customInspect?: boolean; + } + + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; + export function inspect(object: any, options: InspectOptions): string; + export function isArray(object: any): boolean; + export function isRegExp(object: any): boolean; + export function isDate(object: any): boolean; + export function isError(object: any): boolean; + export function inherits(constructor: any, superConstructor: any): void; +} + +declare module "assert" { + function internal (value: any, message?: string): void; + module internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; + + constructor(options?: {message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function}); + } + + export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export var throws: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export var doesNotThrow: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export function ifError(value: any): void; + } + + export = internal; +} + +declare module "tty" { + import net = require("net"); + + export function isatty(fd: number): boolean; + export interface ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + } + export interface WriteStream extends net.Socket { + columns: number; + rows: number; + } +} + +declare module "domain" { + import events = require("events"); + + export class Domain extends events.EventEmitter { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + + addListener(event: string, listener: Function): Domain; + on(event: string, listener: Function): Domain; + once(event: string, listener: Function): Domain; + removeListener(event: string, listener: Function): Domain; + removeAllListeners(event?: string): Domain; + } + + export function create(): Domain; +} diff --git a/typings/rpos/rpos.d.ts b/typings/rpos/rpos.d.ts new file mode 100644 index 00000000..3dca7a36 --- /dev/null +++ b/typings/rpos/rpos.d.ts @@ -0,0 +1,73 @@ +/// +interface rposConfig { + NetworkAdapters: string[]; + IpAddress: string; + ServicePort: number; + RTSPPort: number; + RTSPName: string; + DeviceInformation: DeviceInformation; + logLevel: number; + logSoapCalls: Boolean; +} + +interface DeviceInformation { + Manufacturer: string; + Model: string; + HardwareId: string; + SerialNumber: string; + FirmwareVersion: string; +} + +interface TypeConstructor extends Function { + name: string; +} + +interface SoapServiceOptions { + path: string, + services: any, + xml: any, + wsdlPath: string, + onReady: () => void; +} + +interface Date { + stdTimezoneOffset: () => number; + dst: () => boolean; +} + +interface UserControlOptions { + stringify?: (T) => string, + range?: { + min: T, + max: T, + allowZero?: boolean, + step?: T + } + lookupSet?: UserControlsLookupSet; +} + +interface UserControlsLookup { + value: T; + desc: string; +} +interface UserControlsLookupSet extends Array> { + +} + +interface Resolution { + Width: number; + Height: number; +} +interface CameraSettingsParameter { + gop: number; //keyframe every X sec. + resolution: Resolution; + framerate: number; + bitrate: number; + profile: string; + quality: number; +} +interface CameraSettingsBase { + forceGop: boolean; // Use iframe interval setting from v4l2ctl.json instead of Onvif + resolution: Resolution; + framerate: number; +} \ No newline at end of file diff --git a/typings/tsd.d.ts b/typings/tsd.d.ts new file mode 100644 index 00000000..052093ce --- /dev/null +++ b/typings/tsd.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// diff --git a/views/camera.ntl b/views/camera.ntl new file mode 100644 index 00000000..aefb97fe --- /dev/null +++ b/views/camera.ntl @@ -0,0 +1,17 @@ + + + + + Camera settings + + + + + + {{row}} + + + SET + + + \ No newline at end of file