如何让树莓派4B上的Python3定时录像程序自动无限循环?
树莓派离线循环安防系统解决方案
问题1:实现无需重新编译的定时无限循环录像
你之前用while True嵌套定时导致崩溃,大概率是资源未正确释放(摄像头、文件句柄泄漏)或嵌套逻辑混乱导致的。这里给你两种可靠的实现方式:
方式1:固定时长循环分段录制
每次录制固定时长片段,完成后自动启动下一次,全程单循环避免嵌套:
import time import picamera # 按你实际使用的摄像头库调整 RECORD_DURATION = 3600 # 每次录1小时 SAVE_PATH = "/mnt/usbssd/recordings" # 提前预留问题2的存储路径 def record_segment(): # 每次录制重新初始化摄像头,用with自动释放资源 with picamera.PiCamera() as camera: camera.resolution = (1920, 1080) camera.framerate = 30 # 生成带时间戳的文件名 timestamp = time.strftime("%Y%m%d_%H%M%S") filename = f"{SAVE_PATH}/rec_{timestamp}.h264" camera.start_recording(filename) camera.wait_recording(RECORD_DURATION) camera.stop_recording() print(f"录制完成:{filename}") # 无限循环录制,异常捕获防止程序直接挂掉 while True: try: record_segment() # 可选:录制间隔,比如time.sleep(10) except Exception as e: print(f"录制出错:{e}") time.sleep(60) # 出错后等待1分钟重试
方式2:定时触发录制(如每天固定时段)
用schedule库实现定时任务,无需嵌套循环:
先安装库:pip install schedule
import schedule import time import picamera RECORD_DURATION = 3600 SAVE_PATH = "/mnt/usbssd/recordings" def record_task(): with picamera.PiCamera() as camera: camera.resolution = (1920, 1080) timestamp = time.strftime("%Y%m%d_%H%M%S") filename = f"{SAVE_PATH}/rec_{timestamp}.h264" camera.start_recording(filename) camera.wait_recording(RECORD_DURATION) camera.stop_recording() print(f"定时录制完成:{filename}") # 设置每天8点、20点各录1小时 schedule.every().day.at("08:00").do(record_task) schedule.every().day.at("20:00").do(record_task) # 主循环仅负责调度任务 while True: schedule.run_pending() time.sleep(60) # 每分钟检查一次任务
核心注意点:用with语句自动释放摄像头资源,避免内存泄漏;添加异常捕获,防止单次录制失败导致整个程序崩溃。
问题2:将录像存储到外部USB/SSD设备
步骤1:挂载外部设备(开机自动挂载)
- 插入USB设备,用命令查看设备名:
lsblk,通常为/dev/sda1 - 创建挂载目录:
sudo mkdir /mnt/usbssd - 获取设备UUID(避免重启后设备名变化):
sudo blkid /dev/sda1,复制输出中的UUID值 - 修改
fstab实现开机自动挂载:
添加一行(替换成你的UUID,文件系统格式根据实际调整,比如ext4):sudo nano /etc/fstab
保存后执行UUID=你的UUID值 /mnt/usbssd ext4 defaults,noatime 0 2sudo mount -a测试挂载,无报错则成功。 - 赋予目录读写权限:
sudo chown pi:pi /mnt/usbssd
步骤2:修改代码中的存储路径
直接在代码中设置保存路径,并确保目录存在:
import os SAVE_PATH = "/mnt/usbssd/recordings" if not os.path.exists(SAVE_PATH): os.makedirs(SAVE_PATH)
问题3:自动覆盖最旧的录像文件
每次录制完成后,检查存储目录的文件数量或容量,达到阈值时删除最旧文件:
按文件数量清理(保留100个文件为例)
import os import glob MAX_FILES = 100 SAVE_PATH = "/mnt/usbssd/recordings" def cleanup_old_files(): # 获取所有录像文件(假设后缀为.h264) video_files = glob.glob(f"{SAVE_PATH}/*.h264") if len(video_files) <= MAX_FILES: return # 按修改时间排序(最旧的在前) video_files.sort(key=lambda x: os.path.getmtime(x)) # 删除多余的旧文件 while len(video_files) > MAX_FILES: oldest_file = video_files.pop(0) try: os.remove(oldest_file) print(f"已删除最旧录像:{oldest_file}") except Exception as e: print(f"删除文件出错:{e}")
按存储容量清理(保留50GB空间为例)
import os import glob import shutil MAX_USED_SPACE_GB = 50 SAVE_PATH = "/mnt/usbssd/recordings" def cleanup_by_space(): disk_usage = shutil.disk_usage(SAVE_PATH) used_gb = disk_usage.used / (1024**3) if used_gb <= MAX_USED_SPACE_GB: return video_files = glob.glob(f"{SAVE_PATH}/*.h264") video_files.sort(key=lambda x: os.path.getmtime(x)) # 逐个删除旧文件,直到容量符合要求 while used_gb > MAX_USED_SPACE_GB: oldest_file = video_files.pop(0) file_size_gb = os.path.getsize(oldest_file) / (1024**3) try: os.remove(oldest_file) used_gb -= file_size_gb print(f"已删除最旧录像:{oldest_file}") except Exception as e: print(f"删除文件出错:{e}")
将清理函数放在record_segment()或record_task()的末尾,每次录制完成后自动执行即可。
内容的提问来源于stack exchange,提问作者FootsoreBird03
相关产品推荐
相关产品推荐

