Чи можу я записати 24-годинне відео на Raspberry Pi за допомогою модуля камери?


12

Враховуючи, що у мене є SD-карта з достатньою ємністю, чи теоретично можливо записати цілодобове відео з модулем камери або тривалість запису обмежена? Хтось пробував це?

Як ви вважаєте, 64 Гб буде достатньо для якості запису 360p?

Відповіді:


20

Я мушу визнати, що мені не було відомо про обмеження 2Gb у складі запасів raspivid (згадане у відповіді Лінуса). Альтернативою (якщо ви не хочете перекомпілювати користувальницьку землю) було б використовувати picamera (Python підтримує 64-бітні покажчики файлів поза вікном). Наприклад, наступні фотографії повинні записувати широкоекранне 360p відео в H.264 радісно протягом 24 годин:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 360)
    camera.framerate = 24
    camera.start_recording('one_day.h264')
    camera.wait_recording(24 * 60 * 60)
    camera.stop_recording()

Наступна частина питання полягає в тому, чи буде це вміщуватися на 64Gb SD-картці. Моя думка "напевно", але давайте перевіримо, що ...

bitrateКодеру H.264 Pi може бути задано обмеження бітрейта з параметром у методі start_record picamera або --bitrateпараметром у raspivid. І в raspivid, і в пікамері це значення за замовчуванням до 17 Мбіт / с (мегабіт в секунду), тому теоретично 24-годинне відео, записане з налаштуваннями за замовчуванням, не може бути більшим за:

  24         hours
* 60         minutes per hour
* 60         seconds per minute
* 17000000   bits per second
/ 8          bits per byte
/ 1073741824 bytes per gig
  ----------
  170.990825 Gb

Хм ... це більше, ніж я очікував, але добре. Слід пам’ятати, що за замовчуванням 17 Мбіт / с повинно бути корисним при роздільній здатності запису за замовчуванням, яка є повною 1080p у випадку raspivid (хоча пікамера за замовчуванням до роздільної здатності дисплея або 720p у випадку відсутності дисплея як такої) здавалося "дружнішим", коли я це писав). Якщо ви записуєте лише в 360p, ви, ймовірно, можете піти зі значно нижчим обмеженням бітрейт.

Інша річ, яку слід пам’ятати, - це те, що межа бітрейта - це саме це: верхня межа. Якщо кодеру не потрібно всіх 17 мільйонів біт, щоб створити достатньо хороше представлення вартості руху однієї секунди, він не буде використовувати стільки. Поєднуючись з квантуванням кодера (що є qualityпараметром у picamera, та--qpпараметр в raspivid) ми також можемо коригувати уявлення кодера про те, що означає "досить хороший". Якість представлено значенням від 0 до 40. Нижчі значення означають кращу якість, тому 1 шалено хороший, а 40 - смішно поганий. Типові значення "досить хороших" - приблизно 20-25. Значення 0 (яке також є типовим) виглядає особливим; Я точно не знаю, що це означає для кодера (вам доведеться попросити розробників мікропрограмного забезпечення), але, схоже, він дає схожу якість на значення приблизно в 15-20 (тобто дуже добре).

Отже, якщо припустити середню якість (скажімо, 20), який битрейт нам потрібен для запису широкоекранного 360p відео? Наступний командний рядок raspivid я провів два рази, щоб записати відео на 30 секунд, потім провів перший запис, розмахуючи камерою навколо (за умови, що більше руху означає більше пропускної здатності, і ми хочемо перевірити межі тут), а другий зі сценою абсолютно статичною:

raspivid --width 640 --height 360 --framerate 24 --bitrate 17000000 --qp 20 --timeout 30000 --output test.h264

Отримані файли мали розмір 673675 байт (658Kb) та 2804555 байт (2,7Mb) відповідно, тому бітрейти, що виробляються кодером, були:

  673675   bytes
* 8        bits per byte
/ 30       seconds
  --------
  179646.6 bits per second (static scene)

  2804555  bytes
* 8        bits per byte
/ 30       seconds
  --------
  747881.3 bits per second (full motion scene)

Отже, підключивши ці значення до рівняння вище, ми можемо реально очікувати, що відео, яке коштує 24 години, використовуючи подібні налаштування, прийде десь між 1,8 Гб і 7,5 Гб. Ми можемо переконатися, що він точно не буде більшим за це, встановивши бітрейт на щось на зразок 750000, що, як ми знаємо, надасть кодеру достатньо місця для відтворення руху в потрібній якості (20), або ви могли б експериментувати з нижчими якостями (наприклад, 25 ), щоб побачити, чи вони будуть прийнятними, а потім відповідно знизити бітрейт. При цьому, варто пам’ятати, що ви, швидше за все, зламаєте 2Gb з файлом, тому, як було сказано вище, ви, швидше за все, зіткнетеся з проблемою 64-бітового вказівника на файли, якщо не будете використовувати Python або перекомпілювати користувача.

Для довідки, ось скрипт Python зверху модифікований, щоб включити обмеження, що обговорювалися:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 360)
    camera.framerate = 24
    camera.start_recording('one_day.h264', quality=20, bitrate=750000)
    camera.wait_recording(24 * 60 * 60)
    camera.stop_recording()

Нарешті, просто відповісти на коментар goldilocks щодо відповіді Лінуса: розділити відео-файл на кілька частин досить просто (і легко полегшить будь-які проблеми з 64-бітовим покажчиком файлів). За допомогою raspivid ви можете використовувати --segmentпараметр, щоб вказати, що новий файл повинен відкриватися кожні n мілісекунд, наприклад, для запису одного файлу на кожну годину ( %02dім'я файлу буде замінено на число, наприклад 01, 02, 03, .. .):

raspivid --width 640 --height 360 --framerate 24 --bitrate 750000 --qp 20 --timeout $((24*60*60*1000)) --segment $((1*60*60*1000)) --output hour%02d.h264

Крім того, за допомогою пікамери ви можете використовувати метод record_sequence для поділу на основі часу:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 360)
    camera.framerate = 24
    for filename in camera.record_sequence([
            'hour%02d.h264' % (h + 1)
            for h in range(24)
            ], quality=20, bitrate=750000):
        camera.wait_recording(60 * 60)

Або на основі розміру файлу. У наведеному нижче прикладі я встановив його для створення 100 файлів, що перевертаються, як тільки кожен досягає> 1 Мбіт, і помістив ітератор виводу у свою функцію лише для того, щоб продемонструвати, що можна використовувати і нескінченні ітератори record_sequence:

import io
import itertools
import picamera

def outputs():
    for i in itertools.count(1):
        yield io.open('file%02d.h264' % i, 'wb')

with picamera.PiCamera() as camera:
    camera.resolution = (640, 360)
    camera.framerate = 24
    for output in camera.record_sequence(
            outputs(), quality=20, bitrate=750000):
        while output.tell() < 1048576:
            camera.wait_recording(0.1)
        if output.name == 'file99.h264':
            break

Або ... ну, якою б межею ви не придумали код!


+1 Я відредагував вашу інакше вражаючу відповідь, щоб включити підкреслення синтаксису.
Jacobm001

Ах, дякую - я, мабуть, в якийсь момент, мабуть, навчуся трохи більше варіанту МД ...
Дейв Джонс

3

Якщо ви використовуєте raspivid, щоб записати це "можливо", там було встановлено патч для підтримки великих файлів, розмір яких> 2 Гб ( -D_FILE_OFFSET_BITS=64необхідний у прапорах, що постачаються gcc). Однак ви повинні скомпілювати рівня користувача джерело самостійно.

Слід зазначити, що ви повинні бути дуже обережними, тому що якщо ви заповнюєте системний розділ на Linux, може статися дуже погана поведінка. Тому вам слід створити окремий розділ для своїх довгих відео.

Також може бути хорошою ідеєю зменшити швидкість передачі бітів, якщо у вас є проблеми з розміром файлу.


4
Якщо це прийнятно, ви також можете запустити переривчастий скрипт (наприклад, через cron), щоб зупинити поточний raspividпроцес, перевернути вихідний файл і запустити його знову, таким чином, ви отримаєте ряд менших файлів, що представляють собою певні відрізки часу.
золотинки
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.