[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-78111":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":9,"pushedAt":9,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":15,"starSnapshotCount":15,"syncStatus":29,"lastSyncTime":30,"discoverSource":31},78111,"framedex","Simbastack-hq\u002Fframedex","Simbastack-hq","Framedex — a queryable knowledge base for your video archive",null,"Python",325,21,111,6,0,1,13,127,7,4.03,"MIT License",false,"main",true,[],"2026-06-12 02:03:46","# framedex\n\n**A queryable knowledge base for your video archive.**\n\nTurn a scattered video archive — across multiple SSDs and years — into a portable, plain-text knowledge base. Each clip gets a `.description.md` sidecar with GPS location + place name, a speaker-diarized multilingual transcript, an English translation (if needed), face detection, and an AI vision scene description with a keep\u002Freview\u002Fcull rating.\n\nSidecars live next to the videos. Originals are never modified. Local-first, non-destructive, resumable.\n\nframedex is a [Claude Code](https:\u002F\u002Fdocs.claude.com\u002Fen\u002Fdocs\u002Fclaude-code) skill. It installs the `fdx` command-line tool.\n\n## Install\n\n```bash\n# Clone into your Claude Code skills directory\ngit clone git@github.com:Simbastack-hq\u002Fframedex.git ~\u002F.claude\u002Fskills\u002Fframedex\ncd ~\u002F.claude\u002Fskills\u002Fframedex\n\n# Install Python deps (editable — changes take effect immediately)\nuv pip install -e .\n\n# Verify system binaries + pre-download models\npython3 scripts\u002Fsetup.py\n```\n\n## Quick start\n\n```bash\n# 1. Get a Hugging Face token + accept pyannote terms (one-time, for diarization)\n#    https:\u002F\u002Fhuggingface.co\u002Fpyannote\u002Fspeaker-diarization-3.1   (click Agree)\n#    https:\u002F\u002Fhuggingface.co\u002Fpyannote\u002Fsegmentation-3.0          (click Agree)\n#    https:\u002F\u002Fhuggingface.co\u002Fsettings\u002Ftokens                    (create read token)\nexport HF_TOKEN=hf_yourTokenHere\n\n# 2. (Optional) Set an Anthropic API key — only needed for --backend api\nexport ANTHROPIC_API_KEY=sk-ant-...\n\n# 3. Commands are on PATH after editable install. Use fdx, fdx-summary, fdx-master, fdx-query.\n\n# 4. Test on 5 clips before unleashing on a full drive\nfdx \u002FVolumes\u002FSSD-2024 --max-files 5\n\n# 5. Inspect the sidecars. If happy, run the full drive.\nfdx \u002FVolumes\u002FSSD-2024\n\n# 6. After indexing, generate folder summaries + a master index\nfdx-summary \u002FVolumes\u002FSSD-2024\nfdx-master  \u002FVolumes\u002FSSD-2024\n```\n\n## Per-clip pipeline\n\n1. `ffprobe` → metadata (duration, codec, resolution, creation date)\n2. `exiftool` → GPS lat\u002Flon\u002Faltitude\n3. Nominatim → reverse-geocoded place name (rate-limited 1\u002Fsec, polite UA)\n4. `ffmpeg` → 5 evenly-spaced JPEG frames (≤1920px wide)\n5. `ffmpeg` → mono 16k WAV\n6. WhisperX → Whisper transcribe + word-level alignment + pyannote diarization\n7. WhisperX translate mode → English translation (non-English only)\n8. `insightface` → face detection + 512-dim embeddings on the same frames\n9. Vision model → single-call structured description (Scene\u002FSubjects\u002FAction\u002FMood\u002FShot type\u002FUse cases) + keep\u002Freview\u002Fcull rating\n10. Write `[filename].description.md` next to the video\n\n## What sidecars look like\n\n```markdown\n---\nfile: IMG_4827.mov\npath: 2024-08-construction\u002Fdrone\u002FIMG_4827.mov\nparent_folder: drone\nduration_seconds: 12.3\nresolution: 3840x2160\ncodec: hvc1\nsize_bytes: 245678912\ncreation_time: 2024-08-14T07:23:11Z\nlocation:\n  lat: 37.7456\n  lon: -119.5936\n  altitude_m: 1842.5\n  place: \"Yosemite Valley, Mariposa County, USA\"\nlanguage_detected: es\nspeaker_count: 2\nrating: keep\nindexed_at: 2026-05-17T14:32:01\n---\n\n# IMG_4827.mov\n\n## Description\n\n**Scene:** Wide drone aerial of a construction site at golden hour...\n**Subjects:** Three workers in high-vis vests near a partially-built structure...\n**Action:** Drone slowly orbits; workers carry materials between two structures.\n**Mood:** Industrious, expansive, hopeful.\n**Shot type:** Drone aerial, slow orbit.\n**Use cases:**\n- Construction milestone post\n- \"From the ground up\" origin-story reel\n- B-roll behind a voiceover\n\n## Transcript (es, 2 speakers)\n\n[SPEAKER_00] (00:00:01) Pon esta viga aquí primero.\n[SPEAKER_01] (00:00:04) Sí, vale.\n[SPEAKER_00] (00:00:07) Cuidado con el ángulo.\n\n## English translation\n\nPlace this beam here first. Yes, OK. Careful with the angle.\n```\n\n## Optional folder context\n\nDrop `.video-context.md` at the root of any scan target to give the vision model better priors:\n\n```\n\u002FVolumes\u002FSSD-2024\u002F.video-context.md\n---\nThis drive contains construction-site footage, 2023-2026. Many clips\nare drone aerials, crew training, and site walkthroughs. Languages mix\nEnglish and Spanish.\n---\n```\n\nWithout it, descriptions are generic.\n\n### Proper-noun biasing\n\nA `.video-context.md` can also carry a line of names Whisper should spell correctly:\n\n```\n**Whisper proper nouns:** Yosemite, El Capitan, Half Dome, ...\n```\n\nThese get passed to Whisper as `initial_prompt` + `hotwords` so place names and people names in speech don't come back garbled. A second regex pass (`~\u002F.framedex\u002Fwhisper_fixes.json`) catches anything the prompt bias misses.\n\n## Multiple SSDs\n\nRun on each drive separately:\n\n```bash\nfdx \u002FVolumes\u002FSSD-2023\nfdx \u002FVolumes\u002FSSD-2024\nfdx \u002FVolumes\u002FSSD-2025\n```\n\nEach drive ends up self-contained with its own sidecars + `_INDEX.json`. Knowledge travels with the data. The face DB at `~\u002F.framedex\u002Ffaces.db` is centralized so cross-drive person queries work.\n\n## Common flags\n\n| Flag | Purpose |\n|---|---|\n| `--dry-run` | Show what would be processed; no API\u002Fmodel calls |\n| `--max-files N` | Stop after N clips (testing) |\n| `--force` | Re-process clips even if a sidecar exists |\n| `--whisper-model large-v3` | Higher quality, slower (default is large-v3-turbo) |\n| `--no-diarize` | Skip speaker diarization (faster; no HF_TOKEN needed) |\n| `--no-faces` | Skip face detection + embeddings |\n| `--no-geocode` | Skip Nominatim reverse geocoding (GPS still recorded) |\n| `--max-duration MINUTES` | Skip clips longer than N minutes (default: 30; 0 = no limit) |\n| `--exclude PATTERN` | Skip paths matching substring (repeatable) |\n| `--backend cli\\|api\\|local` | Vision backend (see below) |\n| `--vision-model haiku\\|sonnet` | Claude model for `cli`\u002F`api`. Default `haiku` |\n| `--local-base-url URL` | Override LM Studio endpoint (default `http:\u002F\u002Flocalhost:1234\u002Fv1`) |\n| `--local-model NAME` | Specify which loaded model to use when LM Studio has multiple |\n| `--no-whisper-prompt` | Disable proper-noun biasing |\n| `--whisper-fixes PATH` | Override the canonical-name regex fixes file |\n\n## Vision backends\n\n| Backend | What it uses | Speed | Cost | Privacy |\n|---|---|---|---|---|\n| `cli` (default) | `claude -p` via a Claude Max subscription | ~10-30s\u002Fclip | $0 marginal | Frames sent to Anthropic |\n| `api` | Anthropic SDK with an API key | ~2-3s\u002Fclip | ~$0.002\u002Fclip (Haiku) | Frames sent to Anthropic |\n| `local` | LM Studio (or any OpenAI-compatible server) | ~3-90s\u002Fclip | $0 | Fully local, fully offline |\n\nFor huge archives, `api` is fastest. For routine indexing on a Max plan, `cli` is free. For full privacy, `local` keeps everything on-device.\n\n## Privacy\n\n| Component | Local or cloud? |\n|---|---|\n| ffmpeg, exiftool, Whisper, pyannote, insightface | Local |\n| Nominatim reverse geocode | Cloud — sends lat\u002Flon only, never video. Skip with `--no-geocode` |\n| Vision (`--backend cli`\u002F`api`) | Cloud — sends 5 JPEG frames + a transcript snippet per clip |\n| Vision (`--backend local`) | Fully local |\n| Face DB (`~\u002F.framedex\u002Ffaces.db`) | Local only, never uploaded |\n\n## Languages\n\nWhisper supports 99 languages with auto-detection. For non-English clips the script automatically runs a second translate-mode pass and stores the English version alongside the original transcript. For best quality on important non-English footage:\n\n```bash\nfdx \u002FVolumes\u002FSSD-2024 --whisper-model large-v3 --force\n```\n\n## Speaker diarization\n\nWhisperX uses `pyannote\u002Fspeaker-diarization-3.1` under the hood. First-time setup requires:\n\n1. A Hugging Face account + read token (`HF_TOKEN` env var)\n2. Clicking \"Agree\" on both pyannote model pages (linked in Quick start)\n\nIf `HF_TOKEN` is missing, the script logs a notice and continues without diarization. Transcripts still work; they just won't have speaker labels.\n\n## Resumable + idempotent\n\nAlready-indexed clips are skipped on re-runs (a sidecar existing = done). Ctrl-C any time; a restart picks up where it stopped. `--force` regenerates everything.\n\n## Troubleshooting\n\n**\"Missing dependency: whisperx\"** — Run `setup.py`.\n\n**\"Failed to load diarization pipeline\"** — You didn't accept the pyannote model terms on Hugging Face. Visit the two model pages, click Agree, then re-run.\n\n**Whisper model download stalls** — `setup.py --skip-model-download`, then `index_videos.py` downloads on first use. Make sure you have disk space (~3GB for large-v3, ~1.5GB for turbo).\n\n**\"No GPS data in this file\"** — Many clips don't have GPS metadata. The script handles this silently — the frontmatter just omits the location block.\n\n**Apple Silicon GPU not used** — CTranslate2 (via WhisperX) currently runs on CPU on M-series Macs. For archive indexing, CPU is plenty fast (10-30× realtime).\n\n## Companion tools\n\n| Command | Script | Purpose |\n|---|---|---|\n| `fdx` | `index_videos.py` | Main indexer |\n| `fdx-summary` | `trip_summary.py` | Recursive per-folder summaries |\n| `fdx-master` | `master_index.py` | Drive-level `_INDEX.md` + `_INDEX.json` |\n| `fdx-query` | `query.py` | Filter sidecars by rating, lighting, person, keyword, location, language |\n\n```bash\nfdx-query \u002FVolumes\u002FSSD-2024 --rating keep --time-of-day golden_hour\nfdx-query \u002FVolumes\u002FSSD-2024 --rating cull                  # the cull pile\nfdx-query \u002FVolumes\u002FSSD-2024 --keyword drone --keyword landscape\nfdx-query \u002FVolumes\u002FSSD-2024 --place-contains California --language es\n```\n\n## Known limitations\n\n- Frame sampling is evenly-spaced, not scene-detected\n- pyannote diarization degrades on heavy ambient noise (wind, music, crowd)\n- WhisperX runs on CPU on Apple Silicon\n- Face cluster IDs are temporary hashes until the `fdx-faces` labeling tool ships — embeddings are captured now, so no re-indexing will be needed\n- RAW photo support not yet (videos only)\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","Framedex 是一个可查询的知识库，用于管理和检索视频档案。它通过为每个视频生成包含GPS位置、多语言转录本、英文翻译（如需要）、面部识别以及AI视觉场景描述的`.description.md`侧边文件，将分散在多个SSD上的视频转换成易于查询的形式。此外，Framedex 提供了非破坏性的本地优先处理方式，确保原始文件不被修改。该工具特别适合需要对大量视频内容进行组织、搜索和分析的场景，比如个人或企业视频档案管理。基于Python开发，并作为Claude Code的一个技能存在，用户可以通过命令行轻松安装与使用。",2,"2026-06-11 03:56:28","CREATED_QUERY"]