ghi và phát video trực tiếp từ camera


10

Tôi đang quay video từ Pi bằng Camera Module với 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()

Tôi đã sử dụng kết hợp raspividgstreamerphát trực tiếp video từ pi mà không có bất kỳ độ trễ nào. Có cách nào để lưu trữ và cảnh dòng sử dụng python đồng thời ?

Tôi nghĩ rằng phải có một cách để sử dụng máy ảnh làm đầu vào và tạo hai nguồn đầu ra: một video 720p để lưu trữ và một video 240p được thu nhỏ để phát trực tuyến bằng cách sử dụng công cụ truyền phát ...?


Nếu bạn đang đặt đường ống, raspividbạn có thể teexuất ra một tệp và bộ chuyển đổi hoặc bất cứ thứ gì khác (xem man tee). Miễn là một luồng truyền thẳng vào đĩa, nó sẽ không thêm nhiều chi phí, nhưng nếu bạn muốn xử lý đầu vào thành hai định dạng khác nhau đồng thời tôi nghĩ rằng sẽ có quá nhiều công việc để pi xử lý.
goldilocks

Bạn có thể vui lòng gửi một ví dụ trong mã?
koogee

Câu trả lời:


5

Các teelệnh đọc từ đầu vào và bản tiêu chuẩn để mọi số lượng file cộng thêm đầu ra tiêu chuẩn theo mặc định, xem man teeđể biết thêm chi tiết. Điều này có nghĩa là bạn có thể yêu cầu tee tạo một tệp từ đầu vào và sau đó chuyển đầu ra sang thứ khác.

Về mặt lý thuyết, việc bổ sung một đường ống phụ sẽ làm tăng thêm một chút kém hiệu quả. Về việc điều này có ý nghĩa hay không, bạn sẽ phải tự đánh giá bằng cách sử dụng phương pháp phát trực tuyến của riêng mình. Phương pháp hiện tại của tôi không thỏa đáng ở độ phân giải đầy đủ. Nó không phải là một mối quan tâm lớn ngay bây giờ nhưng khi đó tôi sẽ cố gắng tìm thứ gì đó tốt hơn (ví dụ như được cho là người truyền tải hoạt động tốt hơn clvc).

Tuy nhiên, đáng lưu ý rằng tệp được lưu cục bộ trên pi cùng một lúc là chất lượng hoàn hảo, vì vậy hoạt động không can thiệp vào raspivid. Đây là một ví dụ:

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

Tôi đã chia nó thành hai dòng để dễ đọc; bạn có thể nhấn return sau |(pipe) và hoàn thành lệnh giống như bạn có thể ngắt dòng \. Bạn có thể thay thế cvlcbằng bất cứ điều gì bạn muốn. Một lần nữa, mặc dù luồng có chất lượng kém, test_video.h264đã xuất hiện hoàn hảo.

Nếu tôi hạ độ phân giải xuống 640x360 thì sự sắp xếp này vẫn ổn, với độ trễ một hoặc hai giây là điều tôi thường nhận được. Tôi không nghĩ rằng teeđường ống thứ hai tạo ra bất kỳ sự khác biệt nào đối với chất lượng của luồng; những thứ này có khả năng thông lượng cao hơn nhiều so với mức cần thiết ở đây và không đòi hỏi nhiều về tài nguyên hệ thống.

CPU chạy ở mức 35-45%, tương tự như khi truyền phát video sans tee.


Cảm ơn vì bài đăng của bạn. Vì tôi muốn thực hiện điều này trong tập lệnh của mình, tôi đã xem xét API PiCamera 1.9 và có một phương pháp record_sequencelấy splitter_porttham số. Ngoài ra còn có một ví dụ về ghi lại tối đa 4 đầu ra đồng thời từ máy ảnh.
koogee

Tôi đang vật lộn một chút với việc buộc cùng nhau ghi lại luồng 240p và video 720p để lưu trữ chia tách mỗi giờ nhưng tôi cảm thấy đây là một hướng đi đầy hứa hẹn.
koogee

8

Không có gì sai với câu trả lời của goldilocks ở trên, nhưng đây là một câu hỏi bổ sung liên quan cụ thể đến API picamera. Bạn có thể sử dụng đầu ra tùy chỉnh để thực hiện phân tách như vậy (bao nhiêu cách tùy thích) và gửi đầu ra đến nhiều điểm đến khác nhau. Trong trường hợp của bạn, nếu bạn muốn ghi vào một tệp và một ổ cắm, bạn có thể làm một cái gì đó như thế này:

#!/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()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.