Go to the documentation of this file.00001
00002
00003
00004
00005 from __future__ import print_function
00006 import argparse
00007 import cv2
00008 import os
00009 import rospy
00010 import sys
00011 import time
00012 from BaseHTTPServer import BaseHTTPRequestHandler
00013 from BaseHTTPServer import HTTPServer
00014 from SocketServer import ThreadingMixIn
00015
00016
00017 VIDEO_PATH = None
00018
00019
00020 class MJPGStreamHandler(BaseHTTPRequestHandler):
00021 html_suffix = ['.html']
00022 mjpg_suffix = ['.mjpg', '.avi', '.mov']
00023 capture = None
00024 jpeg_quality = 80
00025 loop_rate = 20.0
00026
00027 def do_GET(self):
00028 path, ext = os.path.splitext(self.path)
00029 if ext in self.html_suffix + self.mjpg_suffix:
00030 self.send_response(200)
00031 if ext in self.html_suffix:
00032 self.html_response()
00033 elif ext in self.mjpg_suffix:
00034 self.mjpg_response()
00035 else:
00036 self.send_response(404)
00037
00038 def html_response(self):
00039 self.send_header('Content-type', 'text/html')
00040 self.end_headers()
00041
00042 self.wfile.write('''
00043 <html>
00044 <head></head>
00045 <body>
00046 <img src="http://127.0.0.1:8080/camera.mjpg"/>
00047 </body>
00048 </html>''')
00049
00050 def mjpg_response(self):
00051 self.send_header(
00052 'Content-type', 'multipart/x-mixed-replace; boundary=--jpgboundary')
00053 self.end_headers()
00054
00055 if self.capture is None:
00056 self.capture = cv2.VideoCapture(VIDEO_PATH)
00057
00058 nframes = self.capture.get(cv2.CAP_PROP_FRAME_COUNT)
00059 iframe = 0
00060
00061 while True:
00062 try:
00063 ok, img = self.capture.read()
00064 if not ok:
00065 continue
00066 iframe += 1
00067 if iframe > nframes:
00068 iframe = 0
00069 self.capture.open(VIDEO_PATH)
00070 ok, img = cv2.imencode('.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, self.jpeg_quality])
00071 if not ok:
00072 continue
00073 jpg = img.tostring()
00074 self.wfile.write('--jpgboundary')
00075 self.send_header('Content-type', 'image/jpeg')
00076 self.send_header('Content-length', str(len(jpg)))
00077 self.end_headers()
00078 self.wfile.write(jpg)
00079 time.sleep(1.0 / self.loop_rate)
00080 except KeyboardInterrupt:
00081 break
00082
00083
00084 class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
00085 pass
00086
00087
00088 def main():
00089 global VIDEO_PATH
00090 p = argparse.ArgumentParser()
00091 p.add_argument('video_path')
00092 p.add_argument('--port', default=8080, type=int)
00093
00094 if rospy.myargv() == sys.argv:
00095 argv = sys.argv
00096 loginfo = print
00097 else:
00098 rospy.init_node('mjpg_server')
00099 argv = rospy.myargv()
00100 loginfo = rospy.loginfo
00101
00102
00103 args = p.parse_args(argv[1:])
00104
00105 VIDEO_PATH = args.video_path
00106 if not os.path.exists(VIDEO_PATH):
00107 raise OSError('video not found: {}'.format(VIDEO_PATH))
00108
00109 server = None
00110 try:
00111 server = ThreadedHTTPServer(('localhost', args.port), MJPGStreamHandler)
00112 loginfo('Server Started')
00113 server.serve_forever()
00114 except Exception as ex:
00115 loginfo('Got exception: {}'.format(str(ex)))
00116 finally:
00117 if server:
00118 server.socket.close()
00119 loginfo('Server Ended')
00120
00121
00122 if __name__ == '__main__':
00123 main()