Skip to content

Реализовать верификацию целостности видеофайла после записи #46

@chelslava

Description

@chelslava

Описание

После завершения записи нет механизма проверки, что видеофайл не повреждён и может быть воспроизведён. Пользователь может не обнаружить проблему до момента, когда запись уже не нужна.

Текущее поведение

Запись завершена → Файл сохранён → ???
Result: Неизвестно, открывается ли файл

Ожидаемое поведение

Запись завершена → Верификация FFprobe → OK/Повреждён → Уведомление
Result: Гарантированная целостность файла

Технические требования

1. Верификация через FFprobe

import subprocess
import json

def verify_video_integrity(file_path: Path) -> tuple[bool, dict]:
    """Проверяет целостность видеофайла через FFprobe.
    
    Returns:
        (is_valid, details) — валидность и детали анализа
    """
    cmd = [
        "ffprobe",
        "-v", "error",
        "-select_streams", "v:0",
        "-show_entries", "stream=codec_name,width,height,duration",
        "-show_entries", "format=duration,size,bit_rate",
        "-of", "json",
        str(file_path)
    ]
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    if result.returncode != 0:
        return False, {"error": result.stderr}
    
    data = json.loads(result.stdout)
    return True, data

2. Расширенная проверка воспроизводимости

def verify_playback(file_path: Path, duration_sec: float = 5.0) -> tuple[bool, str]:
    """Проверяет возможность декодирования видео.
    
    Returns:
        (can_play, error_message)
    """
    cmd = [
        "ffmpeg",
        "-i", str(file_path),
        "-t", str(duration_sec),
        "-f", "null",
        "-"
    ]
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    if result.returncode != 0:
        return False, result.stderr
    
    return True, ""

3. Автоматическое восстановление

def attempt_repair(file_path: Path) -> bool:
    """Пытается восстановить повреждённый файл.
    
    Стратегии:
    1. Пересоздать moov атом (если отсутствует)
    2. Перекодировать с потерей качества
    3. Удалить повреждённые чанки
    """
    # Основная стратегия: пересборка индекса
    temp_path = file_path.with_suffix('.tmp.mp4')
    
    cmd = [
        "ffmpeg",
        "-i", str(file_path),
        "-c", "copy",
        "-movflags", "+faststart",
        str(temp_path)
    ]
    
    result = subprocess.run(cmd, capture_output=True)
    
    if result.returncode == 0:
        temp_path.replace(file_path)
        return True
    
    return False

4. Интеграция с RecordingService

class RecordingService:
    def _on_recording_stopped(self, event: RecordingEvent) -> None:
        """Обработчик завершения записи."""
        file_path = event.payload["file_path"]
        
        # Верификация
        is_valid, details = verify_video_integrity(file_path)
        
        if not is_valid:
            # Попытка восстановления
            if attempt_repair(file_path):
                self._notify_user("Файл восстановлен после проверки")
            else:
                self._mark_as_corrupted(file_path)
                self._notify_user("Внимание: файл может быть повреждён")
        else:
            self._log_verification_success(details)

5. API endpoints

POST /api/v1/recordings/verify
Body: {"file_path": "/path/to/recording.mp4"}
Response: {"valid": true, "details": {...}}

POST /api/v1/recordings/repair
Body: {"file_path": "/path/to/recording.mp4"}
Response: {"repaired": true, "original_size": 12345678}

Критерии приёмки

  • Верификация выполняется автоматически после каждой записи
  • Пользователь уведомляется о результатах проверки (успех/неудача)
  • Повреждённые файлы автоматически помечаются и/или удаляются
  • Настройка verify_on_complete: bool в конфигурации
  • API endpoint для ручной проверки любого файла
  • API endpoint для попытки восстановления
  • Unit-тесты для всех функций верификации

Конфигурация

# config.py
class VideoSettingsSchema(BaseModel):
    verify_on_complete: bool = Field(default=True)
    auto_repair_corrupted: bool = Field(default=False)
    repair_attempts: int = Field(default=1, ge=0, le=3)

Файлы для изменения

  • recorder/ffmpeg_writer.py — верификация файла
  • core/recording_service.py — вызов верификации
  • api/routes_recording.py — новые endpoints
  • config.py — настройки верификации
  • tests/unit/test_ffmpeg_writer.py — тесты верификации

Приоритет: P2

Тэги: reliability, enhancement

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions