124 lines
11 KiB
Markdown
124 lines
11 KiB
Markdown
## Purpose And Scope
|
|
|
|
- Project name: FFX
|
|
- User problem: TV episode files from mixed sources arrive with inconsistent codecs, stream metadata, subtitle layouts, season and episode numbering, and output filenames, which makes them awkward to archive and use in media-player applications.
|
|
- Target users: Individual operators curating a local TV media library on a workstation, especially users willing to define normalization rules per show.
|
|
- Success outcome: A user can inspect source files, define reusable show and pattern rules, and produce output files whose streams, metadata, and filenames follow a predictable schema for web playback and library import.
|
|
- Out of scope:
|
|
- Multi-user or hosted service workflows.
|
|
- General movie-library management.
|
|
- Distributed transcoding or remote job orchestration.
|
|
- Broad media-server administration beyond file preparation.
|
|
|
|
## Required Product
|
|
|
|
- Deliverable type: Installable Python command-line application with a Textual terminal UI for inspection and rule editing.
|
|
- Core capabilities:
|
|
- Maintain an SQLite-backed database of shows, filename-matching patterns, per-pattern stream layouts and metadata tags, and optional season-shift rules.
|
|
- Inspect existing media files through `ffprobe` and compare discovered stream metadata with stored normalization rules.
|
|
- Convert media files through `ffmpeg` into a normalized output layout, including video recoding, audio transcoding to Opus, metadata cleanup and rewrite, and controlled disposition flags.
|
|
- Build output filenames from detected or configured show, season, and episode information, optionally enriched from TMDB and a configurable Jinja-style filename template.
|
|
- Support auxiliary file operations such as subtitle import, unmuxing, crop detection, rename-only conversion runs, and direct in-place episode renaming.
|
|
- Supported environments:
|
|
- Local execution on a Python-capable workstation.
|
|
- Best-supported on Linux-like systems because the implementation assumes `~/.local`, `/dev/null`, `nice`, and `cpulimit`.
|
|
- Requires `ffmpeg`, `ffprobe`, and `cpulimit` on `PATH`.
|
|
- Operational owner: The local user running the tool and maintaining its config, database, and external tooling.
|
|
|
|
## Suggested User Stories
|
|
|
|
- As a library maintainer, I want to define show-specific matching rules once so that future source files can be normalized automatically.
|
|
- As an operator, I want to inspect a file before conversion so that I can compare its actual streams and tags against the stored target schema.
|
|
- As a user preparing web-playback files, I want to recode video and audio with a small set of predictable options so that results are compatible and consistently named.
|
|
- As a user dealing with nonstandard releases, I want CLI overrides for language, title, stream order, default and forced tracks, and season and episode data so that one-off fixes do not require database edits first.
|
|
- As a user importing anime or other shifted numbering schemes, I want season and episode offsets at the show level with optional pattern-specific overrides so that generated filenames align with TMDB and media-library expectations.
|
|
|
|
## Functional Requirements
|
|
|
|
- The system shall provide a CLI entrypoint named `ffx` with commands for `convert`, `inspect`, `shows`, `rename`, `unmux`, `cropdetect`, `setup`, `configure_workstation`, `upgrade`, `version`, and `help`.
|
|
- The system shall support a two-step local installation and preparation flow:
|
|
- `tools/setup.sh` is the bootstrap entrypoint for the first step and shall own bundle virtualenv creation, package installation, shell alias exposure, and optional Python test-package installation.
|
|
- `tools/configure_workstation.sh` is the bootstrap entrypoint for the second step and shall own workstation dependency checks and installation plus local config and directory seeding.
|
|
- After the bundle is installed, `ffx setup` and `ffx configure_workstation` shall remain aligned wrapper entrypoints for those same two steps.
|
|
- The CLI command `ffx setup` shall act as a wrapper for the first-step bundle-preparation flow in `tools/setup.sh`.
|
|
- The CLI command `ffx configure_workstation` shall act as a wrapper for the second-step preparation flow in `tools/configure_workstation.sh`.
|
|
- The system shall persist reusable normalization rules in SQLite for:
|
|
- shows and show formatting digits,
|
|
- optional show-level quality defaults,
|
|
- regex-based filename patterns,
|
|
- per-pattern media tags,
|
|
- per-pattern stream definitions,
|
|
- show-level and pattern-level shifted-season mappings,
|
|
- internal database version properties.
|
|
- The system shall apply supported ordered database migrations automatically when opening an older local database file and shall fail fast when no supported path exists.
|
|
- Before applying a required database migration, the system shall show the current version, target version, required sequential steps, and whether each corresponding migration module is present, then require user confirmation.
|
|
- Before applying a confirmed file-backed database migration, the system shall create an in-place backup copy whose filename includes the covered version range.
|
|
- Detailed show, pattern, and duplicate-match management rules live in `requirements/pattern_management.md`.
|
|
- The system shall inspect source media using `ffprobe` and derive a structured description of container metadata and streams.
|
|
- The system shall optionally open a Textual UI to browse shows, inspect files, and create, edit, or delete shows, patterns, stream definitions, tags, and shifted-season rules.
|
|
- The system shall match filenames against stored regex patterns to decide whether an input file should inherit a target stream and metadata schema.
|
|
- The system shall convert supported input files (`mkv`, `mp4`, `avi`, `flv`, `webm`) with `ffmpeg`, supporting at least:
|
|
- VP9, AV1, and H.264 video encoding,
|
|
- Opus audio encoding with bitrate selection based on channel layout,
|
|
- metadata and disposition rewriting,
|
|
- optional crop detection and crop application,
|
|
- optional deinterlacing and denoising,
|
|
- optional subtitle import from external files,
|
|
- rename-only move mode.
|
|
- The system shall support optional TMDB lookups to resolve show names, years, and episode titles when a show ID, season, and episode are available.
|
|
- The system shall generate output filenames from show metadata, season and episode indices, and episode names using the configured filename template.
|
|
- The system shall allow CLI overrides for stream languages, stream titles, default and forced tracks, stream order, TMDB show and episode data, output directory, label prefix, and processing resource limits.
|
|
- The system shall resolve encoding quality by precedence `CLI override -> pattern -> show -> encoder default` and shall report the chosen value and source.
|
|
- The system shall resolve season shifting by precedence `pattern -> show -> identity default` and shall report the chosen mapping and source.
|
|
- Processing resource limit rules:
|
|
- `--nice` shall accept niceness values from `-20` through `19`; omitting the option shall disable niceness adjustment.
|
|
- `--cpu` shall accept either a positive absolute `cpulimit` value such as `200`, or a percentage suffixed with `%` such as `25%` to represent a share of present CPUs; omitting the option or using `0` shall disable CPU limiting.
|
|
- When both limits are configured, the process wrapper shall execute the target command through `cpulimit` around a `nice -n ...` invocation so both limits apply to the launched media command.
|
|
- The system shall support extracting streams into separate files via `unmux` and reporting suggested crop parameters via `cropdetect`.
|
|
- The system shall support in-place episode renaming via `rename`, requiring a `--prefix`, accepting optional `--season` and `--suffix` overrides, preserving the source extension, and supporting dry-run output without moving files.
|
|
- Crop detection shall use a configurable sampling window, defaulting to a 60-second seek and a 180-second analysis duration, and repeated crop-detection requests for the same source plus sampling window shall reuse cached results within one process.
|
|
- The system shall handle invalid input and system failures gracefully by logging warnings or raising `click` errors for missing files, invalid media, missing TMDB credentials, incompatible database versions, and ambiguous track dispositions when prompting is disabled.
|
|
|
|
## Quality Requirements
|
|
|
|
- The system should stay understandable as a small local tool: controllers, descriptors, models, and screens should remain separate enough for contributors to trace a workflow end to end.
|
|
- The system should produce predictable output for the same database rules, CLI overrides, and source files.
|
|
- The system should preserve a lightweight operational footprint: local SQLite state, local log file, no mandatory background services.
|
|
- The system should be testable through modern automatically discovered tests and through remaining legacy harness coverage during migration.
|
|
- The system should expose enough logging to diagnose failed probes, failed conversions, and rule mismatches without requiring a debugger.
|
|
|
|
## Constraints And Assumptions
|
|
|
|
- Technology constraints:
|
|
- Python package built with setuptools.
|
|
- Primary libraries: `click`, `textual`, `sqlalchemy`, `jinja2`, `requests`.
|
|
- Conversion and inspection rely on external executables rather than pure-Python media libraries.
|
|
- Hosting or infrastructure constraints:
|
|
- Intended for local execution, not server deployment.
|
|
- Stores default state in `~/.local/etc/ffx.json`, `~/.local/var/ffx/ffx.db`, and `~/.local/var/log/ffx.log`.
|
|
- Timeline constraints:
|
|
- The current implemented scope reflects a compact alpha release stream up to version `0.2.4`.
|
|
- Team capacity assumptions:
|
|
- Maintained as a small codebase where simple patterns and direct controller logic are preferred over framework-heavy abstractions.
|
|
- Third-party dependencies:
|
|
- `ffmpeg`, `ffprobe`, and `cpulimit`.
|
|
- TMDB API access through `TMDB_API_KEY` for metadata enrichment.
|
|
- Installation assumptions:
|
|
- The Python-side bundle install step and optional Python test extras are managed by `tools/setup.sh`, with `ffx setup` as the aligned wrapper after bootstrap.
|
|
- The workstation-preparation step is managed separately by `tools/configure_workstation.sh` or `ffx configure_workstation`.
|
|
|
|
## Acceptance Scope
|
|
|
|
- First release boundary:
|
|
- Local installation through `pip`.
|
|
- Working SQLite-backed rule storage.
|
|
- Functional CLI conversion and inspection workflows.
|
|
- Textual CRUD flows for shows, patterns, tags, tracks, and shifted seasons.
|
|
- TMDB-assisted filename generation, subtitle import, season shifting, database versioning, and configurable output filename templating.
|
|
- Excluded follow-up ideas:
|
|
- Completing placeholder screens such as settings and help.
|
|
- Hardening platform portability beyond Linux-like systems.
|
|
- Broader media types, richer release packaging, and production-grade background processing.
|
|
- Demonstration scenario:
|
|
- Inspect a TV episode file, define or update the matching show and pattern in the TUI, then run `ffx convert` so the result uses the stored stream schema, optional TMDB episode naming, and a normalized output filename.
|