My favorites
▼
|
Sign in
madox
Madox.net projects
Project Home
Downloads
Wiki
Issues
Source
Checkout
Browse
Changes
Source path:
svn
/
trunk
/
webcam_stream
/
webcam_stream.py
r14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
"""
Webcam Streamer
Uses Pygame and HTTPServer to stream USB Camera images via HTTP (Webcam)
HTTP Port, camera resolutions and framerate are hardcoded to keep it
simple but the program can be updated to take options.
Default HTTP Port 8080, 320x240 resolution and 6 frames per second.
Point your browser at http://localhost:8080/
http://www.madox.net/
"""
import pygame
import pygame.camera
import signal
import sys
import tempfile
import threading
import time
import BaseHTTPServer
import SocketServer
class CameraCapture():
def __init__(self, device, resolution, fps):
#Initialize the camera
self.camera = pygame.camera.Camera(device, resolution)
self.camera.start()
#Set up a CameraSurface Buffer
self.camera_surface = pygame.Surface(resolution)
self.jpeg = ""
self.jpeg_sema = threading.BoundedSemaphore()
self.period = 1/float(fps)
self.stop = True
#Prepare conditions
self.frame_count = 0
self.frame_available = threading.Condition()
#Kick it off
self.start_capture()
def get_image(self):
self.jpeg_sema.acquire()
jpeg_copy = self.jpeg
self.jpeg_sema.release()
return jpeg_copy
def stop_capture(self):
self.stop = True
def start_capture(self):
if self.stop == True:
self.stop = False
self.capture_image()
def capture_image(self):
#Time start
time_start = time.time()
#Capture the image [Blocking until image received]
self.camera_surface = self.camera.get_image(self.camera_surface)
#Using a tempfile here because pygame image save gets
#filetype from extension. Limiting module use so no PIL.
temp_jpeg = tempfile.NamedTemporaryFile(suffix='.jpg')
pygame.image.save(self.camera_surface, temp_jpeg.name)
#Read back the JPEG from the tempfile and store it to self
temp_jpeg.seek(0)
self.jpeg_sema.acquire()
self.jpeg = temp_jpeg.read()
self.jpeg_sema.release()
temp_jpeg.close()
#Increment frame count and mark new frame condition
self.frame_available.acquire()
self.frame_count += 1
self.frame_available.notifyAll()
self.frame_available.release()
#If not stopped, prepare for the next capture
if self.stop == False:
time_elapsed = time.time() - time_start
if time_elapsed >= self.period:
time_wait = 0
else:
time_wait = self.period - time_elapsed
t = threading.Timer(time_wait, self.capture_image)
t.start()
class HTTPServer(SocketServer.ThreadingMixIn,
BaseHTTPServer.HTTPServer):
def __init__(self, server_address, cam_dev, cam_res, cam_fps):
SocketServer.TCPServer.__init__(self, server_address, HTTPHandler)
self.camera = CameraCapture(cam_dev, cam_res, cam_fps)
class HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
"""
HTTP Request Handler
"""
def do_GET(self):
if self.path == "/":
response = """
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Webcam Streamer</title>
</head>
<body onload="get_new_image();">Select a streaming option below :<br>
<a href="/GetStream">Multipart:
Preferred for fast connections, supported by most browsers.</a><br>
<a href="/JSStream">Javascript:
Backup option, for some mobile browsers (Android) and good for slow
connections.</a>
</body>
</html>
"""
self.send_response(200)
self.send_header("Content-Length", str(len(response)))
self.send_header("Cache-Control", "no-store")
self.end_headers()
self.wfile.write(response)
elif self.path[:9] == "/JSStream":
#HTML with Javascript streaming for browsers that don't support
#multipart jpeg (Android!!!)
response = """
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Webcam Stream (Javascript)</title>
<script type="text/javascript">
function get_new_image(){
var img = new Image();
var d = new Date();
img.style.zIndex = 0;
img.style.position = "absolute";
img.onload = got_new_image;
//Generate unique URL to bypass caching on mobile browsers that ignore
//cache-control
img.src = "/GetImage&n=" + d.getTime();
var webcam = document.getElementById("images");
webcam.insertBefore(img, webcam.firstChild);
}
function got_new_image() {
var d = new Date();
this.style.zIndex = d.getTime()
//Kill the earlier siblings (previous images)
while(this.parentNode.childNodes[1]) {
this.parentNode.removeChild(this.parentNode.childNodes[1]);
}
get_new_image();
}
</script>
</head>
<body onload="get_new_image();">
<div id="images"></div>
</body>
</html>
"""
self.send_response(200)
self.send_header("Content-Length", str(len(response)))
self.send_header("Cache-Control", "no-store")
self.end_headers()
self.wfile.write(response)
elif self.path[:10] == "/GetStream":
#Boundary is an arbitrary string that should not occur in the
#data stream, using own website address here
boundary = "www.madox.net"
self.send_response(200)
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Content-type",
"multipart/x-mixed-replace;boundary=%s"
% boundary)
self.end_headers()
frame_id = self.server.camera.frame_count
while True:
self.server.camera.frame_available.acquire()
while frame_id == self.server.camera.frame_count:
self.server.camera.frame_available.wait()
self.server.camera.frame_available.release()
frame_id = self.server.camera.frame_count
response = "Content-type: image/jpeg\n\n"
response = response + self.server.camera.get_image()
response = response + "\n--%s\n" % boundary
self.wfile.write(response)
elif self.path[:9] == "/GetImage":
response = self.server.camera.get_image()
self.send_response(200)
self.send_header("Content-Length", str(len(response)))
self.send_header("Content-Type", "image/jpeg")
self.send_header("Content-Disposition",
"attachment;filename=\"snapshot.jpg\"")
self.send_header("Cache-Control", "no-store")
self.end_headers()
self.wfile.write(response)
else:
self.send_error(404, "Banana Not Found.")
self.end_headers()
do_HEAD = do_POST = do_GET
if __name__ == '__main__':
print "Started webcam streamer"
def quit(signum, frame):
print "Quitting..."
http_server.camera.stop_capture()
sys.exit(0)
pygame.init()
pygame.camera.init()
signal.signal(signal.SIGINT, quit)
signal.signal(signal.SIGTERM, quit)
#Localhost, Port 8080, camres=320x240, fps=6
http_server = HTTPServer(server_address=("",8080),
cam_dev="/dev/video0",
cam_res=(320,240),
cam_fps=6)
http_server_thread = threading.Thread(target=
http_server.serve_forever())
http_server_thread.setDaemon(true)
http_server_thread.start()
try:
while True:
http_server_thread.join(60)
except KeyboardInterrupt:
quit()
Show details
Hide details
Change log
r10
by madox.net on Jun 12, 2011
Diff
Add Python Webcam Streamer
Go to:
/trunk/webcam_stream
...k/webcam_stream/webcam_stream.py
Project members,
sign in
to write a code review
Older revisions
All revisions of this file
File info
Size: 7345 bytes, 245 lines
View raw file
Powered by
Google Project Hosting