RaspberryPi B+でカメラモジュール使ってnode.jsとsocket.ioでストリーミング配信してみる
RaspberryPi B+でカメラモジュール使ってnode.jsとsocket.ioでストリーミング配信してみます。
純正カメラをつなげました。
ついでにネットワークがつながってるので、シリアルログインが不要のためmicroUSBケーブルで接続してます。
カメラの有効化を行います
# sudo raspi-config
下記を参考にさせて頂きます
Raspberry Pi, Camera and Node.js - Live Streaming with Websockets #IoT | The Jackal of Javascript
liveStreamingフォルダを作って、expressをsocket.io付きでinitします。
http://thejackalofjavascript.com/rpi-live-streaming/ pi@raspberrypi ~ $ cd httpd/ pi@raspberrypi ~/httpd $ ls sample pi@raspberrypi ~/httpd $ mkdir liveStreaming && cd liveStreaming pi@raspberrypi ~/httpd/liveStreaming $ ls pi@raspberrypi ~/httpd/liveStreaming $ npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sane defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg> --save` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. name: (liveStreaming) liveStreaming version: (0.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to /home/pi/httpd/liveStreaming/package.json: { "name": "liveStreaming", "version": "0.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } Is this ok? (yes) pi@raspberrypi ~/httpd/liveStreaming $ npm install express socket.io --save npm WARN package.json liveStreaming@0.0.0 No description npm WARN package.json liveStreaming@0.0.0 No repository field. npm WARN package.json liveStreaming@0.0.0 No README data npm http GET https://registry.npmjs.org/socket.io npm http GET https://registry.npmjs.org/express npm http 200 https://registry.npmjs.org/socket.io npm http 200 https://registry.npmjs.org/express npm http GET https://registry.npmjs.org/socket.io/-/socket.io-1.3.4.tgz npm http 200 https://registry.npmjs.org/socket.io/-/socket.io-1.3.4.tgz npm http GET https://registry.npmjs.org/engine.io npm http GET https://registry.npmjs.org/socket.io-parser npm http GET https://registry.npmjs.org/socket.io-client npm http GET https://registry.npmjs.org/socket.io-adapter npm http GET https://registry.npmjs.org/has-binary-data npm http GET https://registry.npmjs.org/debug npm http 200 https://registry.npmjs.org/has-binary-data npm http 200 https://registry.npmjs.org/debug npm http 200 https://registry.npmjs.org/socket.io-adapter npm http 200 https://registry.npmjs.org/socket.io-parser npm http 200 https://registry.npmjs.org/socket.io-client npm http GET https://registry.npmjs.org/has-binary-data/-/has-binary-data-0.1.3.tgz npm http GET https://registry.npmjs.org/debug/-/debug-2.1.0.tgz npm http GET https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.3.1.tgz npm http GET https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.2.3.tgz npm http 200 https://registry.npmjs.org/has-binary-data/-/has-binary-data-0.1.3.tgz npm http 200 https://registry.npmjs.org/engine.io npm http 200 https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.3.1.tgz npm http 200 https://registry.npmjs.org/debug/-/debug-2.1.0.tgz npm http GET https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.3.4.tgz npm http 200 https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.2.3.tgz npm http 200 https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.3.4.tgz npm http GET https://registry.npmjs.org/engine.io/-/engine.io-1.5.1.tgz npm http 200 https://registry.npmjs.org/engine.io/-/engine.io-1.5.1.tgz npm http GET https://registry.npmjs.org/methods npm http GET https://registry.npmjs.org/fresh npm http GET https://registry.npmjs.org/media-typer npm http GET https://registry.npmjs.org/on-finished npm http GET https://registry.npmjs.org/parseurl npm http GET https://registry.npmjs.org/path-to-regexp npm http GET https://registry.npmjs.org/proxy-addr npm http GET https://registry.npmjs.org/qs npm http GET https://registry.npmjs.org/range-parser npm http GET https://registry.npmjs.org/send npm http GET https://registry.npmjs.org/serve-static npm http GET https://registry.npmjs.org/type-is npm http GET https://registry.npmjs.org/vary npm http GET https://registry.npmjs.org/cookie npm http GET https://registry.npmjs.org/merge-descriptors npm http GET https://registry.npmjs.org/utils-merge npm http GET https://registry.npmjs.org/accepts npm http GET https://registry.npmjs.org/content-disposition npm http GET https://registry.npmjs.org/cookie-signature npm http GET https://registry.npmjs.org/depd npm http GET https://registry.npmjs.org/escape-html npm http GET https://registry.npmjs.org/etag npm http GET https://registry.npmjs.org/finalhandler npm http 304 https://registry.npmjs.org/methods npm http 304 https://registry.npmjs.org/on-finished npm http 304 https://registry.npmjs.org/fresh npm http 304 https://registry.npmjs.org/parseurl npm http 304 https://registry.npmjs.org/path-to-regexp npm http 304 https://registry.npmjs.org/range-parser npm http 200 https://registry.npmjs.org/proxy-addr npm http 200 https://registry.npmjs.org/qs npm http 304 https://registry.npmjs.org/vary npm http 304 https://registry.npmjs.org/media-typer npm http 304 https://registry.npmjs.org/cookie npm http 200 https://registry.npmjs.org/serve-static npm http 200 https://registry.npmjs.org/send npm http GET https://registry.npmjs.org/qs/-/qs-2.3.3.tgz npm http 304 https://registry.npmjs.org/utils-merge npm http 304 https://registry.npmjs.org/merge-descriptors npm http 200 https://registry.npmjs.org/cookie-signature npm http 304 https://registry.npmjs.org/content-disposition npm http 200 https://registry.npmjs.org/accepts npm http 200 https://registry.npmjs.org/qs/-/qs-2.3.3.tgz npm http 200 https://registry.npmjs.org/type-is npm http 304 https://registry.npmjs.org/depd npm http 304 https://registry.npmjs.org/escape-html npm http 304 https://registry.npmjs.org/etag npm http GET https://registry.npmjs.org/send/-/send-0.11.1.tgz npm http 304 https://registry.npmjs.org/finalhandler npm http GET https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.5.tgz npm http 200 https://registry.npmjs.org/send/-/send-0.11.1.tgz npm http 200 https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.5.tgz npm http GET https://registry.npmjs.org/accepts/-/accepts-1.2.4.tgz npm http 200 https://registry.npmjs.org/accepts/-/accepts-1.2.4.tgz npm http GET https://registry.npmjs.org/crc npm http GET https://registry.npmjs.org/ee-first npm http GET https://registry.npmjs.org/mime-types npm http GET https://registry.npmjs.org/negotiator npm http GET https://registry.npmjs.org/ipaddr.js npm http GET https://registry.npmjs.org/forwarded npm http 304 https://registry.npmjs.org/ee-first npm http 304 https://registry.npmjs.org/crc npm http 304 https://registry.npmjs.org/forwarded npm http 304 https://registry.npmjs.org/mime-types npm http 200 https://registry.npmjs.org/negotiator npm http 304 https://registry.npmjs.org/ipaddr.js npm http GET https://registry.npmjs.org/negotiator/-/negotiator-0.5.1.tgz npm http GET https://registry.npmjs.org/object-keys npm http 200 https://registry.npmjs.org/negotiator/-/negotiator-0.5.1.tgz npm http GET https://registry.npmjs.org/debug npm http GET https://registry.npmjs.org/socket.io-parser npm http GET https://registry.npmjs.org/destroy npm http GET https://registry.npmjs.org/mime npm http GET https://registry.npmjs.org/ms npm http 200 https://registry.npmjs.org/object-keys npm http 304 https://registry.npmjs.org/debug npm http 304 https://registry.npmjs.org/socket.io-parser npm http 304 https://registry.npmjs.org/destroy npm http 304 https://registry.npmjs.org/ms npm http 200 https://registry.npmjs.org/mime npm http GET https://registry.npmjs.org/object-keys/-/object-keys-1.0.1.tgz npm http GET https://registry.npmjs.org/debug/-/debug-1.0.2.tgz npm http GET https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.2.2.tgz npm http GET https://registry.npmjs.org/mime/-/mime-1.2.11.tgz npm http 200 https://registry.npmjs.org/object-keys/-/object-keys-1.0.1.tgz npm http 200 https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.2.2.tgz npm http 200 https://registry.npmjs.org/mime/-/mime-1.2.11.tgz npm http 200 https://registry.npmjs.org/debug/-/debug-1.0.2.tgz npm http GET https://registry.npmjs.org/json3 npm http GET https://registry.npmjs.org/component-emitter npm http GET https://registry.npmjs.org/isarray npm http GET https://registry.npmjs.org/benchmark npm http 200 https://registry.npmjs.org/isarray npm http GET https://registry.npmjs.org/debug/-/debug-0.7.4.tgz npm http 200 https://registry.npmjs.org/component-emitter npm http GET https://registry.npmjs.org/mime-db npm http 200 https://registry.npmjs.org/json3 npm http 200 https://registry.npmjs.org/benchmark npm http 200 https://registry.npmjs.org/debug/-/debug-0.7.4.tgz npm http 304 https://registry.npmjs.org/mime-db npm http GET https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz npm http GET https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz npm http GET https://registry.npmjs.org/json3/-/json3-3.2.6.tgz npm http GET https://registry.npmjs.org/benchmark/-/benchmark-1.0.0.tgz npm http 200 https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz npm http 200 https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz npm http 200 https://registry.npmjs.org/json3/-/json3-3.2.6.tgz npm http 200 https://registry.npmjs.org/benchmark/-/benchmark-1.0.0.tgz npm http GET https://registry.npmjs.org/ws npm http GET https://registry.npmjs.org/engine.io-parser npm http GET https://registry.npmjs.org/base64id npm http GET https://registry.npmjs.org/debug npm http 304 https://registry.npmjs.org/debug npm http 200 https://registry.npmjs.org/engine.io-parser npm http 200 https://registry.npmjs.org/ws npm http 200 https://registry.npmjs.org/base64id npm http GET https://registry.npmjs.org/debug/-/debug-1.0.3.tgz npm http GET https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.2.1.tgz npm http GET https://registry.npmjs.org/ws/-/ws-0.5.0.tgz npm http GET https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz npm http 200 https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.2.1.tgz npm http 200 https://registry.npmjs.org/debug/-/debug-1.0.3.tgz npm http 200 https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz npm http 200 https://registry.npmjs.org/ws/-/ws-0.5.0.tgz npm http GET https://registry.npmjs.org/ms npm http 304 https://registry.npmjs.org/ms npm http GET https://registry.npmjs.org/component-emitter npm http GET https://registry.npmjs.org/isarray npm http 304 https://registry.npmjs.org/isarray npm http 304 https://registry.npmjs.org/component-emitter npm http GET https://registry.npmjs.org/engine.io-client npm http GET https://registry.npmjs.org/component-bind npm http GET https://registry.npmjs.org/object-component npm http GET https://registry.npmjs.org/has-binary npm http GET https://registry.npmjs.org/indexof npm http GET https://registry.npmjs.org/parseuri npm http GET https://registry.npmjs.org/to-array npm http GET https://registry.npmjs.org/backo2 npm http GET https://registry.npmjs.org/debug npm http 200 https://registry.npmjs.org/object-component npm http 200 https://registry.npmjs.org/component-bind npm http 200 https://registry.npmjs.org/indexof npm http 200 https://registry.npmjs.org/to-array npm http 200 https://registry.npmjs.org/backo2 npm http 304 https://registry.npmjs.org/debug npm http 200 https://registry.npmjs.org/has-binary npm http 200 https://registry.npmjs.org/parseuri npm http GET https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz npm http GET https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz npm http GET https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz npm http 200 https://registry.npmjs.org/engine.io-client npm http GET https://registry.npmjs.org/to-array/-/to-array-0.1.3.tgz npm http GET https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz npm http 200 https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz npm http GET https://registry.npmjs.org/has-binary/-/has-binary-0.1.6.tgz npm http 200 https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz npm http 200 https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz npm http GET https://registry.npmjs.org/parseuri/-/parseuri-0.0.2.tgz npm http 200 https://registry.npmjs.org/to-array/-/to-array-0.1.3.tgz npm http 200 https://registry.npmjs.org/has-binary/-/has-binary-0.1.6.tgz npm http 200 https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz npm http GET https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.5.1.tgz npm http 200 https://registry.npmjs.org/parseuri/-/parseuri-0.0.2.tgz npm http 200 https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.5.1.tgz npm http GET https://registry.npmjs.org/ms npm http 304 https://registry.npmjs.org/ms npm http GET https://registry.npmjs.org/arraybuffer.slice npm http GET https://registry.npmjs.org/after npm http GET https://registry.npmjs.org/base64-arraybuffer npm http GET https://registry.npmjs.org/blob npm http GET https://registry.npmjs.org/utf8 npm http GET https://registry.npmjs.org/has-binary/-/has-binary-0.1.5.tgz npm http 200 https://registry.npmjs.org/base64-arraybuffer npm http 200 https://registry.npmjs.org/arraybuffer.slice npm http 200 https://registry.npmjs.org/after npm http 200 https://registry.npmjs.org/has-binary/-/has-binary-0.1.5.tgz npm http GET https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.2.tgz npm http GET https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz npm http 200 https://registry.npmjs.org/blob npm http GET https://registry.npmjs.org/after/-/after-0.8.1.tgz npm http 200 https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.2.tgz npm http 200 https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz npm http 200 https://registry.npmjs.org/after/-/after-0.8.1.tgz npm http GET https://registry.npmjs.org/blob/-/blob-0.0.2.tgz npm http 200 https://registry.npmjs.org/utf8 npm http 200 https://registry.npmjs.org/blob/-/blob-0.0.2.tgz npm http GET https://registry.npmjs.org/utf8/-/utf8-2.0.0.tgz npm http 200 https://registry.npmjs.org/utf8/-/utf8-2.0.0.tgz npm http GET https://registry.npmjs.org/better-assert npm http 200 https://registry.npmjs.org/better-assert npm http GET https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz npm http 200 https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz npm http GET https://registry.npmjs.org/nan npm http GET https://registry.npmjs.org/options npm http GET https://registry.npmjs.org/ultron npm http 200 https://registry.npmjs.org/options npm http GET https://registry.npmjs.org/options/-/options-0.0.6.tgz npm http 200 https://registry.npmjs.org/ultron npm http GET https://registry.npmjs.org/isarray npm http 200 https://registry.npmjs.org/nan npm http 200 https://registry.npmjs.org/options/-/options-0.0.6.tgz npm http 304 https://registry.npmjs.org/isarray npm http GET https://registry.npmjs.org/ultron/-/ultron-1.0.1.tgz npm http GET https://registry.npmjs.org/nan/-/nan-1.4.3.tgz npm http 200 https://registry.npmjs.org/ultron/-/ultron-1.0.1.tgz npm http 200 https://registry.npmjs.org/nan/-/nan-1.4.3.tgz npm http GET https://registry.npmjs.org/callsite npm http 200 https://registry.npmjs.org/callsite npm http GET https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz npm http 200 https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz npm http GET https://registry.npmjs.org/parsejson npm http GET https://registry.npmjs.org/parseqs npm http GET https://registry.npmjs.org/component-inherit npm http GET https://registry.npmjs.org/has-cors npm http GET https://github.com/rase-/node-XMLHttpRequest/archive/a6b6f2.tar.gz npm http GET https://registry.npmjs.org/ws npm http GET https://registry.npmjs.org/engine.io-parser npm http GET https://registry.npmjs.org/debug npm http GET https://registry.npmjs.org/parseuri npm http 200 https://registry.npmjs.org/has-cors npm http 200 https://registry.npmjs.org/parseqs npm http 304 https://registry.npmjs.org/engine.io-parser npm http 200 https://registry.npmjs.org/parsejson npm http 304 https://registry.npmjs.org/ws npm http 200 https://registry.npmjs.org/component-inherit npm http 304 https://registry.npmjs.org/debug npm http 304 https://registry.npmjs.org/parseuri npm http GET https://registry.npmjs.org/has-cors/-/has-cors-1.0.3.tgz npm http GET https://registry.npmjs.org/parseqs/-/parseqs-0.0.2.tgz npm http GET https://registry.npmjs.org/parsejson/-/parsejson-0.0.1.tgz npm http GET https://registry.npmjs.org/ws/-/ws-0.4.31.tgz npm http GET https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz npm http GET https://registry.npmjs.org/debug/-/debug-1.0.4.tgz npm http GET https://registry.npmjs.org/parseuri/-/parseuri-0.0.4.tgz npm http 200 https://registry.npmjs.org/parseqs/-/parseqs-0.0.2.tgz npm http 200 https://registry.npmjs.org/debug/-/debug-1.0.4.tgz npm http 200 https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz npm http 200 https://registry.npmjs.org/ws/-/ws-0.4.31.tgz npm http 200 https://registry.npmjs.org/parsejson/-/parsejson-0.0.1.tgz npm http 200 https://registry.npmjs.org/parseuri/-/parseuri-0.0.4.tgz npm http 200 https://registry.npmjs.org/has-cors/-/has-cors-1.0.3.tgz npm http 200 https://github.com/rase-/node-XMLHttpRequest/archive/a6b6f2.tar.gz npm http GET https://registry.npmjs.org/isarray npm http 200 https://registry.npmjs.org/nan/-/nan-0.3.2.tgz > ws@0.4.31 install /home/pi/httpd/liveStreaming/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws > (node-gyp rebuild 2> builderror.log) || (exit 0) make: Entering directory '/home/pi/httpd/liveStreaming/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/build' CXX(target) Release/obj.target/bufferutil/src/bufferutil.o SOLINK_MODULE(target) Release/obj.target/bufferutil.node SOLINK_MODULE(target) Release/obj.target/bufferutil.node: Finished COPY Release/bufferutil.node CXX(target) Release/obj.target/validation/src/validation.o SOLINK_MODULE(target) Release/obj.target/validation.node SOLINK_MODULE(target) Release/obj.target/validation.node: Finished COPY Release/validation.node make: Leaving directory '/home/pi/httpd/liveStreaming/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/build' express@4.11.2 node_modules/express ├── utils-merge@1.0.0 ├── merge-descriptors@0.0.2 ├── methods@1.1.1 ├── fresh@0.2.4 ├── cookie@0.1.2 ├── escape-html@1.0.1 ├── range-parser@1.0.2 ├── cookie-signature@1.0.5 ├── finalhandler@0.3.3 ├── vary@1.0.0 ├── media-typer@0.3.0 ├── parseurl@1.3.0 ├── serve-static@1.8.1 ├── content-disposition@0.5.0 ├── path-to-regexp@0.1.3 ├── depd@1.0.0 ├── on-finished@2.2.0 (ee-first@1.1.0) ├── qs@2.3.3 ├── debug@2.1.1 (ms@0.6.2) ├── proxy-addr@1.0.6 (forwarded@0.1.0, ipaddr.js@0.1.8) ├── etag@1.5.1 (crc@3.2.1) ├── send@0.11.1 (destroy@1.0.3, ms@0.7.0, mime@1.2.11) ├── type-is@1.5.7 (mime-types@2.0.9) └── accepts@1.2.4 (negotiator@0.5.1, mime-types@2.0.9) socket.io@1.3.4 node_modules/socket.io ├── debug@2.1.0 (ms@0.6.2) ├── has-binary-data@0.1.3 (isarray@0.0.1) ├── socket.io-parser@2.2.3 (isarray@0.0.1, debug@0.7.4, component-emitter@1.1.2, benchmark@1.0.0, json3@3.2.6) ├── socket.io-adapter@0.3.1 (object-keys@1.0.1, debug@1.0.2, socket.io-parser@2.2.2) ├── engine.io@1.5.1 (base64id@0.1.0, debug@1.0.3, engine.io-parser@1.2.1, ws@0.5.0) └── socket.io-client@1.3.4 (to-array@0.1.3, indexof@0.0.1, component-bind@1.0.0, debug@0.7.4, backo2@1.0.2, object-component@0.0.3, component-emitter@1.1.2, has-binary@0.1.6, parseuri@0.0.2, engine.io-client@1.5.1)
準備完了したら、
index.js(サーバー側)とindex.html(クライアント側)を作成します。
index.js
var express = require('express'); var app = express(); var http = require('http').Server(app); var io = require('socket.io')(http); var fs = require('fs'); var path = require('path'); var spawn = require('child_process').spawn; var proc; var dateformat = require("dateformat"); app.use('/', express.static(path.join(__dirname, 'stream'))); app.get('/', function(req, res) { res.sendFile(__dirname + '/index.html'); }); var sockets = {}; io.on('connection', function(socket) { sockets[socket.id] = socket; console.log("Total clients connected : ", Object.keys(sockets).length); socket.on('disconnect', function() { delete sockets[socket.id]; // no more sockets, kill the stream if (Object.keys(sockets).length == 0) { app.set('watchingFile', false); if (proc) proc.kill(); fs.unwatchFile('./stream/image_stream.jpg'); } }); socket.on('start-stream', function() { startStreaming(io); }); }); http.listen(3000, function() { console.log('listening on *:3000'); }); function stopStreaming() { if (Object.keys(sockets).length == 0) { app.set('watchingFile', false); if (proc) proc.kill(); fs.unwatchFile('./stream/image_stream.jpg'); } } function startStreaming(io) { if (app.get('watchingFile')) { io.sockets.emit('liveStream', {url:'image_stream.jpg?_t=' + (Math.random() * 100000), time:dateformat(new Date(), "yyyy/mm/dd HH:MM:ss")}); return; } var args = ["-bm", "-w", "320", "-h", "240", "-o", __dirname + "/stream/image_stream.jpg", "-t", "999999999", "-tl", "500", "--nopreview"]; proc = spawn('raspistill', args); console.log('Watching for changes...'); app.set('watchingFile', true); fs.watchFile(__dirname+'/stream/image_stream.jpg', function(current, previous) { console.log('emmit liveStewam'); io.sockets.emit('liveStream', {url:'image_stream.jpg?_t=' + (Math.random() * 100000), time:dateformat(new Date(), "yyyy/mm/dd HH:MM:ss")}); }) proc.stdout.on('data', function(data) { console.log('stdout: ' + data); }) proc.stderr.on('data', function(data) { console.log('stderr: ' + data); }) proc.on('exit', function(code) { console.log('exit code: ' + code); }) }
spawnでraspistillコマンドを実行してストリーミングします。
その後、fs.watchFileで、image_stream.jpgを監視。
変更があったら、io.sockets.emitで画像URLと更新時間を送付します。
proc = spawn('raspistill', args); console.log('Watching for changes...'); app.set('watchingFile', true); fs.watchFile(__dirname+'/stream/image_stream.jpg', function(current, previous) { console.log('emmit liveStewam'); io.sockets.emit('liveStream', {url:'image_stream.jpg?_t=' + (Math.random() * 100000), time:dateformat(new Date(), "yyyy/mm/dd HH:MM:ss")});
raspistillコマンドの - tl 500 は電圧等の関係で値調整が必要ですのでご注意を。
次にindex.html(クライアント側)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>the view from my office </title> <!-- Bootstrap CSS --> <link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"> <style type="text/css"> #stream { height: 99%; margin: 0px auto; display: block; margin-top: 20px; } </style> <!-- jQuery --> <script src="http://code.jquery.com/jquery.js"></script> <!-- Bootstrap JavaScript --> <script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> var socket = io(); socket.on('liveStream', function(data) { $('#stream').attr('src', data.url); $('#timetext').text(data.time); $('.start').hide(); }); function startStream() { socket.emit('start-stream'); $('.start').hide(); } </script> </head> <body class="container"> <h1 class="text-center">the view from my office <small>Powered by PI</small> </h1> <hr> <button type="button" id="" class="btn btn-info start" onclick="startStream()">Start Camera</button> <div class="row"> <img src="" id="stream"> </div> <div id="timetext" class="text-center"></div> </body> </html>
最初にstartStreamで、socket.emitで、"start-stream"を送付します。
後は、socket.onで、"liveStream"を受け取り画像と更新時間を再描画。
socket.on('liveStream', function(data) { $('#stream').attr('src', data.url); $('#timetext').text(data.time); $('.start').hide(); }); function startStream() { socket.emit('start-stream'); $('.start').hide();
node.jsってこんなに簡単にコーティング出来る。感動。
nohup node ./httpd/liveStreaming/index.js &
で起動します。
ターミナル閉じたいのでnohup にしました。
startCameraをクリック
オフィスというか僕のデスクからの外の景色です。
ちなみにカメラのびよ~んの奴がうまい事向きを調整できずに逆さカメラになっております