Add Picture Streams architecture with postprocessing templates and stream test UI
Introduce Picture Stream abstraction that separates the capture pipeline into composable layers: raw streams (display + capture engine + FPS) and processed streams (source stream + postprocessing template). Devices reference a picture stream instead of managing individual capture settings. - Add PictureStream and PostprocessingTemplate data models and stores - Add CRUD API endpoints for picture streams and postprocessing templates - Add stream chain resolution in ProcessorManager for start_processing - Add picture stream test endpoint with postprocessing preview support - Add Stream Settings modal with border_width and interpolation_mode controls - Add stream test modal with capture preview and performance metrics - Add full frontend: Picture Streams tab, Processing Templates tab, stream selector on device cards, test buttons on stream cards - Add localization keys for all new features (en, ru) - Migrate existing devices to picture streams on startup Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -50,9 +50,6 @@
|
||||
"templates.config.show": "Show configuration",
|
||||
"templates.config.none": "No additional configuration",
|
||||
"templates.config.default": "Default",
|
||||
"templates.default": "Default",
|
||||
"templates.custom": "Custom Templates",
|
||||
"templates.default.locked": "Default template (cannot edit/delete)",
|
||||
"templates.created": "Template created successfully",
|
||||
"templates.updated": "Template updated successfully",
|
||||
"templates.deleted": "Template deleted successfully",
|
||||
@@ -195,5 +192,69 @@
|
||||
"modal.discard_changes": "You have unsaved changes. Discard them?",
|
||||
"confirm.title": "Confirm Action",
|
||||
"confirm.yes": "Yes",
|
||||
"confirm.no": "No"
|
||||
"confirm.no": "No",
|
||||
"common.delete": "Delete",
|
||||
"common.edit": "Edit",
|
||||
"streams.title": "\uD83D\uDCFA Picture Streams",
|
||||
"streams.description": "Picture streams define the capture pipeline. A raw stream captures from a display using a capture template. A processed stream applies postprocessing to another stream. Assign streams to devices.",
|
||||
"streams.add": "Add Picture Stream",
|
||||
"streams.edit": "Edit Picture Stream",
|
||||
"streams.name": "Stream Name:",
|
||||
"streams.name.placeholder": "My Stream",
|
||||
"streams.type": "Type:",
|
||||
"streams.type.raw": "Screen Capture",
|
||||
"streams.type.processed": "Processed",
|
||||
"streams.display": "Display:",
|
||||
"streams.capture_template": "Capture Template:",
|
||||
"streams.target_fps": "Target FPS:",
|
||||
"streams.source": "Source Stream:",
|
||||
"streams.pp_template": "Processing Template:",
|
||||
"streams.description_label": "Description (optional):",
|
||||
"streams.description_placeholder": "Describe this stream...",
|
||||
"streams.created": "Stream created successfully",
|
||||
"streams.updated": "Stream updated successfully",
|
||||
"streams.deleted": "Stream deleted successfully",
|
||||
"streams.delete.confirm": "Are you sure you want to delete this stream?",
|
||||
"streams.error.load": "Failed to load streams",
|
||||
"streams.error.required": "Please fill in all required fields",
|
||||
"streams.error.delete": "Failed to delete stream",
|
||||
"streams.test.title": "Test Picture Stream",
|
||||
"streams.test.run": "🧪 Run Test",
|
||||
"streams.test.running": "Testing stream...",
|
||||
"streams.test.duration": "Capture Duration (s):",
|
||||
"streams.test.error.failed": "Stream test failed",
|
||||
"postprocessing.title": "\uD83C\uDFA8 Processing Templates",
|
||||
"postprocessing.description": "Processing templates define color correction and smoothing settings. Assign them to processed picture streams for consistent postprocessing across devices.",
|
||||
"postprocessing.add": "Add Processing Template",
|
||||
"postprocessing.edit": "Edit Processing Template",
|
||||
"postprocessing.name": "Template Name:",
|
||||
"postprocessing.name.placeholder": "My Processing Template",
|
||||
"postprocessing.gamma": "Gamma:",
|
||||
"postprocessing.saturation": "Saturation:",
|
||||
"postprocessing.brightness": "Brightness:",
|
||||
"postprocessing.smoothing": "Smoothing:",
|
||||
"postprocessing.description_label": "Description (optional):",
|
||||
"postprocessing.description_placeholder": "Describe this template...",
|
||||
"postprocessing.created": "Template created successfully",
|
||||
"postprocessing.updated": "Template updated successfully",
|
||||
"postprocessing.deleted": "Template deleted successfully",
|
||||
"postprocessing.delete.confirm": "Are you sure you want to delete this processing template?",
|
||||
"postprocessing.error.load": "Failed to load processing templates",
|
||||
"postprocessing.error.required": "Please fill in all required fields",
|
||||
"postprocessing.error.delete": "Failed to delete processing template",
|
||||
"postprocessing.config.show": "Show settings",
|
||||
"device.button.stream_selector": "Stream Settings",
|
||||
"device.stream_settings.title": "📺 Stream Settings",
|
||||
"device.stream_selector.label": "Assigned Picture Stream:",
|
||||
"device.stream_selector.hint": "Select a picture stream that defines what this device captures and processes",
|
||||
"device.stream_selector.none": "-- No stream assigned --",
|
||||
"device.stream_selector.saved": "Stream settings updated",
|
||||
"device.stream_settings.border_width": "Border Width (px):",
|
||||
"device.stream_settings.border_width_hint": "How many pixels from the screen edge to sample for LED colors (1-100)",
|
||||
"device.stream_settings.interpolation": "Interpolation Mode:",
|
||||
"device.stream_settings.interpolation.average": "Average",
|
||||
"device.stream_settings.interpolation.median": "Median",
|
||||
"device.stream_settings.interpolation.dominant": "Dominant",
|
||||
"device.stream_settings.interpolation_hint": "How to calculate LED color from sampled pixels",
|
||||
"device.tip.stream_selector": "Configure picture stream and LED projection settings for this device"
|
||||
}
|
||||
|
||||
@@ -50,9 +50,6 @@
|
||||
"templates.config.show": "Показать конфигурацию",
|
||||
"templates.config.none": "Нет дополнительных настроек",
|
||||
"templates.config.default": "По умолчанию",
|
||||
"templates.default": "По умолчанию",
|
||||
"templates.custom": "Пользовательские шаблоны",
|
||||
"templates.default.locked": "Системный шаблон (нельзя редактировать/удалить)",
|
||||
"templates.created": "Шаблон успешно создан",
|
||||
"templates.updated": "Шаблон успешно обновлён",
|
||||
"templates.deleted": "Шаблон успешно удалён",
|
||||
@@ -195,5 +192,69 @@
|
||||
"modal.discard_changes": "У вас есть несохранённые изменения. Отменить их?",
|
||||
"confirm.title": "Подтверждение Действия",
|
||||
"confirm.yes": "Да",
|
||||
"confirm.no": "Нет"
|
||||
"confirm.no": "Нет",
|
||||
"common.delete": "Удалить",
|
||||
"common.edit": "Редактировать",
|
||||
"streams.title": "\uD83D\uDCFA Видеопотоки",
|
||||
"streams.description": "Видеопотоки определяют конвейер захвата. Сырой поток захватывает экран с помощью шаблона захвата. Обработанный поток применяет постобработку к другому потоку. Назначайте потоки устройствам.",
|
||||
"streams.add": "Добавить Видеопоток",
|
||||
"streams.edit": "Редактировать Видеопоток",
|
||||
"streams.name": "Имя Потока:",
|
||||
"streams.name.placeholder": "Мой Поток",
|
||||
"streams.type": "Тип:",
|
||||
"streams.type.raw": "Захват экрана",
|
||||
"streams.type.processed": "Обработанный",
|
||||
"streams.display": "Дисплей:",
|
||||
"streams.capture_template": "Шаблон Захвата:",
|
||||
"streams.target_fps": "Целевой FPS:",
|
||||
"streams.source": "Исходный Поток:",
|
||||
"streams.pp_template": "Шаблон Обработки:",
|
||||
"streams.description_label": "Описание (необязательно):",
|
||||
"streams.description_placeholder": "Опишите этот поток...",
|
||||
"streams.created": "Поток успешно создан",
|
||||
"streams.updated": "Поток успешно обновлён",
|
||||
"streams.deleted": "Поток успешно удалён",
|
||||
"streams.delete.confirm": "Вы уверены, что хотите удалить этот поток?",
|
||||
"streams.error.load": "Не удалось загрузить потоки",
|
||||
"streams.error.required": "Пожалуйста, заполните все обязательные поля",
|
||||
"streams.error.delete": "Не удалось удалить поток",
|
||||
"streams.test.title": "Тест Видеопотока",
|
||||
"streams.test.run": "🧪 Запустить Тест",
|
||||
"streams.test.running": "Тестирование потока...",
|
||||
"streams.test.duration": "Длительность Захвата (с):",
|
||||
"streams.test.error.failed": "Тест потока не удался",
|
||||
"postprocessing.title": "\uD83C\uDFA8 Шаблоны Обработки",
|
||||
"postprocessing.description": "Шаблоны обработки определяют настройки цветокоррекции и сглаживания. Назначайте их обработанным видеопотокам для единообразной постобработки на всех устройствах.",
|
||||
"postprocessing.add": "Добавить Шаблон Обработки",
|
||||
"postprocessing.edit": "Редактировать Шаблон Обработки",
|
||||
"postprocessing.name": "Имя Шаблона:",
|
||||
"postprocessing.name.placeholder": "Мой Шаблон Обработки",
|
||||
"postprocessing.gamma": "Гамма:",
|
||||
"postprocessing.saturation": "Насыщенность:",
|
||||
"postprocessing.brightness": "Яркость:",
|
||||
"postprocessing.smoothing": "Сглаживание:",
|
||||
"postprocessing.description_label": "Описание (необязательно):",
|
||||
"postprocessing.description_placeholder": "Опишите этот шаблон...",
|
||||
"postprocessing.created": "Шаблон успешно создан",
|
||||
"postprocessing.updated": "Шаблон успешно обновлён",
|
||||
"postprocessing.deleted": "Шаблон успешно удалён",
|
||||
"postprocessing.delete.confirm": "Вы уверены, что хотите удалить этот шаблон обработки?",
|
||||
"postprocessing.error.load": "Не удалось загрузить шаблоны обработки",
|
||||
"postprocessing.error.required": "Пожалуйста, заполните все обязательные поля",
|
||||
"postprocessing.error.delete": "Не удалось удалить шаблон обработки",
|
||||
"postprocessing.config.show": "Показать настройки",
|
||||
"device.button.stream_selector": "Настройки потока",
|
||||
"device.stream_settings.title": "📺 Настройки потока",
|
||||
"device.stream_selector.label": "Назначенный Видеопоток:",
|
||||
"device.stream_selector.hint": "Выберите видеопоток, определяющий что это устройство захватывает и обрабатывает",
|
||||
"device.stream_selector.none": "-- Поток не назначен --",
|
||||
"device.stream_selector.saved": "Настройки потока обновлены",
|
||||
"device.stream_settings.border_width": "Ширина границы (px):",
|
||||
"device.stream_settings.border_width_hint": "Сколько пикселей от края экрана выбирать для цвета LED (1-100)",
|
||||
"device.stream_settings.interpolation": "Режим интерполяции:",
|
||||
"device.stream_settings.interpolation.average": "Среднее",
|
||||
"device.stream_settings.interpolation.median": "Медиана",
|
||||
"device.stream_settings.interpolation.dominant": "Доминантный",
|
||||
"device.stream_settings.interpolation_hint": "Как вычислять цвет LED из выбранных пикселей",
|
||||
"device.tip.stream_selector": "Настройки видеопотока и проекции LED для этого устройства"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user