カメラからビデオを同時に録画およびストリーミングする


10

Picameraでカメラモジュールを使用して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()

私は別々の組み合わせを使用しているraspividし、gstreamer遅滞なくパイからビデオをストリーミングします。Pythonを同時に使用して映像を保存およびストリーミングする方法はありますか?

私の考えでは、カメラを入力として使用して2つの出力ソースを作成する方法が必要です。ストレージ用の720pビデオと、gstreamerを使用したスト​​リーミング用のダウンスケールされた240pビデオ...?


パイピングしているraspivid場合はtee、ファイル gstreamerなどに出力することができます(を参照man tee)。1つのストリームがディスクに直接接続されている限り、オーバーヘッドはそれほど追加されませんが、入力を2つの異なる形式に同時に処理する場合は、piが処理するには多すぎる作業になると思います。
ゴルディロックス

コードで例を投稿していただけますか?
koogee 2015年

回答:


5

teeコマンドは、デフォルトでは、ファイルに加えて、標準出力の任意の数の標準入力やコピーから読み込み、参照man 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

読みやすくするために、これを2行に分けました。|(パイプ)の後にreturnキーを押して、で改行できるのと同じようにコマンドを終了できます\cvlcを好きなものに置き換えることができます。繰り返しになりますが、ストリームの質は劣っていましたが、test_video.h264完璧になりました。

解像度を640x360に下げると、この配置は問題なく、通常は1秒または2秒のレイテンシになります。teeまたは2番目のパイプがストリームの品質に影響を与えるとは思いません。これらは、ここで必要とされるよりもはるかに高いスループットが可能であり、システムリソースをそれほど必要としません。

CPUは35〜45%で実行されました。これは、ビデオsansをストリーミングするときと同じteeです。


投稿ありがとうございます。スクリプト内でこれを実行したいので、私はPiCamera 1.9 APIを見てきましたが、パラメーターを受け取るメソッドrecord_sequenceがありsplitter_portます。カメラから最大4つの同時出力を記録する例もあります。
koogee

240pストリームと720pビデオを1時間ごとに分割して保存するために一緒に録画することに少し苦労していますが、これは有望な方向だと感じています。
koogee

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()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.