diff --git a/README.md b/README.md index 5d579fd..158bcec 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ the media. Export the final cut — without your file ever leaving your device. - 🔒 **Private by design** — no server, no auth, no uploads; all media processing happens on-device - 📝 **Word-level editing** — select words, press ⌫, the cut follows the text -- 📥 **Import your own transcript** — skip Whisper and edit with an SRT, VTT, or JSON caption file +- 📥 **Import your own transcript** — SRT / VTT / JSON with timestamps, or plain TXT synced to the audio - 🧹 **Filler removal** — one-click cut of "um", "uh", and similar fillers - 🗣️ **Speaker diarization** — the transcript is grouped by speaker - 🎬 **Timeline** — waveform, word labels, cut regions, playhead, zoom @@ -63,7 +63,7 @@ audio track. 2. **Transcribe** — Whisper runs in a Web Worker with `return_timestamps: "word"`, streaming text as it goes; pyannote assigns a speaker to every word. Choose **Whisper Base**, **Whisper Small**, or **Import transcript** - (SRT / VTT / JSON) on the homepage. + (SRT / VTT / JSON / TXT) on the homepage. 3. **Edit** — deleting words produces "cut ranges" of the original media. The preview player skips them in real time and the timeline shows them in red. **Remove fillers** cuts every detected "um" / "uh" / etc. in one click. diff --git a/components/ImportTranscriptOption.tsx b/components/ImportTranscriptOption.tsx index 75f10f0..efab594 100644 --- a/components/ImportTranscriptOption.tsx +++ b/components/ImportTranscriptOption.tsx @@ -1,207 +1,90 @@ "use client"; -import { useCallback, useEffect, useRef, useState } from "react"; -import { FileText, Loader2 } from "lucide-react"; -import { - isTranscriptFile, - parseTranscriptFile, - TRANSCRIPT_ACCEPT, -} from "@/lib/parseTranscript"; -import { isWhisperModel } from "@/lib/models"; +import { useCallback, useState } from "react"; +import { FileText } from "lucide-react"; import { useEditorStore } from "@/lib/store"; +import type { ParsedTranscript } from "@/lib/parseTranscript"; import { ModelOption, useModelOption, useOptionTrigger, - type ModelOptionContextValue, } from "./ModelSelector"; +import PasteTranscriptDialog from "./PasteTranscriptDialog"; /** - * ModelSelector option that opens a caption file picker and surfaces parse - * status / errors on the row (and in the closed trigger). - * - * The file input must NOT be nested inside the option + + +
+

+ Paste a plain-text script to sync with your media, or drop in timed + captions (SRT / VTT / JSON). Optional speaker labels:{" "} + Name: dialogue +

+