Tôi có thể quay video 24 giờ trên Raspberry Pi bằng mô-đun máy ảnh không?


12

Cho rằng tôi có thẻ SD với dung lượng đủ, về mặt lý thuyết có thể quay video 24 giờ bằng mô-đun máy ảnh hay thời lượng ghi bị giới hạn? Có ai đã thử điều này?

Bạn có nghĩ 64GB là đủ với chất lượng ghi 360p không?

Câu trả lời:


20

Tôi phải thừa nhận rằng tôi đã không nhận thức được giới hạn 2Gb trong quá trình xây dựng cổ phiếu của raspivid (được đề cập trong câu trả lời của Linus). Một cách khác (nếu bạn không thích biên dịch lại vùng người dùng) sẽ sử dụng picamera (Python hỗ trợ các con trỏ tệp 64 bit ra khỏi hộp). Ví dụ: những điều sau đây sẽ quay video 360p màn hình rộng ở H.264 một cách vui vẻ trong 24 giờ:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 360)
    camera.framerate = 24
    camera.start_recording('one_day.h264')
    camera.wait_recording(24 * 60 * 60)
    camera.stop_recording()

Phần tiếp theo của câu hỏi là liệu điều đó có phù hợp với thẻ SD 64Gb hay không. Linh cảm của tôi là "có lẽ", nhưng hãy xác minh rằng ...

Bộ mã hóa H.264 của Pi có thể được đưa ra giới hạn bitrate với bitratetham số trong phương thức start_recply của picamera hoặc --bitratetham số trong raspivid. Trong cả raspivid và picamera, giá trị này mặc định là 17Mb / giây (megabits mỗi giây) vì vậy về mặt lý thuyết, một video 24 giờ được ghi với cài đặt mặc định không thể lớn hơn:

  24         hours
* 60         minutes per hour
* 60         seconds per minute
* 17000000   bits per second
/ 8          bits per byte
/ 1073741824 bytes per gig
  ----------
  170.990825 Gb

Hmm ... nó lớn hơn tôi mong đợi, nhưng không sao. Một điều cần lưu ý là mặc định 17Mbps có nghĩa là hữu ích ở độ phân giải ghi mặc định, ở mức 1080p đầy đủ trong trường hợp raspivid (mặc dù picamera mặc định là độ phân giải màn hình hoặc 720p trong trường hợp không hiển thị như vậy dường như "thân thiện hơn" khi tôi viết nó). Nếu bạn chỉ ghi ở 360p, bạn có thể thoát khỏi giới hạn bitrate thấp hơn nhiều.

Một điều khác cần ghi nhớ là giới hạn bitrate chỉ là: giới hạn trên. Nếu bộ mã hóa không cần tất cả 17 triệu bitcoin để tạo ra một đại diện đủ tốt cho giá trị chuyển động của một giây, thì nó sẽ không sử dụng nhiều như vậy. Bằng cách đấu tranh với lượng tử hóa của bộ mã hóa (là qualitytham số trong picamera và--qptham số trong raspivid) chúng ta cũng có thể điều chỉnh ý tưởng của bộ mã hóa về ý nghĩa của "đủ tốt". Chất lượng được biểu thị bằng một giá trị trong khoảng từ 0 đến 40. Giá trị thấp hơn có nghĩa là chất lượng tốt hơn, do đó, 1 là cực kỳ tốt và 40 là cực kỳ xấu. Giá trị "đủ tốt" điển hình là khoảng 20-25. Giá trị 0 (cũng là mặc định) có vẻ đặc biệt; Tôi không chắc chính xác ý nghĩa của nó đối với bộ mã hóa (bạn phải hỏi các nhà phát triển phần sụn đó), nhưng dường như nó tạo ra chất lượng tương tự với các giá trị khoảng 15-20 (tức là rất tốt).

Vì vậy, giả sử chất lượng trung bình (giả sử 20), chúng ta cần loại bitrate nào để quay video màn hình rộng 360p? Tôi đã chạy dòng lệnh raspivid sau đây hai lần để quay video có giá trị 30 giây, sau đó dành bản ghi đầu tiên vẫy máy ảnh (theo giả định rằng nhiều chuyển động hơn có nghĩa là cần nhiều băng thông hơn và chúng tôi muốn kiểm tra giới hạn ở đây) và lần thứ hai với cảnh hoàn toàn tĩnh:

raspivid --width 640 --height 360 --framerate 24 --bitrate 17000000 --qp 20 --timeout 30000 --output test.h264

Các tệp kết quả có kích thước lần lượt là 673675 byte (658Kb) và 2804555 byte (2.7Mb), do đó tốc độ bit được tạo bởi bộ mã hóa là:

  673675   bytes
* 8        bits per byte
/ 30       seconds
  --------
  179646.6 bits per second (static scene)

  2804555  bytes
* 8        bits per byte
/ 30       seconds
  --------
  747881.3 bits per second (full motion scene)

Do đó, việc cắm các giá trị đó vào phương trình trên, chúng ta thực sự có thể mong đợi video có giá trị 24 giờ bằng cách sử dụng các cài đặt tương tự để có kích thước từ 1,8Gb đến 7,5Gb. Chúng tôi có thể đảm bảo rằng nó chắc chắn sẽ không lớn hơn thế bằng cách đặt bitrate thành thứ gì đó như 750000 mà chúng tôi biết sẽ cung cấp cho bộ mã hóa đủ chỗ để tái tạo chuyển động với chất lượng mong muốn của chúng tôi (20) hoặc bạn có thể thử nghiệm với chất lượng thấp hơn (ví dụ 25 ) để xem liệu chúng có được chấp nhận hay không, và sau đó hạ thấp giới hạn bitrate tương ứng. Điều đó nói rằng, đáng lưu ý rằng bạn có khả năng phá vỡ 2Gb với tệp, vì vậy như đã đề cập ở trên, bạn có khả năng gặp phải sự cố con trỏ tệp 64 bit trừ khi bạn sử dụng Python hoặc biên dịch lại vùng người dùng.

Để tham khảo, đây là tập lệnh Python từ trên được sửa đổi để bao gồm các giới hạn vừa thảo luận:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 360)
    camera.framerate = 24
    camera.start_recording('one_day.h264', quality=20, bitrate=750000)
    camera.wait_recording(24 * 60 * 60)
    camera.stop_recording()

Cuối cùng, chỉ để trả lời nhận xét của goldilocks về câu trả lời của Linus: chia tệp video thành nhiều phần khá dễ dàng (và sẽ dễ dàng làm giảm bớt mọi lo ngại về con trỏ tệp 64 bit). Với raspivid, bạn có thể sử dụng --segmenttham số để chỉ định rằng một tệp mới sẽ được mở mỗi n mili giây, ví dụ để ghi một tệp cho mỗi giờ ( %02dtên tệp sẽ được thay thế cho một số, ví dụ: 01, 02, 03, .. .):

raspivid --width 640 --height 360 --framerate 24 --bitrate 750000 --qp 20 --timeout $((24*60*60*1000)) --segment $((1*60*60*1000)) --output hour%02d.h264

Ngoài ra, với picamera, bạn có thể sử dụng phương thức record_ resultence để phân chia dựa trên thời gian:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 360)
    camera.framerate = 24
    for filename in camera.record_sequence([
            'hour%02d.h264' % (h + 1)
            for h in range(24)
            ], quality=20, bitrate=750000):
        camera.wait_recording(60 * 60)

Hoặc dựa trên kích thước tập tin. Trong ví dụ bên dưới, tôi đã thiết lập nó để tạo ra 100 tệp được cuộn qua mỗi lần đạt> 1Mb và đặt trình lặp đầu ra vào chức năng của chính nó để chứng minh rằng nó cũng có thể sử dụng các trình vòng lặp vô hạn record_sequence:

import io
import itertools
import picamera

def outputs():
    for i in itertools.count(1):
        yield io.open('file%02d.h264' % i, 'wb')

with picamera.PiCamera() as camera:
    camera.resolution = (640, 360)
    camera.framerate = 24
    for output in camera.record_sequence(
            outputs(), quality=20, bitrate=750000):
        while output.tell() < 1048576:
            camera.wait_recording(0.1)
        if output.name == 'file99.h264':
            break

Hoặc ... tốt, bất cứ giới hạn nào bạn có thể nghĩ về mã cho!


+1 Tôi đã chỉnh sửa câu trả lời ngoạn mục khác của bạn để bao gồm đánh dấu cú pháp.
Jacobm001

À, cảm ơn - Có lẽ tôi nên tìm hiểu thêm một chút về biến thể MD của SO tại một số điểm ...
Dave Jones

3

Nếu bạn đang sử dụng raspivid để ghi lại thì "có thể", đã có một bản vá để hỗ trợ các tệp lớn, trong đó kích thước> 2 GB ( -D_FILE_OFFSET_BITS=64được yêu cầu trong các cờ được cung cấp cho gcc). Tuy nhiên bạn cần phải biên dịch Userland nguồn của chính mình.

Tuy nhiên, cần lưu ý, bạn nên hết sức cẩn thận, vì nếu bạn điền vào phân vùng hệ thống trên Linux, hành vi rất xấu có thể xảy ra. Vì vậy, bạn nên tạo một phân vùng riêng cho các video dài của bạn.

Nó cũng có thể là một ý tưởng tốt để giảm tốc độ bit nếu bạn gặp vấn đề với kích thước tệp.


4
Nếu có thể chấp nhận được, bạn cũng có thể chạy tập lệnh không liên tục (ví dụ thông qua cron) để dừng raspividquy trình hiện tại , cuộn lại tệp đầu ra và khởi động lại, để bạn kết thúc với một loạt các tệp nhỏ hơn biểu thị các lát thời gian cụ thể.
goldilocks
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.