from dataclasses import dataclass from decimal import Decimal from pathlib import Path DEFAULT_CONTEXT = ( "Brazilian Portuguese conversation. Preserve Brazilian spelling and punctuation. " "Vocabulary may include AWS, Kubernetes, OpenAI, PostgreSQL, Brasília, Banco do Brasil." ) @dataclass(frozen=True, slots=True) class AppSettings: model: str language: str output_directory: Path chunk_duration_seconds: int = 900 chunk_overlap_seconds: int = 15 retain_temporary_files: bool = False context_vocabulary: str = DEFAULT_CONTEXT @dataclass(frozen=True, slots=True) class ToolStatus: ffmpeg_path: Path | None ffprobe_path: Path | None @property def available(self) -> bool: return self.ffmpeg_path is not None and self.ffprobe_path is not None @dataclass(frozen=True, slots=True) class MediaInfo: path: Path size_bytes: int duration_seconds: float | None audio_codec: str | None duration_text: str | None = None has_audio: bool = False has_video: bool = False @dataclass(frozen=True, slots=True) class ChunkBoundary: index: int start_seconds: Decimal end_seconds: Decimal @property def duration_seconds(self) -> Decimal: return self.end_seconds - self.start_seconds