Python MJPEG 服务器

Posted

技术标签:

【中文标题】Python MJPEG 服务器【英文标题】:Python MJPEG Server 【发布时间】:2017-02-03 05:25:29 【问题描述】:

我正在尝试在树莓派上执行视觉处理并在图形界面上监控效果。使用 cv2.imshow 确实会降低帧速率,因此,我尝试将操作流式传输到 MPEG 本地服务器,然后从不同桌面上的 chrome 监视它。这是我开发的代码:

from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
from threading import Thread
import imutils
import sys

class CamHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        print(self.path)
        if self.path.endswith('/stream.mjpg'):
            self.send_response(20)
            self.send_header('Content-type', 'multipart/x-mixed-replace; boundary=--jpgboundary')
            self.end_headers()
            while True:
                try:

                    if(frame != None):
                        pass
                    r, buf = cv2.imencode(".jpg", frame)
                    self.wfile.write("--jpgboundary\r\n".encode())
                    self.end_headers()
                    self.wfile.write(bytearray(buf))
                except KeyboardInterrupt:
                    break
            return

        if self.path.endswith('.html') or self.path == "/":
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write('<html><head></head><body>')
            self.wfile.write('<img src="http://localhost:9090/stream.mjpg"  />')
            self.wfile.write('</body></html>')
            return

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


class WebcamVideoStream:
    def __init__(self, src=0):
        # initialize the video camera stream and read the first frame
        # from the stream
        self.stream = cv2.VideoCapture(src)
        # self.stream.set(3, 1920)
        # self.stream.set(4, 1080)
        # self.stream.set(15,-100)
        (self.grabbed, self.frame) = self.stream.read()

        # initialize the variable used to indicate if the thread should
        # be stopped
        self.stopped = False

    def start(self):
        # start the thread to read frames from the video stream
        Thread(target=self.update, args=()).start()
        return self

    def update(self):
        # keep looping infinitely until the thread is stopped
        while True:
            # if the thread indicator variable is set, stop the thread
            if self.stopped:
                self.stream.release()
                return

            # otherwise, read the next frame from the stream
            (self.grabbed, self.frame) = self.stream.read()

    def read(self):
        # return the frame most recently read
        return self.frame

    def stop(self):
        # indicate that the thread should be stopped
        self.stopped = True


def realmain():
    global frame

    ip = 'localhost'

    try:
        cap = WebcamVideoStream().start()
        server = ThreadedHTTPServer((ip, 9090), CamHandler)
        print("starting server")
        target = Thread(target=server.serve_forever,args=())

        i = 0
        while True:

            img = cap.read()
            img1 = imutils.resize(img, width=600)
            img2 = cv2.GaussianBlur(img1, (5, 5), 0)
            #frame = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)

            frame = cv2.Canny(img, 35, 125)
            if(i == 0):
                target.start()
            i +=1

    except KeyboardInterrupt:
        sys.exit()

if __name__ == '__main__':
    realmain()

现在,我可以从我的桌面运行服务器并在我的桌面上通过 chrome 查看 MPEG 的效果,但我无法从我的树莓派运行服务器,并通过输入以下 url 来访问它:http:/ /“RASPBERRY PI IP”:9090/stream.mjpg,在我的桌面上。当我这样做时,chrome 只是说该网页不可用。即使在 PI 上运行服务器,我也无法在 Epiphany 浏览器上查看 url,它只是下载图像。想知道是否有人对此问题有答案。

另外,在将 jpg 发送到服务器之前,有没有更快的方法来解压缩和重新压缩 jpg?

【问题讨论】:

你可以尝试用 ip = "" (空字符串) 代替 'localhost' 吗? 谢谢,我实际上在我的手机 wifi 热点上尝试了服务器,我能够通过我的桌面连接。一定是有防火墙阻止了连接 【参考方案1】:

您将服务器绑定到本地主机:

ip = 'localhost'

try:
    cap = WebcamVideoStream().start()
    server = ThreadedHTTPServer((ip, 9090), CamHandler)

尝试将'localhost' 更改为'0.0.0.0'。它将服务器绑定到所有网络接口。

【讨论】:

以上是关于Python MJPEG 服务器的主要内容,如果未能解决你的问题,请参考以下文章

从 Axis IP 摄像机重新流式传输 MJPEG

VLC 和 MJPEG 解码器流式传输(无效标头)

ffmpeg 将 rtsp 重新流式传输到 mjpeg

在 Android 上获取 IP Cam 视频流 (MJPEG)

实战物联网安防监控项目———把模拟数据传输到web网页web显示mjpeg-streamer视频图像

是否可以直接在 android 上录制 MJPEG?