前引

不知道因为什么原因Picamera2包调用摄像头拍照,在一个程序中达到一定次数之后就会导致系统的内存泄漏,除了重启软件没有什么好的方法来解决,但作为一个监控性质的软件,经常发生这种错误还是比较无法接受的事情。

因此决定看看能不能直接使用C语言来完成监控人员到访和录像这一系列动作

代码

代码部分十分简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <pigpio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>

int pinNumber = 18;

int getVideo(){
time_t timep;
struct tm *p;
char filePath[28];
time (&timep);
p=gmtime(&timep);

int hour = 8+p->tm_hour;
sprintf(filePath,"%s%d%02d%02d%02d%02d%02d%s","/Disk/MyCloud/Stream/Safe/",1900+p->tm_year,1+p->tm_mon,p->tm_mday,(hour>=24)?(hour-24):hour,p->tm_min,p->tm_sec,".mp4");

char command[1000];
sprintf(command,"%s%s%s%s", "libcamera-vid -t 5000 --width 1280 --height 720 --codec libav -o ",filePath," && sudo chown www-data ",filePath);

return system(command);
}

int main() {
int value = 0;
if (gpioInitialise() < 0) {
printf("pigpio initialization failed\n");
return 1;
}
gpioSetMode(pinNumber, PI_INPUT);
while(1){
value = gpioRead(pinNumber);
if(value==1){
getVideo();
}
time_sleep(1.0);
}

gpioTerminate();
return 0;
}

由于在之前 使用的GPIO库wiringPi.h已经暂停维护,在新版的树莓派系统中不在默认安装,这里使用了pigpio.h

  1. 如果没有安装

    1
    2
    sudo apt update
    sudo apt install pigpio
  2. 编译

    1
    gcc monitor.c -o monitor -lpigpio -lrt -lpthread
  3. 引脚编号

    默认为BCM编号

    1. 主要拍照代码

      1
      system(command)

      实际是为了调用系统的libcamera-vid

      1
      sprintf(command,"%s%s%s%s", "libcamera-vid -t 5000 --codec libav -o ",filePath," && sudo chown www-data ",filePath);

      这部分代码为录一个5秒的视频并保存到filePath目录下,同时修改视频权限方便给Nextcloud修改查看

    2. 人体红外代码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      int value = 0;
      if (gpioInitialise() < 0) {
      printf("pigpio initialization failed\n");
      return 1;
      }
      gpioSetMode(pinNumber, PI_INPUT);
      while(1){
      value = gpioRead(pinNumber);
      if(value==1){
      getVideo();
      }
      time_sleep(1.0);
      }

      gpioTerminate();

      当有人到访时输出高电平,检测到高电平时触发录像