Я пытаюсь создать свой умный глазок. Проект основан на raspberry pi, который работает как сервер, и iphone, который работает как клиент.
На стороне RPi я слушаю сокет для клиентов, и если такой подключается, то я делаю фотографию и отправив его через сокет.
Я написал следующий сервер:
SimpleServer.py
import cv2
from ServerSocket import ServerSocket
server = ServerSocket('', 7070, cv2.VideoCapture(0), 5)
server.start()
print('Server ended')
ServerSocket.py
import socket
import select
import threading
import cv2
from PeepholeClient import PeepholeClient
class ServerSocket():
def __init__(self, host, port, camera, max_clients=1):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.setblocking(False)
self.sock.settimeout(10)
print('Socket created')
self.camera = camera
self.host = host
self.port = port
self.clients_threads = []
self.sock.bind((host, port))
self.sock.listen(max_clients)
print('ServerSoc initialized')
def close(self):
self.sock.close()
self.sock = None
print('Server socket closed')
def start(self):
print(f'ServerSoc started on port {self.port}')
client_numb = 1
shouldStop = False
while not shouldStop:
try:
conn, addr = self.sock.accept()
except socket.timeout:
print('Socket timeout error')
conn = None
print(f'Number of connected clients: {len(self.clients_threads)}')
if conn:
client = PeepholeClient(conn, addr, client_numb, self.camera)
client.start()
self.clients_threads.append(client)
client_numb += 1
for client in self.clients_threads:
if not client.isAlive():
self.clients_threads.remove(client)
if not self.clients_threads:
shouldStop = True
for client in self.clients_threads:
client.join()
print('Clients threads joined')
self.close()
PeepholeClient.py
import socket
import threading
import select
import cv2
import base64
class PeepholeClient(threading.Thread):
def __init__(self, client_sock, client_addr, number, camera):
threading.Thread.__init__(self)
self.client_sock = client_sock
self.client_addr = client_addr
self.client_numb = number
self.running = True
self.camera = camera
time.sleep(2)
print('Created PeepholeClient')
def run(self):
print('Started PeepholeClient thread')
while self.running:
if self.client_sock:
try:
read_ready, write_ready, except_ready = select.select([], [self.client_sock], [])
except:
print(f'Thread number {self.client_numb} Select() failed on socket with {self.client_addr}')
self.stop()
Return
if write_ready:
try:
ret, frame = self.camera.read()
frame = cv2.resize(frame, (640, 480))
encoded, buffer = cv2.imencode('.jpg', frame)
jpg_as_text = base64.b64encode(buffer)
self.client_sock.send(jpg_as_text)
except:
print('Cannot send data to client')
self.stop()
else:
print(f'No available write ready descriptors for client {self.client_numb}')
self.stop()
else:
print(f'There is no connection to the {self.client_addr}')
self.stop()
self.close()
def close(self):
self.client_sock.close()
print(f'Closed client socket for client {self.client_numb}')
self.camera.release()
def stop(self):
self.running = False
На стороне iPhone В настоящее время я только что подключился к RPi. Но как правильно получить изображение на стороне мобильного телефона? В области отладки я вижу, что данные были переданы. Я думал о чем-то вроде функции cycli c, отвечающей за обновление изображения, пока существует соединение. Что Вы думаете об этом? Или, может быть, вы знаете лучшее решение для потоковой передачи видео прямо с камеры Raspberry Pi в мобильное приложение iOS?
В настоящее время мой контроллер просмотра, отвечающий за получение и отображение изображения, выглядит следующим образом:
import UIKit
import Socket
class CameraViewController: UIViewController {
@IBOutlet weak var connectedServerAddrLabel: UILabel!
internal var socket: Socket? = nil
@IBOutlet weak var TestImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
do {
connectedServerAddrLabel!.text = String(socket!.remoteHostname)
let answerFromServer = try socket!.readString()
print("Answer from server: " + answerFromServer!)
}
catch {
print("Problem in camera view")
}
}
@IBAction func backButton_pressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
func updateUI() {
// Update image here somehow?
}
}
Жду любых хороших советов :) Wi sh Вам всего наилучшего!
Спасибо за совет