ElgatoMirror:
題詞機鏡像不會動,我自己寫一個

2026.05.25 ‧ 莊哲昀(AJ)

ElgatoMirror — 把任一螢幕水平鏡像到題詞機 歡迎收看 來源螢幕(正向) 水平翻轉 scaleX(-1) 歡迎收看 Elgato Prompter(鏡像) 鏡頭 🎛 常駐選單列 零干擾、隨手切換來源/目標 🖥 自由指定螢幕 多螢幕也能挑哪台投哪台 ⌘M 切換鏡像 錄影中一鍵啟用/停用 🆘 ⌘⌥M 緊急停用 畫面被遮住也能救回來 ElgatoMirror 給用題詞機錄課的人

那天下午我在家裡那間錄音間,桌上擺著一台 Elgato Prompter——前一陣子買的題詞機,玻璃面 45 度斜架在鏡頭前面,講稿從 MacBook 投到那片玻璃上,讓我讀字的時候眼睛直視鏡頭。錄到一半我把第二集的稿子拖到延伸螢幕,按下播放——玻璃上的字全是反的。「迎歡看收」這種讀法,根本無法錄。重來、再重來,Elgato 官方軟體裡那顆「水平鏡像」按鈕勾下去沒反應、macOS 系統設定 ➜ 顯示器找不到鏡像翻轉的選項。錄影排程那天卡了一個多小時,最後我把稿子印出來貼在鏡頭旁邊讀,當天那集影片我自己看就知道眼神飄。

隔天我用 Claude Code 寫了 ElgatoMirror。

🪞 ElgatoMirror v1.0.2

把任一螢幕水平鏡像到 Elgato Prompter(或任何題詞機)的 macOS 選單列工具——⌘M 一鍵切換、⌘⌥M 救命快速鍵。Elgato 官方軟體不會動,這個會。MIT 開源、macOS 13+。

為什麼題詞機的字必須是反的

題詞機正前方有一片半透明玻璃斜 45 度架在鏡頭前面,鏡頭從玻璃後面拍、我從玻璃前面看講稿。講稿不是直接印上去,是底下螢幕反射上來的——所以螢幕上的字必須先左右翻轉,反射後才會正。原理跟救護車車頭那個反寫的「AMBULANCE」一樣。

問題出在我不用 Elgato 自家那支 prompter app(太陽春、字級配色不能自訂),我用的是把 PDF 開在 macOS 內建「預覽程式」、視窗拖到題詞機這個延伸螢幕。這條路徑下沒人幫我翻轉——延伸螢幕對 macOS 就是普通顯示器,內容原封不動送過去。Elgato Camera Hub 那個「翻轉」管的是攝影機畫面,不是顯示器輸出;系統設定 ➜ 顯示器,從以前到現在沒有「水平鏡像」這個 toggle。翻 Reddit 跟 Elgato 論壇一堆人問同樣的問題,答案五花八門但沒有一個是「macOS 內建可以」。

它做了什麼

ElgatoMirror 是一支 macOS 選單列工具,開起來在右上角放一顆小圖示,點開來選兩件事——要鏡像哪一個螢幕(來源)、把鏡像結果送到哪一個螢幕(目標,通常是題詞機)。按「啟用鏡像」或快速鍵 ⌘M,題詞機那一面玻璃馬上看到正向文字。

🎛 常駐選單列、零干擾 沒有主視窗、不佔 Dock 空間,需要時點選單列那顆圖示,不需要時當沒這支 app。
🖥 自由指定來源/目標 多螢幕也能挑:MacBook 螢幕鏡像到題詞機、外接螢幕鏡像到題詞機、甚至 A 螢幕鏡像到 B 螢幕。
⌨ ⌘M 切換、⌘⌥M 救命 錄影中可以一鍵切換鏡像啟用/停用。萬一鏡像視窗遮住整個畫面點不到,⌘⌥M 強制關掉。
🔌 螢幕拔除自動停用 把題詞機 HDMI 線拔掉、或外接螢幕睡眠,ElgatoMirror 會自動關掉鏡像不掛起。
⚡ 即時水平翻轉 讀 ScreenCaptureKit 串流、套 scaleX(-1) transform、貼到目標螢幕的全螢幕視窗,延遲幾乎察覺不到。
🆓 完全免費、MIT 開源 不上 Mac App Store、不收訂閱、不收一次性買斷——下載 dmg 拖進應用程式就能跑。

那個救命快速鍵的故事

⌘⌥M 緊急停用是 v1.0 沒有、後來才加上去的。某次測試我把 MacBook 內建螢幕同時設成來源和目標——把自己的畫面翻轉之後蓋回自己身上。結果整個畫面變成一片翻轉的視窗、選單列被自己遮住、滑鼠點不到任何地方。那五分鐘只能用 Mission Control 切去別的桌面慢慢救。修完之後加了規則:無論鏡像視窗多大,按 ⌘⌥M 一定強制關掉。這條走 NSEvent.addGlobalMonitorForEvents,比視窗事件優先級高,能穿透自己造成的遮蔽。

# 自己編譯(需要 Apple Developer 帳號 + Apple Development 憑證)
git clone https://github.com/AndyJuang/ElgatoMirror.git
cd ElgatoMirror
# 修改 build.sh 裡的憑證名稱為你自己的
./build.sh
open ElgatoMirror.app

# 權限怪怪的?清掉 TCC 快取重來
tccutil reset All com.zhuangzheyun.ElgatoMirror

背後的技術:ScreenCaptureKit + Metal + 一個全螢幕視窗

這支 app 看起來像在「翻轉顯示器訊號」,實際上做的事拆開來其實單純:

  1. 抓畫面:用 macOS 12.3 開始提供的 ScreenCaptureKit,訂閱來源螢幕的即時 frame stream。這比舊的 CGDisplayStream 高效,也是 Apple 現在唯一推薦的 API。
  2. 翻轉:拿到 CMSampleBuffer 之後丟給一層 Metal shader,做 scaleX = -1 的水平翻轉。這比 Core Image 路徑省一輪 CPU↔GPU 來回。
  3. 顯示:在目標螢幕開一個沒有 title bar、覆蓋整個 display 的 NSWindowlevel = .screenSaver 確保壓在所有東西上面,把翻轉後的 frame 即時繪製上去。
  4. 權限:第一次跑會跳系統授權窗,要在系統設定 ➜ 隱私權與安全性 ➜ 螢幕與系統錄音勾起來。這道牆 Apple 從 macOS 10.15 開始就守得很緊,跳不過。

整個專案 build.shswiftc 直接組出 .app bundle,沒用 Xcode 專案檔。簽碼必須用 Apple Development 憑證(免費 Apple ID 也有)、不能用 ad-hoc——不然 macOS 每次重新編譯都會把「螢幕錄影」權限重新打掉,每次都得進系統設定再勾一次。這個雷我踩了三次才搞清楚。

用 Claude Code 寫的工作流

我不是 Swift 工程師。寫這支 app 的方式跟我寫 iPhoneMirrorWiFiScopeMacPrism 一樣:

  1. 描述痛點:「我要做一個 macOS 選單列工具,能把任一個螢幕的畫面水平翻轉後即時顯示到另一個螢幕上,給 Elgato Prompter 題詞機用。」
  2. Claude Code 提架構:建議用 ScreenCaptureKit 抓畫面、Metal 做翻轉、全螢幕 NSWindow 顯示——順手把舊版 CGDisplayStream 為什麼不該用講了一遍。
  3. 第一版跑起來,我報告問題:「卡頓有點明顯」「拔掉螢幕沒自動關」「我把自己鏡到自己畫面整個沒救」。
  4. 它迭代:卡頓改 Metal 路徑;拔螢幕監聽 NSScreen.didChangeNotification;自己鏡自己這件事加 ⌘⌥M 救命鍵 + UI 偵測同螢幕跳 warning。
  5. v1.0.2 的修正:TCC 權限快取偶爾抽風,這版專門加了 README 一段「跑 tccutil reset All com.zhuangzheyun.ElgatoMirror」的疑難排解。
「I think a lot of people are scared of the idea of letting Claude write code for them. The thing I've found is that if you can describe what you want clearly enough, Claude can do it.」
(很多人不敢讓 Claude 幫你寫程式。但我發現只要你能把要的東西講清楚,它就能做出來。)—— Boris Cherny, Anthropic(Claude Code 共同作者,語出 Latent Space podcast 訪談)

我做的事是:定義要解的痛、看跑起來對不對、報告 bug、加新需求。ScreenCaptureKit 的 frame buffer 格式、Metal pipeline state 怎麼設、NSScreen notification 細節——這些不是我會的,但也不需要我會。

非工程師合集第五件

盤點到目前為止,我用 Claude Code 寫出來、公開放在 GitHub 上的 vibe coding 作品:

  • MacPrism——menu bar 系統監控工具,連 AI 額度都看得到
  • WiFiScope——WiFi 頻譜分析工具,仿 $19 商業軟體 WiFi Explorer
  • iPhoneMirror——上課 demo 手機畫面用的免費投影工具
  • MkDown——每天寫 Markdown 寫到崩潰,週末寫一個
  • 那個數位官網——你正在看的這個,Web + Serverless + Redis

加上 ElgatoMirror 是第六件。共同點是每一個都來自我自己的具體痛——監控不到 AI 額度、上課 WiFi 卡、QuickTime 黑邊、Markdown 編輯器難用、官網沒人寫,現在多加一條:題詞機鏡像不會動。我從來沒先想「我要學 Swift」,是先想「這件事為什麼這麼煩」、再想「能不能自己做」。對也想試的人,我每篇都重講一次的三件事:從你自己的痛開始不要怕陌生的技術棧(會不會 Swift 跟能不能寫出 Swift app 是兩回事)、寫完就開源寫個 README,十個人試用回兩個 issue,這支工具會變得更好。

結語

那一片 45 度斜架在鏡頭前面的玻璃,原本是個會卡住整天錄影排程的東西。現在它對我來說,是選單列圖示點兩下、按 ⌘M、開始錄。題詞機上的字正向、鏡頭裡的我直視觀眾、稿子在玻璃跟瞳孔之間。一行 Swift 我也不會寫的時候,這個問題沒救;願意把痛點描述清楚之後,這個問題不再是問題。

需要的話拿去用。覺得有用幫我按個 star、覺得卡哪裡開個 issue 跟我說。

🪞 立刻下載 ElgatoMirror

macOS 13 Ventura+ ‧ MIT 授權 ‧ 免費 ‧ 開源 ‧ Swift + ScreenCaptureKit + Metal

那個數位的 AI 內訓會帶你的非工程師員工,從 0 開始用 Claude Code 蓋自己的工具——從 web 到 native app、從 HR 流程到工程腳本歡迎預約諮詢

讓你的員工也能自己做工具

從 web 到 native app、從 HR 流程到工程腳本——那個數位的 AI Coding 員工賦能訓練。

預約內訓諮詢