diff --git a/README.md b/README.md index 61c167a..a1037e1 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,9 @@ NodeWebcam.capture( "test_picture", opts, function( err, data ) { --location Location to output webcam capture ---list list available camera devices +--list list available cameras + +--driverType which backend to use (fswebcam, gphoto2, etc...) #Shorthand options @@ -191,6 +193,18 @@ node-webcam --w 500 --h 500 --d 2 --l picture # ./bin/node-webcam.js ``` + +## Usage with actual camera + +Install `gphoto2`. You might need to do [this on linux if you find it does not work](https://gist.github.com/chuckfairy/56587cac70035cb611e1c97eeb59353a) + +```shell +node-webcam --driverType "gphoto2" --list # list available cameras + +node-webcam --driverType "gphoto2" --l ./test/output/test.png # `l` being the location +``` + + # Generated Documentation ``` diff --git a/bin/node-webcam.js b/bin/node-webcam.js index fa68db8..ed722b0 100755 --- a/bin/node-webcam.js +++ b/bin/node-webcam.js @@ -41,6 +41,8 @@ var opts = { bottomBanner: [ Boolean, false ], + driverType: [ String, false ], + skip: [ Number, 0 ], list: [ Boolean, false ], diff --git a/examples/websocket/App.js b/examples/websocket/App.js index 52849eb..4a9c7b0 100644 --- a/examples/websocket/App.js +++ b/examples/websocket/App.js @@ -35,7 +35,8 @@ var NodeWebcam = require( "./../../" ); var Webcam = NodeWebcam.create({ callbackReturn: "base64", - saveShots: false + saveShots: false, + //driverType: "gphoto2" }); @@ -49,7 +50,7 @@ function init() { setupWebcam(); - console.log( "Visit localhost:9090" ); + console.log( "Visit http://localhost:9090" ); } diff --git a/package.json b/package.json index 5f22f44..4d30266 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "capture", "cli", "camera", - "webcamera" + "webcamera", + "gphoto2" ], "author": "chuckfairy", "license": "MIT", diff --git a/src/Factory.js b/src/Factory.js index 0585e31..ec77997 100644 --- a/src/Factory.js +++ b/src/Factory.js @@ -25,7 +25,9 @@ var Factory = new function() { scope.create = function( options, type ) { - var p = type || Factory.Platform; + options = options || {}; + + var p = type || options.driverType || Factory.Platform; var Type = Factory.Types[ p ]; @@ -56,7 +58,9 @@ Factory.Types = { win32: WindowsWebcam, - win64: WindowsWebcam + win64: WindowsWebcam, + + gphoto2: require("./webcams/GPhoto2Webcam.js"), }; diff --git a/src/ShellParamBuilder.js b/src/ShellParamBuilder.js new file mode 100644 index 0000000..09368c4 --- /dev/null +++ b/src/ShellParamBuilder.js @@ -0,0 +1,87 @@ +/** + * Param builder helper + * + * @class ShellParamBuilder + * @constructor + */ +"use strict"; + + +module.exports = function ShellParamBuilder() { + + var scope = this; + + var params = []; + + + /** + * Prefix to append to shell key + * + * @property {String} prefix + */ + + scope.prefix = "--"; + + + /** + * Key value separator for key to value in shell args + * + * @property {String} keyValueSeparator + */ + + scope.keyValueSeparator = " "; + + + /** + * toString main output method + * + * @method toString + * + * @return String + */ + + scope.toString = function() { + return params.join(" "); + } + + + /** + * Add shell build opt + * + * @method add + * + * @param {String} key to get possible prefix + * @param {String} value + * @param {String} noValue option to put if nothing passed in value + * + */ + + scope.add = function(key, value, noValue) { + if( value === null ) { + if( noValue ) { + params.push(noValue); + } + + return; + } + + params.push( + scope.prefix + key + + scope.keyValueSeparator + value + ); + } + + + /** + * Add raw to output + * + * @method addRaw + * + * @param {String} value + * + */ + + scope.addRaw = function(value) { + params.push(value); + } +} diff --git a/src/webcams/GPhoto2Webcam.js b/src/webcams/GPhoto2Webcam.js new file mode 100644 index 0000000..98abde8 --- /dev/null +++ b/src/webcams/GPhoto2Webcam.js @@ -0,0 +1,155 @@ +/** + * API for Gphoto2 + * + * @requires [ gphoto2 ] + * + * @param Object options + * + */ +"use strict"; + +var Webcam = require( "./../Webcam.js" ); + +var Utils = require( "./../utils/Utils.js" ); + +var Shot = require( "./../Shot.js" ); + +var Builder = require( "../ShellParamBuilder.js" ); + + +//Main class + +function GPhoto2Webcam( options ) { + + var scope = this; + + scope.opts = Utils.setDefaults( options, GPhoto2Webcam.Defaults ); + + if (scope.opts.output !== "jpg") { + console.warn("Only jpg is supported"); + scope.opts.output = "jpg"; + } + + Webcam.call( scope, scope.opts ); + +} + +GPhoto2Webcam.prototype = Object.create( Webcam.prototype ); + +GPhoto2Webcam.prototype.constructor = GPhoto2Webcam; + +GPhoto2Webcam.prototype.bin = "gphoto2"; + + +/** + * @override + * + * Generate shell statement + * + * @param String location + * + */ +GPhoto2Webcam.prototype.generateSh = function( location ) { + + var scope = this; + + var build = new Builder; + + build.addRaw(scope.bin); + + build.add("port", scope.opts.inputLocation + ":"); + + build.addRaw("--capture-image-and-download"); + build.addRaw("--stdout"); + build.addRaw("> " + location); + + //build.addRaw(location); + + return build.toString(); + +}; + +/** + * @Override + * + * Webcam list within gphoto2 + * + * @param Function callback + * + */ +GPhoto2Webcam.prototype.list = function( callback ) { + + var scope = this; + + var sh = scope.bin + " -auto-detect"; + + var cams = []; + + EXEC( sh, function( err, data, out ) { + + var lines = data.split( "\n" ); + + var ll = lines.length; + var startingLine = 2; //No need for headers + + for( var i = startingLine; i < ll; i ++ ) { + + var line = lines[ i ]; + + //imagesnap update adds extra stuff + line = line.replace(/.*?\[(.*?)\].*/, "$1"); + + cams.push( line ); + + } + + callback && callback( cams ); + + }); + +}; + + +/** + * Data validations based on fs output + * + * @inheritdoc + * + */ + +GPhoto2Webcam.prototype.runCaptureValidations = function( data ) { + + if( GPhoto2Webcam.Validations.noWebcam.exec( data ) ) { + + return new Error( "No webcam found" ); + + } + + return null; + +}; + + +//Defaults + +GPhoto2Webcam.Defaults = { + + inputLocation: "usb", + + output: "jpg", + +}; + + +//Validations const + +GPhoto2Webcam.Validations = { + + noWebcam: /no.*such.*(file|device)/i + +}; + + +//Export + +module.exports = GPhoto2Webcam;