OpenROV /
openrov-cockpit
| 1 | var logger; |
||
| 2 | |||
| 3 | const exec = require('child_process').exec; |
||
|
0 ignored issues
–
show
Backwards Compatibility
introduced
by
Loading history...
|
|||
| 4 | const fs = require('fs'); |
||
|
0 ignored issues
–
show
|
|||
| 5 | const path = require('path'); |
||
|
0 ignored issues
–
show
|
|||
| 6 | const respawn = require('respawn'); |
||
|
0 ignored issues
–
show
|
|||
| 7 | const io = require('socket.io-client'); |
||
|
0 ignored issues
–
show
|
|||
| 8 | const events = require('events'); |
||
|
0 ignored issues
–
show
|
|||
| 9 | |||
| 10 | var defaults = { |
||
| 11 | port: 8099, |
||
| 12 | wspath: '/geovideo' |
||
| 13 | }; |
||
| 14 | |||
| 15 | var geomux = function geomux(name, deps) { |
||
| 16 | logger= deps.logger; |
||
| 17 | |||
| 18 | logger.info('The geo-mux plugin.'); |
||
| 19 | var self = this; |
||
| 20 | this.deps = deps; |
||
| 21 | this.services = {}; |
||
| 22 | var emitter = new events.EventEmitter(); |
||
| 23 | var global = deps.globalEventLoop; |
||
| 24 | var cockpit = deps.cockpit; |
||
| 25 | this.flag_experimentH264 = false; |
||
| 26 | this._monitor = null; |
||
| 27 | var videoServer = io.connect('http://localhost:' + defaults.port, { |
||
| 28 | path: defaults.wspath, |
||
| 29 | reconnection: true, |
||
| 30 | reconnectionAttempts: Infinity, |
||
| 31 | reconnectionDelay: 10 |
||
| 32 | }); |
||
| 33 | var cameras = {}; |
||
| 34 | // ---------------------------- |
||
| 35 | // Register all other listeners |
||
| 36 | cockpit.on('plugin.geomuxp.command', function(camera, command, params) { |
||
| 37 | // Forward to geo-video-server |
||
| 38 | videoServer.emit('geomux.command', camera, command, params); |
||
| 39 | }); |
||
| 40 | |||
| 41 | global.withHistory.on('settings-change.videosettings',function(settings){ |
||
| 42 | if ((self.flag_experimentH264!==settings.videosettings['use-geoserve']) && (self._monitor !== null)){ |
||
| 43 | self.stop(function(){ |
||
| 44 | self.flag_experimentH264=settings.videosettings['use-geoserve']; |
||
| 45 | self.start(); |
||
| 46 | }); |
||
| 47 | } else { |
||
| 48 | self.flag_experimentH264=settings.videosettings['use-geoserve']; |
||
| 49 | } |
||
| 50 | }); |
||
| 51 | |||
| 52 | videoServer.on('video-deviceRegistration', function(update) { |
||
| 53 | logger.debug('Got device update'); |
||
| 54 | }); |
||
| 55 | // Video endpoint announcement |
||
| 56 | videoServer.on('geomux.video.announcement', function(camera, channel, info) { |
||
| 57 | logger.debug('Announcement info: ' + JSON.stringify(info)); |
||
| 58 | // Emit message on global event loop to register with the Video plugin |
||
| 59 | self.deps.globalEventLoop.emit('CameraRegistration', { |
||
| 60 | location: info.txtRecord.cameraLocation, |
||
| 61 | videoMimeType: info.txtRecord.videoMimeType, |
||
| 62 | resolution: info.txtRecord.resolution, |
||
| 63 | framerate: info.txtRecord.framerate, |
||
| 64 | wspath: info.txtRecord.wspath, |
||
| 65 | relativeServiceUrl: info.txtRecord.relativeServiceUrl, |
||
| 66 | sourcePort: info.port, |
||
| 67 | sourceAddress: info.addresses[0], |
||
| 68 | connectionType: 'socket.io' |
||
| 69 | }); |
||
| 70 | }); |
||
| 71 | // Channel settings |
||
| 72 | videoServer.on('geomux.channel.settings', function(camera, channel, settings) { |
||
| 73 | UpdateCameraInfo(camera, channel); |
||
| 74 | self.deps.cockpit.emit('plugin.geomuxp.' + camera + '_' + channel + '.settings', settings); |
||
| 75 | }); |
||
| 76 | |||
| 77 | // Channel health |
||
| 78 | videoServer.on('geomux.channel.health', function(camera, channel, health) { |
||
| 79 | UpdateCameraInfo(camera, channel); |
||
| 80 | self.deps.cockpit.emit('plugin.geomuxp.' + camera + '_' + channel + '.health', health); |
||
| 81 | }); |
||
| 82 | // Channel api |
||
| 83 | videoServer.on('geomux.channel.api', function(camera, channel, api) { |
||
| 84 | UpdateCameraInfo(camera, channel); |
||
| 85 | self.deps.cockpit.emit('plugin.geomuxp.' + camera + '_' + channel + '.api', api); |
||
| 86 | }); |
||
| 87 | // Channel status |
||
| 88 | videoServer.on('geomux.channel.status', function(camera, channel, status) { |
||
| 89 | UpdateCameraInfo(camera, channel); |
||
| 90 | self.deps.cockpit.emit('plugin.geomuxp.' + camera + '_' + channel + '.status', status); |
||
| 91 | }); |
||
| 92 | // Channel error |
||
| 93 | videoServer.on('geomux.channel.error', function(camera, channel, error) { |
||
| 94 | UpdateCameraInfo(camera, channel); |
||
| 95 | self.deps.cockpit.emit('plugin.geomuxp.' + camera + '_' + channel + '.error', error); |
||
| 96 | }); |
||
| 97 | // Upon connecting to video server, set up listeners |
||
| 98 | videoServer.on('connect', function() { |
||
| 99 | logger.info('Successfully connected to geo-video-server'); |
||
| 100 | // Tell geo-video-server to start the daemons |
||
| 101 | videoServer.emit('geomux.ready'); |
||
| 102 | }); |
||
| 103 | // Disconnection |
||
| 104 | videoServer.on('disconnect', function() { |
||
| 105 | logger.info('Disconnected from video server.'); |
||
| 106 | }); |
||
| 107 | // Error |
||
| 108 | videoServer.on('error', function(err) { |
||
| 109 | logger.error(err,'Video Server Connection Error'); |
||
| 110 | }); |
||
| 111 | // Reconnect attempt |
||
| 112 | videoServer.on('reconnect', function() { |
||
| 113 | logger.info('Attempting to reconnect'); |
||
| 114 | }); |
||
| 115 | // Helper function to update local store of cameras and channels |
||
| 116 | function UpdateCameraInfo(camera, channel) { |
||
| 117 | if (cameras[camera] === undefined) { |
||
| 118 | // Create the camera |
||
| 119 | cameras[camera] = {}; |
||
| 120 | // Add the channel |
||
| 121 | cameras[camera][channel] = {}; |
||
| 122 | self.deps.cockpit.emit('plugin.geomuxp.cameraInfo', cameras); |
||
| 123 | } else if (cameras[camera][channel] === undefined) { |
||
| 124 | // Add the channel |
||
| 125 | cameras[camera][channel] = {}; |
||
| 126 | self.deps.cockpit.emit('plugin.geomuxp.cameraInfo', cameras); |
||
| 127 | } |
||
| 128 | } |
||
| 129 | }; |
||
| 130 | |||
| 131 | geomux.prototype.stop = function stop(callback) |
||
| 132 | { |
||
| 133 | logger.info('Stopping geomux program'); |
||
| 134 | var self = this; |
||
| 135 | this._monitor.stop( function(){ |
||
| 136 | self._monitor = null; |
||
| 137 | if (callback){ |
||
| 138 | callback(); |
||
| 139 | } |
||
| 140 | } |
||
| 141 | ); |
||
| 142 | |||
| 143 | } |
||
|
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: Loading history...
|
|||
| 144 | |||
| 145 | // This gets called when plugins are started |
||
| 146 | geomux.prototype.start = function start() |
||
| 147 | { |
||
| 148 | logger.info('Starting geomux program'); |
||
| 149 | var geoprogram = ''; |
||
| 150 | |||
| 151 | // Figure out which video server to use |
||
| 152 | if( process.env.USE_MOCK == 'true' ) |
||
| 153 | { |
||
| 154 | if (process.env.MOCK_VIDEO_TYPE === "GEOMUX") |
||
| 155 | { |
||
| 156 | geoprogram = require.resolve('geo-video-simulator'); |
||
| 157 | } |
||
| 158 | else |
||
| 159 | { |
||
| 160 | return; |
||
| 161 | } |
||
| 162 | } |
||
| 163 | else |
||
| 164 | { |
||
| 165 | // Find the geo-video-server app |
||
| 166 | try |
||
| 167 | { |
||
| 168 | geoprogram = require.resolve('geo-video-server'); |
||
| 169 | } |
||
| 170 | catch (er) |
||
| 171 | { |
||
| 172 | logger.error('geo-video-server not installed'); |
||
| 173 | return; |
||
| 174 | } |
||
| 175 | } |
||
| 176 | |||
| 177 | var launch_options = []; |
||
| 178 | if( process.env.USE_MOCK != 'true' ){ |
||
| 179 | //Don't use platform specific nice in mock mode |
||
| 180 | launch_options= launch_options.concat([ |
||
| 181 | 'nice', |
||
| 182 | '--19' |
||
| 183 | ]) |
||
|
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: Loading history...
|
|||
| 184 | } |
||
| 185 | |||
| 186 | if (this.flag_experimentH264){ |
||
| 187 | launch_options = launch_options.concat([ |
||
| 188 | 'geoserve' |
||
| 189 | ]) |
||
|
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: Loading history...
|
|||
| 190 | } else { |
||
| 191 | |||
| 192 | // Create all launch options |
||
| 193 | launch_options = launch_options.concat([ |
||
| 194 | 'node', |
||
| 195 | geoprogram, |
||
| 196 | '--p', |
||
| 197 | defaults.port, |
||
| 198 | '--w', |
||
| 199 | defaults.wspath, |
||
| 200 | '--c', |
||
| 201 | 0, |
||
| 202 | '--u', |
||
| 203 | process.env.DEV_MODE === 'true' ? ':8099' : '' |
||
| 204 | ]); |
||
| 205 | } |
||
| 206 | const infinite = -1; |
||
|
0 ignored issues
–
show
|
|||
| 207 | // Set up monitor with specified options |
||
| 208 | var monitor = respawn(launch_options, { |
||
| 209 | name: 'geomux', |
||
| 210 | env: { |
||
| 211 | 'DEBUG': 'app*,camera*,channel*' |
||
| 212 | }, |
||
| 213 | maxRestarts: infinite, |
||
| 214 | sleep: 1000 |
||
| 215 | }); |
||
| 216 | monitor.on('exit', function(code, signal) { |
||
| 217 | logger.error('Geo-video-server exited. Code: [' + code + '] Signal: [' + signal + ']'); |
||
| 218 | }); |
||
| 219 | monitor.on('stdout', function(data) { |
||
| 220 | var msg = data.toString('utf-8'); |
||
| 221 | logger.debug('geo-video-server STDOUT: ' + msg); |
||
| 222 | }); |
||
| 223 | monitor.on('stderr', function(data) { |
||
| 224 | var msg = data.toString('utf-8'); |
||
| 225 | logger.debug('geo-video-server STDERR: ' + msg); |
||
| 226 | }); |
||
| 227 | // Start the monitor |
||
| 228 | monitor.start(); |
||
| 229 | this._monitor = monitor; |
||
| 230 | }; |
||
| 231 | //Export provides the public interface |
||
| 232 | module.exports = function(name, deps) { |
||
| 233 | return new geomux(name, deps); |
||
| 234 | }; |
||
| 235 |