dqpi
Posts: 33
Joined: Fri May 24, 2013 12:22 pm

picamera circular buffer

Sun Jan 25, 2015 7:45 pm

Im trying to get the last 10 seconds of video from the camera using a circular buffer. I started from a picamera example with some changes. I already noticed in the documentation that the circular buffer will never exactly contain 10 seconds of video. My goal is however to have exactly 10 seconds of video (I can use ffmpeg later if I need).

Code: Select all

import io
import random
import picamera
from PIL import Image

prior_image = None

count = 0

def detect_motion(camera):
    global count 

   # print("motioncheck")

    count = count + 1

    if(count > 15):
        count = 0
        return True
        
    else:
        return False
    
    

def write_video(stream):
    # Write the entire content of the circular buffer to disk. No need to
    # lock the stream here as we're definitely not writing to it
    # simultaneously
    with io.open('before.h264', 'wb') as output:
        framecount = 0
        for frame in stream.frames:
            framecount = framecount + 1
        print(framecount)

        splitframe = 0

        for frame in stream.frames:
            splitframe = splitframe + 1
            if frame.frame_type == picamera.PiVideoFrameType.sps_header:
                stream.seek(frame.position)
                break

        print("splitframe")
        print(splitframe)

        while True:
            buf = stream.read1()
            if not buf:
                break
            output.write(buf)
    # Wipe the circular stream once we're done
    stream.seek(0)
    stream.truncate()

with picamera.PiCamera() as camera:
    camera.resolution = (1920, 1080)
    camera.framerate = 30
    camera.sensor_mode = 1 
    stream = picamera.PiCameraCircularIO(camera, seconds=10)
    camera.start_recording(stream, format='h264')
    try:
        while True:
            camera.wait_recording(1)
            if detect_motion(camera):
                print('Motion detected!')
                # As soon as we detect motion, split the recording to
                # record the frames "after" motion
                camera.split_recording('after.h264')
                # Write the 10 seconds "before" motion to disk as well
                write_video(stream)
                # Wait until motion is no longer detected, then split
                # recording back to the in-memory circular buffer
                while detect_motion(camera):
                    camera.wait_recording(1)
               # print('Motion stopped!')
                camera.split_recording(stream)
    finally:
        camera.stop_recording()
However the code here returns me less frames than I expect. I expect at least 10 seconds * 30 frames = 300 frames where the print results are as follows:

Motion detected!
278
splitframe
35
Motion detected!
279
splitframe
36
Motion detected!
277
splitframe
34


How can I make sure that, as the documentation explains, I get at least 300 frames?

Return to “Camera board”