![picamera_v1](https://framboiserobot.ca/wp-content/uploads/2019/09/picamera_v1-678x381.jpg)
Introduction
Comme nous l’avons vu dans cet article, le Raspberry Pi offre plusieurs outils facilitant la transmission d’images vidéo. Le connecteur dédié et la librairie picamera vont nous aider dans cette tâche.
La manipulation d’images vidéo en programmation va nécessiter un lien réseau à haut débit. Le langage python3 nous offre les protocoles UDP et TCP comme mécanismes de transport. Chacun de ces protocoles présente des avantages et des inconvénients. Les logiciels présentés ici utilisent le protocole TCP.
Références
Framboiserobot.ca – Module vidéo
RaspberryPi.org – Camera Module
Construction des programmes
Le langage utilisé est python3. Le serveur exploite la librairie picamera pour capturer les images du module vidéo. Le client se connecte au serveur vidéo à l’aide du protocole TCP qui lui renvoie le flux de données. Le logiciel mplayer est utilisé pour visualiser les images reçues et sera contrôlé par la librairie subprocess de python3. Mplayer est offert dans toutes les distributions Linux et doit être installé manuellement par l’utilisateur.
Serveur Video TCP
Pseudo-code du serveur vidéo.
1 - Initialiser le module vidéo. 2 - Ouvrir un port TCP à l'écoute. 3 - Accepter la connexion d'un client. 4 - Acquérir les images vidéo. 5 - Envoyer les images vidéo au client. 6 - Recommencer à l'étape 4.
code source: TCP_Video_Server.zip
#!/usr/bin/python3 import socket import time import picamera import sys # global definitions DEBUG = True VIDEO_RESOLUTION = (640,480) VIDEO_FRAMERATE = 20 VIDEO_FORMAT = 'h264' VIDEO_LENGTH = -1 SERVER_IP = '0.0.0.0' SERVER_PORT = 10002 # function def start_video_server(ip,port): if DEBUG: print("[MSG]> start video server") with picamera.PiCamera() as camera: camera.resolution = VIDEO_RESOLUTION camera.framerate = VIDEO_FRAMERATE server_socket = socket.socket() server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1) server_socket.bind((ip,port)) server_socket.listen(0) if DEBUG: print("[MSG]> listening on %s:%d" % (ip, port)) (client_socket, client_address) = server_socket.accept() connection = client_socket.makefile('wb') if DEBUG: print("[MSG]> connection from %s:%d" % (client_address)) try: if DEBUG: print("[MSG]> start video capture") camera.start_preview() time.sleep(1) camera.start_recording(connection, format=VIDEO_FORMAT) while True: camera.wait_recording(VIDEO_LENGTH) camera.stop_recording() if DEBUG: print("[MSG]> stop video capture") except: if DEBUG: print("[MSG]> error: exception") camera.stop_recording() connection.close() finally: if DEBUG: print("[MSG]> close network socket") client_socket.close() server_socket.close() # main if __name__ == "__main__": while 1: try: start_video_server(SERVER_IP, SERVER_PORT) except KeyboardInterrupt: if DEBUG: print("[MSG]> Ctrl-C detected ... exiting"); sys.exit() except Exception as e: if DEBUG: print("[MSG]> error: exception %s" % e) time.sleep(1)
Client Video TCP
Pseudo-code du client vidéo .
1 - Établir une connexion avec le serveur vidéo. 2 - Ouvrir le programme de visualisation mplayer. 3 - Recevoir les images vidéo. 4 - Envoyer les images au logiciel de visualisation mplayer. 5 - Recommencer à l'étape 3.
code source: TCP_Video_Client.zip
#!/usr/bin/python3 import socket import subprocess import time import sys # global definitions DEBUG = True SERVER_IP = '192.168.99.1' SERVER_PORT = 10002 # function def start_video_client(robot_ip,robot_port): total_data_recv = 0 PKT_SIZE = 1024 cmdline = ['mplayer','-fps','40', '-xy', '800','-msglevel','all=-1','-cache','256','-'] if DEBUG: print("[MSG]> start_video_client()") try: client_socket = socket.socket() client_socket.connect((robot_ip,robot_port)) if DEBUG: print("[MSG]> success: connected to {}:{}".format(robot_ip,robot_port)) except Exception as e: if DEBUG: print("[MSG]> error: {}".format(str(e))) print("[MSG]> error: not connected to {}:{}".format(robot_ip,robot_port)) try: player = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stderr=subprocess.PIPE) while True: data = client_socket.recv(PKT_SIZE) if not data: if DEBUG: print('[MSG]> error: connection closed') break total_data_recv += len(data) if DEBUG: print("[MSG]> {} bytes received".format(total_data_recv)) player.stdin.write(data) except Exception as e: print("[MSG]> error: {}".format(str(e))) finally: player.terminate() client_socket.close() time.sleep(1) if DEBUG: print("[MSG]> video channel closed") # main if __name__ == "__main__": try: start_video_client(SERVER_IP, SERVER_PORT) except KeyboardInterrupt: if DEBUG: print("[MSG]> Ctrl-C detected ... exiting"); sys.exit()