實現效果
使用opencv
調用USB外置攝像頭進行循環錄像,視頻分段錄製後進行保存(代碼中是每5分鐘存一下),當tf卡的可用空間不足50%的時候刪除已保存視頻最早的文件,然後繼續新的錄製
依賴輪子
- opencv-python 圖像處理必備
- logzero 日誌記錄神器
完整代碼
#!/usr/bin/env python3
import glob
import os
from datetime import datetime
import cv2
import logzero
from logzero import logger
# 配置logzero保存日誌到文件,單文件最大5MB,最多保存3份
logzero.logfile('/home/pi/video/log.log', maxBytes=5e6, backupCount=3)
# 限制至少保留可用磁盤空間百分比
SPACE_LIMIT = 50
# 錄製視頻的分段時長(單位秒)
PER_LENGTH = 5 * 60
# 視頻保存位置
LOCATION = '/home/pi/video/'
def disk_per():
"""
計算當前/目錄可用空間比率
:return: 返回整數百分比結果
"""
info = os.statvfs('/')
free_size = info.f_bsize * info.f_bavail
total_size = info.f_blocks * info.f_bsize
percent = round(free_size / total_size * 100)
return percent
def get_files_list(exp):
"""
獲取指定位置下的指定後綴文件列表,根據文件創建時間正序排列(從早到後順序)
:param exp: 搜索路徑表達式.格式: /home/pi/*.avi
:return:
"""
files = list(filter(os.path.isfile, glob.glob(exp)))
# 按照文件創建時間倒序排列
files.sort(key=lambda x: os.path.getctime(x), reverse=False)
return files
def record():
"""
錄製視頻
:return:
"""
WIDTH = 640
HEIGHT = 480
FPS = 24.0
cap = cv2.VideoCapture(0)
# 設置攝像頭設備分辨率
cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT)
# 設置攝像頭設備幀率,如不指定,默認600
cap.set(cv2.CAP_PROP_FPS, 24.0)
# 建議使用XVID編碼,圖像質量和文件大小比較都兼顧的方案
fourcc = cv2.VideoWriter_fourcc(*'XVID')
start_time = datetime.now()
filename = LOCATION + start_time.strftime('%Y-%m-%d_%H-%M-%S') + '.avi'
out = cv2.VideoWriter(filename, fourcc, FPS, (WIDTH, HEIGHT))
flag = True
while flag:
# 檢測磁盤空間是否充足
if disk_per() > SPACE_LIMIT:
# 開始當前錄製視頻時段
if (datetime.now() - start_time).seconds >= PER_LENGTH:
# 到達視頻分段時長後停止錄製
logger.info(f'分段錄製結束,文件保存爲{filename}')
out.release()
# 重新開始新的視頻錄製
start_time = datetime.now()
filename = LOCATION + start_time.strftime('%Y-%m-%d_%H-%M-%S') + '.avi'
out = cv2.VideoWriter(filename, fourcc, FPS, (WIDTH, HEIGHT))
else:
ret, frame = cap.read()
if ret:
out.write(frame)
else:
# 磁盤使用空間達到配額後刪除最早的視頻文件
logger.warn(f'磁盤可用空間不足{SPACE_LIMIT}%,將刪除最早保存的視頻文件')
files = get_files_list(LOCATION + '*.avi')
os.remove(files[0])
logger.info(f'{files[0]}已刪除')
cap.release()
if __name__ == '__main__':
logger.info('開始錄製視頻')
record()
後臺執行
$ chmod +x cam.py
$ vim run.sh
//內容如下
nohup ./cam.py >/dev/null 2>&1 &
$ chmod +x run.sh
$ ./run.sh