Skip to content

li41/VoiceCue

Repository files navigation

VoiceCue

簡報逐段語音朗讀工具。 載入簡報 PDF 或直接貼上講稿,簡報者按鍵逐段觸發語音; 觀眾只看到投影片,講稿與控制項留在簡報者畫面。

零後端、零安裝、可匯出成單一 HTML 檔帶去任何電腦雙擊即用。

English summary — A presenter-paced text-to-speech tool for slide decks. Load a PDF (or just paste your script), edit the auto-extracted segments, then cue each segment aloud with the spacebar during your talk. The audience window shows only the slide; your script, timers and controls stay on your laptop. Pure static frontend — no backend, no API keys, no install. Exports to a single self-contained HTML file. Built with a focus on Traditional Chinese (zh-TW).


特色

  • 兩種輸入 — PDF 自動抽取各頁文字區塊,或直接貼上講稿(支援換頁分隔符)
  • 可編輯的分段 — 自動分段只是初稿,可改字、拆段、合段、拖曳排序、標記略過
  • 三段式分段粒度 — 段落 / 一般 / 逐句,切換時已手動編輯的段落不會被覆寫
  • 簡報者畫面 — 深色控制台、講稿全文、逐字跟讀高亮、計時器、下一頁預覽
  • 觀眾視窗保持安靜 — 純黑底、無按鈕、隱藏游標、載入失敗也不在投影機上顯示錯誤
  • 投影畫面可縮放 — 放大看細節,超出畫面時出現捲軸,簡報者捲動時觀眾同步移動
  • 快捷鍵兩邊都能按 — 觀眾視窗全螢幕後焦點在它身上,按鍵會轉發回簡報者視窗
  • 單檔匯出 — PDF 與講稿全部內嵌,任何電腦雙擊即可簡報
  • 繁中優先 — CJK 逐字黏合、中文斷句、繁中語音自動降級

快速開始

只想使用

Releases 下載 index.html,用 Chrome 或 Edge 開啟即可。 不需要安裝任何東西。

從原始碼建置

npm install
npm run build

然後雙擊 dist/index.html

先決定用哪個瀏覽器。 語音清單由瀏覽器提供,Edge 與 Chrome 各有不同的線上 自然語音,而且因機器而異——同一台電腦可能 Chrome 有「Google 國語(臺灣)」 而 Edge 只有系統內建語音,也可能相反。

兩個瀏覽器都開一次,到「設定」試聽比較。專案可以分別記住每個瀏覽器要用哪個 語音,兩邊都設好之後,簡報包在哪個瀏覽器開都會挑到對的語音。

使用流程

1. 準備(辦公室)

  • 載入 PDF — 自動渲染各頁並抽取文字區塊當講稿初稿
  • 或直接貼上講稿 — PDF 抽不到文字時,或講稿另外撰寫時
    • 支援從 Word / Google 文件 / Email 貼上,會自動清洗格式
    • 用空行分段,或用 === / --- / [P2] / 【第二頁】 標記換頁

PDF 抽不到文字時:用 Windows 內建的文字辨識

轉曲線或掃描的 PDF 沒有文字層,抽不出講稿。本工具沒有內建 OCR, 但 Windows 11 已經內建一套又快又準的:

  1. Win+Shift+S 框選那一頁投影片
  2. 在截圖預覽點「文字動作」→「複製全部文字
  3. 回到 VoiceCue 按「貼上講稿」,直接貼

Windows 的文字辨識會在每個中文字之間插入空格(「本 季 工 作 報 告」)。 貼上時會自動偵測並移除,同時把每一行視為獨立項目(不做硬換行接合, 因為 OCR 的每一行就是投影片上的一行)。

為什麼不內建 OCR:瀏覽器無法呼叫 Windows 的 OCR 引擎(那是原生 API)。 改用 Tesseract.js 的話,繁中語言資料會讓單檔簡報包從 2 MB 膨脹到 15 MB 以上, 而且投影片常見的裝飾字體與底圖辨識率遠不如系統內建的。借用系統的比較划算。

  • 編輯 — 改字、拆段、合段、拖曳排序、標記略過、逐段試聽與語音覆寫
  • 匯出 — 單檔 .html 簡報包,或 .vcp.json 專案檔(建議兩個都存)

2. 簡報(會議室)

雙擊匯出的 .html → 直接進入簡報者控制台 → 按「開啟觀眾視窗」→ 把觀眾視窗拖到投影機 → 在該視窗上雙擊進入全螢幕 → 用空白鍵逐段播放。

全螢幕的兩種方式,都要在觀眾視窗上操作:

方式 說明
在觀眾視窗雙擊 最順手。拖到投影機後本來就要點一下取得焦點,雙擊一次到位
在觀眾視窗按 F 鍵盤替代。再按一次或 Esc 離開

控制台刻意沒有全螢幕按鈕:瀏覽器規定 requestFullscreen() 必須由 該視窗自己的使用者操作觸發,且只在操作後約 5 秒內有效,跨視窗遙控不算數。 做成按鈕會是一顆時靈時不靈的控制項,不如不放。

全螢幕時按 Esc 只會離開全螢幕,不會中斷朗讀。

  • Windows 需先 Win+P「延伸」(選「複製」的話兩螢幕相同,就分不開了)
  • 快捷鍵在兩個視窗都有效
  • 聲音走系統預設音訊裝置。要從會議室喇叭出聲,請在 Windows 音效設定 把預設輸出改成 HDMI 或會議室音響

快捷鍵

動作
空白 / 下一段
上一段
R 重播本段
PgDn / PgUp 翻頁
P 暫停 / 繼續
B 黑屏
+ / - 放大 / 縮小投影畫面
0 回到 100%(貼合畫面)
F / 雙擊 觀眾視窗全螢幕(須在該視窗上操作
Esc 停止朗讀(全螢幕時則為離開全螢幕)
Ctrl+Z 復原(編輯器)

放大超過 100% 時,觀眾視窗會出現捲軸;簡報者拉動預覽窗格的捲軸,觀眾畫面會同步移動, 所以你看到哪一塊、觀眾就看到哪一塊。縮放百分比在調整後短暫浮現再淡出, 不會一直佔著投影畫面。

縮放與捲動位置跨頁保留——版面一致的簡報不必每頁重調。要回到整頁按 0

語音來源與降級

語音完全由執行的瀏覽器提供,本工具無法跨瀏覽器取用。實測差異很大:

瀏覽器 可能提供的線上自然語音
Microsoft Edge Microsoft *** Online (Natural),如 HsiaoChen
Google Chrome Google 國語(臺灣)
兩者皆有 Windows 內建的 Hanhan / Yating / Zhiwei(離線可用,音質較機械)

哪些線上語音實際可用因機器而異,請務必在「設定」裡試聽確認。

降級順序:

情境 行為
有網路 + 該瀏覽器有線上語音 使用線上自然語音(最佳)
斷網 / 該瀏覽器沒有線上語音 自動退到系統內建 zh-TW 語音,畫面顯示提示
簡報包指定的語音在這台電腦不存在 改用最接近的語音,簡報者畫面明確警告已換人
完全找不到中文語音 顯示「請確認網路連線,或改用 Edge 開啟本頁」

簡報者控制台常駐顯示目前使用哪個語音,不會上台才發現變成機械音。

技術架構

純靜態前端,零後端、零第三方 TTS 函式庫。

Vite + React + TypeScript
├─ pdf.js                      PDF 渲染 + 文字區塊抽取
├─ speechSynthesis             瀏覽器原生 TTS(Web Speech API)
├─ window.open + postMessage   雙視窗同步
├─ Tailwind CSS + Radix UI     介面
└─ 單檔 HTML 匯出器             PDF + 講稿內嵌

語音走 W3C 標準的 speechSynthesis,不依賴逆向工程的協定。 SpeechEnginesrc/lib/speech/types.ts)是抽象介面,日後要換成 edge-tts 或 Azure Speech 只需新增實作,UI 層不動。

專案結構

src/
├── types.ts                    資料模型(Project / Slide / Segment)
├── lib/
│   ├── speech/                 語音引擎(介面 + Web Speech 實作 + 降級邏輯)
│   ├── text/                   斷句、貼上清洗、自動分段
│   ├── pdf/                    pdf.js 載入、高 DPI 渲染、文字區塊抽取
│   ├── project/                狀態管理(含 undo)、存讀、匯入、匯出
│   ├── playback.ts             逐段播放控制
│   └── channel.ts              簡報者 ↔ 觀眾視窗通訊
├── components/                 UI 元件
└── views/                      EditorView / PresenterView / AudienceView

開發

指令 說明
npm run build 建置成單一 HTML(dist/index.html,約 2 MB)
npm run dev 開發伺服器(localhost:5173)。程式碼未打包,無法匯出簡報包
npm run preview 用 http 提供建置產物(localhost:4173
npm run typecheck TypeScript 檢查
npm run selftest 純邏輯測試(65 項,不需瀏覽器)
npm run smoke 端對端測試(58 項)
npm run smoke:file file:// 雙擊情境的端對端測試(23 項)
npm run smoke:fullscreen 全螢幕控制測試(8 項,會開啟真實視窗約 20 秒)

瀏覽器測試需要先 npm run build,並額外安裝 npm i -D puppeteer-core (僅測試需要,刻意不列入專案相依,以免一般使用者多裝 80 個套件)。 測試會使用系統既有的 Microsoft Edge,不下載 Chromium。

已知限制

  • 簡報時仍需網路才能使用線上自然語音;離線會降級為系統語音(不會中斷)
  • 不同瀏覽器提供不同語音,無法選擇語音來源——決定用哪個瀏覽器就是決定語音
  • 企業電腦可能被 Edge 群組原則 ConfigureOnlineTextToSpeech 關閉線上語音
  • PDF 無文字層(轉曲線/掃描件)抽不到文字,未內建 OCR—— 改用 Windows 的文字辨識再貼上(見上方說明),貼上端已針對 OCR 輸出最佳化
  • 逐字高亮依賴 onboundary 事件,CJK 精度視瀏覽器引擎而定,作為輔助提示
  • 字型使用系統堆疊(Windows 上為微軟正黑體),未內嵌字型檔
  • 段落清單未做虛擬捲動,超大型簡報(數百頁)可能較慢

貢獻

歡迎 issue 與 PR,請先讀 CONTRIBUTING.md

回報語音相關問題時,請務必附上「設定」畫面裡的語音清單—— 語音因機器與瀏覽器而異,沒有這個資訊幾乎無法重現問題。

授權

MIT

About

簡報逐段語音朗讀工具:載入 PDF 或貼上講稿,簡報者按鍵觸發朗讀,觀眾只看到投影片。純前端、免安裝、可匯出單一 HTML 檔。

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages