MeshPTT App 圖示:對講機、聲波與網路節點

MeshPTT:iOS 離線對講研究

目標:手機與手機之間不靠網路、不經路由器,直接點對點即時對講。本頁整理可行性研究、架構設計與實機驗證的結果;完全離線(飛航模式)的實測排在下一步。

2026-11-14(六)~11-15(日) PoC 實機驗證中

結論Summary

標記規則:確定=在官方文件或其他出處直接看到;判讀=推論,會寫依據;查不到=找過沒有可信出處。

可行性研究Feasibility

在動手寫程式之前,先針對傳輸、音訊延遲、Apple 內建功能、現成 App 與開源專案做了一輪調研(2026-11-14)。以下摘要保留原本的「確定/判讀」標記與出處連結。

2.1 傳輸路線比較

路線即時語音背景/限制與結論
MultipeerConnectivity可(.unreliable 模式)。Apple DTS:「good latency but poor throughput」單一 session 上限 8 人;進背景就停止廣播並斷線;Xcode 27 整個框架棄用確定
→ 新專案不建議
Network.framework 點對點(includePeerToPeer,走 AWDL)可。UDP 一包語音封包不需分片與 Multipeer 共用底層 AWDL;研究者報告 AWDL 會讓 Wi‑Fi 延遲在 3–90 ms 間跳動;背景可跑,被 suspend 就停
→ 備案與對照組
Wi‑Fi Aware(iOS 26+、iPhone 12 起)可。官方有 realtime 模式與 interactiveVoice 存取類別Apple 未公布毫秒數、距離與人數上限;每一對裝置需配對一次(輸入 PIN);realtime 較耗電
→ 主線,需實測
藍牙 LE(L2CAP)頻寬夠,但連線參數 App 不可控iPhone 對 iPhone 延遲查不到;背景可探索與喚醒,不是持續通道
→ 只當探索與喚醒
PushToTalk 框架只管系統 UI、頻道狀態與背景喚醒,音訊與傳輸自備離線沒有喚醒路徑(見 2.4)
→ 離線版不適合

確定出處: TN3213、 Multipeer 框架頁、 MCSession、 Apple 論壇(Multipeer 與 Network.framework 共用底層)、 AWDL jitter 與 Wi‑Fi Aware 建議、 Wi‑Fi Aware 框架頁、 官方範例、 WWDC25 228、 iOS 26 Release Notes、 The Register:AWDL 延遲研究報導(摘要,非原文)、 藍牙 L2CAP(Apple 論壇)、 CBL2CAPChannel。

判讀建議路線:Wi‑Fi Aware 負責配對與資料通道,Network.framework 的點對點當 A/B 對照。依據:Apple 文件把低延遲、多連線、背景可連都寫進 Wi‑Fi Aware;論壇上 Apple 工程師在 AWDL 抖動的討論中,直接建議改試 Wi‑Fi Aware 的 realtime。

判讀3–6 人不需要多跳 mesh:單跳全連接或星狀就夠(相鄰的人在同一個空間;Apple 沒有現成的多跳路由機制,查不到)。全連接的連線數為 3 人 3 條、4 人 6 條、5 人 10 條、6 人 15 條;頻寬不是問題。

2.2 AirPods 的瓶頸:用了麥克風,播放就掉到 HFP

2.3 端到端延遲預算(單向,口到耳)

路徑 A:AirPods 麥克風+AirPods 播放(HFP、voiceChat、語音處理,標準做法)。傳輸與 jitter buffer 兩欄是假設值,其餘多為推估。單位:毫秒。

段落樂觀典型悲觀依據
聲學(嘴到麥克風)112判讀距離換算
AirPods 麥克風+HFP 上行254580判讀信心低;查不到任何實測
iPhone 擷取 IO+語音處理102040判讀
Opus 編碼12.522.530確定RFC 6716:幀長加 look-ahead
點對點傳輸51560假設;Wi‑Fi Aware 無公開數字
接收端 jitter buffer104080假設;1–4 個 20 ms 幀
解碼+混音+輸出 IO51225判讀
HFP 下行+AirPods 喇叭254070判讀信心低
合計約 94約 196約 387

判讀把幀長改 10 ms、jitter buffer 20 ms、傳輸 8 ms,典型仍約 159 ms,超過 150。結論:AirPods 路徑只有全部押樂觀才可能 <150 ms,現實區間約 160–260 ms,中位約 195 ms。

四條路徑對照(單向,毫秒)

路徑樂觀典型悲觀說明
A. AirPods 麥克風+播放(HFP)94196387標準做法
B. AirPods 高品質錄音209371637不建議;上下行數字為示意量級,無出處
C. 內建麥克風+AirPods 播放(A2DP)129246447比 A 更慢:A2DP 下行約 140 ms
D. 有線耳機(對照)42111237典型可達 <150 ms

確定A2DP 播放延遲的錨點:Stephen Coyle 量測 AirPods Pro 2 約 126 ms(9to5Mac、原文);開發者回報 outputLatency 約 160 ms(論壇);Game Mode 下 151 ms 降到 60 ms(論壇)。

判讀ITU‑T G.114 的說法是多數使用者在口到耳 200 ms 以內仍滿意;路徑 A 典型約 196 ms 剛好在邊緣。對講是輪流說話,容忍度可能比電話高,但這一點沒有出處,需要實驗與使用者試用確認。

產品面風險:「坐在隔壁」。隔壁的人會直接聽到你的聲音(約 3 ms),電子通道晚 150–250 ms 才到,兩者疊加就是回音。要靠耳機降噪壓低直達聲,這比追 150 ms 更該先驗證。判讀

2.4 PushToTalk 框架:沒有網路時能不能用?

確定官方唯一列出的收音喚醒路徑是 APNs 的 pushtotalk 推播;替代路徑是 Local Push Connectivity(需要區網上的自家伺服器、依 Wi‑Fi SSID 啟動、要向 Apple 申請受管 entitlement)。

出處:PushToTalk 教學、Local Push Connectivity、Apple 論壇:後端需求、WWDC22 10117(後兩者為摘要)。

2.5 Apple 內建功能:有沒有重造輪子?

確定沒有。Apple 內建的沒有任何一個能滿足「3–6 人、AirPods、雙向、不用網路」。

功能做什麼為什麼不能滿足
即時聆聽(Live Listen)iPhone 麥克風的聲音送到你的 AirPods單向;沒有把耳機這端的聲音傳給別人
對話感知/對話增強你開口時降低媒體音量、放大面前說話者的聲音只改你自己聽到的,不傳給任何人
Apple Watch 對講機以 FaceTime 為基礎的按住說話依賴 FaceTime 與網路;watchOS 27 已正式停用(Apple 支援頁日期 2026-09-17)
FaceTime 群組、SharePlay群組通話要經 Apple 伺服器,不離線判讀
共享音訊(Share Audio)把一台手機播的聲音分享給第二副耳機不是雙向語音
AirDrop近距離傳檔只傳檔案

判讀iOS 26/27 沒有新增相關功能;Apple 在 2026 年不但沒補上這個缺口,還移除了自家唯一的對講功能。這代表沒有官方產品會競爭,也沒有官方方案可以借。

2.6 現成 App 與開源專案

需要網路的(只能當 UX 參考)

App備註
Zello頻道最多 6,000 人;無網路不能用
Voxer偏語音訊息

不需網路、點對點的

確定有約十個以上,都是獨立開發者小品,沒有任何一個公布延遲數字;評分樣本極少。「有真實使用者長期驗證的離線 iOS 即時對講 App」:查不到。

App機制AirPods 線索狀態
DirectTalkWi‑Fi 直連,可經 Bonjour 擴大範圍使用者評論提到搭配 AirPods Pro 當摩托車對講機2025‑09 後未更新
TalkyMultipeer,最多 8 台官網寫支援 AirPods近期仍活躍
RockyTalkieWi‑Fi Direct+藍牙,Mesh(beta)更新說明有 AirPods 中鍵按住說話、可背景使用評分樣本極少

判讀共同弱點:多數建在已棄用的 Multipeer;上限多在 8 台上下(剛好涵蓋 3–6 人);變現靠廣告與訂閱。硬體端早已解決這個需求,例如 Sena 60S(Group Mesh 24 人)、Cardo PACKTALK(最多 31 人),但那是專用無線電晶片加專用耳機,不是手機加 AirPods。確定

開源

專案授權與需求的距離
andreapianidev/WalkieTalkie(Talky 原始碼)PolyForm Noncommercial(非商用)最接近,但只能當設計參考;Multipeer,音訊走 PCM
wpu3325/roger-thatMITBLE+Multipeer;Opus 仍是 TODO
alta/swift-opusBSD-3-ClauseOpus 的 Swift 封裝,可用但缺文件
Apple Wi‑Fi Aware 範例Apple 範例UDP+realtime,但傳的是座標,不是音訊
bitchatUnlicenseBLE 多跳文字 mesh,沒有語音;可借對等發現與加密做法

開源專案的授權於 2026‑11‑14 讀取。「以 Bonjour 當信令、不需伺服器的 iOS WebRTC 範例」沒找到成熟的。

失敗案例與教訓判讀

研究的限制。Apple 官方文件頁的事實(Multipeer 棄用、Walkie‑Talkie 停用、bluetoothHighQualityRecording、allowBluetoothA2DP 等)已對照原文;其餘事實來自分工調研,Apple 論壇與 WWDC 頁面為摘要而非逐字原文,引言請視為轉述。整份研究最弱的環節:AirPods 麥克風上行延遲沒有公開實測、傳輸與 jitter buffer 是假設值、多篇論壇實測是單一發文者。Apple 論壇連結對自動檢查回 403(擋機器人,非連結失效),請用瀏覽器開啟。

架構Architecture

PoC 以原生 Swift/SwiftUI 實作:一個 Universal App(iPhone+iPad),核心邏輯放在 iOS 與 macOS 共用的 Swift Package,並附一個 macOS 命令列對等端方便自動測試。

3.1 音訊管線

MeshPTT 音訊管線 說話端:麥克風、編碼、加密,經點對點連線;收聽端:解密、抖動緩衝、混音、播放。 裝置 A(說話端) 裝置 B(收聽端) 1 麥克風語音處理 2 編碼PCM16,20 ms 幀 3 加密AES‑GCM 4 點對點連線不經路由器 無線傳送 5 解密驗證+防重放 6 抖動緩衝目標 2 幀 7 混音多人合成單聲道 8 播放喇叭/聽筒
單向流程:說話端的麥克風經編碼與加密送上點對點連線;收聽端解密、經抖動緩衝與混音後播放。虛線代表無線傳送。每一幀都帶時間戳,用來量測各階段延遲。

3.2 傳輸抽象層

所有傳輸實作同一個介面(單一封包 ≤ 1200 bytes),上層的配對、加密、抖動緩衝與量測完全不知道底下是哪一種無線電。

Wi‑Fi Aware(主線,iOS 26+)

使用 WiFiAware 與 DeviceDiscoveryUI:配對畫面由系統提供,每一對裝置配對一次後會保留;以 Publisher/Subscriber 宣告與探索服務。實機上可用,簽章時由 Xcode 自動加上 entitlement。

Network.framework 點對點(備案與對照)

UDP+Bonjour 探索,實機啟用 includePeerToPeer,實際走 AWDL(Apple 的點對點 Wi‑Fi)。沒有 Wi‑Fi Aware 的舊裝置也能跑;模擬器上則退化為本機迴路,用於自動化測試。

另有記憶體內的 Loopback 實作,用來做握手、重連、重複連線與敵意輸入的單元測試。專案沒有使用已被標為棄用的 MultipeerConnectivity。

3.3 配對與加密(概要)

  1. 同一房間的裝置輸入相同的 6 位數 PIN。
  2. 由 PIN 以 HKDF 推導出金鑰,雙方互送 HMAC 做相互驗證;未完成握手的對象送來的封包一律丟棄。
  3. 之後每個封包以 AES‑GCM 加密,帶方向性 nonce 與重放視窗。
已知弱點:6 位數 PIN 若被人錄下配對過程的封包,可離線窮舉。目前定位為「一般程度」的 PoC;正式上線前應改用 PAKE(例如 SPAKE2 或 OPAQUE)。研究階段的教訓也指出:「按下就開麥」是高風險功能,配對與提示要設計得最嚴格。

3.4 從實機學到的事

模擬器階段看不到、上實機才暴露的問題(都已修正並補回歸測試):

前期幾輪量測因實作缺陷作廢、修正後重測;本頁只採用修正後的數字。

使用方式How it works for the user

  1. 兩台(或以上)裝置各自開啟 App,設定相同的 6 位數房間 PIN;顯示名稱預設帶入機型,可自行修改。
  2. 選擇連線方式(預設為點對點;支援的裝置可選 Wi‑Fi Aware,首次需配對一次),選擇說話模式:按住說話或常開。
  3. 按「開始對講」。首次使用會詢問「本機網路」與「麥克風」權限,兩者都需要允許。
  4. 房間畫面顯示連線狀態,成員卡顯示對方名稱、連線方式與往返時間;按住圓鈕說話,放開就停止,對方說話時會出現跳動的波形。
  5. 「延遲量測」卡即時顯示 p50、p95,以及三項驗收門檻:p50 ≤ 200 ms、p95 ≤ 300 ms、斷線 = 0(暫定值)。

目前通話中不要手動鎖屏:鎖屏會讓通話中斷。房間畫面已關閉自動鎖定。

實測數字Measurements

讀數字前請先看條件。下表每一列都標明量測條件與傳輸方式。模擬器的數字來自同一台 Mac 上的兩台模擬器,網路段只是本機迴路、播放是虛擬計時器、音源是合成音,不代表任何真實無線延遲。只有標示實機的才是真實裝置上量到的。

怎麼讀:「斷線」欄為非預期斷線次數。total=收音時間戳到播放時刻,單位毫秒(ms)。每格「A/B」是兩台各自量到的「對方 → 自己」方向。p50 的差異來自兩台各自的收音與播放計時器相位差,不是不穩定。實機的 total 是 App 內部延遲,不含喇叭與麥克風硬體(實機量到兩者合計約 3~9 ms)。

5.1 實機(真實裝置)

條件:用 Mac 遙控自動測試,每次 40~45 秒,程式模擬每 6 秒按住說話 4 秒;真實麥克風;兩台互相收音會回授,所以播放端靜音,但播放路徑照常執行並量測。「實機・真麥克風」指真實麥克風訊號(非合成音),按住說話由程式模擬。

條件/版本total p50total p95斷線
改版歷程(舊版對照)
實機・真麥克風AWDL 點對點
修正後、舊收音(tap)
iPhone 14 Pro ↔ iPad mini
145/156223/2180
實機・真麥克風AWDL 點對點
舊收音(tap),同環境對照
iPhone 14 Pro ↔ iPad Pro 11 吋
182/180244/2400
實機・真麥克風AWDL 點對點
新收音(sink),未保溫
iPhone 14 Pro ↔ iPad Pro 11 吋
111/111251/3700
實機・真麥克風AWDL 點對點
新收音(sink),常開模式
iPhone 14 Pro ↔ iPad Pro 11 吋
98/8399/830
最終版
實機・真麥克風AWDL 點對點
sink+保溫+看門狗
iPhone 14 Pro ↔ iPad Pro 11 吋
77/74117/1150
實機・真麥克風區網 Wi‑Fi(en0)
最終版,真正的 App 畫面流程(自動進房、按住說話)
iPhone 14 Pro ↔ iPad Pro 11 吋
91/69—0
實機・真麥克風AWDL 點對點
最終版;其中一台第 20 秒自動鎖屏,只算前 20 秒
iPad Pro 11 吋 ↔ iPad mini
103/84264/—1
鎖屏後
Wi‑Fi Aware(僅有合成音數據)
實機・合成音Wi‑Fi Aware
當日早上版本,非最終版
iPhone 14 Pro ↔ iPad mini
50/4451/450

最終版分段數據(實機・真麥克風AWDL 點對點,iPhone 14 Pro ↔ iPad Pro 11 吋):

其他實機觀察:

5.2 模擬器(同一台 Mac,不代表無線延遲)

條件:兩台模擬器(最多同時 2 台)在同一台 10 核心 Mac 上;網路段為本機迴路,sendToRecv 約 0.8 ms;播放為每 20 ms 一次的虛擬計時器;音源為合成音;RTT p50 約 1.3–2.0 ms。抖動緩衝目標預設 2 幀。除另有標註外,以下各列的掉包、PLC、underrun 皆為 0。

條件/情境total p50total p95
模擬器本機迴路
iPhone ↔ iPhone,常開 90 s
4,453/4,455 幀
22.6/32.823.1/33.6
模擬器本機迴路
iPhone ↔ iPhone,按住說話(4 s 講、2 s 停)60 s
1,994/1,957 幀
40.2/34.240.7/35.0
模擬器本機迴路
iPhone ↔ iPhone,浸泡 480 s
p99 24.5/25.8;23,941/23,948 幀
23.6/24.224.2/25.5
模擬器本機迴路
iPhone ↔ iPad,常開 90 s
23.3/27.324.2/27.8
模擬器本機迴路
iPhone ↔ iPad,按住說話 60 s
32.4/32.233.5/34.2
模擬器本機迴路
iPad ↔ iPad,常開 90 s
39.9/21.341.8/22.8
模擬器本機迴路
iPhone ↔ iPad,浸泡 300 s
40.2/24.340.9/25.8
模擬器本機迴路
兩台模擬器+macOS 命令列,共 3 個節點,60 s(6 個方向)
p99 ≤ 42.7
25.6–40.3—
模擬器本機迴路
iPhone + iPad + macOS,常開 60 s(6 個方向)
max ≤ 49.3;underrun 合計 3
25.1–40.3≤ 42.3

最後一列的 3 次 underrun:2 次發生在測試最後 1–2 秒(對方正在離開),1 次在 macOS 命令列端第 13 秒(單次,沒有 PLC)。模擬器上的 iPad 只證明同一套程式能在 iPad 版面下編譯、啟動、互通,不證明實機 iPad 的行為。

抖動緩衝目標對照(模擬器本機迴路,iPhone ↔ iPhone,常開 45 s,每列 A/B)

目標total p50total p95說明
0 幀11.7/19.012.7/19.4本機迴路沒有網路抖動,看不出風險;實機上 0 幀幾乎一定會 underrun
1 幀13.8/9.014.3/10.7同上
2 幀(預設)見上表—建議起點
4 幀80.2/73.681.0/74.0延遲約等於 4×20 ms,確認緩衝深度與延遲成線性

模擬器斷線恢復:對方被強制結束再重開,音訊停在第 21 秒;第 26.0 秒偵測逾時(設定值 5 秒);重開後約第 27 秒已連上,握手 0.6–0.9 ms。聲音中斷共約 6 秒,其中 5 秒是逾時偵測。

5.3 尚未量測

真實無線延遲在 Wi‑Fi Aware 最終版上的重測、完全離線(飛航模式+Wi‑Fi)情境、走遠與穿牆、鎖屏與背景、電量與發熱、AirPods、三台同時實機對講、6 人以上。

畫面Screens

截圖由模擬器截取。畫面中出現的延遲數字(約 37 ms)是模擬器數值,不代表無線延遲;實機數字請見「實測數字」。
MeshPTT 主 App 與備案版的 App 圖示,各有淺色、深色、單色三種外觀
App 圖示。自繪的對講機、聲波與網路節點。主 App(藍綠色系)與備案版(暖色系)各有淺色、深色與單色三種外觀,一眼可分。備案版為不含 Wi‑Fi Aware 的測試變體,已從裝置上移除。
啟動動畫的淺色、深色與減少動態效果三組連續截圖,節點逐一亮起並連線,最後進入首頁
啟動動畫。以 SwiftUI Canvas 自繪,全程 1.8 秒:圖示彈出 → 網路節點一個個亮起並放出光環 → 連線一條條長出 → 光點沿線流動 → 名稱淡入。動畫疊在已載入的首頁上,不拖慢進入 App,點一下可略過。上排淺色、中排深色;下排是系統開啟「減少動態效果」時的版本,改為靜態構圖加淡入淡出。
首頁與對講房間畫面:iPhone 淺色與深色、iPad 淺色與深色,房間顯示已連線、成員卡、延遲量測卡與橘色按住說話圓鈕
首頁與房間。首頁分為「你是誰」「連線方式」「說話與聲音」「進階」四張卡片,「開始對講」固定在底部。房間上方是連線狀態、輸出路由與系統音量;成員卡顯示名稱、連線方式與往返時間,說話時有跳動波形;延遲量測卡以綠紅標示三格門檻;大顆圓鈕按下變橘色並有脈動光環與觸覺回饋,切到背景時會自動放開。支援 VoiceOver,深淺色模式與 iPhone/iPad 版面皆已檢查。

已知問題Known issues

兩台裝置距離很近、喇叭外放時會互相收音形成回授(嘯叫);防回授(半雙工、發言權、嘯叫偵測自動靜音)正在開發中。

下一步Next

  1. 防回授(優先)。半雙工、發言權、嘯叫偵測自動靜音;這是近距離喇叭外放時最直接的體驗問題。
  2. 離線打字互傳。沿用同一條加密點對點連線,不另開通道,讓語音不方便時也能傳文字。
  3. AirPods 實驗 E1。單一 iPhone,voiceChat+語音處理,AirPods 麥克風錄到立即回放到同一副 AirPods(不經網路),用外部麥克風錄拍手聲量間隔,Pro 2、Pro 3、AirPods 4 各量一次。環路 ≤110 ms 整條才有機會 <150 ms;110–170 ms 需改目標;>170 ms 表示 AirPods 與 <150 ms 確定不相容。PoC 的真麥克風模式與 audioSession 診斷欄位可直接沿用。判讀
  4. 補齊實機驗證。完全離線情境、Wi‑Fi Aware 最終版重測、三台同時對講、走遠與穿牆、中途切換音訊路由。
  5. 鎖屏與背景保活。評估 PushToTalk 框架或 CallKit,並實測 audio 背景模式在鎖屏下的存活時間(研究中看到有回報約 50 秒被系統結束,未確認)。
  6. 品質與安全。自適應抖動緩衝、PLC 品質、PAKE 配對、換成 Opus 編碼。
  7. 其他研究階段規劃的實驗。E2:A2DP 下行與漂移;E3:Wi‑Fi Aware 單向延遲(1/3/10 m,30 分鐘);E5:鎖屏存活 30 分鐘;E6:路由與聽感(Conversation Awareness、通透模式、側音);E7(選配):6 人壓力。

尚待決定