我有一台AXIS IP摄像机,我可以使用http
和rtsp
协议进行检查。
http://ca.me.ra.ip/axis-cgi/mjpg/video.cgi?resolution=1024x768&dummy=1520
rtsp://ca.me.ra.ip:554/axis-media/media.amp?videocodec=h264&resolution=640x480
我要做的是获取流,将其缓冲在我的服务器中,然后进行广播,以便通过一个连接到相机,我可以预览给多个用户。
我通过这段代码以某种方式解决了这个问题:
#!/usr/bin/python
'''
Author: Igor Maculan - n3wtron@gmail.com
A Simple mjpg stream http server
'''
import cv2
from PIL import Image
import threading
from http.server import BaseHTTPRequestHandler,HTTPServer
from socketserver import ThreadingMixIn
from io import StringIO,BytesIO
import time
capture=None
class CamHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path.endswith('.mjpg'):
self.send_response(200)
self.send_header('Content-type','multipart/x-mixed-replace; boundary=--jpgboundary')
self.end_headers()
while True:
try:
rc,img = capture.read()
if not rc:
continue
imgRGB=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
jpg = Image.fromarray(imgRGB)
tmpFile = BytesIO()
jpg.save(tmpFile,'JPEG')
self.wfile.write("--jpgboundary".encode())
self.send_header('Content-type','image/jpeg')
self.send_header('Content-length',str(tmpFile.getbuffer().nbytes))
self.end_headers()
jpg.save(self.wfile,'JPEG')
time.sleep(0.05)
except KeyboardInterrupt:
break
return
if self.path.endswith('.html'):
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
self.wfile.write('<html><head></head><body>'.encode())
self.wfile.write('<img src="http://127.0.0.1:8080/cam.mjpg"/>'.encode())
self.wfile.write('</body></html>'.encode())
return
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
def main():
global capture
capture = cv2.VideoCapture("rtsp://ca.me.ra.ip:554/axis-media/media.amp?videocodec=h264&resolution=640x480")
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 320);
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 240);
capture.set(cv2.CAP_PROP_SATURATION,0.2);
global img
try:
server = ThreadedHTTPServer(('0.0.0.0', 8080), CamHandler)
print( "server started")
server.serve_forever()
except KeyboardInterrupt:
capture.release()
server.socket.close()
if __name__ == '__main__':
main()
然后我可以在浏览器中使用此地址检查本地机器中的摄像头:
http://ca.me.ra.ip:8080/cam.mjpg
问题是,如果我在两个浏览器中打开它,服务器会因此错误而崩溃:
断言fctx-&gt; async_lock在libavcodec / pthread_frame.c上失败:155
152 static void async_unlock(FrameThreadContext *fctx)
153 {
154 pthread_mutex_lock(&fctx->async_mutex);
155 av_assert0(fctx->async_lock); <-- This is the line which throws error
156 fctx->async_lock = 0;
157 pthread_cond_broadcast(&fctx->async_cond);
158 pthread_mutex_unlock(&fctx->async_mutex);
159 }
注意:
如果我将本地机器中的摄像机地址更改为capture = cv2.VideoCapture(0)
以广播我的笔记本电脑摄像头,无论我运行多少浏览器,一切正常。
我没能在网上找到更好的解决方案,所以我问是否有人知道更好的方式来流式传输相机并进行广播,或者可能是修复此代码的解决方案。
谢谢。