Skip to content

Commit

Permalink
Reworked the way the streaming backed works
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Keur committed Feb 24, 2016
1 parent 0b30824 commit 30a9fc2
Show file tree
Hide file tree
Showing 7 changed files with 284 additions and 15 deletions.
Empty file added README.md
Empty file.
17 changes: 11 additions & 6 deletions foscam.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,11 @@ module.exports = (env) ->
@getCGIResponse('getDevState',
(obj) ->
console.dir obj
if obj.infraLedState == '1'
@irEnabled = true
else
@irEnabled = false
if obj != null
if obj.infraLedState == '1'
@irEnabled = true
else
@irEnabled = false
)

stream = new Stream({
Expand All @@ -110,8 +111,12 @@ module.exports = (env) ->
'&usr=' + @username + '&pwd=' + @password

request cgiUrl, (err, res, body) ->
parseString body, (err, parsedObj) ->
cb? parsedObj.CGI_Result
console.log "err " + err
if err?.length
parseString body, (err, parsedObj) ->
cb? parsedObj.CGI_Result
else
cb? null

getImgPath: ->
imgPath = ""
Expand Down
45 changes: 45 additions & 0 deletions lib/mpeg1muxer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

140 changes: 140 additions & 0 deletions lib/videoStream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
(function() {
var Mpeg1Muxer, STREAM_MAGIC_BYTES, VideoStream, events, util, ws;

ws = require('ws');

util = require('util');

events = require('events');

Mpeg1Muxer = require('./mpeg1muxer');

STREAM_MAGIC_BYTES = "jsmp";

VideoStream = function(options) {
this.name = options.name;
this.streamUrl = options.streamUrl;
this.width = options.width;
this.height = options.height;
this.wsPort = options.wsPort;

this.stream = void 0;
this.initMpeg1Muxer();
this.initWebsocketServer();
return this;
};

util.inherits(VideoStream, events.EventEmitter);

VideoStream.prototype.initMpeg1Muxer = function() {
var gettingInputData, gettingOutputData, inputData, outputData, self;
this.mpeg1Muxer = new Mpeg1Muxer({
url: this.streamUrl
});
self = this;

this.mpeg1Muxer.on('mpeg1data', function(data) {
return self.emit('camdata', data);
});
gettingInputData = false;
inputData = [];
gettingOutputData = false;
outputData = [];
this.mpeg1Muxer.on('ffmpegError', function(data) {
var size;
data = data.toString();
if (data.indexOf('Input #') !== -1) {
gettingInputData = true;
}
if (data.indexOf('Output #') !== -1) {
gettingInputData = false;
gettingOutputData = true;
}
if (data.indexOf('frame') === 0) {
gettingOutputData = false;
}
if (gettingInputData) {
inputData.push(data.toString());
size = data.match(/\d+x\d+/);
if (size != null) {
size = size[0].split('x');
if (self.width == null) {
self.width = parseInt(size[0], 10);
}
if (self.height == null) {
return self.height = parseInt(size[1], 10);
}
}
}
});
//this.mpeg1Muxer.on('ffmpegError', function(data) {
// return global.process.stderr.write(data);
//});
return this;
};

VideoStream.prototype.initWebsocketServer = function() {
var self;
self = this;
this.wsServer = new ws.Server({
port: this.wsPort
});
this.wsServer.on("connection", function(socket) {
return self.onSocketConnect(socket);
});
this.wsServer.broadcast = function(data, opts) {
var i, _results;
_results = [];
for (i in this.clients) {
if (this.clients[i].readyState === 1) {
_results.push(this.clients[i].send(data, opts));
} else {
_results.push(console.log("Error: Client (" + i + ") not connected."));
}
}
return _results;
};
return this.on('camdata', function(data) {
return self.wsServer.broadcast(data);
});
};

function sendHeader(socket, width, height) {
streamHeader = new Buffer(8);
streamHeader.write(STREAM_MAGIC_BYTES);
streamHeader.writeUInt16BE(width, 4);
streamHeader.writeUInt16BE(height, 6);
socket.send(streamHeader, {
binary: true
});
}

VideoStream.prototype.onSocketConnect = function(socket) {
var self, streamHeader;
self = this;

self.mpeg1Muxer.startStream();

if(self.width == undefined){
setTimeout(function(){
sendHeader(socket, self.width, self.height);
}, 2500);
}else{
sendHeader(socket, self.width, self.height);
}

console.log(("" + this.name + ": New WebSocket Connection (") + this.wsServer.clients.length + " total)");

socket.on("close", function(code, message) {
console.log(("" + self.name + ": Disconnected WebSocket (") + self.wsServer.clients.length + " total)");

if(self.wsServer.clients.length < 1){
self.mpeg1Muxer.stopStream();
console.log("Tearing down the mpeg1Muxer.");
}
});
};

module.exports = VideoStream;

}).call(this);
49 changes: 40 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,52 @@
{
"name": "pimatic-foscam",
"description": "A plugin to display foscam HD cameras in the UI. Also provides an action to take snapshots.",
"author": "Marco Keur <marco@precision-it.nl> (http://precision-it.nl)",
"main": "foscam",
"files": [
"foscam.coffee",
"README.md",
"foscam-config-schema.coffee",
"device-config-schema.coffee",
"app/ipcamera-page.coffee",
"app/ipcamera-template.html",
"app/jsmpg.js"
],
"version": "0.8.6",
"homepage": "http://precision-it.nl",
"repository": {
"type":"git",
"url": "git://github.com/marcokeur/pimatic-foscam.git"
},
"configSchema": "foscam-config-schema.coffee",
"dependencies": {
"xml2js": "*"
}
}


{
"_args": [
[
"pimatic-foscam",
"/home/pi/pimatic-app"
]
],
"_from": "pimatic-foscam@latest",
"_id": "pimatic-foscam@0.8.3",
"_from": "pimatic-foscam@",
"_id": "pimatic-foscam@0.8.6",
"_inCache": true,
"_installable": true,
"_location": "/pimatic-foscam",
"_nodeVersion": "0.12.7",
"_nodeVersion": "0.10.24",
"_npmOperationalInternal": {
"host": "packages-5-east.internal.npmjs.com",
"tmp": "tmp/pimatic-foscam-0.8.6.tgz_1454680652064_0.0077676111832261086"
},
"_npmUser": {
"email": "marco@precision-it.nl",
"name": "marcokeur"
},
"_npmVersion": "2.12.1",
"_npmVersion": "3.5.3",
"_phantomChildren": {},
"_requested": {
"name": "pimatic-foscam",
Expand All @@ -28,8 +59,8 @@
"_requiredBy": [
"#USER"
],
"_resolved": "https://registry.npmjs.org/pimatic-foscam/-/pimatic-foscam-0.8.3.tgz",
"_shasum": "420187946c7f16ebe1dca9039eb077fc9943f4d8",
"_resolved": "https://registry.npmjs.org/pimatic-foscam/-/pimatic-foscam-0.8.6.tgz",
"_shasum": "422d23cfbbefc5dc389f5a673b98070cccdcca8f",
"_shrinkwrap": null,
"_spec": "pimatic-foscam",
"_where": "/home/pi/pimatic-app",
Expand All @@ -50,8 +81,8 @@
"devDependencies": {},
"directories": {},
"dist": {
"shasum": "420187946c7f16ebe1dca9039eb077fc9943f4d8",
"tarball": "http://registry.npmjs.org/pimatic-foscam/-/pimatic-foscam-0.8.3.tgz"
"shasum": "422d23cfbbefc5dc389f5a673b98070cccdcca8f",
"tarball": "http://registry.npmjs.org/pimatic-foscam/-/pimatic-foscam-0.8.6.tgz"
},
"engines": {
"node": ">0.8.x",
Expand Down Expand Up @@ -85,5 +116,5 @@
"url": "git://github.com/marcokeur/pimatic-foscam.git"
},
"scripts": {},
"version": "0.8.5"
"version": "0.8.6"
}
42 changes: 42 additions & 0 deletions test/videoStream/frontend.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=320, initial-scale=1"/>
<title>jsmpeg streaming</title>
<style type="text/css">
body {
background: #333;
text-align: center;
margin-top: 10%;
}
#videoCanvas {
/* Always stretch the canvas to 640x480, regardless of its
internal size. */
width: 640px;
height: 480px;
}
</style>
</head>
<body>
<!-- The Canvas size specified here is the "initial" internal resolution. jsmpeg will
change this internal resolution to whatever the source provides. The size the
canvas is displayed on the website is dictated by the CSS style.
-->
<canvas id="videoCanvas" width="640" height="480">
<p>
Please use a browser that supports the Canvas Element, like
<a href="http://www.google.com/chrome">Chrome</a>,
<a href="http://www.mozilla.com/firefox/">Firefox</a>,
<a href="http://www.apple.com/safari/">Safari</a> or Internet Explorer 10
</p>
</canvas>
<script type="text/javascript" src="../../app/jsmpg.js"></script>
<script type="text/javascript">
// Setup the WebSocket connection and start the player
var client = new WebSocket( 'ws://localhost:9999/' );

var canvas = document.getElementById('videoCanvas');
var player = new jsmpeg(client, {canvas:canvas});
</script>
</body>
</html>
6 changes: 6 additions & 0 deletions test/videoStream/testVideoStream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Stream = require('../../lib/videoStream.js');
stream = new Stream({
name: 'name',
streamUrl: 'rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov',
wsPort: 9999
});

0 comments on commit 30a9fc2

Please sign in to comment.