简体   繁体   English

使用python套接字流式传输视频并发送响应

[英]stream video and send response using python sockets

I modified the picamera script from https://picamera.readthedocs.io/en/latest/recipes2.html#rapid-capture-and-streaming to be able to stream video from my raspberry to my computer and at the same time send commands from the computer to the raspberry.我修改了来自https://picamera.readthedocs.io/en/latest/recipes2.html#rapid-capture-and-streaming的 picamera 脚本,以便能够将视频从我的树莓传输到我的计算机,同时发送命令从电脑到树莓派。

My client code looks like this:我的客户端代码如下所示:

while True:
        stream.seek(0)
        stream.truncate()

        camera.capture(stream, 'jpeg', use_video_port=True)

        connection.write(struct.pack('<L', stream.tell()))
        connection.flush()

        stream.seek(0)
        connection.write(stream.read())

        returnmessage = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
        print(returnmessage)

        if returnmessage:
            if returnmessage == 1: 
                #do something
            else: 
                #do something else

and my server code:和我的服务器代码:

while True:

    image_len = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]

    if not image_len:
        break

    image_stream = io.BytesIO()
    image_stream.write(connection.read(image_len))

    image_stream.seek(0)

    data = np.frombuffer(image_stream.getvalue(), dtype=np.uint8)
    image = cv2.imdecode(data, cv2.IMREAD_COLOR)

    cv2.imshow('stream',image)
    key = cv2.waitKey(1)

    if key != -1:
        if key == ord("g"):
            print("pressed g")
            connection.write(struct.pack('<L', 1))
            connection.flush()
        elif key == ord("h"):
            print("pressed a")
            connection.write(struct.pack('<L', 2))
            connection.flush()
    else:
        connection.write(struct.pack('<L', 0))
        connection.flush()

This works but does not feel right and can be really laggy from time to time.这有效,但感觉不对,并且有时会非常滞后。 Depending on the streaming fps, I do not have to send a command after each frame so the waiting for the response is not always necessary but drops the streaming fps.根据流式 fps,我不必在每帧之后发送命令,因此等待响应并不总是必要的,但会丢弃流式 fps。

How can I approach this problem?我该如何解决这个问题? Should I open another thread and another socket on each side for the responses?我应该在每一侧打开另一个线程和另一个套接字以获得响应吗?

You can set the client socket to be non-blocking.您可以将客户端套接字设置为非阻塞。

That way, when you try to read - the socket won't wait for a command from the server.这样,当您尝试读取时 - 套接字不会等待来自服务器的命令。 If no command is received, connection.read will return immediately.如果没有收到命令, connection.read将立即返回。

In order to do so, call connection.setblocking(False) .为此,请调用connection.setblocking(False)

For my purpose I found that adding the following to the client script seemed to do the job出于我的目的,我发现将以下内容添加到客户端脚本似乎可以完成这项工作

reader, _, _ = select.select([connection], [], [], 0)

if reader: 
    returnmessage = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]

Thanks for your answer anyway.无论如何,感谢您的回答。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM