одночасно записувати та передавати відео з камери


10

Я записую відео з Pi за допомогою модуля камери з пікамерою:

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 ...?


Якщо ви працюєте з протоколом, raspividви можете teeвивести файл і gstreamer або інше (див. man tee). Поки один потік знаходиться прямо на диску, він не додасть великих накладних витрат, але якщо ви хочете одночасно обробити вхід у два різні формати, я думаю, що для пі-пір це буде занадто багато роботи.
золотинки

Чи можете ви люб’язно розмістити приклад у коді?
koogee

Відповіді:


5

teeКоманда зчитує дані зі стандартного вводу і копіює будь-яку кількість файлів , плюс стандартного виводу за замовчуванням см man teeдля більш докладної інформації. Це означає, що ви можете попросити трійника створити файл із введення, а потім передати вихід на щось інше.

Додавання додаткової труби теоретично додає трохи неефективності. Щодо значущого чи ні, вам доведеться судити про себе, використовуючи власний метод потокового передачі. Мій сучасний метод не є задовільним при повному дозволі. Зараз це не величезний інтерес, але коли він є, я спробую знайти щось краще (наприклад, нібито gstreamer працює краще, ніж clvc).

Однак варто зазначити, що файл, який зберігається локально на pi одночасно, є ідеальною якістю, тому активність не заважає raspivid. Ось приклад:

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

Я розбив це на два рядки для читабельності; ви можете натиснути return after |(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 пікамери. Ви можете використовувати спеціальний висновок, щоб виконати такий розкол (стільки способів, скільки вам подобається) та надіслати вихід у різні напрямки. У вашому випадку, якщо ви хочете записати у файл та сокет, ви можете зробити щось подібне:

#!/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()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.