"""Options dialog for "Создать из ролика…" — sampling mode, step, downscale. Keeps the speed levers in one place: keyframe-only (fast) vs every-Nth-frame, the step, and an optional max-side downscale (smaller files → less disk/AV pressure). """ from __future__ import annotations from PySide6.QtWidgets import ( QComboBox, QDialog, QDialogButtonBox, QFormLayout, QLabel, QSpinBox, QWidget, ) class ExtractDialog(QDialog): def __init__(self, parent: QWidget | None = None) -> None: super().__init__(parent) self.setWindowTitle("Создать из ролика") self.mode = QComboBox() self.mode.addItem("Только ключевые кадры (быстро)", userData=True) self.mode.addItem("Каждый N-й кадр", userData=False) self.mode.currentIndexChanged.connect(self._sync) self.step = QSpinBox() self.step.setRange(1, 100000) self.step.setValue(1) # Default to "every frame" (every-N-th mode, step=1) — keyframes are # faster but too sparse; the user usually wants every frame. self.mode.setCurrentIndex(1) self.max_dim = QSpinBox() self.max_dim.setRange(0, 8192) self.max_dim.setSingleStep(120) self.max_dim.setValue(0) self.max_dim.setSpecialValueText("оригинал") self.quality = QSpinBox() self.quality.setRange(1, 100) self.quality.setValue(92) self.quality.setToolTip( "Качество JPEG (1–100). Ниже = быстрее кодирование и меньше файлы,\n" "но больше артефактов. 92 — хороший баланс." ) form = QFormLayout(self) form.addRow("Режим:", self.mode) form.addRow("Брать каждый N-й кадр:", self.step) form.addRow("Макс. сторона, px:", self.max_dim) form.addRow("Качество JPEG:", self.quality) hint = QLabel( "Ключевые кадры — в разы быстрее (декодируются только I-кадры),\n" "но реже по времени. Даунскейл и меньшее качество уменьшают файлы\n" "и нагрузку на диск (качество чуть ускоряет кодирование)." ) hint.setWordWrap(True) form.addRow(hint) buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) form.addRow(buttons) self._sync() def _sync(self) -> None: self.step.setEnabled(not self.mode.currentData()) def options(self) -> tuple[bool, int, int, int]: """Return (keyframes_only, step, max_dim, jpg_quality).""" return ( bool(self.mode.currentData()), self.step.value(), self.max_dim.value(), self.quality.value(), )