允许多个客户端监听ThreadedHTTPServer python 3

时间:2019-01-14 10:48:34

标签: python http server client

我需要将网络摄像头图像传递给本地主机,以便在浏览器中查看网络摄像头。同时,我需要使用网络摄像头来提供YouTube流。我的语言是python3。

当我从网络摄像头cv2.capture('/dev/video0')捕获时,网络摄像头已锁定,因此直到释放它我才能第二次接触它。我不想每秒释放并重新捕获它60次。

我将以下代码用于http服务器:

server = ThreadedHTTPServer(('localhost', port), CamHandler)

在这里,CamHandler是一个类,其功能do_GET(self)每秒从网络摄像头中获取60次静止图像,并一起发送正确的标头。

因此,它会在浏览器中显示,并在流到youtube的流中(通过ffmpeg)起作用,但不能同时出现。

我该怎么办?如果您的答案是“使用插座”,请在上面详细说明。

更新

这是完整的代码:

#!/usr/bin/env python3 
import sys 
sys.path.append("cv2") 
import cv2 
from PIL import Image 
import threading 
from http.server import BaseHTTPRequestHandler, HTTPServer 
from socketserver import ThreadingMixIn 
from io import BytesIO 
import time 

capture=None



class CamHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global capture
        if self.path.endswith('stream.mjpeg'):
            self.send_response(200)
            self.send_header('Content-type','multipart/x-mixed-replace; boundary=--jpgboundary')
            self.end_headers()
            camId = "http://localhost:8091/camera.mjpeg"
            font = cv2.FONT_HERSHEY_SIMPLEX
            fontsize = .8
            while True:
                try:
                    with open("currentCamera.txt","r") as f:
                        newCamId = f.read().splitlines() 
                    if newCamId != camId:
                        capture.release();
                        capture = cv2.VideoCapture(''.join(newCamId))
                        print ("camera changed from ", camId, " to ", newCamId)
                        camId = newCamId

                    rc,img = capture.read()
                    if not rc:
                        continue

                    with open("subtitle.txt","r") as f:
                        subtitle = f.read().splitlines()
                        subtitle = ''.join(subtitle).strip()
                        if len(subtitle) > 2:
                            textsize = cv2.getTextSize(subtitle, font, fontsize, 2)[0]
                            textX = (img.shape[1] - textsize[0]) // 2
                            textY = img.shape[0] - textsize[1] - 30
                            cv2.rectangle(img,(textX-10,textY-20),(textX+textsize[0]+10,textY+textsize[1]),(255,255,255),-1)
                            cv2.putText(img,subtitle,(textX,textY+8),font,fontsize,(0,0,0),2)

                    imgRGB=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
                    jpg = Image.fromarray(imgRGB)
                    tmpFile = BytesIO() 
                    jpg.save(tmpFile,'JPEG')
                    self.wfile.write(b"--jpgboundary")
                    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(1/60)
                except KeyboardInterrupt:
                    break
            return
        if self.path.endswith('camera.mjpeg'):
            self.send_response(200)
            self.send_header('Content-type','multipart/x-mixed-replace; boundary=--jpgboundary')
            self.end_headers()
            camId = "/dev/video0"
            font = cv2.FONT_HERSHEY_SIMPLEX
            fontsize = .8
            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(b"--jpgboundary")
                    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(1/60)
                except KeyboardInterrupt:
                    break
            return


class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """Handle requests in a separate thread."""

def main():
    global capture
    capture = cv2.VideoCapture("/dev/video0")
    capture.set(3,1920)
    capture.set(4,1080)
    global img

    try:
        server = ThreadedHTTPServer(('localhost', 8091), CamHandler)
        print ("server started on port 8091")
        server.serve_forever()
    except KeyboardInterrupt:
        capture.release()
        server.socket.close()

if __name__ == '__main__':
    main()

我无法在浏览器中同时显示http://localhost:8091/stream.mjpeghttp://localhost:8091/camera.mjpeg。此外,当我尝试使用http://localhost:8091/stream.mjpeg作为ffmpeg的输入时,python脚本崩溃了。

更新2 错误是:

[mpjpeg @ 0xaa4148c0] Expected boundary '--' not found, instead found a line of # bytes
Segmentation fault

0 个答案:

没有答案