บันทึกและสตรีมวิดีโอจากกล้องพร้อมกัน


10

ฉันกำลังบันทึกวิดีโอจาก Pi โดยใช้โมดูลกล้องด้วย picamera:

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การสตรีมวิดีโอจาก pi แยกต่างหากโดยไม่ล่าช้า มีวิธีในการจัดเก็บและสตรีมวิดีโอโดยใช้ไพ ธ อนพร้อมกันไหม?

ความคิดของฉันคือต้องมีวิธีใช้กล้องเป็นอินพุตและสร้างแหล่งสัญญาณสอง: วิดีโอ 720p สำหรับการจัดเก็บและวิดีโอ 240p downscaled สำหรับการสตรีมโดยใช้ gstreamer ... ?


หากคุณกำลัง piping raspividคุณสามารถteeส่งออกไปยังไฟล์และ gstreamer หรืออะไรก็ได้ (ดูman tee) ตราบใดที่กระแสหนึ่งตรงไปยังดิสก์มันจะไม่เพิ่มโอเวอร์เฮดมากนัก แต่ถ้าคุณต้องการประมวลผลอินพุตเป็นสองรูปแบบที่ต่างกันพร้อมกันฉันคิดว่ามันจะทำงานได้มากเกินไปสำหรับ pi ที่จะจัดการ
goldilocks

คุณสามารถโพสต์ตัวอย่างในรหัสได้ไหม
koogee

คำตอบ:


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

ฉันแยกมันออกเป็นสองบรรทัดเพื่อให้อ่านได้ คุณสามารถตีกลับมาหลัง|(ท่อ) \และเสร็จสิ้นคำสั่งเช่นเดียวกับที่คุณสามารถทำลายสอดคล้องกับ คุณสามารถแทนที่cvlcด้วยสิ่งที่คุณต้องการ อีกครั้งถึงแม้ว่าสตรีมจะมีคุณภาพต่ำ แต่test_video.h264ก็สมบูรณ์แบบ

หากฉันลดความละเอียดลงเหลือ 640x360 การจัดเรียงนี้ก็ทำได้ดีโดยมีเวลาแฝงที่สองหรือสองซึ่งเป็นสิ่งที่ฉันได้รับตามปกติ ฉันไม่คิดว่าteeหรือท่อที่สองสร้างความแตกต่างใด ๆ กับคุณภาพของสตรีม สิ่งเหล่านี้มีความสามารถในการรับส่งข้อมูลที่สูงกว่าความจำเป็นที่นี่และไม่ต้องการทรัพยากรระบบ

วิ่ง CPU ที่ 35-45% teeซึ่งเป็นเช่นเดียวกับที่มันไม่เมื่อสตรีมมิ่งวิดีโอซันส์


ขอบคุณสำหรับการโพสต์ของคุณ ในขณะที่ฉันต้องการทำสิ่งนี้ภายในสคริปต์ของฉันฉันได้ดู PiCamera 1.9 API และมีวิธีการrecord_sequenceที่ใช้splitter_portพารามิเตอร์ นอกจากนี้ยังมีตัวอย่างของการบันทึกเอาต์พุตสูงสุดพร้อมกัน 4 ตัวจากกล้อง
koogee

ฉันพยายามดิ้นรนนิดหน่อยด้วยการผูกบันทึกวิดีโอสตรีม 240p และวิดีโอ 720p ไว้สำหรับจัดเก็บข้อมูลที่แยกกันทุกชั่วโมง แต่ฉันรู้สึกว่านี่เป็นทิศทางที่มีแนวโน้ม
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.