-
Notifications
You must be signed in to change notification settings - Fork 159
/
mjpg_server.py
executable file
·125 lines (102 loc) · 3.38 KB
/
mjpg_server.py
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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Yuki Furuta <furushchev@jsk.imi.i.u-tokyo.ac.jp>
from __future__ import print_function
import argparse
import cv2
import os
import rospy
import sys
import time
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
from SocketServer import ThreadingMixIn
VIDEO_PATH = None
class MJPGStreamHandler(BaseHTTPRequestHandler):
html_suffix = ['.html']
mjpg_suffix = ['.mjpg', '.avi', '.mov']
capture = None
jpeg_quality = 80
loop_rate = 20.0
def do_GET(self):
path, ext = os.path.splitext(self.path)
if ext in self.html_suffix + self.mjpg_suffix:
self.send_response(200)
if ext in self.html_suffix:
self.html_response()
elif ext in self.mjpg_suffix:
self.mjpg_response()
else:
self.send_response(404)
def html_response(self):
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write('''
<html>
<head></head>
<body>
<img src="http://127.0.0.1:8080/camera.mjpg"/>
</body>
</html>''')
def mjpg_response(self):
self.send_header(
'Content-type', 'multipart/x-mixed-replace; boundary=--jpgboundary')
self.end_headers()
if self.capture is None:
self.capture = cv2.VideoCapture(VIDEO_PATH)
nframes = self.capture.get(cv2.CAP_PROP_FRAME_COUNT)
iframe = 0
while True:
try:
ok, img = self.capture.read()
if not ok:
continue
iframe += 1
if iframe > nframes:
iframe = 0
self.capture.open(VIDEO_PATH)
ok, img = cv2.imencode('.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, self.jpeg_quality])
if not ok:
continue
jpg = img.tostring()
self.wfile.write('--jpgboundary')
self.wfile.write(os.linesep)
self.send_header('Content-type', 'image/jpeg')
self.send_header('Content-length', str(len(jpg)))
self.end_headers()
self.wfile.write(jpg)
self.wfile.write(os.linesep)
time.sleep(1.0 / self.loop_rate)
except KeyboardInterrupt:
break
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
pass
def main():
global VIDEO_PATH
p = argparse.ArgumentParser()
p.add_argument('video_path')
p.add_argument('--port', default=8080, type=int)
if rospy.myargv() == sys.argv:
argv = sys.argv
loginfo = print
else:
rospy.init_node('mjpg_server')
argv = rospy.myargv()
loginfo = rospy.loginfo
args = p.parse_args(argv[1:])
VIDEO_PATH = args.video_path
if not os.path.exists(VIDEO_PATH):
raise OSError('video not found: {}'.format(VIDEO_PATH))
server = None
try:
server = ThreadedHTTPServer(('localhost', args.port), MJPGStreamHandler)
loginfo('Server Started')
server.serve_forever()
except Exception as ex:
loginfo('Got exception: {}'.format(str(ex)))
finally:
if server:
server.socket.close()
loginfo('Server Ended')
if __name__ == '__main__':
main()