{"id":49384876,"url":"https://github.com/sirmews/textcast","last_synced_at":"2026-04-28T08:30:46.237Z","repository":{"id":351785796,"uuid":"1210925879","full_name":"sirmews/textcast","owner":"sirmews","description":"Browser audio recorder with Whisper transcription","archived":false,"fork":false,"pushed_at":"2026-04-23T21:44:37.000Z","size":173,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-23T22:20:54.690Z","etag":null,"topics":["silero","transformers-js","vad","webaudio","webgpu","whisper"],"latest_commit_sha":null,"homepage":"https://textcast-six.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sirmews.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-14T22:36:38.000Z","updated_at":"2026-04-23T21:44:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sirmews/textcast","commit_stats":null,"previous_names":["sirmews/textcast"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sirmews/textcast","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirmews%2Ftextcast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirmews%2Ftextcast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirmews%2Ftextcast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirmews%2Ftextcast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sirmews","download_url":"https://codeload.github.com/sirmews/textcast/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirmews%2Ftextcast/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32373312,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-27T20:07:02.737Z","status":"online","status_checked_at":"2026-04-28T02:00:07.250Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["silero","transformers-js","vad","webaudio","webgpu","whisper"],"created_at":"2026-04-28T08:30:42.788Z","updated_at":"2026-04-28T08:30:46.228Z","avatar_url":"https://github.com/sirmews.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TextCast\n\n![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/sirmews/textcast?utm_source=oss\u0026utm_medium=github\u0026utm_campaign=sirmews%2Ftextcast\u0026labelColor=171717\u0026color=FF570A\u0026link=https%3A%2F%2Fcoderabbit.ai\u0026label=CodeRabbit+Reviews)\n\nEdit audio by editing text. A local-first, browser-based audio editor for podcasters.\n\n## Features\n\n- 🎙️ **Record** - Capture studio-quality PCM audio directly to disk via AudioWorklet + OPFS streaming\n- 🧹 **Clean** - Reduce noise, normalize volume, trim silence with Web Audio API preprocessing\n- 📝 **Transcribe** - Local Whisper transcription (WebGPU-accelerated, falls back to WASM)\n- ✏️ **Edit** - Non-destructive text-based editing using a Piece Table engine with 10ms crossfades\n- 💾 **Save** - Persistent recording to Origin Private File System (OPFS)\n- 📦 **Export** - \"Bake\" your edits into a final WAV file using OfflineAudioContext\n\n## How It Works\n\n### Two-Stage Transcription Pipeline\n\nTextCast uses a two-stage architecture for frame-accurate word timestamps:\n\n1. **Whisper Transcription** - Uses `@huggingface/transformers` to generate accurate text\n2. **CTC Forced Alignment** - Uses the MMS forced aligner with Viterbi decoding to map words to exact audio frames\n\nThis approach eliminates timestamp drift and hallucinations common in seq2seq models. For more on this problem, see [WhisperX](https://github.com/m-bain/whisperX).\n\n### Non-Destructive Editing\n\nEdits don't modify the original audio. Instead, a [Piece Table](https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation) maintains an Edit Decision List (EDL) of which segments to play. The `PlaylistPlayer` schedules Web Audio nodes with microsecond precision and 10ms crossfades for seamless playback.\n\n## Quick Start\n\n```bash\nnpm install\nnpm run dev\n```\n\nOpen http://localhost:4002 in Chrome (WebGPU recommended for faster transcription).\n\n## Deployment\n\nConfigured for Vercel with required COOP/COEP headers for SharedArrayBuffer:\n\n```bash\nnpm run build\nvercel --prod\n```\n\n## Browser Requirements\n\n- Chrome 113+ (required for OPFS and WebGPU)\n- Requires secure context (HTTPS) for MediaRecorder and OPFS\n\n## Known Limitations\n\n- **Mobile Support** - OPFS and Web Audio worklets have limited support on mobile browsers\n\n## Project Structure\n\n```\nsrc/\n├── components/\n│   ├── editor/           # TranscriptEditor with Piece Table visualization\n│   ├── recorder/         # Recording UI with OPFS streaming\n│   └── ui/               # Shared UI components\n├── hooks/\n│   └── useAudioPlayer.ts # Piece Table-backed playback hook\n├── lib/\n│   ├── audio/\n│   │   ├── PieceTable.ts     # Non-destructive EDL engine\n│   │   ├── PlaylistPlayer.ts # Web Audio scheduler\n│   │   ├── RecorderEngine.ts # AudioWorklet + OPFS streaming\n│   │   └── offlineRender.ts  # WAV export renderer\n│   ├── db/               # IndexedDB for project metadata\n│   └── transcription/\n│       ├── transformers-whisper.ts  # Whisper integration\n│       ├── aligner.ts               # Viterbi CTC forced alignment\n│       └── vad.ts                   # Voice Activity Detection\n└── types/\n```\n\n## Tech Stack\n\n| Feature | Technology |\n|---------|------------|\n| Frontend | React 19 + TypeScript + Vite |\n| Styling | Tailwind CSS v4 |\n| Storage | OPFS (audio) + IndexedDB (metadata) |\n| Transcription | [@huggingface/transformers](https://huggingface.co/docs/transformers.js) (WebGPU/WASM) |\n| Forced Alignment | [MMS-300M Forced Aligner](https://huggingface.co/onnx-community/mms-300m-1130-forced-aligner-ONNX) |\n| VAD | [@ricky0123/vad-web](https://github.com/ricky0123/vad) (Silero v5) |\n\n## References \u0026 Inspiration\n\n- [WhisperX](https://github.com/m-bain/whisperX) - Two-stage transcription + alignment architecture\n- [VS Code Piece Table](https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation) - Non-destructive editing data structure\n- [Silero VAD](https://github.com/snakers4/silero-vad) - Voice Activity Detection\n- [Transformers.js](https://huggingface.co/docs/transformers.js) - Running ML models in the browser\n- [OPFS](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system) - Origin Private File System for high-performance storage\n- [AudioWorklet](https://developer.mozilla.org/en-US/docs/Web/API/AudioWorklet) - Low-latency audio processing in a separate thread\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsirmews%2Ftextcast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsirmews%2Ftextcast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsirmews%2Ftextcast/lists"}