потоковое видео и отправка ответа с использованием python сокетов - PullRequest
0 голосов
/ 19 марта 2020

Я изменил сценарий picamera с https://picamera.readthedocs.io/en/latest/recipes2.html#rapid -capture-and-streaming , чтобы иметь возможность передавать видео с моей малины на мой компьютер и одновременно отправлять команды с компьютера на малину.

Мой код клиента выглядит следующим образом:

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

и код моего сервера:

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()

Это работает, но не выглядит правильным и может быть очень медленным со временем ко времени. В зависимости от потокового fps, мне не нужно отправлять команду после каждого кадра, поэтому ожидание ответа не всегда необходимо, но отбрасывает потоковый fps.

Как я могу подойти к этой проблеме? Должен ли я открыть другой поток и другой сокет на каждой стороне для ответов?

Ответы [ 2 ]

0 голосов
/ 19 марта 2020

Для моей цели я обнаружил, что добавление следующего к клиентскому скрипту, кажется, делает работу

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

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

Спасибо за ваш ответ в любом случае.

0 голосов
/ 19 марта 2020

Можно установить неблокируемый сокет клиента.

Таким образом, когда вы пытаетесь читать - сокет не будет ждать команды от сервера. Если команда не получена, connection.read немедленно вернется.

Для этого позвоните connection.setblocking(False).

...