Removed python based webcam support (didn't work well with the raspi), switched instead to external stream (mjpg-streamer being the preferred webcam server)

master
Gina Häußge 2013-01-03 00:39:17 +01:00
parent 8dc5e249d5
commit 4e4eed84bb
7 changed files with 67 additions and 124 deletions

View File

@ -12,6 +12,7 @@ allows
* reading the communication log and send arbitrary codes to be executed by the printer
* moving the X, Y and Z axis (jog controls, although very ugly ones right now)
* changing the speed modifiers for inner & outer wall, fill and support
* optional: visual monitoring of the printer via webcam stream integrated into the UI (using MJPG-Streamer)
The intended usecase is to run the Printer WebUI on a single-board computer like the Raspberry Pi and a WiFi module,
connect the printer to the server and therefore create a WiFi-enabled 3D printer.
@ -61,6 +62,60 @@ The following example config should explain the available options:
# use this option to define the port to which to bind the server, defaults to 5000
port = 5000
[webcam]
# use this option to enable display of a webcam stream in the UI, e.g. via MJPG-Streamer
stream = http://10.0.0.2:8080/?action=stream
Setup on a Raspberry Pi running Raspbian
----------------------------------------
I currently run the Printer WebUI on a Raspberry Pi running Raspbian (http://www.raspbian.org/). For the basic
package you'll need Python 2.7 (should be installed by default), pip and flask:
cd ~
sudo apt-get install python-pip git
git clone https://github.com/foosel/PrinterWebUI.git
cd PrinterWebUI
pip install -r requirements.txt
You should then be able to start the WebUI server:
pi@raspberrypi ~/PrinterWebUI $ python -m printer_webui.server
* Running on http://0.0.0.0:5000/
If you also want webcam support, you'll need to download and compile MJPG-Streamer:
cd ~
sudo apt-get install libjpeg8-dev imagemagick
wget -Omjpg-streamer.tar.gz http://mjpg-streamer.svn.sourceforge.net/viewvc/mjpg-streamer/mjpg-streamer/?view=tar
tar xfz mjpg-streamer.tar.gz
cd mjpg-streamer
make
This should hopefully run through without any compilation errors. You should then be able to start the webcam server:
pi@raspberrypi ~/mjpg-streamer $ ./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so"
MJPG Streamer Version: svn rev:
i: Using V4L2 device.: /dev/video0
i: Desired Resolution: 640 x 480
i: Frames Per Second.: 5
i: Format............: MJPEG
[...]
o: www-folder-path...: disabled
o: HTTP TCP port.....: 8080
o: username:password.: disabled
o: commands..........: enabled
If you now point your browser to http://<your Raspi's IP>:8080/?action=stream, you should see a moving picture at 5fps.
Open `~/.printerwebui/config.ini` and add the following lines to it:
[webcam]
stream = http://<your Raspi's IP>:8080/?action=stream
Restart the WebUI server and reload its frontend. You should now see a Webcam tab with content.
If everything works, add the startup commands to `/etc/rc.local`.
Credits
-------
@ -76,3 +131,7 @@ It also uses the following libraries and frameworks for backend and frontend:
* Knockout.js: http://knockoutjs.com/
* Flot: http://www.flotcharts.org/
* jQuery File Upload: http://blueimp.github.com/jQuery-File-Upload/
And this for Webcam support:
* MJPG-Streamer: http://sourceforge.net/apps/mediawiki/mjpg-streamer/index.php?title=Main_Page

View File

@ -7,7 +7,6 @@ from werkzeug import secure_filename
from printer_webui.printer import Printer, getConnectionOptions
from printer_webui.settings import settings
from printer_webui.webcam import hasWebcamSupport, Webcam
import sys
import os
@ -28,14 +27,10 @@ if not os.path.isdir(WEBCAM_FOLDER):
app = Flask("printer_webui")
printer = Printer()
if hasWebcamSupport():
webcam = Webcam()
else:
webcam = None
@app.route("/")
def index():
return render_template("index.html")
return render_template("index.html", webcamStream = settings().get("webcam", "stream"))
#~~ Printer state
@ -261,19 +256,6 @@ def setSettings():
s.save()
return getSettings()
#~~ webcam
@app.route(BASEURL + "webcam/image", methods=["GET"])
def getImage():
if webcam is None:
abort(404)
image = webcam.get()
strIO = StringIO.StringIO()
image.save(strIO, "JPEG", quality=80)
strIO.seek(0)
return send_file(strIO, mimetype="image/jpeg")
#~~ helper functions
def sizeof_fmt(num):

View File

@ -24,6 +24,9 @@ default_settings = {
"server": {
"host": "0.0.0.0",
"port": 5000
},
"webcam": {
"stream": None
}
}

View File

@ -97,12 +97,4 @@ table th.gcode_files_action, table td.gcode_files_action {
#webcam_container {
height: 440px;
background-color: #000000;
}
#webcam_placeholder {
height: 440px;
line-height: 440px;
text-align: center;
color: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}

View File

@ -438,32 +438,6 @@ function DataUpdater(connectionViewModel, printerStateViewModel, temperatureView
}
var dataUpdater = new DataUpdater(connectionViewModel, printerStateViewModel, temperatureViewModel, speedViewModel, terminalViewModel);
function WebcamViewModel() {
var self = this;
self.webcamUpdateInterval = 5000;
self.offlineUrl = "/static/img/webcam-offline.png";
self.url = ko.observable(undefined);
self.enabled = ko.observable(undefined);
self.enabled.subscribe(function(newValue) {
if (newValue) {
self.requestData();
} else {
$("#webcam_image")
}
});
self.requestData = function() {
if (!self.enabled())
return;
self.url(AJAX_BASEURL + "webcam/image?" + (new Date()).getTime());
setTimeout(self.requestData, self.webcamUpdateInterval);
}
}
var webcamViewModel = new WebcamViewModel();
$(function() {
//~~ Print job control
@ -603,7 +577,6 @@ $(function() {
ko.applyBindings(printerStateViewModel, document.getElementById("jog"));
ko.applyBindings(terminalViewModel, document.getElementById("term"));
ko.applyBindings(speedViewModel, document.getElementById("speed"));
ko.applyBindings(webcamViewModel, document.getElementById("webcam"));
//~~ startup commands

View File

@ -115,7 +115,7 @@
<li><a href="#jog" data-toggle="tab">Jog</a></li>
<li><a href="#speed" data-toggle="tab">Speed</a></li>
<li><a href="#term" data-toggle="tab">Term</a></li>
<li><a href="#webcam" data-toggle="tab">Webcam</a></li>
{% if webcamStream %}<li><a href="#webcam" data-toggle="tab">Webcam</a></li>{% endif %}
</ul>
<div class="tab-content">
@ -216,15 +216,13 @@
<button class="btn" type="button" id="terminal-send">Send</button>
</div>
</div>
{% if webcamStream %}
<div class="tab-pane" id="webcam">
<label class="checkbox">
<input type="checkbox" id="webcam_enable" data-bind="checked: enabled"> Enable webcam
</label>
<div id="webcam_container">
<img id="webcam_image" data-bind="attr: { src: url }, visible: enabled()">
<div id="webcam_placeholder" data-bind="visible: !enabled()">Offline</div>
<img id="webcam_image" src="{{ webcamStream }}">
</div>
</div>
{% endif %}
</div>
</div>
</div>

View File

@ -1,64 +0,0 @@
# coding=utf-8
__author__ = "Gina Häußge <osd@foosel.net>"
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
try:
#Try to find the OpenCV library for video capture.
import cv
except:
cv = None
try:
import VideoCapture as win32vidcap
except:
win32vidcap = None
import PIL
def hasWebcamSupport():
if cv == None and win32vidcap == None:
return False
return True
class Webcam(object):
def __init__(self):
self._cam = None
if cv != None:
self._cam = cv.CreateCameraCapture(-1)
elif win32vidcap != None:
try:
self._cam = win32vidcap.Device()
self._cam.setResolution(640, 480)
except:
pass
def get(self):
if self._cam is None:
return None
if cv is not None:
frame = cv.QueryFrame(self._cam)
image = PIL.Image.fromstring("L", frame.GetSize(), frame.tostring())
return image
elif win32vidcap is not None:
image = self._cam.getImage()
return image
else:
return None
def save(self, filename):
if self._cam is None:
return
if cv is not None:
frame = cv.QueryFrame(self._cam)
cv.SaveImage(filename, frame)
elif win32vidcap is not None:
self._cam.saveSnapshot(filename)
if __name__ == "__main__":
from printer_webui.settings import settings
import os
webcam = Webcam()
webcam.save(os.path.join(settings().settings_dir, "image.png"))