从IP摄像机广播视频流

时间:2018-04-05 16:26:54

标签: python-3.x video-streaming ip-camera cv2

我有一台AXIS IP摄像机,我可以使用httprtsp协议进行检查。

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

链接到pthread_frame.c

  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)以广播我的笔记本电脑摄像头,无论我运行多少浏览器,一切正常。

我没能在网上找到更好的解决方案,所以我问是否有人知道更好的方式来流式传输相机并进行广播,或者可能是修复此代码的解决方案。

谢谢。

0 个答案:

没有答案