You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让树莓派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:挂载外部设备(开机自动挂载)

  1. 插入USB设备,用命令查看设备名:lsblk,通常为/dev/sda1
  2. 创建挂载目录:sudo mkdir /mnt/usbssd
  3. 获取设备UUID(避免重启后设备名变化):sudo blkid /dev/sda1,复制输出中的UUID值
  4. 修改fstab实现开机自动挂载:
    sudo nano /etc/fstab
    
    添加一行(替换成你的UUID,文件系统格式根据实际调整,比如ext4):
    UUID=你的UUID值 /mnt/usbssd ext4 defaults,noatime 0 2
    
    保存后执行sudo mount -a测试挂载,无报错则成功。
  5. 赋予目录读写权限: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:23:19