Python OpenCV сокет живого видео отстает - PullRequest
1 голос
/ 01 апреля 2020

Я создал приложение чата в python с использованием сокетов и хотел реализовать функцию видеовызова. Если я запускаю код для сервера и клиента на одном компьютере, он работает отлично. Но как только я перевожу их на разные машины, видео отстает. Скорость передачи данных слишком низкая. Ниже приведен код сервера и клиентского компьютера соответственно:

server.py

import socket
import cv2
import pickle

HEADER_SIZE = 10

server = socket.socket()
server.bind(("localhost", 1234))
server.listen(5)
client, addr = server.accept()

while True:
    full_msg = b''
    new_msg = True

    while True:
        msg = client.recv(4096)

        if new_msg:
            print(f"New message of length{msg[:HEADER_SIZE]}")
            msglen = int(msg[:HEADER_SIZE])
            new_msg = False

        full_msg += msg

        if len(full_msg) - HEADER_SIZE == msglen:
            print("Full msg received")

            frame = pickle.loads(full_msg[HEADER_SIZE:])
            cv2.imshow('server', frame)

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            new_msg = True
            full_msg = b''

    cv2.destroyAllWindows()
    break

client.py

import socket
import pickle
import cv2

client = socket.socket()
client.connect(("localhost", 1234))
cap = cv2.VideoCapture(0)

HEADER_SIZE = 10

while True:
    ret, frame = cap.read()

    data = pickle.dumps(frame)

    msg = bytes(f"{len(data):<{HEADER_SIZE}}", "utf-8") + data
    client.sendall(msg)

Кто-нибудь знает, как предотвратить эту задержку и сделать видеозвонок? Заранее спасибо.

1 Ответ

1 голос
/ 01 апреля 2020

Здесь следует помнить о нескольких вещах:

  • Потоковое видео почти всегда имеет буфер для потоковых кадров. Если ваш сервер принимает кадры, он должен их буферизовать на несколько секунд, чтобы если качество сети падает, он может воспроизводиться из буфера в ожидании новых кадров.
  • Вы используете изображения, а не видео. Кодирование видео работает, посылая ключевые кадры время от времени и частичные меньшие кадры между ключевыми кадрами (в видеокодеках также есть множество оптимизаций для борьбы с буферизацией, сбросом кадров и т. Д. c). Если вы транслируете видео кадр за кадром как полное изображение, ваша пропускная способность будет намного выше. Возможно, вы захотите использовать реальную библиотеку потокового видео (что будет сложнее)
  • Использование здесь pickle может добавить накладные расходы, вы, вероятно, захотите получить необработанные байты изображения и отправить их через сокет, чтобы вы могли Можно создать образ без десериализации, хотя две проблемы, описанные выше, скорее всего, связаны с проблемами производительности.

С учетом всего вышесказанного, если вы добавите буфер (может быть трудно в python?) И не выберете каждый кадр, вы можете увидеть некоторое улучшение.

edit: похоже, эта библиотека может быть полезна для вас: https://github.com/jeffbass/imagezmq

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...