Video gleichzeitig von der Kamera aufnehmen und streamen

10

Ich nehme Video von Pi mit dem Kameramodul mit Picamera auf:

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()

Ich habe separat eine Kombination von raspividund verwendet, gstreamerum Videos von pi ohne Verzögerung zu streamen. Gibt es eine Möglichkeit, Filmmaterial gleichzeitig mit Python zu speichern und zu streamen ?

Meiner Meinung nach muss es eine Möglichkeit geben, die Kamera als Eingabe zu verwenden und zwei Ausgabequellen zu erstellen: ein 720p-Video für die Speicherung und ein verkleinertes 240p-Video für das Streaming mit gstreamer ...?

Koogee
quelle
Wenn Sie Piping betreiben, können raspividSie teedie Ausgabe in eine Datei und einen Gstreamer oder was auch immer (siehe man tee). Solange ein Stream direkt auf die Festplatte übertragen wird, entsteht kein großer Overhead. Wenn Sie jedoch die Eingabe gleichzeitig in zwei verschiedene Formate verarbeiten möchten, ist dies meiner Meinung nach zu viel Arbeit für den Pi.
Goldlöckchen
Können Sie bitte ein Beispiel im Code posten?
Koogee

Antworten:

5

Der teeBefehl liest von der Standardeingabe und kopiert standardmäßig in eine beliebige Anzahl von Dateien plus Standardausgabe. man teeWeitere Informationen finden Sie unter. Dies bedeutet, dass Sie tee bitten können, eine Datei aus der Eingabe zu erstellen und die Ausgabe dann an etwas anderes weiterzuleiten.

Das Hinzufügen eines zusätzlichen Rohrs führt theoretisch zu einer gewissen Ineffizienz. Ob dies von Bedeutung ist oder nicht, müssen Sie anhand Ihrer eigenen Streaming-Methode selbst beurteilen. Meine derzeitige Methode ist bei voller Auflösung nicht zufriedenstellend. Es ist momentan kein großes Interesse, aber wenn es so ist, werde ich versuchen, etwas Besseres zu finden (zB angeblich funktioniert gstreamer besser als clvc).

Es ist jedoch erwähnenswert, dass die gleichzeitig lokal auf dem Pi gespeicherte Datei von perfekter Qualität ist, sodass die Aktivität die Raspivid nicht beeinträchtigt. Hier ist ein Beispiel:

raspivid -o - -t 0 | tee test_video.h264 |
cvlc -v stream:///dev/stdin --sout '#standard{access=http,mux=ts,dest=:8080' :demux=h264

Ich habe dies zur besseren Lesbarkeit in zwei Zeilen unterteilt. Sie können die Eingabetaste nach |(Pipe) drücken und den Befehl beenden, genauso wie Sie eine Zeile mit brechen können \. Sie können das cvlcdurch alles ersetzen, was Sie wollen. Obwohl der Stream von schlechter Qualität war, test_video.h264kam er wieder perfekt heraus.

Wenn ich die Auflösung auf 640x360 reduziere, ist diese Anordnung in Ordnung, mit ein oder zwei Sekunden Latenz, die ich normalerweise bekomme. Ich glaube nicht, dass die teeoder die zweite Pipe einen Unterschied für die Qualität des Streams macht. Diese können einen viel höheren Durchsatz erzielen als hier erforderlich und erfordern nicht viel Systemressourcen.

Die CPU lief mit 35-45%, was dem Streaming von Videos ohne Video entspricht tee.

Goldlöckchen
quelle
Vielen Dank für Ihren Beitrag. Da ich dies in meinem Skript tun möchte, habe ich mir die PiCamera 1.9-API angesehen und es gibt eine Methode record_sequence, die einen splitter_portParameter akzeptiert . Es gibt auch ein Beispiel für die Aufzeichnung von bis zu 4 gleichzeitigen Ausgängen von der Kamera.
Koogee
Ich habe ein bisschen Probleme damit, einen 240p-Stream und ein 720p-Video für die Speicherung zusammenzubinden, die sich jede Stunde teilen, aber ich halte dies für eine vielversprechende Richtung.
Koogee
7

Mit der obigen Antwort auf Goldlöckchen ist überhaupt nichts falsch, aber hier ist eine zusätzliche, die sich speziell mit der Picamera-API befasst. Sie können eine benutzerdefinierte Ausgabe verwenden , um eine solche Aufteilung durchzuführen (so viele Möglichkeiten wie Sie möchten) und die Ausgabe an eine Vielzahl von Zielen zu senden. In Ihrem Fall könnten Sie Folgendes tun, wenn Sie in eine Datei und einen Socket aufnehmen möchten:

#!/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()
Dave Jones
quelle