[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-83164":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":16,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":17,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":20,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":38,"readmeContent":39,"aiSummary":40,"trendingCount":15,"starSnapshotCount":15,"syncStatus":41,"lastSyncTime":42,"discoverSource":43},83164,"echocut","BillLucky\u002Fechocut","BillLucky","Turn raw footage into brand-ready, platform-optimized video with one command. Local-first: FFmpeg + WhisperX\u002FMLX + Ollama.","https:\u002F\u002Fgithub.com\u002FBillLucky\u002Fechocut",null,"JavaScript",60,14,51,0,9,1,3.53,"Apache License 2.0",false,"main",[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"asr","captions","cli","ffmpeg","llm","local-first","media","ollama","pipeline","subtitles","video","video-cut-tool","video-editing","whisper","workflow","2026-06-12 02:04:31","# echocut\n\n> **English** | [简体中文](README.zh-CN.md)\n\n[![CI](https:\u002F\u002Fgithub.com\u002FBillLucky\u002Fechocut\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002FBillLucky\u002Fechocut\u002Factions\u002Fworkflows\u002Fci.yml)\n[![License: Apache-2.0](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-Apache_2.0-blue.svg)](LICENSE)\n[![Node](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fnode-%3E%3D18-brightgreen.svg)](https:\u002F\u002Fnodejs.org)\n[![PRs welcome](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FPRs-welcome-brightgreen.svg)](CONTRIBUTING.md)\n\n**Turn raw footage into brand-ready, platform-optimized video — with one command.**\n\n`echocut` is a **local-first** video CLI. Point it at a video and it transcribes the\nspeech, burns in big readable subtitles, adds your brand band + cover, optionally cuts\nfillers\u002Fsilence, slices highlights, and writes a multi-platform publish kit — all on\nyour own machine. No cloud upload, no editor, no timeline.\n\n```bash\nechocut burn talk.mp4 --cut-fillers\n# → talk_burn.mp4  (subtitles + title + brand band + cover + fade)  +  cover.jpg  +  subtitles.srt  +  publish.md\n```\n\n## ✨ Features\n\n| | |\n|---|---|\n| 🎬 | **Subtitle burn-in** — word-level ASR (WhisperX cross-platform; Qwen3\u002FMLX on Apple Silicon), large readable captions, your `@brand` capsule on every frame |\n| 🖼️ | **Brand cover** as first frame + smooth fade-out + end CTA card |\n| ✂️ | **Filler \u002F silence cutting** at the video-track level (removes \"um\" and dead air — video, audio and subtitles stay in sync) |\n| 🎯 | **Highlights** — slice a long video into shareable clips |\n| 📐 | **Any aspect ratio** — vertical \u002F landscape \u002F square \u002F 4:3 auto-fit; **`--obs`** mode for face-on-top + screen-below recordings |\n| 📤 | **Publish kit** — titles + descriptions + hashtags for multiple platforms |\n| 🌏 | **Multi-brand** — every brand is one JSON file |\n| ⚡ | **Built for long videos** — chunked transcription with resume, cross-run transcript cache, hardware encode\u002Fdecode on Apple Silicon |\n\n## 🚀 Quickstart\n\n### 1. Prerequisites\n\n| Dependency | Why | Install |\n|---|---|---|\n| **Node.js 18+** | the CLI | \u003Chttps:\u002F\u002Fnodejs.org> |\n| **Python 3.11+** | speech-to-text | \u003Chttps:\u002F\u002Fpython.org> |\n| **FFmpeg** | video\u002Faudio processing | `brew install ffmpeg` · `apt install ffmpeg` |\n| **Ollama** | local LLM (titles, caption fixes) | \u003Chttps:\u002F\u002Follama.com> → `ollama pull qwen3.5:9b` |\n\n> **Platform:** works cross-platform via **WhisperX** (CPU or CUDA). The fastest ASR\n> (`qwen3`, `mlx`) is **Apple Silicon only** and falls back to WhisperX elsewhere.\n> Video encoding uses hardware acceleration on Mac and software `libx264` elsewhere\n> (correct, just slower) — see [Troubleshooting](docs\u002FTROUBLESHOOTING.md#cross-platform-expectations--跨平台说明).\n\n### 2. Install\n\n#### Quickstart — macOS (Apple Silicon)\n\nOn a Mac (M1\u002FM2\u002FM3\u002FM4), one idempotent script installs everything — Homebrew, FFmpeg,\nNode, the Python ASR stack, fonts and the CLI:\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002F\u003Cyou>\u002Fechocut.git && cd echocut\nbash scripts\u002Fsetup-macos.sh                  # idempotent — safe to re-run\nUSE_CN_MIRROR=1 bash scripts\u002Fsetup-macos.sh  # mainland China — use domestic mirrors\n```\n\nTwo gotchas the script handles for you (mind them if you install by hand): FFmpeg must be\n**`ffmpeg-full`**, not the slim `ffmpeg` (the slim build has no libass → subtitle burn-in\nfails), and Node must be the LTS **`node@22`**, not the latest (better-sqlite3 has no\nprebuilt binary for bleeding-edge Node). Full details, mirrors and troubleshooting:\n**[docs\u002FINSTALL-MACOS.md](docs\u002FINSTALL-MACOS.md)**.\n\n#### Manual install (any platform)\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002F\u003Cyou>\u002Fechocut.git && cd echocut\nnpm install                                                  # Node deps + CLI\npython3 -m venv .venv && .venv\u002Fbin\u002Fpip install -r requirements.txt   # Python ASR\nnpm run fetch-fonts                                          # download default CJK font (Noto Sans SC, OFL)\ncp .env.example .env                                         # optional keys (proxy, MiniMax, …)\nnpm link                                                     # register the `echocut` command\nechocut doctor                                               # environment self-check\n```\n\n### 3. Make your first video\n\n```bash\n# Subtitles + title + brand band + cover + publish kit\nechocut burn \u002Fpath\u002Fto\u002Fvideo.mp4 --cut-fillers\n\n# OBS screen recording (face on top, screen below) — face stays visible, compact title\nechocut burn \u002Fpath\u002Fto\u002Fobs.mov --obs --headline \"Title\" --subline \"Subtitle\"\n\n# Long landscape tutorial — stays full-screen landscape, readable\nechocut burn \u002Fpath\u002Fto\u002Ftutorial.mp4 --no-title\n\n# Slice a long video into highlight clips\nechocut highlights \u002Fpath\u002Fto\u002Flong.mp4 --segments 4\n```\n\nOutput → `debug_outputs\u002Fvideo\u002F\u003Crun_id>\u002F`: the `*.mp4`, a `*_cover.jpg`, `*.srt`, and `publish.md`.\n\n> Re-rendering the same video reuses the cached transcription instantly. `--fresh`\n> forces a re-transcribe; `--reuse-captions \u003Cfile>` skips transcription + LLM entirely.\n\n## 🎨 Make it yours — brands\n\nEvery brand is one file: `configs\u002Fbrands\u002F\u003Cid>.json` — identity, colors, brand capsule,\nCTA, BGM defaults and the LLM persona. Start from the template:\n\n```bash\ncp configs\u002Fbrands\u002F_template.json configs\u002Fbrands\u002Fmybrand.json\n#  edit name \u002F colors \u002F @handle \u002F CTA …\nechocut burn \u002Fpath\u002Fto\u002Fvideo.mp4 --brand mybrand\n```\n\nSee `configs\u002Fbrands\u002Fexample.json` for a filled-in example and `_README.md` for the field reference.\n\n## 📐 Output layouts\n\nechocut keeps **one frame size per file** and adapts the overlays to the source shape.\nYour `@brand` capsule is drawn on **every** frame — it's your traceable mark.\n\n**Vertical** `9:16` (1080×1920) — the default for talking-head clips:\n\n```\n┌────────────────────────────┐\n│ [@yourhandle]   Headline    │  ← brand capsule (top-left) + title + subline\n│                 Subline     │\n├────────────────────────────┤\n│                             │\n│         video content        │\n│                             │\n│   ┌─────────────────────┐   │\n│   │    BIG  SUBTITLE     │   │  ← large captions, emphasis words highlighted\n│   └─────────────────────┘   │\n└────────────────────────────┘\n   echocut burn clip.mp4 --cut-fillers\n```\n\n**Landscape** `16:9` — full-screen screencasts \u002F tutorials stay landscape (readable):\n\n```\n┌──────────────────────────────────────────┐\n│ [@yourhandle]                              │  ← capsule only (use --no-title)\n│                                            │\n│              video content                 │\n│                                            │\n│   ┌────────────────────────────────────┐  │\n│   │           BIG  SUBTITLE            │  │  ← captions on a bottom band\n│   └────────────────────────────────────┘  │\n└──────────────────────────────────────────┘\n   echocut burn tutorial.mp4 --no-title\n   (cover is exported as a separate .jpg, not prepended)\n```\n\n**OBS** — `--obs` for \"face on top, screen below\" recordings: a compact top band keeps\nthe face visible, with a small title beside the capsule:\n\n```\n┌────────────────────────────┐\n│ [@you]  Small title         │  ← compact band — face below stays visible\n│  ┌──────────────────────┐   │\n│  │      webcam \u002F face    │   │\n│  └──────────────────────┘   │\n│                             │\n│         screen share         │\n│   ┌─────────────────────┐   │\n│   │    BIG  SUBTITLE     │   │\n│   └─────────────────────┘   │\n└────────────────────────────┘\n   echocut burn obs.mov --obs --headline \"Title\"\n```\n\nAny other shape (e.g. 4:3 live-stream) → `--auto-pad` fits it into the target container,\n`--strip-top \u003Cpx>` wipes a top watermark band.\n\n## 🧰 Commands\n\n`echocut` is a toolbox. Full reference + agent-friendly guide: **[docs\u002FCLI.md](docs\u002FCLI.md)**.\nEvery subcommand has live help — `echocut \u003Ccommand> --help` — with examples.\n\n| Group | Commands |\n|---|---|\n| **Video core** | `burn` (transcribe→subtitles→title→brand→cover→publish kit) · `package` (already-edited video → cover+BGM+CTA) · `batch` (a whole folder) |\n| **Long video** | `highlights` (auto-slice N clips) · `hls` (analyze + list segments) · `hmk` (render chosen segments) · `afc` (article from a segment) |\n| **Multi-person** | `panel-clip` (panel → per-speaker clips) · `identity-card` (name\u002Ftitle overlay) |\n| **Marketing** | `distribute` (per-platform packages) · `hook-gen` (5 opening hooks) · `cover` (standalone cover .jpg) · `publish` (upload → signed URL) |\n| **Text** | `article` · `essay` · `translate` · `cross-lang` (zh→en\u002Fja\u002Fes) · `weekly-retro` |\n| **Media \u002F AI** | `music` (BGM) · `minimax` (tts\u002Fimage\u002Fvideo) · `vlog` \u002F `ingest` |\n| **Ops** | `doctor` (self-check) · `studio` (admin UI) · `brand` (list\u002Fshow\u002Fvalidate) |\n\nMost flags live on `burn` — see the [full flag table in docs\u002FCLI.md](docs\u002FCLI.md#5-burn--full-flag-reference)\nfor `--engine`, `--ratio`, `--cut-fillers`, `--golden-hook`, `--reuse-captions`, and more.\n\n## 📚 More\n\n- **CLI reference (agent-friendly):** [docs\u002FCLI.md](docs\u002FCLI.md)\n- **Troubleshooting \u002F FAQ:** [docs\u002FTROUBLESHOOTING.md](docs\u002FTROUBLESHOOTING.md)\n- **ASR engine selection:** [docs\u002FASR-ENGINES.md](docs\u002FASR-ENGINES.md)\n- **Contributing & dev setup:** [CONTRIBUTING.md](CONTRIBUTING.md) · **Roadmap:** [ROADMAP.md](ROADMAP.md)\n- **AI coding tools (Claude Code \u002F Cursor):** [CLAUDE.md](CLAUDE.md) · [AGENTS.md](AGENTS.md)\n- **Changelog:** [CHANGELOG.md](CHANGELOG.md) — **Security:** [SECURITY.md](SECURITY.md)\n- **All commands:** `echocut --help` (every subcommand has `--help` with examples)\n- **简体中文文档:** [README.zh-CN.md](README.zh-CN.md)\n\n## 📄 License\n\n[Apache-2.0](LICENSE). Bundled\u002Fdeclared third-party components keep their own licenses —\nsee [NOTICE](NOTICE). The default font (Noto Sans SC) is downloaded at setup under the\nSIL Open Font License 1.1. The optional Remotion render path is licensed separately and\nis **not** required by the default FFmpeg pipeline.\n","echocut 是一个命令行工具，用于将原始视频转换为适合品牌发布和平台优化的视频。其核心功能包括自动语音识别（ASR）、字幕烧录、品牌水印添加、剪辑填充词与静默片段以及生成多平台发布的配套文件。技术上，echocut 利用 FFmpeg 进行音视频处理，结合 WhisperX 或 MLX 实现精准的语音转文字，并通过 Ollama 提供本地化的语言模型支持以优化字幕和标题。该工具特别适用于需要快速从未经编辑的素材中生成高质量成品视频的内容创作者或营销团队，整个过程无需上传云端，在本地即可完成所有操作，保证了数据的安全性和处理效率。",2,"2026-06-11 04:10:20","CREATED_QUERY"]