假设我有足够容量的SD卡,从理论上讲是否可以使用摄像头模块录制24小时视频,或者录制持续时间受到限制?有没有人尝试过?

您认为64GB的360p录制质量就足够了吗?

#1 楼

我必须承认,我不知道raspivid的库存版本中有2Gb的限制(在Linus的回答中提到)。一种替代方法(如果您不希望重新编译用户空间)将使用picamera(Python支持开箱即用的64位文件指针)。例如,以下代码应愉快地在H.264中录制24小时宽屏360p视频:

 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卡。我的预感是“大概”,但是让我们验证一下...

可以使用picamera的start_recording方法中的bitrate参数或raspivid中的--bitrate参数为Pi的H.264编码器提供比特率限制。在raspivid和picamera中,此默认值均为17Mbps(兆位/秒),因此从理论上讲,使用默认设置录制的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
 


嗯……比我预期的要大,但是还可以。要记住的一件事是,默认的17Mbps在默认的记录分辨率下很有用,在raspivid的情况下为全1080p(尽管picamera默认为显示分辨率,在没有显示的情况下为720p,因为当我写的时候似乎“友好”。如果您仅以360p录制,则可能会获得更低的比特率限制。

要记住的另一件事是比特率限制就是:上限。如果编码器不需要全部1700万位来产生足以表示一秒钟的运动值,则编码器将不会使用那么多的值。通过摆弄编码器的量化(在picamera中为quality参数,在raspivid中为--qp参数),我们还可以调整编码器的“足够好”含义。质量用介于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.8Gb和7.5Gb之间。我们可以通过将比特率设置为750000来确保绝对不会大于该值,我们知道这将为编码器提供足够的空间来以所需的质量(20)再现运动,或者您可以尝试使用较低的质量(例如25 )以查看它们是否可以接受,然后相应降低比特率限制。就是说,值得牢记的是您可能会用文件破坏2Gb,因此如上所述,除非您使用Python或重新编译userland,否则您很可能会遇到64位文件指针问题。 >
作为参考,以下是经过修改的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()
 
--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


,对于picamera,您可以使用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个文件,每次达到> 1Mb时将其翻转,并将输出迭代器放置在其自己的函数中,以演示也可以在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♦
16年2月19日在18:33

啊,谢谢-我可能应该在某个时候了解更多SO的MD变量...

–戴夫·琼斯(Dave Jones)
16年2月20日在17:14

#2 楼

如果您使用raspivid记录它是“可能的”,则有一个修补程序可支持大文件,大小大于2 GB(在提供给gcc的标志中需要-D_FILE_OFFSET_BITS=64)。但是,您需要自己编译userland源。

但是应注意,您应该非常小心,因为如果在Linux上填充系统分区,则可能会发生非常糟糕的行为。因此,您应该为长视频创建一个单独的分区。

如果文件大小有问题,最好降低比特率。

评论


如果可以接受的话,您还可以运行一个间歇性脚本(例如通过cron)来停止当前的raspivid进程,将输出文件悬停并重新启动,以便最终得到一系列代表特定时间段的较小文件。

– goldilocks♦
2015年1月11日在18:15