В проекте участвует клиент, передающий видеокамеру с сервера через сокеты. Сервер ждет ввода пользователя все время, и всякий раз, когда нажимается клавиша, кадр, захваченный камерой клиента в этот конкретный момент, должен быть добавлен к объекту-пустышке. Потоковый код для того же выглядит следующим образом:
Поток-server-
import io
import os
import socket
import struct
import cv2
import numpy as np
from PIL import Image
server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 6677))
server_socket.listen(0)
connection = server_socket.accept()[0].makefile('rb')
print('connection accepted')
try:
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)
image = Image.open(image_stream)
print('Image is %dx%d' % image.size)
cv2.imshow('Pi', cv2.cvtColor(np.array(image), cv2.COLOR_BGR2RGB))
cv2.waitKey(1)
finally:
connection.close()
server_socket.close()
Поток-client-
import io
import time
import socket
import struct
import picamera
class SplitFrames(object):
def __init__(self, connection):
self.connection = connection
self.stream = io.BytesIO()
self.count = 0
def write(self, buf):
if buf.startswith(b'\xff\xd8'):
size = self.stream.tell()
if size > 0:
self.connection.write(struct.pack('<L', size))
self.connection.flush()
self.stream.seek(0)
self.connection.write(self.stream.read(size))
self.count += 1
self.stream.seek(0)
self.stream.write(buf)
client_socket = socket.socket()
client_socket.connect(('my-server', 6677))
connection = client_socket.makefile('wb')
try:
output = SplitFrames(connection)
with picamera.PiCamera(resolution='640x480', framerate=60) as camera:
camera.start_preview()
time.sleep(2)
start = time.time()
camera.start_recording(output, format='mjpeg')
camera.wait_recording(30)
camera.stop_recording()
connection.write(struct.pack('<L', 0))
finally:
connection.close()
client_socket.close()
finish = time.time()
print('Sent %d images in %d seconds at %.2ffps' % (output.count, finish-start, output.count / (finish-start)))
Мне не удалось написать код для пользовательского ввода и сохранить часть проекта. Поиск в Google привел меня к асинхронным сокетам ввода / вывода, но не было ясно, как он подойдет для моего варианта использования.