dvr
Различия
Показаны различия между двумя версиями страницы.
| Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия | ||
| dvr [07.05.2024 08:16] – [DVR] augin | dvr [08.07.2024 11:51] (текущий) – внешнее изменение 127.0.0.1 | ||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| - | {{ : | ||
| - | |||
| [[https:// | [[https:// | ||
| Строка 94: | Строка 92: | ||
| # Directory containing camera folders | # Directory containing camera folders | ||
| base_dir="/ | base_dir="/ | ||
| + | |||
| + | # Найти и удалить пустые папки | ||
| + | find " | ||
| # Iterate over camera folders | # Iterate over camera folders | ||
| Строка 117: | Строка 118: | ||
| fi | fi | ||
| done | done | ||
| + | |||
| </ | </ | ||
| Строка 396: | Строка 398: | ||
| generateFileTree(data, | generateFileTree(data, | ||
| addFileClickHandlers(); | addFileClickHandlers(); | ||
| + | |||
| + | |||
| + | |||
| playSecondFileDefault(); | playSecondFileDefault(); | ||
| Строка 434: | Строка 439: | ||
| }); | }); | ||
| } | } | ||
| + | |||
| + | const video = document.getElementById(' | ||
| + | |||
| + | // Добавление обработчика события " | ||
| + | video.addEventListener(' | ||
| + | const activeFileElement = document.querySelector('# | ||
| + | if (activeFileElement) { | ||
| + | const previousFileElement = activeFileElement.previousElementSibling; | ||
| + | if (previousFileElement) { | ||
| + | // Воспроизведение предыдущего файла | ||
| + | previousFileElement.click(); | ||
| + | } else { | ||
| + | // Если предыдущего файла нет, можно воспроизвести последний файл | ||
| + | const lastFileElement = document.querySelector('# | ||
| + | if (lastFileElement) { | ||
| + | lastFileElement.click(); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| + | |||
| // Функция для воспроизведения второго файла по умолчанию | // Функция для воспроизведения второго файла по умолчанию | ||
| Строка 442: | Строка 468: | ||
| } | } | ||
| } | } | ||
| + | |||
| </ | </ | ||
| Строка 496: | Строка 523: | ||
| </ | </ | ||
| + | ===== python3 dvr.py --config_file ' | ||
| + | < | ||
| + | import argparse | ||
| + | import time | ||
| + | import os | ||
| + | import yaml | ||
| + | from datetime import datetime | ||
| + | import subprocess | ||
| + | import schedule | ||
| + | from pathlib import Path | ||
| + | |||
| + | |||
| + | # Настройка парсера аргументов командной строки | ||
| + | parser = argparse.ArgumentParser(description=' | ||
| + | parser.add_argument(' | ||
| + | # Чтение аргументов командной строки | ||
| + | args = parser.parse_args() | ||
| + | dvr_config_file = args.config_file | ||
| + | |||
| + | def read_dvr_config(config_file): | ||
| + | with open(dvr_config_file, | ||
| + | return yaml.safe_load(file) | ||
| + | |||
| + | config = read_dvr_config(dvr_config_file) | ||
| + | base_dir = config[' | ||
| + | stream_server = config[' | ||
| + | target_size_gb = config[' | ||
| + | go2rtc_config_path = config[' | ||
| + | |||
| + | |||
| + | # Функция очистки папок | ||
| + | def clean_camera_folders(base_dir, | ||
| + | """ | ||
| + | Очищает папки камер, удаляя самые старые файлы, пока размер папки не уменьшится до целевого размера. | ||
| + | |||
| + | :param base_dir: Путь к каталогу, | ||
| + | :param target_size_gb: | ||
| + | """ | ||
| + | base_dir = Path(base_dir) | ||
| + | # Удалить пустые папки | ||
| + | for folder in base_dir.iterdir(): | ||
| + | if folder.is_dir() and not any(folder.iterdir()): | ||
| + | folder.rmdir() | ||
| + | # Перебор папок камер | ||
| + | for camera_dir in base_dir.iterdir(): | ||
| + | if camera_dir.is_dir(): | ||
| + | # Получить текущий размер папки камеры в ГБ без десятичной части | ||
| + | size_gb = sum(f.stat().st_size for f in camera_dir.glob(' | ||
| + | |||
| + | # Рассчитать, | ||
| + | space_to_free_gb = size_gb - target_size_gb | ||
| + | |||
| + | # Проверить, | ||
| + | if size_gb > target_size_gb: | ||
| + | print(f" | ||
| + | # Удалить самые старые файлы, пока размер папки не уменьшится до целевого размера | ||
| + | while space_to_free_gb > 0: | ||
| + | # Найти самый старый файл в папке | ||
| + | oldest_file = min(camera_dir.glob(' | ||
| + | # Удалить самый старый файл | ||
| + | oldest_file_size = oldest_file.stat().st_size / (1024 ** 3) | ||
| + | try: | ||
| + | oldest_file.unlink() | ||
| + | print(f" | ||
| + | # Обновить текущий размер | ||
| + | space_to_free_gb -= oldest_file_size | ||
| + | except Exception as e: | ||
| + | print(f" | ||
| + | |||
| + | # Функция для записи потоков | ||
| + | def record_streams(duration, | ||
| + | with open(go2rtc_config_path, | ||
| + | config_data = yaml.safe_load(file) | ||
| + | streams = config_data[' | ||
| + | |||
| + | now = datetime.now() | ||
| + | year, month, day = now.strftime(" | ||
| + | current_time = now.strftime(" | ||
| + | M = now.strftime(" | ||
| + | |||
| + | processes = [] | ||
| + | |||
| + | for stream_name in streams: | ||
| + | directory = os.path.join(base_dir, | ||
| + | os.makedirs(directory, | ||
| + | output_file = os.path.join(directory, | ||
| + | command = [ | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ] | ||
| + | #log_file = os.path.join(base_dir, | ||
| + | # Запуск субпроцесса без ожидания его завершения | ||
| + | process = subprocess.Popen(command, | ||
| + | processes.append(process) | ||
| + | |||
| + | # Возвращаем список запущенных процессов, | ||
| + | return processes | ||
| + | # Очистка папок до размера 90 Гб | ||
| + | clean_camera_folders(base_dir, | ||
| + | |||
| + | ## Запуск записи при старте. | ||
| + | now = datetime.now() | ||
| + | #if now.minute % 10 != 0: | ||
| + | next_interval = (now.minute // 10 + 1) * 10 | ||
| + | remaining_time = (next_interval - now.minute) * 60 - now.second | ||
| + | record_streams(remaining_time, | ||
| + | |||
| + | duration = 607 | ||
| + | # Планируем задачу на каждые 10 минут | ||
| + | schedule.every().hour.at(": | ||
| + | schedule.every().hour.at(": | ||
| + | schedule.every().hour.at(": | ||
| + | schedule.every().hour.at(": | ||
| + | schedule.every().hour.at(": | ||
| + | schedule.every().hour.at(": | ||
| + | |||
| + | # Основной цикл | ||
| + | while True: | ||
| + | schedule.run_pending() | ||
| + | time.sleep(1) | ||
| + | </ | ||
| + | ===== dvr.yaml ===== | ||
| + | < | ||
| + | base_dir: '/ | ||
| + | stream_server: | ||
| + | target_size_gb: | ||
| + | go2rtc_config_path: | ||
| + | |||
| + | </ | ||
| + | |||
| + | ===== Docker ===== | ||
| + | docker container rm simple_nvr | ||
| + | docker build -t augin/ | ||
| + | docker run -v / | ||
| + | | ||
dvr.1715069804.txt.gz · Последнее изменение: (внешнее изменение)
