|
@@ -0,0 +1,74 @@
|
|
|
|
|
+# Video Note Extractor — Design Spec
|
|
|
|
|
+
|
|
|
|
|
+## Purpose
|
|
|
|
|
+
|
|
|
|
|
+Extract timed text transcripts and single-frame screenshots from tutorial video
|
|
|
|
|
+directories, for use in AI-assisted markdown note writing. Targeted at STM32 /
|
|
|
|
|
+embedded tutorial collections, but intentionally collection-agnostic.
|
|
|
|
|
+
|
|
|
|
|
+## Commands
|
|
|
|
|
+
|
|
|
|
|
+### `parse` — Extract timed text from subtitle files
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+python tools/extract.py parse <input> [--outdir <dir>]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+- **input**: path to a single `.mp4` file, or a **directory** containing `.mp4`
|
|
|
|
|
+ files (scans recursively).
|
|
|
|
|
+- **outdir**: output root. Default `./transcripts/`.
|
|
|
|
|
+
|
|
|
|
|
+**Output structure** (mirrors input directory layout):
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+<outdir>/
|
|
|
|
|
+└── transcripts/
|
|
|
|
|
+ └── <collection-name>/
|
|
|
|
|
+ └── <video-name>.txt
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Each `.txt` file contains lines of:
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+[HH:MM:SS.mmm] <subtitle text>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### `frame` — Extract a single frame as JPEG
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+python tools/extract.py frame <video> <timestamp> --outpath <path>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+- **video**: path to `.mp4` file.
|
|
|
|
|
+- **timestamp**: `HH:MM:SS` or `SSS` (seconds).
|
|
|
|
|
+- **outpath**: where to write the JPEG image (parent directory created
|
|
|
|
|
+ automatically).
|
|
|
|
|
+
|
|
|
|
|
+## Subtitle resolution priority
|
|
|
|
|
+
|
|
|
|
|
+For each `.mp4`, find the best-matching subtitle file:
|
|
|
|
|
+
|
|
|
|
|
+1. Same basename + `.srt`, excluding `_英文.srt` / `_English.srt`.
|
|
|
|
|
+2. Same basename + `.ass` (parse `[Events]` → `Dialogue` lines, strip ASS
|
|
|
|
|
+ override tags like `{\\fn...}`).
|
|
|
|
|
+3. Neither → print warning, skip.
|
|
|
|
|
+
|
|
|
|
|
+## Dependencies
|
|
|
|
|
+
|
|
|
|
|
+- Python ≥ 3.10 (stdlib only for `parse`)
|
|
|
|
|
+- `ffmpeg` / `ffprobe` on PATH (only for `frame`)
|
|
|
|
|
+
|
|
|
|
|
+## Anti-goals (explicitly out of scope)
|
|
|
|
|
+
|
|
|
|
|
+- No VAD / Silero / ONNX integration.
|
|
|
|
|
+- No ASR / API calls.
|
|
|
|
|
+- No batch screenshot extraction.
|
|
|
|
|
+- No markdown generation — the output `.txt` files are consumed by a human or
|
|
|
|
|
+ AI note-writer.
|
|
|
|
|
+
|
|
|
|
|
+## Usage flow (intended)
|
|
|
|
|
+
|
|
|
|
|
+1. `python tools/extract.py parse <collection-dir> --outdir ./transcripts`
|
|
|
|
|
+2. Read `.txt` files → decide which timestamps need screenshots.
|
|
|
|
|
+3. `python tools/extract.py frame <video> <ts> --outpath <notes>/assets/<name>.jpg`
|
|
|
|
|
+4. Write markdown notes, embedding relevant screenshots.
|