Access Webcam with NodeJS

Want to create a Web application to stream webcams, capture and upload images in browsers? You can use a JavaScript webcam library and Node.js.

Dynamsoft Camera SDK (DCS) allows developers to build web camera software with pure HTML, CSS, and JavaScript. In this article, let’s see how to upload captured images from within web browsers to the server using JavaScript camera APIs and Node.js.

Webcam Capture and Image Upload in NodeJS

Development Environment

Here we use Visual Studio Code (VSCode) as editor. Things needed:

  • Install Dynamsoft Camera SDK — the JavaScript webcam library
  • Install DCS code snippet extension for VSCode:

ext install dcs

npm install express formidable --save

Webcam Capture in JavaScript

Create index.htm. If you have installed the DCS extension, simply type the prefix ‘dcs’ to quickly insert the code snippet.

The code snippet has included the functionality of capturing images.

Add a new button for uploading files.

<input type="button" value="Upload" class="d-btn bgBlue" onclick="onUpload();" />

function onUpload() {

if (!dcsObject || !imageViewer) return;
if (imageViewer.image.getCount() === 0) {
alert('Please grab an image first.');
return;
}

var counter,
url = getCurPagePath() + 'upload',
fileName = new Date().getMilliseconds() + '.jpg',
imageType = imageViewer.io.EnumImageType.JPEG,
bMultiImages = false,
imageIndexArray = [];
if (bMultiImages) {
for (counter = 0; counter < imageViewer.image.getCount(); counter++) imageIndexArray.push(counter);
} else imageIndexArray.push(imageViewer.image.getIndex());
imageViewer.io.setHTTPFormFields({
"fileName": fileName
});

imageViewer.io.httpUploadAsync(url, imageIndexArray, imageType, onUploadSuccess, onUploadFailure);
}

Parameters used in httpUploadAsync()?

  • URL: the action page to receive and process the image data on the server side.
  • indices: the indices of images that needed to be sent.
  • imageType: the format of the file you want to upload as. E.g. jpg, pdf, png.
  • onHttpUploadSuccess: the callback function triggered when the file is uploaded successfully.
  • onHttpUploadFailure: the callback function triggered when the file failed to be uploaded.

So far, the client-side code is finished. The next step is to implement the action page logic.

Upload Images in NodeJS

Create server.js and setup the web server using Express.

var formidable = require('formidable'); 
var express = require('express');
var fs = require('fs');
var app = express();
var path = require('path');

app.use(express.static(__dirname));
app.use(function (req, res, next) {

res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
res.header("Access-Control-Allow-Headers", "X-Requested-With, content-type");
res.header("Access-Control-Allow-Credentials", true);
next();
});

var server = app.listen(2017, function () {
var host = server
.address()
.address;
var port = server
.address()
.port;

console.log('listening at http://%s:%s', host, port);
});

Use Formidable to parse the incoming form data, then save images and send a response.

app.post('/upload', function (req, res) { 
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var dir = 'uploads';

fs.mkdir(dir, function (err) {
fs.readFile(files.RemoteFile.path, function (err, data) {
// save file from temp dir to new dir
var fileName = path.join(__dirname, dir, files.RemoteFile.name);
console.log(fileName);
fs.writeFile(fileName, data, function (err) {
if (err)
throw err;
res.json({success: 'true'});
});
});
});
});
});

Note:

When invoking the DCS API, you do not need to specify the form field. The default name is RemoteFile.

After saving uploaded images, you have to send a response with JSON data which at least contains the key ‘success’ and its corresponding boolean value. Otherwise, the callback functions onUploadSuccess and onUploadFailure will not be triggered.

Here is the final look of the web camera application.

Sample Code

Originally published at www.dynamsoft.com/blog