Raspberry Pi и CSI камера, стриминг на сервер, библеотека picamera, io.BytesIO, буфер и проблемы

Тема в разделе "Raspberry Pi", создана пользователем Sanchez5890, 23 июн 2019.

  1. Sanchez5890

    Sanchez5890 Нерд

    Доброго времени суток форум! Можете, пожалуйста, помочь с решением проблемы?
    Что я хочу сделать:
    • К Raspberry Pi 3 подключена CSI камера, Raspberry делает стрим с камеры и отсылает его на сервер, где его считывает MPlayer
    • Сервер и mplayer уже работают исправно
    • Я хочу написать клиент для малины на python, чтобы данный клиент работал аналогично этой команде:
      Код (Text):
      raspivid -t -0 -ifx negative -w 800 -h 600 -hf -ih -fps 20 -o - | nc 192.168.1.200 11000
    Можно представить всю эту систему по схеме:

    малина с камерой(клиент) -----видеопоток-----> сервер(исправен) ------------> mplayer(исправен)(клиент)

    Ещё пояснение: всё что я называю малиной, raspbperry это Raspberry pi с CSI камерой. Ещё хотелось бы пояснить кто клиент кто сервер:
    • Raspberry - клиент
    • Сервер - сервер
    • Mplayer - клиент
    Сегодня эта схема у меня работает только через команду выше. Повторюсь, что цель к которой я иду это питоновский код.
    Я попробовал это сделать, вот мой код:
    Код (Python):
    import socket
    import time
    import picamera
    import io

    with picamera.PiCamera() as camera:
        camera.resolution = (640, 480)
        camera.framerate = 24

        sock.connect(('192.168.1.200', 11000))
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # необходимо для повторного использования адреса
        connection = sock.makefile('wb')
        stream = io.BytesIO()
        try:
            camera.start_recording(stream, format='h264')
            while True:

       
                connection.write(stream.read())
                connection.flush()
     
         
        finally:
            camera.stop_recording()
            connection.close()
            sock.close()
     
    Что получается:
    • Данный скетч не работает, но запускается :)
    • Если мы в while влепим stream.seek(0), то в таком случае мы получим видео, но оно будет ускоренное и циклическое.
    • Если мы в while допишем stream.truncate(), а stream.read(), заменим на stream.getbuffer(), то в таком случае мы получим видео, но в нем будет просто статичная картинка.
    Помогите пожалуйста, знающие, решить данную проблему.
    Извините, пожалуйста, если вам режут глаз слишком очевидные подробности
     
    Последнее редактирование: 23 июн 2019
  2. Sanchez5890

    Sanchez5890 Нерд

  3. NikitOS

    NikitOS Король шутов Администратор

    Для кого это пояснение?
    ----
    :D
    Код (Python):

    import os

    cmd = "raspivid -t -0 -ifx negative -w 800 -h 600 -hf -ih -fps 20 -o - | nc 192.168.1.200 11000"

    os.system(cmd)
     
     
    Sanchez5890 нравится это.
  4. Sanchez5890

    Sanchez5890 Нерд

    Спасибо большое, но это скорее будет не самое надежное решение в плане обработок ошибок сокета и переподключения?
     
  5. Sanchez5890

    Sanchez5890 Нерд

    Я в прошлой теме, не совсем корректно объяснил кто кем является, из-за чего все запутались
     
  6. NikitOS

    NikitOS Король шутов Администратор

    А вот это не моя епархия :)
     
  7. Sanchez5890

    Sanchez5890 Нерд

    Это печально, значит будем ждать, кто подскажет, как это ещё можно реализовать. В любом случае, спасибо!
     
    NikitOS нравится это.
  8. Sanchez5890

    Sanchez5890 Нерд

    Я вернулся к истокам, оказывается вся сила в простоте, вот рабочий клиент:
    Код (Python):
    import socket
    import time
    import picamera


    with picamera.PiCamera() as camera:
        camera.resolution = (640, 480)
        camera.framerate = 24
        sock = socket.socket()
        sock.connect(('192.168.1.200', 11000))
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # необходимо для повторного использования адреса
       
        connection = sock.makefile('wb')
       
        try:
            camera.start_recording(connection, format='h264')
            while True:
                connection.flush()
           
               
        finally:
            camera.stop_recording()
            connection.close()
            sock.close()
    Теперь кому-то будет жить немного проще
     
    Igor68 и NikitOS нравится это.