-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathweb_cap.py
More file actions
103 lines (83 loc) · 2.85 KB
/
web_cap.py
File metadata and controls
103 lines (83 loc) · 2.85 KB
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
import os, cv2, time, struct, threading
from http.server import HTTPServer, BaseHTTPRequestHandler
from threading import Thread, RLock # threading
#from socketserver import Thread, RLock # threading
from select import select
class JpegStreamer(Thread):
def __init__(self, camera):
super().__init__()
self.cap = cv2.VideoCapture(camera)
self.lock = RLock()
self.pipes = {}
def register(self):
pr, pw = os.pipe()
self.lock.acquire()
self.pipes[pr] = pw
self.lock.release()
return pr
def unregister(self, pr):
self.lock.acquire()
self.pipes.pop(pr)
self.lock.release()
pr.close()
pw.close()
def capture(self):
cap = self.cap
while cap.isOpened():
ret, frame = cap.read()
if ret:
data = cv2.imencode('.jpg',
frame, (cv2.IMWRITE_JPEG_QUALITY, 40))
yield data[1]
def send(self, frame):
n = struct.pack('l', len(frame))
self.lock.acquire()
if len(self.pipes):
_, pipes, _ = select([].self.pipes.itervalues(),[],1)
for pipe in pipes:
os.write(pipe,n)
os.write(pipe,frame)
self.lock.release()
def run(self):
for frame in self.capture():
self.send(frame)
class JpegRetriever():
def __init__(self, streamer):
self.streamer = streamer
self.pipe = streamer.register()
def retrieve(self):
while 1:
ns = os.read(self.pipe, 8)
n = struct.unpack('l', ns)[0]
data = os.read(self.pipe,n)
yield data
def cleanup(self):
self.streamer.unregister(self.pipe)
class Handler(BaseHTTPRequestHandler):
retriever = None
@staticmethod
def setJpegRetriever(self):
Handler.retriever = retriever
def do_GET(self):
if self.retriver is None:
raise RuntimeError('No retriever')
if self.path != '/':
return
self.send_response(200)
self.send_header('Content-type', 'multipart/x-mixed-replace;boundary=abcde')
self.send_headers()
for frame in self.retriever.retrieve():
self.send_frame(frame)
def send_frame(self, frame):
self.wfile.write('--abcde\r\n')
self.wfile.write('Content-Type: image/jpeg\r\n')
self.wfile.write('Content-Length: %d' %len(frame))
self.wfile.write(frame)
if __name__ == '__main__':
streamer = JpegStreamer(0)
streamer.start()
retriever = JpegRetriever(streamer)
Handler.setJpegRetriever(retriever)
print('starting...')
httpd = HTTPServer(('',9000), Handler)
httpd.server_forever()