Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
# OpenSpec Change: enterprise-video-thumbnails
- **Change ID**: `enterprise-video-thumbnails`
- **Package**: `@suaveplan/video-thumbnails`
- **Category**: `media` / **Plugin**: `video`
- **Target path**: `packages/media/video/video-thumbnails`
- **Status**: PROPOSED
- **Date**: 2026-05-25
- **Design**: ./design.md
- **Spec delta**: ./specs/video-thumbnails/spec.md
- **Upstream**: [`../suaveplan/packages/universal/video-thumbnails`](/mnt/s/web/suaveplan/packages/universal/video-thumbnails)
- **Enterprise audit**: [`../suaveplan/enterprise/video-thumbnails.md`](/mnt/s/web/suaveplan/enterprise/video-thumbnails.md)
## Summary
Migrate `@suaveplan/video-thumbnails` from main into the genesis monorepo at enterprise quality. The package generates video thumbnails (single-frame extraction at arbitrary timestamps, batched time-based extracts, sliding-window sampling) and sprite sheets (NxM grid via ffmpeg `tile` filter) over JPEG/PNG/WebP outputs, on top of an injectable `FfmpegRunner` and the bundled `@ffmpeg-installer/ffmpeg` binary surfaced through `fluent-ffmpeg`. The migration adds OTel histograms/counters, structured `VideoThumbnailsError` (extends `SuaveplanError`) codes via `defineCodes`, Zod-validated option boundaries, `AbortSignal` propagation, a sliding-window extractor that upstream lacked, and 100/100/100/100 coverage using real fixture videos generated on-the-fly with ffmpeg (no mocks).
## Parity Checklist
| Capability | Upstream | Migrated | Notes |
|---|---|---|---|
| Single-frame extract `ThumbnailGenerator.generate` | ✅ | ✅ | Same `timestamp`, `fit`, `outputDir`, `format`, `quality` semantics. |
| Multi-timestamp extract `generateMultiple` | ✅ | ✅ | `AbortSignal`-aware. |
| `getMetadata` via ffprobe | ✅ | ✅ | Through `FfmpegRunner.probe`. |
| `isAvailable()` | ✅ | ✅ | Through `runner.isAvailable()`. |
| Sprite-sheet `SpriteSheetGenerator.generate` | ✅ | ✅ | Same N×M tile algorithm; auto-detect duration. |
| `CommandExecutor` injection | ✅ | ⬆️ | Replaced with the stronger `FfmpegRunner` interface (typed `extract`, `tile`, `probe`, `isAvailable`); default = `FluentFfmpegRunner`. |
| Error codes `THUMBNAIL_*` | ✅ | ⬆️ | Re-issued under `VIDEO_THUMBNAILS.*` namespace via `defineCodes`. Added: `RUNNER_UNAVAILABLE`, `INVALID_TIMESTAMP`, `INVALID_OPTIONS`, `ABORTED`. |
| Sliding-window extraction | 🚫 | ⬆️ | New `extractSlidingWindow(count, durationSeconds)` evenly samples N frames. |
| OTel counters + histograms | 🚫 | ⬆️ | `video_thumbnails.extract.duration_ms`, `extract.total{outcome,format}`, `sprite_sheet.duration_ms`, `sprite_sheet.frames`. |
| Zod option validation | 🚫 | ⬆️ | All public surfaces validate at the boundary. |
| `AbortSignal` propagation | 🚫 | ⬆️ | Threaded through `FfmpegRunner` (kills the child process). |
| Output jpeg / png / webp | partial | ✅ | All three exercised against real ffmpeg + fixtures. |
| 100/100/100/100 coverage | 🚫 | ✅ | Vitest istanbul, no mocks, real fixtures. |
## Current-state audit (genesis)
Package does not exist on `genesis`. Status: `–` in `STATUS.md`. Direct upstream consumers in genesis: none. The `video` plugin is added to the `media` super-category in `scripts/folder-reorg/assignment.yml` as part of this change (the closed-vocabulary supercategory list is unchanged).
## Dependencies
- Workspace: `@suaveplan/error`
- External (via catalog `audio`): `fluent-ffmpeg`, `@ffmpeg-installer/ffmpeg`, `@types/fluent-ffmpeg`
- External (other catalogs): `tslib` (`build`), `zod` (`forms`), `@opentelemetry/api` (`observability`)
- Dev: `@suaveplan/testing` (`workspace:^`), `vitest` + `@vitest/coverage-istanbul` (`testing`)
## Impact
- Adds package `packages/media/video/video-thumbnails`.
- Adds spec capability `video-thumbnails`.
- Adds `video` plugin to the `media` super-category in `scripts/folder-reorg/assignment.yml`.
### Affected dependents
None — fresh genesis migration, no existing consumers.