Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions components/ExportDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ type ExportTab = "video" | "audio" | "transcript" | "timeline";

/** Document formats that support an optional timestamps toggle. */
const DOC_FORMATS = new Set<TranscriptFormat>(["txt", "md", "docx", "pdf"]);
/** Caption formats that support the short-cues toggle. */
const SUBTITLE_FORMATS = new Set<TranscriptFormat>(["srt", "vtt"]);

const VIDEO_FORMATS: { value: VideoExportFormat; label: string }[] = [
{ value: "mp4", label: "MP4" },
Expand Down Expand Up @@ -110,6 +112,7 @@ export default function ExportDialog() {
const [audioFormat, setAudioFormat] = useState<AudioExportFormat>("m4a");
const [textFormat, setTextFormat] = useState<TranscriptFormat>("txt");
const [includeTimestamps, setIncludeTimestamps] = useState(false);
const [shortCues, setShortCues] = useState(true);
const [timelineFormat, setTimelineFormat] =
useState<TimelineExportFormat>("resolve");
const [timelineFrameRate, setTimelineFrameRate] =
Expand Down Expand Up @@ -269,6 +272,7 @@ export default function ExportDialog() {
]);

const textSupportsTimestamps = DOC_FORMATS.has(textFormat);
const textSupportsShortCues = SUBTITLE_FORMATS.has(textFormat);

const exportText = useCallback(() => {
// Read live store state at click time so a rename / replace-in-project
Expand All @@ -282,20 +286,24 @@ export default function ExportDialog() {
cuts: liveCuts,
speakers: speakersFromWords(s.words, s.speakers),
...(textSupportsTimestamps ? { timestamps: includeTimestamps } : {}),
...(textSupportsShortCues ? { shortCues } : {}),
});
setError(null);
trackEvent("export_completed", {
kind: "transcript",
format: textFormat,
...(textSupportsTimestamps ? { timestamps: includeTimestamps } : {}),
...(textSupportsShortCues ? { shortCues } : {}),
});
} catch (err) {
setError(err instanceof Error ? err.message : en["error.export"]);
}
}, [
textFormat,
textSupportsTimestamps,
textSupportsShortCues,
includeTimestamps,
shortCues,
baseName,
]);

Expand Down Expand Up @@ -506,9 +514,24 @@ export default function ExportDialog() {
<span>{t("export.includeTimestamps")}</span>
</label>
)}
{textSupportsShortCues && (
<label className="flex cursor-pointer items-center gap-2.5 rounded-lg bg-zinc-50 px-3 py-2.5 text-sm text-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-200">
<input
type="checkbox"
checked={shortCues}
onChange={(e) => setShortCues(e.target.checked)}
className="h-3.5 w-3.5 rounded border-zinc-300 text-zinc-900 focus:ring-zinc-400 dark:border-zinc-600 dark:bg-zinc-900"
/>
<span>{t("export.shortCues")}</span>
</label>
)}
<p className="text-xs text-zinc-500 dark:text-zinc-400">
{textFormat === "srt" || textFormat === "vtt" || textFormat === "json"
? t("export.subtitlesHelp")
{textFormat === "srt" || textFormat === "vtt"
? shortCues
? t("export.subtitlesHelpShortCues")
: t("export.subtitlesHelp")
: textFormat === "json"
? t("export.subtitlesHelp")
: includeTimestamps
? t("export.transcriptHelpTimestamps")
: t("export.transcriptHelp")}
Expand Down
3 changes: 3 additions & 0 deletions lib/i18n/messages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,16 @@ export const de: Record<MessageKey, string> = {
"export.statCuts": "Schnitte",
"export.statEdited": "Bearbeitet",
"export.includeTimestamps": "Zeitstempel einbeziehen",
"export.shortCues": "Kurze Untertitel (≤5 s)",
"export.transcriptHelp": "Text mit Sprecherlabels und entfernten Schnitten.",
"export.transcriptHelpTimestamps":
"Text mit Sprecherlabels und entfernten Schnitten. Jeder Abschnitt beginnt mit der Zeit auf der bearbeiteten Timeline.",
"export.transcriptHelpPdf":
"PDF nutzt eine lateinische Standardschrift — für volles Unicode (CJK usw.) besser DOCX verwenden.",
"export.subtitlesHelp":
"SRT und VTT verwenden die bearbeitete Timeline (Schnitte angewendet). JSON behält die vollständige Wortliste für den erneuten Import.",
"export.subtitlesHelpShortCues":
"SRT und VTT verwenden die bearbeitete Timeline (Schnitte angewendet), aufgeteilt in kurze satzweise Untertitel (≤5 s). JSON behält die vollständige Wortliste für den erneuten Import.",
"export.encodingHelp": "Neucodierung mit ffmpeg.wasm — längere Dateien dauern eine Weile.",
"export.reexport": "Mit neuesten Änderungen erneut exportieren",
"export.rendering": "Rendering in deinem Browser…",
Expand Down
3 changes: 3 additions & 0 deletions lib/i18n/messages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,16 @@ export const en = {
"export.statCuts": "Cuts",
"export.statEdited": "Edited",
"export.includeTimestamps": "Include timestamps",
"export.shortCues": "Short cues (≤5s)",
"export.transcriptHelp": "Speaker-labeled text with cuts removed.",
"export.transcriptHelpTimestamps":
"Speaker-labeled text with cuts removed. Each turn starts with its edited-timeline time.",
"export.transcriptHelpPdf":
"PDF uses a standard Latin font — prefer DOCX for full Unicode (CJK, etc.).",
"export.subtitlesHelp":
"SRT and VTT use the edited timeline (cuts applied). JSON keeps the full word list for re-import.",
"export.subtitlesHelpShortCues":
"SRT and VTT use the edited timeline (cuts applied), split into short sentence-sized cues (≤5s). JSON keeps the full word list for re-import.",
"export.encodingHelp": "Re-encoding with ffmpeg.wasm — longer files take a while.",
"export.reexport": "Re-export with latest edits",
"export.rendering": "Rendering in your browser…",
Expand Down
3 changes: 3 additions & 0 deletions lib/i18n/messages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,16 @@ export const es: Record<MessageKey, string> = {
"export.statCuts": "Cortes",
"export.statEdited": "Editado",
"export.includeTimestamps": "Incluir marcas de tiempo",
"export.shortCues": "Subtítulos cortos (≤5 s)",
"export.transcriptHelp": "Texto con etiquetas de hablante y cortes eliminados.",
"export.transcriptHelpTimestamps":
"Texto con etiquetas de hablante y cortes eliminados. Cada turno empieza con su tiempo en la línea de tiempo editada.",
"export.transcriptHelpPdf":
"PDF usa una fuente latina estándar — preferir DOCX para Unicode completo (CJK, etc.).",
"export.subtitlesHelp":
"SRT y VTT usan la línea de tiempo editada (con cortes aplicados). JSON conserva la lista completa de palabras para reimportar.",
"export.subtitlesHelpShortCues":
"SRT y VTT usan la línea de tiempo editada (con cortes aplicados), divididos en subtítulos cortos por frase (≤5 s). JSON conserva la lista completa de palabras para reimportar.",
"export.encodingHelp": "Recodificando con ffmpeg.wasm — los archivos largos tardan un poco.",
"export.reexport": "Reexportar con las últimas ediciones",
"export.rendering": "Renderizando en tu navegador…",
Expand Down
3 changes: 3 additions & 0 deletions lib/i18n/messages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,16 @@ export const fr: Record<MessageKey, string> = {
"export.statCuts": "Coupes",
"export.statEdited": "Monté",
"export.includeTimestamps": "Inclure les horodatages",
"export.shortCues": "Sous-titres courts (≤5 s)",
"export.transcriptHelp": "Texte avec étiquettes de locuteur et coupes retirées.",
"export.transcriptHelpTimestamps":
"Texte avec étiquettes de locuteur et coupes retirées. Chaque tour commence par son temps sur la timeline montée.",
"export.transcriptHelpPdf":
"Le PDF utilise une police latine standard — préférez DOCX pour l’Unicode complet (CJK, etc.).",
"export.subtitlesHelp":
"SRT et VTT utilisent la timeline montée (coupes appliquées). JSON conserve la liste complète des mots pour une réimportation.",
"export.subtitlesHelpShortCues":
"SRT et VTT utilisent la timeline montée (coupes appliquées), découpés en sous-titres courts par phrase (≤5 s). JSON conserve la liste complète des mots pour une réimportation.",
"export.encodingHelp": "Réencodage avec ffmpeg.wasm — les fichiers longs prennent un moment.",
"export.reexport": "Réexporter avec les dernières modifications",
"export.rendering": "Rendu dans votre navigateur…",
Expand Down
3 changes: 3 additions & 0 deletions lib/i18n/messages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,16 @@ export const ja: Record<MessageKey, string> = {
"export.statCuts": "カット",
"export.statEdited": "編集後",
"export.includeTimestamps": "タイムスタンプを含める",
"export.shortCues": "短い字幕(≤5秒)",
"export.transcriptHelp": "話者ラベル付きテキスト。カット部分は除外されます。",
"export.transcriptHelpTimestamps":
"話者ラベル付きテキスト。カット部分は除外され、各発話は編集後タイムラインの時刻で始まります。",
"export.transcriptHelpPdf":
"PDF はラテン系の標準フォントを使います。CJK など完全な Unicode には DOCX を推奨します。",
"export.subtitlesHelp":
"SRT と VTT は編集後のタイムライン(カット適用済み)を使用します。JSON は再インポート用に完全な単語リストを保持します。",
"export.subtitlesHelpShortCues":
"SRT と VTT は編集後のタイムライン(カット適用済み)を使い、短い文単位の字幕(≤5秒)に分割します。JSON は再インポート用に完全な単語リストを保持します。",
"export.encodingHelp": "ffmpeg.wasm で再エンコード中 — 長いファイルは時間がかかります。",
"export.reexport": "最新の編集で再書き出し",
"export.rendering": "ブラウザでレンダリング中…",
Expand Down
3 changes: 3 additions & 0 deletions lib/i18n/messages/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,16 @@ export const ko: Record<MessageKey, string> = {
"export.statCuts": "컷",
"export.statEdited": "편집본",
"export.includeTimestamps": "타임스탬프 포함",
"export.shortCues": "짧은 자막 (≤5초)",
"export.transcriptHelp": "화자 라벨이 포함된 텍스트이며 컷한 내용은 제거됩니다.",
"export.transcriptHelpTimestamps":
"화자 라벨이 포함된 텍스트이며 컷한 내용은 제거됩니다. 각 발화는 편집된 타임라인 시각으로 시작합니다.",
"export.transcriptHelpPdf":
"PDF는 표준 라틴 글꼴을 사용합니다. 완전한 유니코드(CJK 등)에는 DOCX를 권장합니다.",
"export.subtitlesHelp":
"SRT와 VTT는 편집된 타임라인(컷 적용)을 사용합니다. JSON은 다시 가져오기 위해 전체 단어 목록을 유지합니다.",
"export.subtitlesHelpShortCues":
"SRT와 VTT는 편집된 타임라인(컷 적용)을 사용하며 짧은 문장 단위 자막(≤5초)으로 나눕니다. JSON은 다시 가져오기 위해 전체 단어 목록을 유지합니다.",
"export.encodingHelp": "ffmpeg.wasm으로 다시 인코딩 중 — 긴 파일은 시간이 걸립니다.",
"export.reexport": "최신 편집으로 다시 내보내기",
"export.rendering": "브라우저에서 렌더링 중…",
Expand Down
3 changes: 3 additions & 0 deletions lib/i18n/messages/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,16 @@ export const pt: Record<MessageKey, string> = {
"export.statCuts": "Cortes",
"export.statEdited": "Editado",
"export.includeTimestamps": "Incluir marcas de tempo",
"export.shortCues": "Legendas curtas (≤5 s)",
"export.transcriptHelp": "Texto com rótulos de falante e cortes removidos.",
"export.transcriptHelpTimestamps":
"Texto com rótulos de falante e cortes removidos. Cada turno começa com o tempo na linha do tempo editada.",
"export.transcriptHelpPdf":
"PDF usa uma fonte latina padrão — prefira DOCX para Unicode completo (CJK etc.).",
"export.subtitlesHelp":
"SRT e VTT usam a linha do tempo editada (com cortes aplicados). JSON conserva a lista completa de palavras para reimportar.",
"export.subtitlesHelpShortCues":
"SRT e VTT usam a linha do tempo editada (com cortes aplicados), divididos em legendas curtas por frase (≤5 s). JSON conserva a lista completa de palavras para reimportar.",
"export.encodingHelp": "Recodificando com ffmpeg.wasm — arquivos longos demoram um pouco.",
"export.reexport": "Reexportar com as últimas edições",
"export.rendering": "Renderizando no seu navegador…",
Expand Down
3 changes: 3 additions & 0 deletions lib/i18n/messages/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,16 @@ export const zhCN: Record<MessageKey, string> = {
"export.statCuts": "剪除",
"export.statEdited": "成片",
"export.includeTimestamps": "包含时间戳",
"export.shortCues": "短字幕(≤5 秒)",
"export.transcriptHelp": "带说话人标签的文本,已移除剪除内容。",
"export.transcriptHelpTimestamps":
"带说话人标签的文本,已移除剪除内容。每段以成片时间轴上的时间开头。",
"export.transcriptHelpPdf":
"PDF 使用标准拉丁字体 — 完整 Unicode(如中日韩)请优先选择 DOCX。",
"export.subtitlesHelp":
"SRT 和 VTT 使用已应用剪除的成片时间轴;JSON 保留完整词表以便重新导入。",
"export.subtitlesHelpShortCues":
"SRT 和 VTT 使用已应用剪除的成片时间轴,并拆成短句字幕(≤5 秒)。JSON 保留完整词表以便重新导入。",
"export.encodingHelp": "使用 ffmpeg.wasm 重新编码,较长文件需要更多时间。",
"export.reexport": "按最新编辑重新导出",
"export.rendering": "正在浏览器中渲染…",
Expand Down
3 changes: 3 additions & 0 deletions lib/i18n/messages/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,16 @@ export const zhTW: Record<MessageKey, string> = {
"export.statCuts": "剪除",
"export.statEdited": "成片",
"export.includeTimestamps": "包含時間戳",
"export.shortCues": "短字幕(≤5 秒)",
"export.transcriptHelp": "帶有說話人標籤的文字,已移除剪除內容。",
"export.transcriptHelpTimestamps":
"帶有說話人標籤的文字,已移除剪除內容。每段以編輯後時間軸上的時間開頭。",
"export.transcriptHelpPdf":
"PDF 使用標準拉丁字型 — 完整 Unicode(如中日韓)請優先選擇 DOCX。",
"export.subtitlesHelp":
"SRT 和 VTT 使用已套用剪除的編輯後時間軸。JSON 保留完整詞表以便重新匯入。",
"export.subtitlesHelpShortCues":
"SRT 和 VTT 使用已套用剪除的編輯後時間軸,並拆成短句字幕(≤5 秒)。JSON 保留完整詞表以便重新匯入。",
"export.encodingHelp": "使用 ffmpeg.wasm 重新編碼 — 較長的檔案需要一些時間。",
"export.reexport": "以最新編輯重新匯出",
"export.rendering": "正在瀏覽器中算出…",
Expand Down
Loading
Loading