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

Record the past 5 seconds

Mon Oct 07, 2013 6:27 pm

Using motion it is possible to say create a video from 5 seconds ago and then for 20 seconds for example. Motion gives really poor quality videos though. I have one raspberry pi running a motion script triggering another raspberry pi for recording. I was wondering if there is a possibility with raspivid to buffer files from the past. I know that when you stream files there is a delay. Can I use this delay for making a recording of the past? How would I approach this?

mogabe
Posts: 14
Joined: Wed Dec 12, 2012 11:30 am

Re: Record the past 5 seconds

Mon Oct 07, 2013 7:26 pm

I have experimented with a similar thing. You have to use some kind of buffer i wrote one in C and it works pretty good. Could you tell us more about how you want the system to work. More like a usecase.

poing
Posts: 1131
Joined: Thu Mar 08, 2012 3:32 pm

Re: Record the past 5 seconds

Mon Oct 07, 2013 9:08 pm

One usecase, not my idea but I like it, is a dashcam that's continually recording to a buffer and when you press a button (or a shock is detected) the last minute is saved to disk.

mogabe
Posts: 14
Joined: Wed Dec 12, 2012 11:30 am

Re: Record the past 5 seconds

Mon Oct 07, 2013 10:41 pm

Easiest way of doing that is just record to files. And the default is to delete files unless you press that button which marks the file to be kept. This approach works better if the clips are longer. 5 second clips would miss the action since there is a delay in starting and stopping the camera.

My project is currently only about viewing the camera with a delay. Using this timed_buffer.c:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>

#ifndef max
    #define max(a,b) (((a) (b)) ? (a) : (b))
    #define min(a,b) (((a) < (b)) ? (a) : (b))
#endif


#define BLOCK_SIZE 512
#define BUFFER_SIZE 64*1024*1024

int main(int argc, const char *argv[])
{

    //printf("Debug");

    int delay = 0;
    if (argc != 1) { 
        delay  = atoi( argv[1]);
    }

    int output = 0; //to be set to 1 when delay is reached

    uint8_t *buffer= malloc(BUFFER_SIZE);
    uint8_t *write = buffer;
    uint8_t *read = buffer;
    int n_read = BLOCK_SIZE;
    int n_write = 0;

    struct timeval tv;
    gettimeofday(&tv,NULL);

    struct timeval tv2;


    while(1) {
        if(!output){
             gettimeofday(&tv2,NULL);
	     if(tv2.tv_sec - tv.tv_sec >= delay){
                 output = 1;
		 fprintf(stderr, "Required buffer size: %iKb\n", (int) (write - read)/1024);
             }
	}

        n_read = min(BLOCK_SIZE,BUFFER_SIZE - (write-buffer));

        //printf("Debug %i %ui %ui %ui",n_read, write, buffer, read );

        size_t bytes = fread(write,sizeof(uint8_t), n_read, stdin);

        //printf("Debug");
        if(bytes==0){
            sleep(1);
        }else{
	
            write = write+bytes;
	    if(write>=buffer+BUFFER_SIZE){
		if(!output){
			fprintf(stderr, "Buffer overflow\n");
			exit(1);
		}else{
                	write = buffer;
		}
            }
            if(output){
                
		n_write = min(bytes,buffer+BUFFER_SIZE-read);
                fwrite(read, sizeof(uint8_t), n_write,stdout);
                read+=n_write;
                if(bytes >n_write){
		    n_write = bytes - n_write;
		    read = buffer;
                    fwrite(read, sizeof(uint8_t), n_write,stdout);
                    read+=n_write;
                }
            }
        }
    }
    return 0;
}
And then a shell script (delay_play.sh) for simplifying running of delayed camera:

Code: Select all

#!/bin/bash
DELAY=$1

rm -f video.h264
mkfifo video.h264

/opt/vc/src/hello_pi/hello_video/hello_video.bin video.h264 &

raspivid -t 0 -w 1280 -h 720 -o - -fps 30  -n | ./timed_buffer.out $DELAY > video.h264
running shell script with 30 sec delay:
./delay_play.sh 30

Sorry for ugly code. I'm not very fluent in C or shell scripting.

XAPBob
Posts: 91
Joined: Tue Jan 03, 2012 2:40 pm

Re: Record the past 5 seconds

Tue Oct 08, 2013 11:53 am

Depending on file sizes and RasPi version you might be able to use a RAM disk for much of the recording to reduce load on the SD card.

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

Re: Record the past 5 seconds

Tue Oct 08, 2013 11:59 am

I have a video of someone walking by. I want the camera to start when motion is detected but I also want to have the person come walk into the video. Recording short videos and throwing away is not an option because what if I erase the last video and then motion happens. I need a continuous buffer or a delayed stream that I can record? Is this possible?

mogabe
Posts: 14
Joined: Wed Dec 12, 2012 11:30 am

Re: Record the past 5 seconds

Wed Oct 09, 2013 11:35 am

I don't have any clues on how the same camera could be used for motion detection and video recording simultaneously.

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

Re: Record the past 5 seconds

Wed Oct 09, 2013 11:54 am

Sorry if that was not clear. I am using one raspberry pi for motion detection. It has a socket connection to another raspberrry pi. If pi 1 registers activity it sends a message to pi 2 and I want this pi to record a video from -5 seconds to 25 seconds (30 seconds long). How can I always have a 5 seconds buffer in pi 2?

mogabe
Posts: 14
Joined: Wed Dec 12, 2012 11:30 am

Re: Record the past 5 seconds

Wed Oct 09, 2013 3:05 pm

I have tried a lot. My code posted earlier dose a good job of delaying the video. But the problem is how to only save that stream when needed. You would need some nonblocking fifo. But my linux fu is not that strong.

mikerr
Posts: 2768
Joined: Thu Jan 12, 2012 12:46 pm
Location: UK
Contact: Website

Re: Record the past 5 seconds

Wed Oct 09, 2013 3:18 pm

Instead of starting/stopping raspivd, you could pipe it into ffmpeg and have that split video into 5 second segments without re-encoding, something like:

Code: Select all

raspivid -o - | ffmpeg -i - -map 0 -c copy -f segment -segment_time 5 -reset_timestamps 1 %02d.h264
(totally untested!)

XAPBob
Posts: 91
Joined: Tue Jan 03, 2012 2:40 pm

Re: Record the past 5 seconds

Thu Oct 10, 2013 11:33 am

dqpi wrote:I have a video of someone walking by. I want the camera to start when motion is detected but I also want to have the person come walk into the video. Recording short videos and throwing away is not an option because what if I erase the last video and then motion happens. I need a continuous buffer or a delayed stream that I can record? Is this possible?
Don't delete the last video - always leave a couple on (ram)disk

Note that repeatedly calling raspivid isn't a good way to do this since the camera takes a (short) while to start up each time. I like the ffmpeg splitting idea.

bunnycoitus
Posts: 2
Joined: Fri May 22, 2015 5:24 pm

Re: Record the past 5 seconds

Fri May 22, 2015 5:27 pm

I have little doubt that I'm missing something obvious, but when I try to run your script I receive a 'Permission denied' message. I assumed I just needed to login as root but that did not solve the problem. Any idea why or what I'm missing?

User avatar
mad-hatter
Posts: 419
Joined: Sun Feb 26, 2012 2:58 pm
Location: By the UK seaside

Re: Record the past 5 seconds

Fri May 22, 2015 11:37 pm

Hello,

You have to run chmod on the script file to set permissions.

man chmod (in a terminal)

have a loook here :- http://www.computerhope.com/unix/uchmod.htm

u the user can read, write, and execute it;
g members of your group can read and execute it; and
o others may only read it.

chmod u=rwx,g=rx,o=r myfile

Regards

Return to “Camera board”