同时记录和流式传输来自摄像机的视频


10

我正在使用带有picamera的Camera Module从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()

我分别使用的组合raspividgstreamer从pi流式传输视频,没有任何延迟。有没有一种方法可以同时使用python存储和传输素材?

我的想法是必须有一种使用相机作为输入并创建两个输出源的方法:一个用于存储的720p视频和一个使用gstreamer进行流传输的缩小的240p视频...?


如果您使用管道传输,则raspivid可以tee将输出输出到文件 gstreamer或其他文件中(请参阅参考资料man tee)。只要一个流直接进入磁盘,就不会增加太多开销,但是如果您想同时将输入处理成两种不同的格式,我认为对于pi来说这将是太多的工作。
goldilocks

您能在代码中张贴一个示例吗?
koogee,2015年

Answers:


5

tee命令默认从标准输入读取并复制到任意数量的文件以及标准输出,man tee有关详细信息,请参阅。这意味着您可以要求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

为了便于阅读,我将其分为两行;您可以在|(pipe)之后按回车键并完成命令,就像可以通过断开一行一样\。您可以cvlc用任何您想要的替换。同样,尽管溪流质量较差,但效果还是test_video.h264不错的。

如果我将分辨率降低到640x360,则这种安排很好,通常会有一到两秒的延迟。我认为tee或第二根管道对流的质量没有任何影响;这些服务器的吞吐量比此处所需的吞吐量高得多,并且不需要太多系统资源。

CPU的运行速度为35-45%,与无视频流时相同tee


谢谢你的文章。当我想在脚本中执行此操作时,我一直在查看PiCamera 1.9 API,并且有一个record_sequence采用splitter_port参数的方法。还有一个示例,可以记录来自摄像机的多达4个同时输出。
koogee,2015年

我在录制240p流和720p视频以进行每小时分割的存储方面遇到了一些麻烦,但是我认为这是一个有希望的方向。
koogee,2015年

8

上面的goldilocks答案一点都没错,但这是专门针对picamera 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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.