запись и потоковое видео с камеры одновременно

10

Я записываю видео с Pi с помощью Camera Module с picamera:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.start_recording('1.h264')
    camera.wait_recording(5)
    for i in range(2, 11):
        camera.split_recording('%d.h264' % i)
        camera.wait_recording(5)
    camera.stop_recording()

Я отдельно использовал комбинацию raspividи gstreamerдля потоковой передачи видео с пи без каких-либо задержек. Есть ли способ хранить и передавать видеоматериалы одновременно с использованием Python ?

Я думаю, что должен быть способ использовать камеру в качестве входного сигнала и создать два выходных источника: видео 720p для хранения и уменьшенное видео 240p для потоковой передачи с использованием gstreamer ...?

koogee
источник
Если вы передаете по трубопроводу, raspividвы можете сделать teeвывод в файл и gstreamer или что-то еще (см. man tee). Пока один поток направляется прямо на диск, это не приведет к большим накладным расходам, но если вы хотите обрабатывать ввод в двух разных форматах одновременно, я думаю, что это будет слишком большой работой для пи.
Златовласка
Можете ли вы опубликовать пример в коде?
Koogee

Ответы:

5

Команда teeчитает из стандартного ввода и копирует в любое количество файлов плюс стандартный вывод по умолчанию, см. man teeПодробности. Это означает, что вы можете попросить tee создать файл из ввода, а затем направить вывод во что-то еще.

Добавление дополнительной трубы теоретически добавляет немного неэффективности. Что касается того, важно это или нет, вам придется судить самим, используя собственный метод потоковой передачи. Мой текущий метод не является удовлетворительным при полном разрешении. Сейчас это не очень интересно, но когда это произойдет, я постараюсь найти что-то лучше (например, предположительно, gstreamer работает лучше, чем clvc).

Однако стоит отметить, что файл, сохраненный локально на пи одновременно, имеет отличное качество, поэтому активность не мешает распивиду. Вот пример:

raspivid -o - -t 0 | tee test_video.h264 |
cvlc -v stream:///dev/stdin --sout '#standard{access=http,mux=ts,dest=:8080' :demux=h264

Я разбил это на две строки для удобства чтения; вы можете нажать return после |(pipe) и завершить команду так же, как вы можете разбить строку \. Вы можете заменить на cvlcто, что вы хотите. Опять же, хотя поток был низкого качества, test_video.h264получилось идеально.

Если я уменьшу разрешение до 640x360, то это нормально, с задержкой в ​​секунду или две, что я обычно получаю. Я не думаю, что teeвторой канал влияет на качество потока; они способны иметь гораздо более высокую пропускную способность, чем это необходимо, и не требуют большого количества системных ресурсов.

Процессор работал на 35-45%, что соответствует скорости потоковой передачи видео tee.

Златовласка
источник
Спасибо за ваше сообщение. Поскольку я хочу сделать это в своем скрипте, я смотрел на API PiCamera 1.9, и есть метод, record_sequenceкоторый принимает splitter_portпараметр. Также есть пример записи до 4 одновременных выходов с камеры.
koogee
Я немного борюсь за то, чтобы связать воедино запись потока 240p и видео 720p для хранения, которое разделяется каждый час, но я чувствую, что это многообещающее направление.
koogee
8

Нет ничего плохого в ответе Златовласка выше, но вот еще один, который конкретно касается API-интерфейса Picamera. Вы можете использовать пользовательский вывод для выполнения такого разделения (так много способов, как вам нравится) и отправлять выходные данные в различные пункты назначения. В вашем случае, если вы хотите записать в файл и сокет, вы можете сделать что-то вроде этого:

#!/usr/bin/env python

import io
import picamera
import socket


# An output (as far as picamera is concerned), is just a filename or an object
# which implements a write() method (and optionally the flush() and close()
# methods)
class MyOutput(object):
    def __init__(self, filename, sock):
        self.output_file = io.open(filename, 'wb')
        self.output_sock = sock.makefile('wb')

    def write(self, buf):
        self.output_file.write(buf)
        self.output_sock.write(buf)

    def flush(self):
        self.output_file.flush()
        self.output_sock.flush()

    def close(self):
        self.output_file.close()
        self.output_sock.close()


# Connect a socket to a remote server on port 8000
sock = socket.socket()
sock.connect(('my_server', 8000))

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

    # Construct an instance of our custom output splitter with a filename
    # and a connected socket
    my_output = MyOutput('output.h264', sock)

    # Record video to the custom output (we need to specify the format as
    # the custom output doesn't pretend to be a file with a filename)
    camera.start_recording(my_output, format='h264')
    camera.wait_recording(30)
    camera.stop_recording()
Дейв Джонс
источник