安安~我是ChiYu~
今天下午開了一個新的 repo,到晚上把「觀眾同步」推上去,前後一共 6 個 commit。做出來的東西叫 PPT-Web:把做好的 PPT 丟進網頁,手機掃一下 QR Code,就變成一支能看講稿的簡報筆。
這個工具不是憑空冒出來的。它是從我之前做的 MD2PPT 裡,把最好用的那一塊拆出來重做。
- 線上直接用: https://huangchiyu.com/PPT-Web/
- GitHub 原始碼: https://github.com/eric861129/PPT-Web
MD2PPT 裡最好用的,是手機遙控而不是轉檔
以前我做過 MD2PPT-Evolution ,目標是把 Markdown 直接轉成 PowerPoint。有一說一,這個轉檔功能不太實用,不像 MD2DOC-Evolution 那樣真的有人拿去用在實際工作上。
但 MD2PPT 裡有一個功能,我自己覺得非常好用:手機遙控。它用免費的 PeerJS Cloud 當配對伺服器,手機和電腦在同一個網路下,掃 QR Code 就能翻頁、在手機上看備忘錄,還能一鍵切黑幕。
問題是,這個功能被綁在 MD2PPT 裡。想用手機遙控,簡報就得先用 MD2PPT 的 Markdown 格式寫。可是要上台的簡報,很多本來就是在 PowerPoint 裡做好的。
所以 PPT-Web 的方向很單純:不碰轉檔,直接吃你已經做好的 PPT,把力氣全部放在「手機當簡報筆」這件事上。
瀏覽器讀不了 PPTX:PDF 負責畫面,PPTX 負責備忘稿
把 PPT 放進網頁,第一個問題就是瀏覽器沒辦法原生顯示 PPTX。前端直接渲染 PPTX 的套件是有,但字型、圖表、SmartArt 很容易跑版。
PPT-Web 的做法是把工作拆成兩半:
- 畫面交給 PDF:用 PowerPoint 自己匯出的 PDF,交給 pdf.js 向量渲染,看起來就跟原本的投影片一樣。
- 備忘稿交給 PPTX:PPTX 其實是一個 zip 檔,解開後讀 XML,把每一頁的講稿抓出來。
實際用起來是這三步:
- 在 PowerPoint 選「檔案 → 匯出 → 建立 PDF/XPS 文件」,存一份 PDF。
- 打開 PPT-Web,把 PDF 和原本的 PPTX 一起拖進去。
- 按上方的「手機遙控」(或按
Q),用手機掃 QR Code。
兩個檔案拖進去之後,電腦端會進入檢視模式。下面這張是用 repo 內附的範例簡報開起來的畫面:

PPT-Web 電腦端的檢視模式:左邊縮圖、中間投影片、下方是從 PPTX 讀出來的備忘稿
上方那排按鈕,就是這篇的主角:手機遙控、觀眾同步、講者檢視。鍵盤操作照 PowerPoint 的習慣走,F5 從頭放映、Shift + F5 從目前頁放映、B 黑幕、Esc 結束;多數實體簡報筆送出的也是這些按鍵,所以原本的簡報筆照樣能用。
整個網站是純靜態的,簡報檔案不會上傳到任何伺服器。開過的簡報會記在這個瀏覽器裡,下次在開始頁點一下就能再打開。
隱藏投影片會讓備忘稿錯頁,所以要先對齊頁數
拆成 PDF 加 PPTX 之後,有一個很容易被忽略的坑:PowerPoint 匯出 PDF 時,預設不含隱藏投影片。
PPTX 裡有 8 張投影片、其中 1 張隱藏,匯出的 PDF 就只有 7 頁。如果直接照順序把備忘稿貼上去,從隱藏頁之後,每一頁的講稿都會錯開一頁。
PPT-Web 會先比對頁數再決定怎麼對:
- PDF 頁數等於可見投影片數:拿掉隱藏投影片的備忘稿。
- PDF 頁數等於全部投影片數:全部保留。
- 兩個都對不上:照順序對齊,並跳出警告請使用者確認。
投影片的順序也不是看 slide1.xml、slide2.xml 這種檔名,而是讀 presentation.xml 裡記錄的播放順序。搬動過順序的投影片,檔名跟播放順序本來就可能對不上。
手機遙控:翻頁、看備忘稿、切黑幕都在拇指範圍內
手機掃完 QR Code,畫面是直式的深色版面,在台上不刺眼。下面這張是我用自己的手機實際連上的畫面:

手機遙控端的實際畫面:上方是目前頁和下一頁,中間是備忘稿,下方三顆按鈕用拇指就按得到
這張截的是 PowerPoint 模式、還沒開始放映的時候,所以中間那顆按鈕是綠色的「從這頁放映」;開始放映後,這個位置就是黑幕按鈕。下一頁按鈕最大,拇指最好按到。
從最上面往下看,每一區都是上台時真的會用到的東西:
- 連線狀態旁的數字是手機跟電腦之間的延遲,像截圖裡的 20ms;超過 200ms 會變黃、500ms 變紅。
- 頁碼可以點:點下去會打開跳頁清單,附縮圖和標題,點一下就跳過去。
- 時間也可以點:打開計時器,可以開始、暫停、重設,所有手機和電腦共用同一個計時器。
- 備忘稿可以調字級:用 A− / A+ 調整,設定會記在手機上。
- 黑幕有明顯提示:黑幕開著時,整個遙控端外框變紅,按鈕變成紅色的「取消黑幕」,不會忘記自己還在黑幕。
- 螢幕不會自己鎖:用 Screen Wake Lock 讓手機保持亮著(需要 https,iOS 16.4 以上支援)。
斷線也有處理。配對過的手機斷線、重新整理之後,都會自己連回來;也可以同時連好幾支手機,例如請助理幫忙翻頁,所有手機畫面會同步。
QR Code 被投上大螢幕,台下的人也搶不走簡報
手機遙控有一條規則:只有電腦上的「手機遙控」視窗開著時,新的手機才能配對。
QR Code 很可能在開場前就被投到大螢幕上。有了這條規則,台下的人就算掃了,也沒辦法在簡報中途接手翻頁。已經配對過的手機不受這條規則影響。
專案的規劃文件記錄了一組瀏覽器實測(電腦加模擬手機,走真實的 PeerJS 連線):掃碼後約 1.4 秒連上,手機按下去到電腦換頁約 50ms。
接投影機的時候,電腦端還可以按「講者檢視」(Alt + F5,跟 PowerPoint 一樣):觀眾視窗拖到投影機上全螢幕,筆電自己看目前頁、下一頁、備忘稿和計時。
PDF 會吃掉動畫,所以改讓 PowerPoint 自己放映
PDF 模式有一個繞不過去的限制:PDF 只會留下每張投影片「動畫全部播完」的樣子。原本逐項出現的條列,在 PDF 裡會一次全部攤開。
瀏覽器也沒辦法正確播放 PPTX 的動畫,真正能把動畫播對的,只有 PowerPoint 本身。我自己的簡報常用逐項出現,所以這裡選擇讓 PowerPoint 負責放映,PPT-Web 只負責把手機的指令轉過去。
整條路線是這樣接起來的:
flowchart LR
phone["手機遙控端"] -- "WebRTC" --> web["電腦瀏覽器<br/>PPT-Web 網站"]
web -- "ws://127.0.0.1:48210" --> bridge["PPT-Web-Bridge.cmd<br/>本機橋接程式"]
bridge -- "COM" --> ppt["PowerPoint<br/>負責放映與動畫"]中間的 PPT-Web-Bridge.cmd 是這個模式的關鍵。它同一個檔案既是批次檔也是 PowerShell 腳本,雙擊就交給 Windows 內建的 PowerShell 5.1 執行,不用安裝,也不需要系統管理員權限。它透過 COM 控制你自己開著的 PowerPoint,每 250 毫秒讀一次狀態,有變化才回報給網站。
用法是這四步:
- 在 PPT-Web 開始頁選「用 PowerPoint 放映」,下載
PPT-Web-Bridge.cmd,雙擊執行並讓它開著。第一次執行時 Windows 可能跳出警告,選「其他資訊 → 仍要執行」。 - 用 PowerPoint 打開簡報。
- 網站會自動連上橋接程式。瀏覽器詢問是否允許存取這台裝置上的其他應用程式時,選「允許」。
- 按「手機遙控」配對手機,從網站、手機或 PowerPoint 開始放映都可以。
切到這個模式後,手機上會多顯示目前是第幾個動畫步驟,例如「動畫 1 / 3」;還沒開始放映時,中間的按鈕會變成「從這頁放映」。規劃文件記錄的實測是:手機按下一步,到 PowerPoint 換頁並回報,大約 80–115ms。
能控制 PowerPoint 的本機程式,只接受 PPT-Web 的連線
一支能遙控 PowerPoint 的本機程式,最怕的是任何網站都能連過來。所以橋接程式做了兩層限制:
- 只聽
127.0.0.1,同一個網路裡的其他電腦連不到。 - WebSocket 握手時檢查
Origin,只接受https://huangchiyu.com、https://eric861129.github.io和本機開發網址。
其他網站就算知道埠號,也控制不了你的 PowerPoint。
這個模式的限制也要先講清楚:只支援 Windows 加上桌面版 PowerPoint,Mac 版 PowerPoint 沒有 COM 可以接。放映期間,瀏覽器的網站分頁要開著,可以放在 PowerPoint 後面,但不能關掉。
觀眾同步:台下的手機也能跟著看簡報
最後一個 commit 加的是觀眾同步。講者按「觀眾同步」開始分享,台下觀眾掃另一個 QR Code,就能在自己的手機上跟著看目前這一頁。
觀眾端的規則刻意收得很緊:
- 只能看、不能控制:觀眾用的是跟手機遙控不同的連線 id,觀眾頁永遠碰不到翻頁指令。
- 只看得到講過的頁:電腦只把放映中出現過的頁送出去,備忘稿和標題清單都不送。講者在檢視模式裡自己翻來翻去,也不會同步出去。
- 可以往回翻:觀眾可以翻回前面講過的頁,按「回到目前頁」再跟上講者。
QR Code 的部分也有顧到上台的流程。同一台電腦的觀眾連結會一直沿用,所以可以把 QR Code 下載成圖片,直接放進投影片;要讓舊連結失效,就按「換新連結」。放映中按 V 會把 QR Code 投到大螢幕上,按任意鍵收起,而且收起的那一下不會順便翻頁。
觀眾人數上限是 100 位。原因很實際:每換一頁,每位觀眾都要從筆電收一張圖,人再多,筆電的上傳頻寬會先撐不住。規劃文件裡用 21 支模擬手機實測,翻頁後所有觀眾約 0.1 秒內同步。
PowerPoint 模式下要注意一件事:觀眾收到的是整張投影片的匯出圖,所以動畫還沒出現的內容,觀眾會先看到。
免費 PeerJS Cloud 的代價:網路環境與連線上限
PPT-Web 沿用了 MD2PPT 的做法:手機和電腦用 WebRTC 直連,只在配對那一刻借用免費的 PeerJS Cloud 交換連線資訊。不用自架後端,代價是幾個要先知道的限制。
手機和電腦都要能上網。兩邊連同一個 Wi-Fi 很穩;現場網路不穩時,讓電腦連手機熱點最穩。手機用 4G、電腦用場地 Wi-Fi 多半也可以,但遇到擋 UDP 的公司網路或對稱型 NAT,就可能連不上。完全沒有網路時無法配對,不過鍵盤和實體簡報筆照常能用。
PeerJS Cloud 會限制同一個 IP 的新連線數量,超過會被擋大約一小時。觀眾同步特別容易撞到,因為台下的手機多半共用同一個 Wi-Fi 的對外 IP。規劃文件記錄,21 支手機一起重試、每次都開新連線時,公用伺服器就開始拒絕這個 IP。所以觀眾頁整頁只開一條到配對伺服器的連線,重試時間也加上隨機,避免大家同時重連。觀眾真的很多時,可以自架 PeerJS 伺服器
,build 時用 VITE_PEER_SERVER 環境變數指過去。
網頁拿不到手機的音量鍵,所以沒辦法用音量鍵翻頁。
最後要補一句:除了手機截圖上的那個延遲,文章裡其他延遲和同步的數字,都是規劃文件在瀏覽器環境裡量的。依照 repo 裡的規劃文件,iPhone Safari、Android Chrome 的實機測試,以及手機熱點、同一個 Wi-Fi、4G 對 Wi-Fi 這幾種網路情境,都還列在下一步。
要不要幫 PPT-Web 買一個獨立網域?
PPT-Web 目前放在 https://huangchiyu.com/PPT-Web/
,push 到 main 後由 GitHub Actions 自動測試、build,再部署到 GitHub Pages。
我現在在考慮要不要幫它買一個獨立網域。如果你拿去用,覺得好用,給我一點回饋:在文章下方留言,或到 GitHub Issues 都可以。如果方便,也附上你用的手機和連線的網路環境,這正好是目前還沒實機測完的部分。用的人覺得有幫助,我就買一個獨立網域,讓這個工具更好分享。
真的要換網域,也不是只改 DNS 就好。橋接程式的 Origin 白名單現在寫的是 huangchiyu.com 和 eric861129.github.io,新網域要加進去,PowerPoint 模式才連得上。手機遙控和觀眾同步的 QR Code 網址是從目前網址推算的,換網域後會自動跟著變;但已經下載下來、放進投影片裡的觀眾 QR Code,還是會指向舊網址。
今天做完,手機遙控從 MD2PPT 裡的附屬功能,變成一個能直接吃現成 PPT 的獨立工具,還多了保留動畫的 PowerPoint 模式和觀眾同步。接下來缺的,是把它真的帶上台:真的手機、真的會場網路。這一步,也需要用過的人告訴我結果。