Cámara Pi Zero que graba clips de movimiento en tu NAS
Una cámara pequeña y barata que guarda un clip de video, incluyendo los segundos antes del movimiento, directo a una carpeta de red.
Picamera2 puede guardar en memoria los últimos segundos de video con un búfer circular. Cuando la vista de baja resolución cambia lo suficiente, el script guarda ese búfer y lo que sigue en tu NAS, así casi no se usa la tarjeta SD.
Graba solo áreas que sean tuyas o que tengas permiso de grabar, y dile a la gente que vive contigo dónde están las cámaras.
Pasos de la misión
Conecta la cámara
Usa el cable de 22 a 15 pines: el extremo angosto va al Pi Zero 2 W, con los contactos hacia la placa. Prueba con rpicam-hello.
Monta la carpeta del NAS
Crea una carpeta en tu NAS y agrega una entrada CIFS o NFS en /etc/fstab con las opciones nofail y _netdev, montada en /mnt/nas.
Corre el script
Guarda el script de abajo y córrelo con python3. Mueve la mano frente a la cámara y verifica que aparezca un archivo en el NAS.
Ajusta la sensibilidad
Sube THRESHOLD si los árboles o cambios de luz la disparan; bájalo si pasa gente sin que se active.
Arranca al encender
Crea un servicio de systemd con Restart=always para que siga funcionando tras reinicios y fallas del NAS.
Código
import time, datetime
import numpy as np
from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import CircularOutput
SAVE, THRESHOLD = '/mnt/nas/porch', 7
W, H = 320, 240
picam2 = Picamera2()
picam2.configure(picam2.create_video_configuration(main={'size': (1280, 720)}, lores={'size': (W, H), 'format': 'YUV420'}))
encoder = H264Encoder(2000000, repeat=True)
encoder.output = CircularOutput(buffersize=150) # about 5 s at 30 fps
picam2.start()
picam2.start_encoder(encoder)
prev, recording, last_motion = None, False, 0
while True:
cur = picam2.capture_buffer('lores')[:W * H].reshape(H, W).astype(np.int16)
if prev is not None:
if np.square(cur - prev).mean() > THRESHOLD:
last_motion = time.time()
if not recording:
name = datetime.datetime.now().strftime('%Y%m%d-%H%M%S')
encoder.output.fileoutput = f'{SAVE}/{name}.h264'
encoder.output.start(); recording = True
print('motion ->', name)
elif recording and time.time() - last_motion > 10:
encoder.output.stop(); recording = False
prev = curCode comments are in English, like most libraries and docs — a good habit for makers.
Preguntas
¿Cómo reproduzco los archivos .h264?
VLC los reproduce directamente. Para tener archivos MP4 normales, corre ffmpeg -i clip.h264 -c copy clip.mp4 en el NAS o en tu PC.
¿Puedo usar motionEye en su lugar?
Sí, si prefieres una interfaz web. Verifica que la versión actual de motionEye soporte tu cámara y sistema; este script es más liviano y usa la librería oficial Picamera2.