Fun from cli and host as websocket
This commit is contained in:
parent
7b6680ee59
commit
48658e1f33
4 changed files with 378 additions and 9 deletions
298
console.html
Normal file
298
console.html
Normal file
|
@ -0,0 +1,298 @@
|
|||
<!--
|
||||
websocketd console
|
||||
Full documentation at http://websocketd.com/
|
||||
{{license}}
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf8">
|
||||
<title>websocketd console</title>
|
||||
<style>
|
||||
.template {
|
||||
display: none !important;
|
||||
}
|
||||
body, input {
|
||||
font-family: dejavu sans mono, Menlo, Monaco, Consolas, Lucida Console, tahoma, arial;
|
||||
font-size: 13px;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
.header {
|
||||
background-color: #efefef;
|
||||
padding: 2px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 32px;
|
||||
}
|
||||
.header button {
|
||||
font-size: 19px;
|
||||
width: 30px;
|
||||
margin: 2px 2px 0 2px;
|
||||
padding: 0;
|
||||
float: left;
|
||||
}
|
||||
.header .url-holder {
|
||||
position: absolute;
|
||||
left: 38px;
|
||||
top: 4px;
|
||||
right: 14px;
|
||||
bottom: 9px;
|
||||
}
|
||||
.header .url {
|
||||
border: 1px solid #999;
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 2px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
.messages {
|
||||
overflow-y: scroll;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 36px;
|
||||
bottom: 0;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
.message {
|
||||
border-bottom: 1px solid #bbb;
|
||||
padding: 2px;
|
||||
}
|
||||
.message-type {
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
width: 80px;
|
||||
display: block;
|
||||
}
|
||||
.message-data {
|
||||
margin-left: 90px;
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
white-space: pre;
|
||||
}
|
||||
.type-input,
|
||||
.type-send {
|
||||
background-color: #ffe;
|
||||
}
|
||||
.type-onmessage {
|
||||
background-color: #eef;
|
||||
}
|
||||
.type-open,
|
||||
.type-onopen {
|
||||
background-color: #efe;
|
||||
}
|
||||
.type-close,
|
||||
.type-onclose {
|
||||
background-color: #fee;
|
||||
}
|
||||
.type-onerror,
|
||||
.type-exception {
|
||||
background-color: #333;
|
||||
color: #f99;
|
||||
}
|
||||
.type-send .message-type,
|
||||
.type-onmessage .message-type {
|
||||
opacity: 0.2;
|
||||
}
|
||||
.type-input .message-type {
|
||||
color: #090;
|
||||
}
|
||||
.send-input {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
background-color: inherit;
|
||||
}
|
||||
.send-input:focus {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
<header class="header">
|
||||
<button class="disconnect" title="Disconnect" style="display:none">×</button>
|
||||
<button class="connect" title="Connect" style="display:none">✔</button>
|
||||
<div class="url-holder">
|
||||
<input class="url" type="text" value="{{addr}}" spellcheck="false">
|
||||
</div>
|
||||
</header>
|
||||
<section class="messages">
|
||||
<div class="message template">
|
||||
<span class="message-type"></span>
|
||||
<span class="message-data"></span>
|
||||
</div>
|
||||
<div class="message type-input">
|
||||
<span class="message-type">send »</span>
|
||||
<span class="message-data"><input type="text" class="send-input" spellcheck="false"></span>
|
||||
</div>
|
||||
</section>
|
||||
<script>
|
||||
var ws = null;
|
||||
function ready() {
|
||||
select('.connect').style.display = 'block';
|
||||
select('.disconnect').style.display = 'none';
|
||||
select('.connect').addEventListener('click', function() {
|
||||
connect(select('.url').value);
|
||||
});
|
||||
select('.disconnect').addEventListener('click', function() {
|
||||
disconnect();
|
||||
});
|
||||
select('.url').focus();
|
||||
select('.url').addEventListener('keydown', function(ev) {
|
||||
var code = ev.which || ev.keyCode;
|
||||
// Enter key pressed
|
||||
if (code == 13) {
|
||||
updatePageUrl();
|
||||
connect(select('.url').value);
|
||||
}
|
||||
});
|
||||
select('.url').addEventListener('change', updatePageUrl);
|
||||
select('.send-input').addEventListener('keydown', function(ev) {
|
||||
var code = ev.which || ev.keyCode;
|
||||
// Enter key pressed
|
||||
if (code == 13) {
|
||||
var msg = select('.send-input').value;
|
||||
select('.send-input').value = '';
|
||||
send(msg);
|
||||
}
|
||||
// Up key pressed
|
||||
if (code == 38) {
|
||||
moveThroughSendHistory(1);
|
||||
}
|
||||
// Down key pressed
|
||||
if (code == 40) {
|
||||
moveThroughSendHistory(-1);
|
||||
}
|
||||
});
|
||||
window.addEventListener('popstate', updateWebSocketUrl);
|
||||
updateWebSocketUrl();
|
||||
}
|
||||
function updatePageUrl() {
|
||||
var match = select('.url').value.match(new RegExp('^(ws)(s)?://([^/]*)(/.*)$'));
|
||||
if (match) {
|
||||
var pageUrlSuffix = match[4];
|
||||
if (history.state != pageUrlSuffix) {
|
||||
history.pushState(pageUrlSuffix, pageUrlSuffix, pageUrlSuffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
function updateWebSocketUrl() {
|
||||
var match = location.href.match(new RegExp('^(http)(s)?://([^/]*)(/.*)$'));
|
||||
if (match) {
|
||||
var wsUrl = 'ws' + (match[2] || '') + '://' + match[3] + match[4];
|
||||
select('.url').value = wsUrl;
|
||||
}
|
||||
}
|
||||
function appendMessage(type, data) {
|
||||
var template = select('.message.template');
|
||||
var el = template.parentElement.insertBefore(template.cloneNode(true), select('.message.type-input'));
|
||||
el.classList.remove('template');
|
||||
el.classList.add('type-' + type.toLowerCase());
|
||||
el.querySelector('.message-type').textContent = type;
|
||||
el.querySelector('.message-data').textContent = data || '';
|
||||
el.querySelector('.message-data').innerHTML += ' ';
|
||||
el.scrollIntoView(true);
|
||||
}
|
||||
function connect(url) {
|
||||
function action() {
|
||||
appendMessage('open', url);
|
||||
try {
|
||||
ws = new WebSocket(url);
|
||||
} catch (ex) {
|
||||
appendMessage('exception', 'Cannot connect: ' + ex);
|
||||
return;
|
||||
}
|
||||
select('.connect').style.display = 'none';
|
||||
select('.disconnect').style.display = 'block';
|
||||
ws.addEventListener('open', function(ev) {
|
||||
appendMessage('onopen');
|
||||
});
|
||||
ws.addEventListener('close', function(ev) {
|
||||
select('.connect').style.display = 'block';
|
||||
select('.disconnect').style.display = 'none';
|
||||
appendMessage('onclose', '[Clean: ' + ev.wasClean + ', Code: ' + ev.code + ', Reason: ' + (ev.reason || 'none') + ']');
|
||||
ws = null;
|
||||
select('.url').focus();
|
||||
});
|
||||
ws.addEventListener('message', function(ev) {
|
||||
if (typeof(ev.data) == "object") {
|
||||
var rd = new FileReader();
|
||||
rd.onload = function(ev){
|
||||
appendMessage('onmessage', "BLOB: "+rd.result);
|
||||
};
|
||||
rd.readAsBinaryString(ev.data);
|
||||
} else {
|
||||
appendMessage('onmessage', ev.data);
|
||||
}
|
||||
});
|
||||
ws.addEventListener('error', function(ev) {
|
||||
appendMessage('onerror');
|
||||
});
|
||||
select('.send-input').focus();
|
||||
}
|
||||
if (ws) {
|
||||
ws.addEventListener('close', function(ev) {
|
||||
action();
|
||||
});
|
||||
disconnect();
|
||||
} else {
|
||||
action();
|
||||
}
|
||||
}
|
||||
function disconnect() {
|
||||
if (ws) {
|
||||
appendMessage('close');
|
||||
ws.close();
|
||||
}
|
||||
}
|
||||
function send(msg) {
|
||||
appendToSendHistory(msg);
|
||||
appendMessage('send', msg);
|
||||
if (ws) {
|
||||
try {
|
||||
ws.send(msg);
|
||||
} catch (ex) {
|
||||
appendMessage('exception', 'Cannot send: ' + ex);
|
||||
}
|
||||
} else {
|
||||
appendMessage('exception', 'Cannot send: Not connected');
|
||||
}
|
||||
}
|
||||
function select(selector) {
|
||||
return document.querySelector(selector);
|
||||
}
|
||||
var maxSendHistorySize = 100;
|
||||
currentSendHistoryPosition = -1,
|
||||
sendHistoryRollback = '';
|
||||
function appendToSendHistory(msg) {
|
||||
currentSendHistoryPosition = -1;
|
||||
sendHistoryRollback = '';
|
||||
var sendHistory = JSON.parse(localStorage['websocketdconsole.sendhistory'] || '[]');
|
||||
if (sendHistory[0] !== msg) {
|
||||
sendHistory.unshift(msg);
|
||||
while (sendHistory.length > maxSendHistorySize) {
|
||||
sendHistory.pop();
|
||||
}
|
||||
localStorage['websocketdconsole.sendhistory'] = JSON.stringify(sendHistory);
|
||||
}
|
||||
}
|
||||
function moveThroughSendHistory(offset) {
|
||||
if (currentSendHistoryPosition == -1) {
|
||||
sendHistoryRollback = select('.send-input').value;
|
||||
}
|
||||
var sendHistory = JSON.parse(localStorage['websocketdconsole.sendhistory'] || '[]');
|
||||
currentSendHistoryPosition += offset;
|
||||
currentSendHistoryPosition = Math.max(-1, Math.min(sendHistory.length - 1, currentSendHistoryPosition));
|
||||
var el = select('.send-input');
|
||||
el.value = currentSendHistoryPosition == -1
|
||||
? sendHistoryRollback
|
||||
: sendHistory[currentSendHistoryPosition];
|
||||
setTimeout(function() {
|
||||
el.setSelectionRange(el.value.length, el.value.length);
|
||||
}, 0);
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", ready, false);
|
||||
</script>
|
|
@ -20,10 +20,11 @@ using namespace std;
|
|||
using namespace affdex;
|
||||
|
||||
|
||||
std::string getAsJson(const std::map<FaceId, Face> faces, const double timeStamp)
|
||||
std::string getAsJson(int framenr, const std::map<FaceId, Face> faces, const double timeStamp)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "{" << "'t':" << timeStamp << ",";
|
||||
ss << "'nr':" << framenr << ",";
|
||||
ss << "'faces':[";
|
||||
|
||||
int i(0);
|
||||
|
@ -85,7 +86,6 @@ std::string getAsJson(const std::map<FaceId, Face> faces, const double timeStamp
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Project for demoing the Windows SDK CameraDetector class (grabbing and processing frames from the camera).
|
||||
/// </summary>
|
||||
|
@ -189,11 +189,21 @@ int main(int argsc, char ** argsv)
|
|||
frameDetector->setFaceListener(faceListenPtr.get());
|
||||
frameDetector->setProcessStatusListener(videoListenPtr.get());
|
||||
|
||||
/*std::string cameraPipeline;
|
||||
cameraPipeline ="v4l2src device=/dev/video0 extra-controls=\"c,exposure_auto=1,exposure_absolute=500\" ! ";
|
||||
cameraPipeline+="video/x-raw, format=BGR, framerate=30/1, width=(int)1280,height=(int)720 ! ";
|
||||
cameraPipeline+="appsink";
|
||||
|
||||
cv::VideoCapture webcam;
|
||||
webcam.open(cameraPipeline);*/
|
||||
cv::VideoCapture webcam(camera_id); //Connect to the first webcam
|
||||
webcam.set(CV_CAP_PROP_FPS, camera_framerate); //Set webcam framerate.
|
||||
webcam.set(CV_CAP_PROP_FRAME_WIDTH, resolution[0]);
|
||||
webcam.set(CV_CAP_PROP_FRAME_HEIGHT, resolution[1]);
|
||||
std::cerr << "Setting the webcam frame rate to: " << camera_framerate << std::endl;
|
||||
std::cerr << "Camera: " << camera_id << std::endl;
|
||||
std::cerr << "- Setting the frame rate to: " << camera_framerate << std::endl;
|
||||
//~ webcam.set(CV_CAP_PROP_FPS, camera_framerate); //Set webcam framerate.
|
||||
std::cerr << "- Setting the resolution to: " << resolution[0] << "*" << resolution[1] << std::endl;
|
||||
webcam.set(CV_CAP_PROP_FRAME_HEIGHT, 240);
|
||||
webcam.set(CV_CAP_PROP_FRAME_WIDTH, 320);
|
||||
|
||||
auto start_time = std::chrono::system_clock::now();
|
||||
if (!webcam.isOpened())
|
||||
{
|
||||
|
@ -218,7 +228,7 @@ int main(int argsc, char ** argsv)
|
|||
|
||||
//Start the frame detector thread.
|
||||
frameDetector->start();
|
||||
|
||||
int framenr = 0;
|
||||
do{
|
||||
|
||||
cv::Mat img;
|
||||
|
@ -227,6 +237,8 @@ int main(int argsc, char ** argsv)
|
|||
std::cerr << "Failed to read frame from webcam! " << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
imread(img);
|
||||
|
||||
//Calculate the Image timestamp and the capture frame rate;
|
||||
const auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start_time);
|
||||
|
@ -241,7 +253,8 @@ int main(int argsc, char ** argsv)
|
|||
// For each frame processed
|
||||
if (listenPtr->getDataSize() > 0)
|
||||
{
|
||||
|
||||
framenr++;
|
||||
|
||||
std::pair<Frame, std::map<FaceId, Face> > dataPoint = listenPtr->getData();
|
||||
Frame frame = dataPoint.first;
|
||||
std::map<FaceId, Face> faces = dataPoint.second;
|
||||
|
@ -260,8 +273,20 @@ int main(int argsc, char ** argsv)
|
|||
//Output metrics to the file
|
||||
//listenPtr->outputToFile(faces, frame.getTimestamp());
|
||||
|
||||
std:cout << getAsJson(faces, frame.getTimestamp()) << std::endl;
|
||||
std:cout << getAsJson(framenr, faces, frame.getTimestamp()) << std::endl;
|
||||
|
||||
char buff[100];
|
||||
snprintf(buff, sizeof(buff), "frame%06d.jpg", framenr);
|
||||
std::string targetFilename = buff; // convert to std::string
|
||||
|
||||
vector<int> compression_params;
|
||||
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
|
||||
compression_params.push_back(90);
|
||||
|
||||
imwrite(targetFilename, img, compression_params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
@ -0,0 +1 @@
|
|||
git+https://github.com/dpallot/simple-websocket-server.git
|
45
run.py
Normal file
45
run.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
#sudo ~/build/opencv-webcam-demo/opencv-webcam-demo --data ~/affdex-sdk/data --faceMode 1 --numFaces 40 --draw 1
|
||||
|
||||
import subprocess
|
||||
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
|
||||
|
||||
proc = subprocess.Popen([
|
||||
'/home/crowd/build/opencv-webcam-demo/opencv-webcam-demo',
|
||||
"--data", "/home/crowd/affdex-sdk/data",
|
||||
"--faceMode", "1",
|
||||
"--numFaces", "40",
|
||||
"--draw", "1",
|
||||
"--pfps", "5",
|
||||
"--cfps", "5",
|
||||
],stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
clients = []
|
||||
class EchoOutput(WebSocket):
|
||||
|
||||
# def handleMessage(self):
|
||||
# # echo message back to client
|
||||
# self.sendMessage(self.data)
|
||||
|
||||
def handleConnected(self):
|
||||
clients.append(self)
|
||||
print(self.address, 'connected')
|
||||
|
||||
def handleClose(self):
|
||||
clients.remove(self)
|
||||
print(self.address, 'closed')
|
||||
|
||||
server = SimpleWebSocketServer('', 8080, EchoOutput)
|
||||
|
||||
def send_message(msg):
|
||||
print "send", msg, "to", len(clients), "clients"
|
||||
for client in list(clients):
|
||||
client.sendMessage(u''+msg)
|
||||
|
||||
while proc.poll() is None:
|
||||
server.serveonce()
|
||||
line = proc.stdout.readline()
|
||||
if line == '':
|
||||
continue
|
||||
send_message(line)
|
||||
#print "test:", line.rstrip()
|
||||
|
Loading…
Reference in a new issue