rekam dan streaming video dari kamera secara bersamaan

10

Saya merekam video dari Pi menggunakan Modul Kamera dengan kamera:

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

Saya secara terpisah menggunakan kombinasi raspividdan gstreameruntuk streaming video dari pi tanpa penundaan. Apakah ada cara untuk menyimpan dan mengalirkan rekaman menggunakan python secara bersamaan ?

Pemikiran saya adalah harus ada cara untuk menggunakan kamera sebagai input dan membuat dua sumber output: video 720p untuk penyimpanan dan video 240p downscaled untuk streaming menggunakan gstreamer ...?

koogee
sumber
Jika Anda mem-piping, raspividAnda bisa teeoutput ke file dan gstreamer atau apa pun (lihat man tee). Selama satu aliran langsung ke disk, itu tidak akan menambah banyak overhead, tetapi jika Anda ingin memproses input menjadi dua format yang berbeda secara bersamaan, saya pikir itu akan terlalu banyak pekerjaan untuk pi untuk menangani.
goldilocks
Bisakah Anda memposting contoh dalam kode?
koogee

Jawaban:

5

The teeperintah membaca dari input standar dan salinan ke sejumlah file ditambah output standar secara default, lihat man teeuntuk lebih jelasnya. Ini berarti Anda dapat meminta tee untuk membuat file dari input dan kemudian mengirimkan hasilnya ke sesuatu yang lain.

Penambahan pipa tambahan secara teori menambah sedikit inefisiensi. Mengenai apakah ini penting atau tidak, Anda harus menilai sendiri menggunakan metode streaming Anda sendiri. Metode saya saat ini tidak memuaskan pada resolusi penuh. Ini bukan minat besar sekarang tetapi ketika itu saya akan mencoba untuk menemukan sesuatu yang lebih baik (misalnya seharusnya Gstreamer bekerja lebih baik daripada CLVC).

Namun, perlu dicatat bahwa file yang disimpan secara lokal pada pi pada saat yang sama adalah kualitas yang sempurna, sehingga aktivitasnya tidak mengganggu raspivid. Ini sebuah contoh:

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

Saya membagi ini menjadi dua baris untuk dibaca; Anda dapat menekan kembali setelah |(pipa) dan menyelesaikan perintah sama seperti Anda dapat memutuskan garis \. Anda dapat mengganti cvlcdengan apa pun yang Anda inginkan. Sekali lagi, meskipun kualitas alirannya buruk, test_video.h264hasilnya sempurna.

Jika saya menurunkan resolusi ke 640x360 pengaturan ini baik-baik saja, dengan satu atau dua latensi yang biasanya saya dapatkan. Saya tidak berpikir teeatau pipa kedua membuat perbedaan pada kualitas aliran; ini mampu throughput yang jauh lebih tinggi dari yang diperlukan di sini dan tidak memerlukan banyak sumber daya sistem.

CPU bekerja pada 35-45%, yang sama dengan CPU streaming video tee.

goldilocks
sumber
Terima kasih atas kiriman Anda. Karena saya ingin melakukan ini dalam skrip saya, saya telah melihat PiCamera 1.9 API dan ada metode record_sequenceyang mengambil splitter_portparameter. Ada juga contoh merekam hingga 4 keluaran simultan dari kamera.
koogee
Saya berjuang sedikit dengan mengikat bersama-sama merekam streaming 240p dan video 720p untuk penyimpanan yang terpecah setiap jam, tetapi saya merasa ini adalah arah yang menjanjikan.
koogee
8

Tidak ada yang salah sama sekali dengan goldilocks yang menjawab di atas, tapi di sini ada satu tambahan yang berhubungan secara khusus dengan picamera API. Anda dapat menggunakan output khusus untuk melakukan pemisahan seperti itu (sebanyak mungkin cara yang Anda suka) dan mengirim output ke berbagai tujuan. Dalam kasus Anda, jika Anda ingin merekam ke file dan soket Anda bisa melakukan sesuatu seperti ini:

#!/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
sumber