我无法从Picamera流式传输图像

时间:2019-04-18 15:58:50

标签: python sockets streaming

我在https://picamera.readthedocs.io/en/release-1.13/recipes2.html#rapid-capture-and-streaming第4.9节中找到了一个项目的代码

我成功地使它工作了,但是当我尝试将服务端放在树莓派上而不是客户端上时,我将无法工作。

编辑: 编辑: 我找到了答案:在服务器上,文件需要以写操作(wb)打开,而在客户端上,文件需要以读操作(rb)打开 但是,我们在服务器和客户端之间有7秒钟的延迟,您知道如何降低它吗?


LE SERVEUR

# -*-coding:utf-8  -*
import io
import socket
import struct
from PIL import Image, ImageTk
from threading import Thread
import time

class ControleurClientVideo():

    def __init__(self, controleur_client):
        self.adresse='0.0.0.0'
        self.port=8000

        self._client_socket = socket.socket()
        self._connection = None

        self._thread = None
        self._stop = False

    def connection_raspberry(self):
        self._thread = Thread(target=self._connection_avec_raspberry)
        self._thread.start()

    def _connection_avec_raspberry(self):
        try:
            self._client_socket.connect((self.adresse, self.port))
            self._connection = self._client_socket.makefile('wb')
            self._connection_active=True
            print("Connection avec le serveur etabli")
            time.sleep(2)
            self._recevoir_flux_image()

        except Exception as e:
            print(e)

    def _recevoir_flux_image(self):
        try:
            while not (self._stop):
                # Read the length of the image as a 32-bit unsigned int. If the
                # length is zero, quit the loop
                image_len = struct.unpack('<L', 
                self._connection.read(struct.calcsize('<L')))[0]
                if not image_len:
                    self.connection_perdu = True
                    break
                # Construct a stream to hold the image data and read the image
                # data from the connection
                image_stream = io.BytesIO()
                image_stream.write(self._connection.read(image_len))
                # Rewind the stream, open it as an image with PIL and do some
                image_stream.seek(0)
                image_pill = Image.open(image_stream)
                image_pill = image_pill.resize((320, 240), Image.ANTIALIAS)

                image_tk = ImageTk.PhotoImage(image_pill)
                print(image_tk)
                self.controleur_client.changer_image(image_tk)

        finally:
            self.fermer_connection()


    def fermer_connection(self):
        self._stop = True
        time.sleep(0.5)
        if not (self._connection == None):
            self._connection.close()
            self._connection = None
        self._client_socket.close()
        self._client_socket=None 
        self._thread = None
        print("Connection avec le serveur fermer")

LE CLIENT

# -*-coding:utf-8  -*
import io
import socket
import struct
import time
import picamera
from threading import Thread


class ControleurStreamingVideo():

    def __init__(self):
        self.adresse='0.0.0.0'
        self.port=8000

        self._serveur_socket = socket.socket()
        self._serveur_socket.bind((self.adresse, self.port))
        self._connection = None

        self._thread=None

    def ouvrir_serveur(self):
        self._thread = Thread(target=self._connection_avec_client)
        self._thread.start()

    def _connection_avec_client(self):
        try:
            print("Serveur en attente d'une connection...")
            self._serveur_socket.listen(5)
            self._connection = self._serveur_socket.accept()[0].makefile('rb')
            print("Connection réussi, début de la vidéo")

        except Exception as e:
            repr(e)

        finally:
            self._envoit_image()
            self._serveur_socket.close()

    def _envoit_image(self):
        try:
            self.output = SplitFrames(self._connection)
            with picamera.PiCamera(resolution='VGA', framerate=30) as camera:
                time.sleep(1)  #warmup la caméra
                camera.start_recording(self.output, format='mjpeg')
                camera.wait_recording(30)
                camera.stop_recording()
                self._serveur_socket.close()


        except Exception as e:
            print(e)



class SplitFrames(object):

    def __init__(self, connection):
        self.connection = connection
        self.stream = io.BytesIO()

    def write(self, buf):
        if buf.startswith(b'\xff\xd8'):
            # Start of new frame; send the old one's length
            # then the data
            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.stream.seek(0)
            self.stream.write(buf)

当我运行程序时,它说只写错误。我发现问题出在SplitFrames中。导致原因的任何想法

SERVEUR: Serveur en attente d'une连接... Connectionréussi,德拉维多首府 写

客户: 连接服务器 伺服连接器 阅读

编辑: 我找到了答案:在服务器上,文件需要以写操作(wb)打开,而在客户端上,文件需要以读操作(rb)打开 但是,我们在服务器和客户端之间有7秒钟的延迟,您知道如何降低它吗?

0 个答案:

没有答案