11 Commits

Autor SHA1 Mensagem Data
Bernhard K. Weisshuhn 7606a9f35c it's one point ohhhhh, baby! 2012-12-15 16:13:44 +01:00
Bernhard K. Weisshuhn e5a5960106 add @karlwestin as a contributor 2012-12-15 16:13:09 +01:00
Bernhard Weißhuhn 73e3b48356 Merge pull request #3 from karlwestin/modulize
Modulize
2012-12-15 04:36:38 -08:00
Bernhard Weißhuhn 91f60fc341 Update README.md
praise @karlwestin
2012-12-12 12:33:39 +01:00
Karl Westin 94dce52391 Update README.md
todo: fix the readme
2012-12-09 09:26:56 -08:00
Karl Westin 4feaaddbe7 Added a normal http.createServer example 2012-12-09 09:25:12 -08:00
Karl Westin 2c0641547e Adding a really stupid buildscript for the client, feel free to improve
:)
Also, removing html5 boilerplate from the example
2012-12-09 09:02:48 -08:00
Karl Westin 9787c83ad0 Added a package.json for the example
Bumped version no
2012-12-09 08:44:00 -08:00
Karl Westin cb6b2014a4 DS_Store to effin gitignore 2012-12-09 08:27:29 -08:00
Karl Westin 35e84bb038 Modularize, to make it easier to use in other apps
Howto:
// pass in a node http server object:
require("node-dronestream").listen(server);
// attach the 5 js files. Yes let's make a build some time
2012-12-09 08:26:06 -08:00
Karl Westin 808079f780 In between, working on making a module of the stream 2012-12-09 07:10:34 -08:00
37 arquivos alterados com 1535 adições e 119 exclusões
+1
Ver Arquivo
@@ -1,2 +1,3 @@
node_modules
.*.swp
.DS_Store
+4
Ver Arquivo
@@ -3,6 +3,8 @@
Get a realtime live video stream from your
[Parrot AR Drone 2.0](http://ardrone2.parrot.com/) straight to your browser.
## Documentation is a little out of date, please check the two examples for now!
## Requirements
You'll need a decent and current browser and some cpu horsepower.
@@ -45,3 +47,5 @@ is enough to be used as a starting point for your own integration.
- Brian Leroux for being not content with the original solution and for
cleaning up the predecessor, nodecopter-stream.
- @karlwestin for picking up where I was to lazy to actually make this usable.
-82
Ver Arquivo
@@ -1,82 +0,0 @@
'use strict';
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, http = require('http')
, path = require('path')
, app = express()
, server = http.createServer(app)
, WebSocketServer = require('ws').Server
, wss = new WebSocketServer({server: server})
, sockets = []
, Parser = require('./lib/PaVEParser')
, arDrone = require('ar-drone')
;
function init() {
var tcpVideoStream = new arDrone.Client.PngStream.TcpVideoStream({timeout: 4000})
, p = new Parser();
console.log("Connecting to stream");
tcpVideoStream.connect(function () {
tcpVideoStream.pipe(p);
});
tcpVideoStream.on("error", function(err) {
console.log("There was an error: %s", err.message);
tcpVideoStream.end();
tcpVideoStream.emit("end");
init();
});
p.on('data', function (data) {
sockets.forEach(function(socket) {
socket.send(data, {binary: true});
});
});
}
init();
wss.on('connection', function (socket) {
sockets.push(socket);
socket.on("close", function() {
console.log("Closing socket");
sockets = sockets.filter(function(el) {
return el !== socket;
});
});
});
app.configure(function () {
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade', { pretty: true });
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function () {
app.use(express.errorHandler());
app.locals.pretty = true;
});
app.get('/', routes.index);
if (module.parent) {
module.exports = server;
} else {
server.listen(app.get('port'), function () {
console.log("Express server listening on port " + app.get('port'));
});
}
Arquivo executável
+3
Ver Arquivo
@@ -0,0 +1,3 @@
#!/bin/bash
cat dist/vendor/broadway/sylvester.js dist/vendor/broadway/glUtils.js dist/vendor/broadway/util.js dist/vendor/broadway/avc-codec.js dist/vendor/broadway/avc.js dist/vendor/broadway/canvas.js dist/nodecopter-stream.js > dist/nodecopter-client.js
+1162
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+33
Ver Arquivo
@@ -0,0 +1,33 @@
var express = require('express')
, routes = require('./routes')
, app = express()
, path = require('path')
, server = require("http").createServer(app)
;
app.configure(function () {
app.set('views', __dirname + '/views');
app.set('view engine', 'jade', { pretty: true });
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function () {
app.use(express.errorHandler());
app.locals.pretty = true;
});
app.get('/', routes.index);
/*
* Important:
*
* pass in the server object to listen, not the express app
* call 'listen' on the server, not the express app
*/
// should be require("node-dronestream").listen(server)
require("../lib/server").listen(server);
server.listen(3000);
+10
Ver Arquivo
@@ -0,0 +1,10 @@
var http = require("http"),
drone = require("../../index");
var server = http.createServer(function(req, res) {
require("fs").createReadStream(__dirname + "/index.html").pipe(res);
});
drone.listen(server);
server.listen(5555);
+16
Ver Arquivo
@@ -0,0 +1,16 @@
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Stream as module</title>
<script src="/dronestream/nodecopter-client.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1 id="heading">Stream through a normal require("http").createServer</h1>
<div id="droneStream" style="width: 640px; height: 360px"> </div>
<script type="text/javascript" charset="utf-8">
new NodecopterStream(document.getElementById("droneStream"));
</script>
</body>
</html>
+33
Ver Arquivo
@@ -0,0 +1,33 @@
var express = require('express')
, routes = require('./routes')
, app = express()
, path = require('path')
, server = require("http").createServer(app)
;
app.configure(function () {
app.set('views', __dirname + '/views');
app.set('view engine', 'jade', { pretty: true });
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function () {
app.use(express.errorHandler());
app.locals.pretty = true;
});
app.get('/', routes.index);
/*
* Important:
*
* pass in the server object to listen, not the express app
* call 'listen' on the server, not the express app
*/
// should be require("node-dronestream").listen(server)
require("../../index").listen(server);
server.listen(3000);
+13
Ver Arquivo
@@ -0,0 +1,13 @@
{
"name": "dronestream-example",
"version": "0.1.0",
"dependencies": {
"express": "3.0.0rc5",
"jade": "*"
},
"scripts": {
"start": "node app"
},
"author": "Bernhard K. Weisshuhn <bkw@codingforce.com>",
"license": "BSD"
}
+22
Ver Arquivo
@@ -0,0 +1,22 @@
extends layout
block append head
script(type='text/javascript', src='/dronestream/nodecopter-client.js')
-# for developing the client, use those url:s
-# script(type='text/javascript', src='/dronestream/vendor/broadway/sylvester.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/glUtils.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/util.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/avc-codec.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/avc.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/canvas.js')
-# script(type='text/javascript', src='/dronestream/nodecopter-stream.js')
-# concatenated version of client
block append bodyscripts
script
var copterStream = new NodecopterStream(document.querySelector('#dronestream'));
block content
div#dronestream(width=640, height=360)
@@ -7,7 +7,6 @@ html
title= title
link(rel='stylesheet', href='/css/normalize.min.css')
link(rel='stylesheet', href='/css/style.css')
script(src='/js/vendor/h5bp/modernizr-2.6.1-respond-1.1.0.min.js')
body
div.header-container
header.wrapper.clearfix
+13
Ver Arquivo
@@ -0,0 +1,13 @@
{
"name": "dronestream-example",
"version": "0.1.0",
"dependencies": {
"express": "3.0.0rc5",
"jade": "*"
},
"scripts": {
"start": "node app"
},
"author": "Bernhard K. Weisshuhn <bkw@codingforce.com>",
"license": "BSD"
}
+50
Ver Arquivo
@@ -0,0 +1,50 @@
/*! normalize.css v1.0.1 | MIT License | git.io/normalize */
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section,summary{display:block}
audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
audio:not([controls]){display:none;height:0}
[hidden]{display:none}
html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}
html,button,input,select,textarea{font-family:sans-serif}
body{margin:0}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
h2{font-size:1.5em;margin:.83em 0}
h3{font-size:1.17em;margin:1em 0}
h4{font-size:1em;margin:1.33em 0}
h5{font-size:.83em;margin:1.67em 0}
h6{font-size:.75em;margin:2.33em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
blockquote{margin:1em 40px}
dfn{font-style:italic}
mark{background:#ff0;color:#000}
p,pre{margin:1em 0}
code,kbd,pre,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}
pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}
q{quotes:none}
q:before,q:after{content:'';content:none}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-0.5em}
sub{bottom:-0.25em}
dl,menu,ol,ul{margin:1em 0}
dd{margin:0 0 0 40px}
menu,ol,ul{padding:0 0 0 40px}
nav ul,nav ol{list-style:none;list-style-image:none}
img{border:0;-ms-interpolation-mode:bicubic}
svg:not(:root){overflow:hidden}
figure{margin:0}
form{margin:0}
fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0;white-space:normal;*margin-left:-7px}
button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}
button,input{line-height:normal}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible}
button[disabled],input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*height:13px;*width:13px}
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
+8
Ver Arquivo
@@ -0,0 +1,8 @@
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
+10
Ver Arquivo
@@ -0,0 +1,10 @@
'use strict';
/*
* GET home page.
*/
exports.index = function (req, res) {
res.render('index', { title: 'Express' });
};
+22
Ver Arquivo
@@ -0,0 +1,22 @@
extends layout
block append head
script(type='text/javascript', src='/dronestream/nodecopter-client.js')
-# for developing the client, use those url:s
-# script(type='text/javascript', src='/dronestream/vendor/broadway/sylvester.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/glUtils.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/util.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/avc-codec.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/avc.js')
-# script(type='text/javascript', src='/dronestream/vendor/broadway/canvas.js')
-# script(type='text/javascript', src='/dronestream/nodecopter-stream.js')
-# concatenated version of client
block append bodyscripts
script
var copterStream = new NodecopterStream(document.querySelector('#dronestream'));
block content
div#dronestream(width=640, height=360)
+30
Ver Arquivo
@@ -0,0 +1,30 @@
!!! 5
html
block head
head
meta(http-equiv='X-UA-Compatible', content='IE=edge,chrome=1')
meta(name='viewport', content='width=device-width')
title= title
link(rel='stylesheet', href='/css/normalize.min.css')
link(rel='stylesheet', href='/css/style.css')
body
div.header-container
header.wrapper.clearfix
block header
nav
block navigation
div.main-container
div.main.wrapper.clearfix
block content
div.footer-container
footer.wrapper
block footer
block bodyscripts
// script(src='//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js')
// script
// window.jQuery || document.write('<script src="/js/vendor/h5bp/jquery-1.8.2.min.js"><\\x3C/script>')
+1
Ver Arquivo
@@ -0,0 +1 @@
module.exports = require("./lib/server");
+49
Ver Arquivo
@@ -0,0 +1,49 @@
/*
* Drone Stream listen:
* Takes a) a port number or b) a server object (node http or express, etc);
*/
var staticDir = "dronestream"
, check = new RegExp("^/" + staticDir, "i")
, dist = __dirname + "/../dist"
;
module.exports.listen = function listen(server) {
if(typeof server == "number") {
var port = server;
server = require("http").createServer();
server.listen(port);
}
/*
* Serving up the static files needed
*/
var oldHandlers = server.listeners("request").splice(0);
server.on("request", function(req, res) {
if(handler(req, res)) {
return;
}
for(var i = 0; i < oldHandlers.length; i++) {
oldHandlers[i].call(server, req, res);
}
});
function handler(req, res, next) {
if(!check.test(req.url)) {
return false;
}
var path = dist + req.url.replace(check, "");
console.log("checking static path: %s", path);
var read = require('fs').createReadStream(path);
read.pipe(res);
read.on("error", function(e) { console.log("Stream error: %s", e.message); });
return true;
}
/*
* Connecting stream + websocket server
*/
return require("./stream").attach(server);
};
+47
Ver Arquivo
@@ -0,0 +1,47 @@
/*
* Sets up a real stream + attaches it to a server
*/
module.exports.attach = function droneStream(server) {
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({server: server})
, sockets = []
, Parser = require('./PaVEParser')
, arDrone = require('ar-drone')
;
function init() {
var tcpVideoStream = new arDrone.Client.PngStream.TcpVideoStream({timeout: 4000})
, p = new Parser();
console.log("Connecting to stream");
tcpVideoStream.connect(function () {
tcpVideoStream.pipe(p);
});
tcpVideoStream.on("error", function(err) {
console.log("There was an error: %s", err.message);
tcpVideoStream.end();
tcpVideoStream.emit("end");
init();
});
p.on('data', function (data) {
sockets.forEach(function(socket) {
socket.send(data, {binary: true});
});
});
}
init();
wss.on('connection', function (socket) {
sockets.push(socket);
socket.on("close", function() {
console.log("Closing socket");
sockets = sockets.filter(function(el) {
return el !== socket;
});
});
});
};
+8 -6
Ver Arquivo
@@ -1,11 +1,12 @@
{
"name": "dronestream",
"description": "video live stream from your parrot ar.drone 2.0 to your browser in pure javascript",
"version": "0.2.0",
"version": "1.0.0",
"repository": {
"type": "git",
"url": "git@github.com:bkw/node-dronestream.git"
},
"main": "index",
"keywords": [
"drone",
"nodecopter",
@@ -15,16 +16,17 @@
"browser",
"x264"
],
"scripts": {
"start": "node app"
},
"dependencies": {
"express": "3.0.0rc5",
"jade": "*",
"ws": "~0.4.22",
"ar-drone": "0.0.3",
"buffy": "0.0.4"
},
"author": "Bernhard K. Weisshuhn <bkw@codingforce.com>",
"contributors": [
{
"name": "Karl Westin",
"email": "karl.westin@gmail.com"
}
],
"license": "BSD"
}
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
-17
Ver Arquivo
@@ -1,17 +0,0 @@
extends layout
block append head
script(type='text/javascript', src='/js/vendor/broadway/sylvester.js')
script(type='text/javascript', src='/js/vendor/broadway/glUtils.js')
script(type='text/javascript', src='/js/vendor/broadway/util.js')
script(type='text/javascript', src='/js/vendor/broadway/avc-codec.js')
script(type='text/javascript', src='/js/vendor/broadway/avc.js')
script(type='text/javascript', src='/js/vendor/broadway/canvas.js')
script(type='text/javascript', src='/js/nodecopter-stream.js')
block append bodyscripts
script
var copterStream = new NodecopterStream(document.querySelector('#dronestream'));
block content
div#dronestream(width=640, height=360)