Update README.md with project details, features, requirements, architecture, and data management for PLib video library manager.
This commit is contained in:
@@ -1,2 +1,66 @@
|
||||
# PLib
|
||||
|
||||
Менеджер видеотеки на Avalonia: сканирует папки, вытаскивает превью через ffmpeg и
|
||||
показывает всё сеткой карточек.
|
||||
|
||||
## Что уже работает
|
||||
|
||||
- Сканирование указанных папок, инкрементальное — файл, который не изменился, не переиндексируется.
|
||||
- Метаданные (длительность, разрешение, кодек) через ffprobe.
|
||||
- Постеры кадром из видео через ffmpeg, с кэшем на диске.
|
||||
- Виртуализированная сетка карточек, ленивая загрузка превью, поиск и сортировка.
|
||||
- Светлая и тёмная темы.
|
||||
- Клик или Enter по карточке — открыть в системном плеере, правая кнопка — контекстное меню.
|
||||
|
||||
## Требования
|
||||
|
||||
- .NET 10 SDK
|
||||
- `ffmpeg` и `ffprobe` в `PATH`
|
||||
|
||||
## Запуск
|
||||
|
||||
```bash
|
||||
dotnet run --project src/PLib.Desktop
|
||||
```
|
||||
|
||||
```bash
|
||||
dotnet test
|
||||
```
|
||||
|
||||
## Архитектура
|
||||
|
||||
Четыре слоя, зависимости направлены только внутрь:
|
||||
|
||||
| Проект | Отвечает за | Знает о |
|
||||
| --- | --- | --- |
|
||||
| `PLib.Domain` | Сущность `VideoItem` и её инварианты | ни о чём |
|
||||
| `PLib.Application` | Сценарии (`LibraryService`) и абстракции портов | Domain |
|
||||
| `PLib.Infrastructure` | EF Core + SQLite, ffmpeg, файловая система | Application |
|
||||
| `PLib.Desktop` | Avalonia, ViewModel'и, composition root | Infrastructure |
|
||||
|
||||
Ключевые решения:
|
||||
|
||||
- **Сканирование — поток событий.** `ILibraryService.ScanAsync` возвращает
|
||||
`IAsyncEnumerable<LibraryScanEvent>`: карточки появляются по мере находок, а не после
|
||||
завершения всего прохода. Тяжёлая часть (ffprobe + ffmpeg) идёт параллельно через
|
||||
`Parallel.ForEachAsync`, результаты собираются в `Channel` и применяются к сущностям
|
||||
по одному — трекер изменений EF не потокобезопасен.
|
||||
- **Вся работа вне UI-потока.** ViewModel оборачивает конвейер в `Task.Run` и возвращает
|
||||
каждое событие в UI явно через `Dispatcher.UIThread`.
|
||||
- **Превью живут только пока видны.** `AsyncImage` запрашивает битмап при попадании в
|
||||
визуальное дерево и отпускает при выходе; `ThumbnailCache` — LRU на 256 записей с
|
||||
декодированием в нужную ширину. Память зависит от размера окна, а не от размера библиотеки.
|
||||
- **Scope на операцию.** `DbContext` живёт ровно одну операцию — ViewModel берёт
|
||||
`IServiceScopeFactory` и создаёт scope на каждый вызов.
|
||||
|
||||
## Данные
|
||||
|
||||
Всё пользовательское лежит в `%LOCALAPPDATA%\PLib`:
|
||||
|
||||
- `library.db` — SQLite с метаданными;
|
||||
- `thumbnails/` — кэш постеров (ключ = путь + размер + время изменения файла);
|
||||
- `settings.json` — список папок, перечитывается на лету;
|
||||
- `logs/` — Serilog, ротация по дням.
|
||||
|
||||
Схема создаётся через `EnsureCreated`. Когда форма таблицы устоится — заменить на
|
||||
миграции EF Core (`DatabaseInitializer` — единственное место, которое надо будет тронуть).
|
||||
|
||||
Reference in New Issue
Block a user