Инструменты пользователя

Инструменты сайта


dvr

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
dvr [10.05.2024 23:13] – [Заголовок] augindvr [08.07.2024 11:51] (текущий) – внешнее изменение 127.0.0.1
Строка 1: Строка 1:
-{{ :favicon.ico |}} 
- 
 [[https://github.com/AlexxIT/go2rtc/releases/]] [[https://github.com/AlexxIT/go2rtc/releases/]]
  
Строка 525: Строка 523:
  
 </code> </code>
-===== Заголовок ===== +===== python3 dvr.py --config_file 'dvr.yaml' ===== 
-<code bash>+<code> 
 +import argparse
 import time import time
 import os import os
Строка 532: Строка 531:
 from datetime import datetime from datetime import datetime
 import subprocess import subprocess
 +import schedule
 +from pathlib import Path
 +
 +
 +# Настройка парсера аргументов командной строки
 +parser = argparse.ArgumentParser(description='Запись видеопотоков.')
 +parser.add_argument('--config_file', type=str, help='Путь к файлу конфигурации', required=True)
 +# Чтение аргументов командной строки
 +args = parser.parse_args()
 +dvr_config_file = args.config_file
 +
 +def read_dvr_config(config_file):
 +    with open(dvr_config_file, 'r') as file:
 +        return yaml.safe_load(file)
 +
 +config = read_dvr_config(dvr_config_file)
 +base_dir = config['base_dir']
 +stream_server = config['stream_server']
 +target_size_gb = config['target_size_gb']
 +go2rtc_config_path = config['go2rtc_config_path']
 +
 +
 +# Функция очистки папок
 +def clean_camera_folders(base_dir, target_size_gb):
 +    """
 +    Очищает папки камер, удаляя самые старые файлы, пока размер папки не уменьшится до целевого размера.
 +
 +    :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('**/*') if f.is_file()) / (1024 ** 3)
 +
 +            # Рассчитать, сколько нужно удалить, чтобы достичь целевого размера
 +            space_to_free_gb = size_gb - target_size_gb
 +
 +            # Проверить, превышает ли текущий размер целевой размер
 +            if size_gb > target_size_gb:
 +                print(f"Cleaning {camera_dir}")
 +                # Удалить самые старые файлы, пока размер папки не уменьшится до целевого размера
 +                while space_to_free_gb > 0:
 +                    # Найти самый старый файл в папке
 +                    oldest_file = min(camera_dir.glob('**/*'), key=os.path.getmtime)
 +                    # Удалить самый старый файл
 +                    oldest_file_size = oldest_file.stat().st_size / (1024 ** 3)
 +                    try:
 +                        oldest_file.unlink()
 +                        print(f"Deleted {oldest_file}")
 +                        # Обновить текущий размер
 +                        space_to_free_gb -= oldest_file_size
 +                    except Exception as e:
 +                        print(f"Error deleting file {oldest_file}: {e}")
  
 # Функция для записи потоков # Функция для записи потоков
-def record_streams(duration): +def record_streams(duration, base_dir, stream_server): 
-    config_file = "/opt/go2rtc/go2rtc.yaml" +    with open(go2rtc_config_path, 'r') as file:
-    with open(config_file, 'r') as file:+
         config_data = yaml.safe_load(file)         config_data = yaml.safe_load(file)
     streams = config_data['streams'].keys()     streams = config_data['streams'].keys()
  
-    base_dir = "/media/disk1/video" 
     now = datetime.now()     now = datetime.now()
     year, month, day = now.strftime("%Y"), now.strftime("%m"), now.strftime("%d")     year, month, day = now.strftime("%Y"), now.strftime("%m"), now.strftime("%d")
     current_time = now.strftime("%H-%M")     current_time = now.strftime("%H-%M")
     M = now.strftime("%M")     M = now.strftime("%M")
-    stream_server "rtsp://10.10.15.103:8554"+ 
 +    processes []
  
     for stream_name in streams:     for stream_name in streams:
Строка 558: Строка 616:
             '-c:v', 'copy', '-c:a', 'aac', '-strict', 'experimental', '-t', str(duration), output_file             '-c:v', 'copy', '-c:a', 'aac', '-strict', 'experimental', '-t', str(duration), output_file
         ]         ]
-        log_file = os.path.join(base_dir, f"{stream_name}_{M}.txt"+        #log_file = os.path.join(base_dir, f"{stream_name}_{M}.txt"
-        try: +        # Запуск субпроцесса без ожидания его завершения 
-            with open(log_file, 'a') as log: +        process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
-                subprocess.run(command, stdout=log, stderr=log, check=True+        processes.append(process)
-        except subprocess.CalledProcessError as e: +
-            print(f"Ошибка при записи потока {stream_name}: {e}")+
  
-Основной цикл, который проверяет текущее время и запускает функцию записи +    Возвращаем список запущенных процессов, если нужно контролировать их в будущем 
-# в минуты, не кратные 10, с уменьшенным временем записи +    return processes 
-while True: +    # Очистка папок до размера 90 Гб 
-    now = datetime.now() +    clean_camera_folders(base_dir, target_size_gb)
-    if now.minute % 10 != 0:  # Проверяемне кратна ли текущая минута числу 10 +
-        next_interval = (now.minute // 10 + 1) * 10  # Следующий интервал, кратный 10 +
-        remaining_time = (next_interval - now.minute) * 60 - now.second  # Оставшееся время в секундах +
-        record_streams(remaining_time) +
-    time.sleep(60)  Пауза на 1 минуту, чтобы избежать повторного запуска в ту же минуту+
  
 +## Запуск записи при старте.
 +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, base_dir, stream_server)
  
 +duration = 607
 +# Планируем задачу на каждые 10 минут
 +schedule.every().hour.at(":00").do(record_streams, duration, base_dir, stream_server)
 +schedule.every().hour.at(":10").do(record_streams, duration, base_dir, stream_server)
 +schedule.every().hour.at(":20").do(record_streams, duration, base_dir, stream_server)
 +schedule.every().hour.at(":30").do(record_streams, duration, base_dir, stream_server)
 +schedule.every().hour.at(":40").do(record_streams, duration, base_dir, stream_server)
 +schedule.every().hour.at(":50").do(record_streams, duration, base_dir, stream_server)
 +
 +# Основной цикл
 +while True:
 +    schedule.run_pending()
 +    time.sleep(1)
 </code> </code>
 +===== dvr.yaml =====
 +<code>
 +base_dir: '/media/disk1/vt'
 +stream_server: 'rtsp://10.10.15.103:8554'
 +target_size_gb: 90
 +go2rtc_config_path: '/opt/go2rtc/go2rtc.yaml'
 +
 +</code>
 +
 +===== Docker =====
 +  docker container rm  simple_nvr
 +  docker build -t augin/nvr:v1 .
 +  docker run -v /usr/share/hassio/homeassistant/go2rtc.yaml:/config/go2rtc.yaml -v /mnt:/mounts/disk1/video  --name simple_nvr augin/nvr:v1
 +  
  
dvr.1715382818.txt.gz · Последнее изменение: 08.07.2024 11:48 (внешнее изменение)