您认为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
或者...好吧,无论您能想到的代码有多大限制!
#2 楼
如果您使用raspivid记录它是“可能的”,则有一个修补程序可支持大文件,大小大于2 GB(在提供给gcc的标志中需要-D_FILE_OFFSET_BITS=64
)。但是,您需要自己编译userland源。但是应注意,您应该非常小心,因为如果在Linux上填充系统分区,则可能会发生非常糟糕的行为。因此,您应该为长视频创建一个单独的分区。
如果文件大小有问题,最好降低比特率。
评论
如果可以接受的话,您还可以运行一个间歇性脚本(例如通过cron)来停止当前的raspivid进程,将输出文件悬停并重新启动,以便最终得到一系列代表特定时间段的较小文件。
– goldilocks♦
2015年1月11日在18:15
评论
+1我已经编辑了您原本引人注目的答案,其中包括语法突出显示。
–Jacobm001♦
16年2月19日在18:33
啊,谢谢-我可能应该在某个时候了解更多SO的MD变量...
–戴夫·琼斯(Dave Jones)
16年2月20日在17:14