Respostas:
Devo admitir que não estava ciente da limitação de 2 GB no estoque de raspivid (mencionado na resposta de Linus). Uma alternativa (se você não gosta de recompilar a terra do usuário) seria usar o picamera (o Python suporta ponteiros de arquivo de 64 bits prontos para uso ). Por exemplo, o seguinte deve gravar um vídeo de tela ampla 360p em H.264 felizmente por 24 horas:
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()
A próxima parte da questão é se isso cabe em um cartão SD de 64Gb. Meu palpite é "provavelmente", mas vamos verificar se ...
O codificador H.264 do Pi pode receber um limite de taxa de bits com o bitrate
parâmetro no método start_recording do picamera ou com o --bitrate
parâmetro raspivid. Tanto no modo raspividado quanto no picamera, o padrão é 17 Mbps (megabits por segundo); portanto, teoricamente, um vídeo de 24 horas gravado com a configuração padrão não pode ser maior que:
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
Hmm ... é maior do que eu esperava, mas tudo bem. Uma coisa a ter em mente é que o padrão de 17 Mbps deve ser útil na resolução de gravação padrão, que é de 1080p total no caso de raspivid (embora o padrão da câmera seja a resolução da tela ou 720p no caso de nenhuma tela como essa). parecia "mais amigável" quando eu escrevi). Se você estiver gravando apenas em 360p, provavelmente poderá obter um limite de taxa de bits muito mais baixo.
A outra coisa a ter em mente é que o limite de taxa de bits é exatamente isso: um limite superior. Se o codificador não precisar de todos os 17 milhões de bits para produzir uma representação suficientemente boa do movimento de um segundo, ele não utilizará tantos. Brincando com a quantização do codificador (que é o quality
parâmetro em picamera e o--qp
raspivid) também podemos ajustar a idéia do codificador do que significa "bom o suficiente". A qualidade é representada por um valor entre 0 e 40. Valores mais baixos significam melhor qualidade, então 1 é incrivelmente bom e 40 é ridiculamente ruim. Os valores "bons o suficiente" são em torno de 20 a 25. O valor 0 (que também é o padrão) parece ser especial; Não sei exatamente o que isso significa para o codificador (você teria que perguntar isso aos desenvolvedores de firmware), mas parece produzir qualidade semelhante aos valores entre 15 e 20 (isto é, muito bom).
Então, supondo qualidade média (digamos 20), que tipo de taxa de bits precisamos para gravar vídeo em tela cheia de 360p? Eu executei a seguinte linha de comando raspividada duas vezes para gravar 30 segundos de vídeo, depois passei a primeira gravação agitando a câmera (sob a suposição de que mais movimento significa mais largura de banda necessária e queremos testar os limites aqui), e a segunda com a cena absolutamente estática:
raspivid --width 640 --height 360 --framerate 24 --bitrate 17000000 --qp 20 --timeout 30000 --output test.h264
Os arquivos resultantes tinham 673675 bytes (658 KB) e 2804555 bytes (2,7 Mb) em tamanho, respectivamente, portanto as taxas de bits produzidas pelo codificador eram:
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)
Portanto, ao conectar esses valores à equação acima, podemos realisticamente esperar 24 horas de vídeo usando configurações semelhantes entre algo entre 1,8 Gb e 7,5 Gb de tamanho. Podemos garantir que definitivamente não seja maior do que isso, definindo a taxa de bits para algo como 750000, que sabemos que dará ao codificador espaço suficiente para reproduzir o movimento com a qualidade desejada (20), ou você poderá experimentar qualidades mais baixas (por exemplo, 25 ) para ver se eles seriam aceitáveis e reduza o limite de taxa de bits de acordo. Dito isso, vale lembrar que você provavelmente quebrará 2 GB com o arquivo; portanto, como mencionado acima, você provavelmente encontrará o problema do ponteiro de arquivo de 64 bits, a menos que use o Python ou recompile a terra do usuário.
Para referência, aqui está o script Python acima modificado para incluir os limites que acabamos de discutir:
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()
Finalmente, apenas para responder ao comentário de goldilocks sobre a resposta de Linus: dividir o arquivo de vídeo em várias partes é bastante fácil (e aliviaria facilmente qualquer preocupação com o ponteiro de arquivo de 64 bits). Com raspivid, você pode usar o --segment
parâmetro para especificar que um novo arquivo deve ser aberto a cada n milissegundos, por exemplo, para gravar um arquivo a cada hora ( %02d
o nome do arquivo será substituído por um número, por exemplo, 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
Como alternativa, com o picamera, você pode usar o método record_sequence para dividir com base no tempo:
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)
Ou com base no tamanho do arquivo. No exemplo abaixo, eu o configurei para produzir 100 arquivos rolando quando cada um atingir> 1Mb e coloquei o iterador de saída em sua própria função apenas para demonstrar que é possível usar infinitos iteradores record_sequence
também:
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
Ou ... bem, seja qual for o limite para o qual você possa pensar no código!
Se você estiver usando raspivid para gravar, é "possível", houve um patch para suportar arquivos grandes, em que o tamanho> 2 GB ( -D_FILE_OFFSET_BITS=64
é necessário nos sinalizadores fornecidos ao gcc). No entanto, você precisa compilar a fonte da terra do usuário sozinho.
Deve-se notar, no entanto, você deve ter muito cuidado, porque se você preencher a partição do sistema no Linux, poderá ocorrer um comportamento muito ruim. Portanto, você deve criar uma partição separada para seus vídeos longos.
Também pode ser uma boa idéia diminuir a taxa de bits se você tiver problemas com o tamanho do arquivo.
cron
) para interromper o raspivid
processo atual , passar o mouse sobre o arquivo de saída e iniciá-lo novamente, para que você acabe com uma série de arquivos menores que representam fatias específicas de tempo.