Raspberry Pi 3 и CSI камера. Cтриминг как клиент, через netcat и mplayer

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

  1. Igor68

    Igor68 Гуру

    Следует отметить, что п.1 и п.2 (в начале) в одной программе.
     
  2. Sanchez5890

    Sanchez5890 Нерд

    Возможно я опять не понял. А почему нельзя сделать только 1 сервер, он принимает слушает соединение с малиной, которая передаёт этому серверу данные с камеры и сервер даёт mplayer-у слушать эти данные. Хранит видеопоток в буфере.

    Вот как я себе представляю эту схему:
    малина с камерой(клиент)-----видеопоток------>(порт А)сервер(порт Б, здесь открыт доступ к видеопотоку)<------->mplayer(берет видеопоток)
    Ведь как я понял, мы не можем ничего отправлять mplayer-у он сам должен посмотреть этот видеопоток.
    Код (Text):
    mplayer -fps 200 -demuxer h264es ffmpeg://tcp://192.168.1.200:2222
    Или у меня есть очередная безумная идея, может сервер просто примет видеопоток и загрузит его в какой-нибудь буфер, а mplayer его прочитает (тоже не знаю как, могу поискать в мануалах mplayer)
    Вот я ещё уточню я собираюсь использовать 1 малину с камерой и один mplayer который находится на том же компьютере, где и сервер
     
  3. Sanchez5890

    Sanchez5890 Нерд

    Вот такую штуку в одно объединить, мне же будет проще сделать (пока неособо известно как):
     
  4. Sanchez5890

    Sanchez5890 Нерд

    А то эти два сервера ещё связывать...
    В итоге тогда мы имеем 2 клиента - малина и mplayer
    1 сервер
     
  5. Sanchez5890

    Sanchez5890 Нерд

  6. Sanchez5890

    Sanchez5890 Нерд

    Igor68, помогите пожалуйста, разобраться, как решить данную задачу
     
  7. Sanchez5890

    Sanchez5890 Нерд

    Думаю всё-таки серверный вариант подключения mplayer получше
     
    Последнее редактирование: 20 июн 2019
  8. Igor68

    Igor68 Гуру

    Доброго времени суток!
    mplayer может быть сервером? Это лично меня не трогало - нет необходимости. И понимаю, что за белый IP капает сумма.
    Так он может быть сервером?
     
  9. Igor68

    Igor68 Гуру

    Ессли вам надо какое-то видеонаблюдение из далека без звука и не так много кадров в секунду, то можете воспользоваться (тут на флудилке есть мой промежуточный вариант опытов) тестом.
    Вам на малине портебуется OpenCV и gcc. Только надо несколько скорректировать в пране того, что бы малина стала клиентом. Так же на вашем ПК должен быть Linux с Apache. Mpleyer вообще ни к чему. На веб станице будете смотреть динамическую картику и иметь кнопки управления для удалённой малины.
    Что-то на вроде этого http://forum.amperka.ru/threads/ras...-и-вопрос-в-последнем-сообщении.10001/page-13
    При этом при желании картику сможете сделать цветной. Поймите я не хвастаюсь, а только то что Ваш IP белый не бесплатный.
    Но если надо только ваш вариант с mplayer, то пока нет столько времени что бы оказать содействие. Попробую конечно найти ещё и какой-нибудь стандартный вариант.

    Дрлжен привести уточнения в прошлом примере:
    Код (Text):
    socat tcp-l:2222,fork tcp-connect:10.7.8.53:2222
    mplayer -fps 200 -demuxer h264es ffmpeg://tcp://127.0.0.1:2222
    добавьте "&" вот так
    Код (Text):
    socat tcp-l:2222,fork tcp-connect:10.7.8.53:2222 &
    mplayer -fps 200 -demuxer h264es ffmpeg://tcp://127.0.0.1:2222
     
  10. Sanchez5890

    Sanchez5890 Нерд

    Доброй день, нет mplayer сервером быть не может. Только клиент
     
  11. Sanchez5890

    Sanchez5890 Нерд

    Спасибо вам большое, за вашу помощь, белый ip не дорогой, 100 р в месяц
     
  12. Sanchez5890

    Sanchez5890 Нерд

    Я сейчас попробую кое-что на сокетах.
    Спасибо за ваш вариант, думаю оставлю как резервный, если вообще ничего с mplayer не получится
     
  13. Sanchez5890

    Sanchez5890 Нерд

    У меня всё получилось. Сейчас я расскажу как я это сделал.
    Сначала пишем на python вот такую программу
    Код (Python):
    import socket
    sock = socket.socket()
    sock.bind(('', 11000))
    sock.listen(2)
    malina, addr = sock.accept()
    print('Connected Malina', addr)
    mplayer, addr = sock.accept()
    print('Connected Mplayer', addr)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        while True:
            mplayer.send(malina.recv(1024))
    finally:
        malina.close()
        mplayer.close()
        sock.close()
    Это сервер он ждет подключения малины, а затем mplayer-а и банально перегоняет данные с малины на mplayer.
    Теперь запускаем малину через неткэт (можно и через сокэт :))
    Код (Text):
    raspivid -t -0 -ifx negative -w 800 -h 600 -hf -ih -fps 20 -o - | nc 192.168.1.200 11000
    Теперь запускаем mplayer:
    Код (Text):
    mplayer -fps 200 -demuxer h264es ffmpeg://tcp://192.168.1.200
    Profit
     
  14. Sanchez5890

    Sanchez5890 Нерд

    Просто огромное спасибо Igor68 за его постоянную и очень большую поддержку и, конечно, Дяде Вите :) за его советы.
    Вот теперь у меня появились вопросы, касающиеся оптимизации всего этого.
    • У меня не получилось оформить клиент малины как python-программу, поэтому я сделал это через netcat. Не получилось оформить потому, что нечего отправлять:
    • Код (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)

          # Accept a single connection and make a file-like object out of it

          try:
              while True:
                  sock.send(camera.start_recording(источник, format='h264')[0].makefile('wb'))
          finally:
              camera.stop_recording()
              sock.close()
       
    • Можно ли оформить вот эту строку с mplayer как какой-нибудь скрипт, чтобы можно было этот скрипт запустить из python-программы (например из программы-сервера)? Заранее ещё раз большое спасибо!
     
  15. Igor68

    Igor68 Гуру

    Рад, что всё успешно!
    В питоне я балван, потому понимаю только поверхностно.
    ...и не понятно, как ведёт себя сервер при том, что малина давно подключена и передаёт ему данные, в вот отдавать некому - mplayer не поключен?
     
  16. Sanchez5890

    Sanchez5890 Нерд

    А сервер будет ждать пока оба подключатся. В начале подключаем малину, потом сервер ждёт подключения mplayer-а, игнорируя пока малину. Как только оба подключены сервер перегоняет видеопоток с малины на mplayer
     
  17. Igor68

    Igor68 Гуру

    При подключении малины, она ничего не передаёт серверу до подключения mplayer? А если передаёт, то куда деваются данные от малины если не подключен mplayer? Никакого переполнения в сервере? Ведь соединение с малиной активно.
    Димаю, что читать сокет надо, если малина передаёт невзирая на соединение с mplayer. И при наличии соединения с mplayer передавать последнему эти данные. Тогда сервер будет устойчив. Хотя не скажу как в библиотеках питона сделано.

    По поводу удалённого управления малиной, сделайте ещё один сервер контроля и т.п.
     
  18. Sanchez5890

    Sanchez5890 Нерд

    Хорошо, спасибо, буду пробовать
     
  19. Sanchez5890

    Sanchez5890 Нерд

    Доброго времени суток форум! Последние дни я пытался модифицировать сделанное, но у меня не получилось. Проблема возникла с использованием буфера, куда заливается трансляция с малинки.
    Можете пожалуйста помочь?
    Что я стараюсь сделать:
    • Малина с камерой - клиент, она передаёт трансляцию серверу, который их затем передаёт mplayer-у для воспроизведения
    • В работе mplayera и сервера можно не беспокоится они ок (позже докажу почему)
    • Я предположил на основе чужих скетчей (которые не соответсвуют моей идее), что мне необходимо записывать стрим в буфер, а затем считывать с него данные и передавать по сокетам
    • Я хочу написать именно python программу, а не команду (как уже было сделано выше), тк это даст возможность максимально контролировать всю трансляцию, делать переподключения бла бла бла.
    • Я стараюсь сделать результат таким, как он выглядит при использовании netcat в качестве клиента (см выше). Это означает, что всё гладко без задержек и хорошее качество.
    Собственно, я стал копипастить и дописывать свой клиент-python-скетч используя разные источники:
    Код (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), то в таком случае мы получим видео, но оно будет ускоренное и циклическое. (док-во работоспособности плеера и сервера, также опыты с netcat это тоже доказывают :) )
    • Если мы в while допишем stream.truncate(), а stream.read(), заменим на stream.getbuffer(), то в таком случае мы получим видео, но в нем будет просто статичная картинка.
    Помогите пожалуйста, знающие, решить данную проблему.
     
  20. Sanchez5890

    Sanchez5890 Нерд

    Я думаю, создам новую тему, уже никто не будет разбираться в этой куче сообщений.