API Docs for: 0.0.1
Show:

File: plugins/webcam/index.js

if (typeof define !== 'function') {
  var define = require('amdefine')(module);
}

/**
 * Webcam Plugin. Plugin that uses streamer to create images from the webcam and pushes them to the clients
 *
 * @class Webcam
 * @constructor 
 */
define([ 'child_process', 'delivery', 'fs', 'http' ], function( ChildProcess, Delivery, Fs, Http ) {

  var Webcam = function(app) {

    this.name = 'Webcam';
    this.id = 'webcam';
    this.collection = 'Webcam';
    this.icon = 'icon-play-circle';

    this.app = app;
    this.pluginHelper = app.get('plugin helper');

    /**
     * Use the following command to get a list of supported resolutions of your webcam:
     * 
     * ````
     * $ v4l2-ctl --list-formats-ext
     * ````
     * 
     * Microsoft® LifeCam HD-3000: 640x480, 1280x720, 960x544, 800x448, 640x360, 424x240, 352x288, 320x240, 800x600, 176x144, 160x120, 1280x800
     */
    this.webcamResolution = '960x544';

    this.webcamList = [];
    this.webcams = {};

    this.deliveryList = [];

    this.init();

    var that = this;

    app.get('events').on('settings-saved', function() {
      that.init();
    });

    app.get('sockets').on('connection', function(socket) {
      var delivery = Delivery.listen(socket);
      that.deliveryList.push(delivery);

      socket.on('disconnect', function() {
        that.deliveryList.forEach(function(delivery) {
          if (delivery.socket.id == socket.id) {
            var i = that.deliveryList.indexOf(delivery);
            that.deliveryList.splice(i,1);
          }
        });
      });

    });
  };

  /**
   * Initialize the webcams
   * 
   * @method init
   */
  Webcam.prototype.init = function() {

    var that = this;
    this.webcamList.forEach(function(webcam) {
      clearInterval(webcam);
    });
    this.webcamList = [];

    return this.app.get('db').collection(that.collection, function(err, collection) {
      collection.find().toArray(function(err, result) {
        if ((!err) && (result.length > 0)) {
          result.forEach(function(item) {

            if (item.method == 'streamer') {
              function capture() {
                if (that.app.get('clients').length > 0) {
                  var filename = '/tmp/' + item._id + '.jpeg';
                  that.streamer(item.input, filename, that.webcamResolution, function(err, result) {
                    if (err) {
                      console.log(err);
                    } else {
                      that.deliveryList.forEach(function(delivery) {
                        delivery.send({
                          name: item._id + '.jpg',
                          path : filename,
                        });
                      });
                    }
                  });             
                }
              }
              var intervalId = setInterval(capture, parseInt(item.interval)*1000);
              that.webcamList.push(intervalId);
            }

            if (item.method == 'motion') {
              // check if authorized and forward motion stream
              that.app.get('/webcam/motion/' + item._id, that.app.get('routes').isAuthorized, function(req, res) {
                var creq = Http.request({
                  host:   'localhost',
                  port:   item.port,
                  path:   '/',
                  method: 'GET',
                  headers: req.headers
                }, function(cres) {
                  res.setHeader('Content-Type', cres.headers['content-type']);
                  res.setHeader('Connection', cres.headers.connection);
                  res.setHeader('Pragma', cres.headers.pragma);
                  res.setHeader('Cache-Control', cres.headers['cache-control']);
                  res.setHeader('Expires', cres.headers.expires);
                  res.setHeader('Max-Age', cres.headers['max-age']);
                  cres.on('data', function(chunk){
                    res.write(chunk);
                  });
                  cres.on('close', function(){
                    res.writeHead(cres.statusCode);
                    res.end();
                  });
                }).on('error', function(e) {
                  // we got an error, return 500 error to client and log error
                  res.write('Error connecting to motion stream: ' + e.message);
                  res.end();
                });
                creq.end();
              });
            }
          });
        }
      });
    });
  }

  /**
   * Create an image using streamer
   *
   * @method streamer
   * @param {String} input The input to use, e.g. '/dev/video0'
   * @param {String} output The output file, e.g. '/tmp/image.jpg'
   * @param {String} resolution The resolution to use, e.g. '1280x720'
   * @param {Function} callback The callback method to execute after manipulation
   * @param {String} callback.err null if no error occured, otherwise the error
   * @param {Object} callback.result The result of the exec call
   */
  Webcam.prototype.streamer = function(input, output, resolution, callback) {

    var exec = ChildProcess.exec;
    var cmd = 'streamer -c ' + input + ' -o ' + output + ' -s ' + resolution;
    exec(cmd, function(err, stdout, stderr) {
      if(err) {
        callback(err);
      } else {
        callback(null, stdout);
      }
    });    
  }
  /**
   * Manipulate the items array before render
   *
   * @method beforeRender
   * @param {Array} items An array containing the items to be rendered
   * @param {Function} callback The callback method to execute after manipulation
   * @param {String} callback.err null if no error occured, otherwise the error
   * @param {Object} callback.result The manipulated items
   */
  Webcam.prototype.beforeRender = function(items, callback) {
    var that = this;
    var devList = Fs.readdirSync('/dev/');
    var deviceList = [];
    devList.forEach(function(dev) {
      if (dev.substr(0,5) == 'video') {
        deviceList.push('/dev/' + dev);
      }
    })
    items.forEach(function(item) {
      if (deviceList.indexOf(item.input)==-1) {
        console.log('Webcam Plugin: Device "' + item.input + '" not found.');
        var i = items.indexOf(item);
        items.splice(i,1);
      }
    });
    return callback(null, items, {'devices': deviceList});
  }

  var exports = Webcam;

  return Webcam;

});