changelogkit static export (read-only): 69 documents, 15 features.
使用指南(8)
Docs/README.md · app
# 文件索引
本目錄收錄開發/除錯/設計文件。主專案說明請見上層 [README.md](../README.md)。
- 新增**修復紀錄** → 執行 `python Scripts/change_log.py`(或雙擊 `Scripts/change_log.cmd`)開本機網頁 GUI,或直接寫進 [ChangeHistory.md](ChangeHistory.md)
- 新增**主題文件** → 在下面對應分類加一行連結
## 分類設定與靜態站規劃
根目錄 `.changelog.toml` 依 …
Docs/development/APP_ICON_AND_PACKAGE_SIZE.md · app
# App 圖示診斷與包體占用
## 已發布產物比較
直接讀取 GitHub Release 的原始 IPA ZIP,未安裝或執行內容。
- [17.2.8](https://github.com/TwhomeGH/ReplyKit/releases/tag/17.2.8):5,148,762 bytes,約 4.91 MiB。
- [17.2.9](https://github.com/TwhomeGH/ReplyKit/releases/tag/17.2.9):7,711,578 bytes,約 7.35 …
Docs/development/README.md · app
# 開發索引與 API 文件
## 功能文件
- [MetricKit 本機效能報告](METRICKIT.md)
- [ScreenCaptureKit 本地錄影:錄後壓縮](RECORDING_COMPRESSION.md)
## 開啟方式
雙擊 `Scripts/change_log.cmd`,點「功能/API/近期改動索引」。原有新增/修改變更紀錄功能保留。
也可執行 `python Scripts/change_log.py serve --no-browser`,依終端機列出的本機位址開啟 ` …
Docs/development/SETTINGS_BACKUP.md · app
# 設定備份與側載到期資料保留
## 使用入口
工具 → 備份與還原。設定變更後約兩秒自動檢查並備份,不需要停留在備份頁。
內容未變不重寫;進背景時補存。系統凍結或簽署到期後不能再執行備份,請查看最近成功時間。
## 刪除 App 前先搬走
若 App 掉簽無法開啟,使用「檔案 → 我的 iPhone/iPad → 松鼠推流」,將下列資料複製至 iCloud Drive、其他 App 或電腦。
確認副本可讀後再刪除 App;存放在 App 文件裡的備份不會在刪除 App 後保留。
| 目錄 | 內容 |
…
Docs/development/version.md · app
# 版本標記說明
Release tag 只保留 `x.y.z`;標記由 CI 讀取 tag 之間的變更與 commit trailer 自動產生,寫入 GitHub Release 名稱與 body。Tag 本身不帶 `-Core`、`-Exp` 等字樣,以免影響 AltStore URL 與 tag 遞增規則。
## 自動分類
| 標籤 | 觸發方式 |
| ------ | ------ |
| `Core` | `SharedCapture/**`、`ReplyKIT/**`、`liveAPP/Cap …
Docs/sponsor.md · app
# 贊助支持說明
本專案為個人開發,致力於提供優質的直播推流應用。為了維持持續開發與更新,我們誠摯邀請您參與贊助支持。
## 贊助管道
目前支援以下贊助方式:
- **Twitch**: [https://twitch.tv/twhomegh](https://twitch.tv/twhomegh)
## 贊助用途
您的贊助將用於:
- 維持開發與更新
- 或支持其他項目開發
- 提升技術研發能力
## 感謝您的支持
感謝您對本專案的贊助,您的支持是我們持續開發的重要動力。
Docs/tts-filter-configuration.md · app
# TTS 過濾器 JSON 匯入與匯出
## 使用方式
進入「TTS 朗讀 → TTS 過濾詞管理」。每條排除/替換規則旁有啟用開關,停用只略過處理,不刪除規則。替換規則依畫面順序執行,可按「編輯」拖曳調整。
- **匯出目前配置**:將完整過濾配置儲存至主 App 的 Documents,與 `log.txt` 相同目錄。完成後可按「分享最近匯出的配置」,或從檔案 App 的本機 App 目錄取用。
- **匯入 JSON**:從系統文件選擇器匯入副本,背景讀取並完整驗證後,直接在目前頁面預覽數量與衝突。 …
README.md · app
# 松鼠🐿️推流
適用於iOS的直播推流應用
最近註冊了 愛發電有興趣可以去看看
[愛發電 快樂大松鼠](https://ifdian.net/a/coffee0709)

> [!WARNING]
> 說明文件不即時 由於後續更新迭代多次
>
> 文檔可能沒有更新 所以實際包含功能會有所區別
## 更新紀錄
近期更新包含:
- **擷取與錄影**:新增 ScreenCaptureKit 擷取路徑,保留 ReplayKit;提供本地錄 …
Docs/bitrate_mode.md · app
# 位元率模式說明
## 模式一覽
| 模式 | 值 | HaishinKit | 特性 | 適合 |
| ------ | ---- | ------------ | ------ | ------ |
| ABR | 0 | `.average` | 長期貼近目標 bitrate,允許短期波動 | **推薦** — 直播首選,穩定與畫質的平衡 |
| CBR | 1 | `.constant` | 嚴格維持固定 bitrate,波動最小 | 上傳頻寬極度受限或不穩定的環境 |
| VBR | 2 | `.v …
Docs/development/AV_LAG.md · app
# A/V 內容延遲診斷(AVLag)
## 快速入口
- 裝置資訊頁 → **A/V Lag** → **查看目前 AV Lag 報告**
- 報告頁可複製/分享 JSON,給回放 retime 工具做交叉比對;分享的是實際 `.json` 檔案,可直接交給分析工具
- 日誌關鍵字:`[AVLag]`
## 這份報告回答什麼
`videoContentAge`(介面顯示「影片內容延遲」)是「擷取回呼到達時間 - 影片來源 PTS」:
```text
videoContentAge = arrival - …
Docs/development/COMPRESSED_VIDEO_LIBRARY.md · app
# 壓縮成品與暫存管理
工具分頁與影片壓縮頁均可開啟「已壓縮影片」。清單直接掃描 Documents/CompressedVideos,支援播放、分享、多選永久刪除;刪除前確認,正在壓縮或選取項目是目前來源時禁止刪除。返回清單或 App 回前景會重新掃描。
## 空間與清理範圍
- 成品、目前程序暫存、前次程序暫存分開計量;不是 iOS「文件與資料」總量。
- 新相簿副本與手動轉碼檔案使用 tmp/ManagedVideoWork/程序 UUID/Imports 或 Transcodes。
- 正常轉碼收尾刪 …
Docs/development/COMPRESSION_TEST_FIXTURE.md · app
# 壓縮測試影片
`liveAPPTests/compression-source.mp4` 是 FFmpeg 產生的合成圖樣,不包含實際錄影或個人資料。規格為 H.264 Baseline、320×240、30 FPS、1 秒、無音訊、YUV 4:2:0 有限範圍與 BT.709 色彩標記。
測試 target 使用檔案系統同步群組,MP4 由 Xcode 當作資源加入測試 bundle。測試以 bundle 內的固定影片複製到獨立暫存目錄,然後真正執行手動碼率與系統品質壓縮;不再於準備階段另啟動編碼器。樣本 …
Docs/development/ENCODING_CAPABILITIES.md · app
# 編碼選項與健康指標入口
## H.264 裝置能力
主頁 → 編碼設定,展開後查詢 VideoToolbox ProfileLevel 支援清單。清單是該尺寸與模式的編碼器回報值,不保證所有 FPS、碼率、像素格式组合均可用。沒有清單時保留原值並顯示未確認;不補入猜測選項。
- `H264EncodingProfile.resolve`:共用設定解析。舊 Baseline/Main/High 改為同 Profile 的 AutoLevel;舊 Auto 與 Constrained/Extended 名稱仍 …
Docs/development/RECORDING_COMPRESSION.md · app
# ScreenCaptureKit 本地錄影:錄後壓縮
## 使用入口
主頁 → 擷取與開始 → ScreenCaptureKit → 本地錄影設定 →「錄後壓縮(SDR)」。預設關閉,設定在下次開錄時固定,與 RTMP 推流設定分開。
系統錄製編碼與錄後壓縮編碼是兩個階段。HEVC 是有損壓縮編碼,不是 MP4 容器;選用 HEVC 本身不保證檔案比 H.264 小。
| 選項 | 預設 | 用途 |
| --- | --- | --- |
| 完成錄影後壓縮 | 關閉 | 系統完成檔案後,才進行處理 …
Docs/development/SCREEN_CAPTURE_CALLBACKS.md · app
# ScreenCaptureKit 回呼入口診斷
`[CaptureCallbacks] schema=1` 與 CaptureSource 使用同一 session。擷取期間約每五秒回報,收尾排空後另記 stage=finished。
- callbacks:全部回呼,包含被忽略的樣本;video/audio/mic/unknown 分開。
- outcomes:invalid、notReady、missingStatus、nonComplete、missingImage、unknownType 為略過原因 …
Docs/development/VIDEO_COMPRESSION.md · app
# 手動影片壓縮
## 入口與輸出
主頁「常用工具」或「工具 → 影片工具 → 影片壓縮」可直接進入;也可使用碼率分析頁工具列「壓縮影片」,或本地錄影詳細頁「壓縮影片」。兩個入口都以頁面推入,不開臨時表單。可從相簿或檔案選取影片;分析頁目前選取的檔案也可帶入。
輸出為 MP4,存入 App 的 Documents/CompressedVideos,可從檔案 App 或文件共享取得,不依賴 App Group。名稱包含原檔名與 UUID,避免覆寫。原檔唯讀;暫存輸出在 App temporaryDirector …
Docs/haishinkit-fixes.md · app
# HaishinKit 修正記錄
## 問題:RTMP 連線卡在 `handshakeDone`,無法進 `connected`
### 現象
- RTMP TCP handshake 成功後狀態卡在 `handshakeDone`
- 伺服器等不到 `connect command`(SRS 30s timeout)
- 音影 sample 正常流入 MediaMixer,但從未 publish
- Twitch / SRS 皆受影響
### 根因
**`RTMPChunk.swift` — `chu …
Docs/metal-shader-optimizations.md · app
# Metal Shader 性能優化
## 2026.07.30 三項改進
### 1. 移除 `unsharpY` 死碼
**檔案:** `ReplyKIT/rotateNV12.metal`
`kernel void unsharpY` 已編譯進 Metal library 但 Swift 端從未呼叫。移除後減少 Metal library 編譯時間與 binary size。
相關:`catmullRom1D_uv` helper function 也一併移除(僅被 `bicubicSampleU …
Docs/screencapturekit-integration.md · app
# ScreenCaptureKit 雙來源接入
## 使用方式
在開播頁的「螢幕擷取方式」選擇 ReplayKit 或 ScreenCaptureKit。預設維持 ReplayKit;新來源標為測試中。停止直播後才能更換來源。
ScreenCaptureKit 路徑會呈現系統分享選擇器,取得使用者選擇後,依工作模式啟動推流、錄製或兩者。主 App 的「停止擷取」會關閉擷取、樣本消費端、Mixer 與 RTMP,再釋放跨程序直播鎖。取消選擇不會改用 ReplayKit。直播中更改系統分享選項會停止,請重新開始 …
Docs/video-dimensions.md · app
# 影片尺寸設計:AD / OD
本文整理 ReplyKit 影片尺寸設定的語意,避免把 GPU 中間處理尺寸誤當成最終輸出解析度。
## 欄位語意
| App Group / Socket 欄位 | Extension 狀態 | 用途 |
| --- | --- | --- |
| `dstW` / `dstH` | `ADWidth` / `ADHeight` | GPU 旋轉/縮放的中間處理尺寸 |
| `odstW` / `odstH` | `ODWidth` / `ODHeight` | 最終畫布尺 …
Docs/video-output-pool-lifetime.md · app
# GPU 輸出 Pool 與使用期限
## 2026-09-10 修正
原本 GPU completion 將 `ReusableOutputSet` 放回陣列,再回傳包裝同一個 pixel buffer 的 sample buffer。下游尚未讀完時,下一幀可能取出並覆寫相同儲存空間。陣列的鎖不能保護下游讀取期限。
現在每個輸出尺寸使用 `CVPixelBufferPool`,透過 `CVPixelBufferPoolCreatePixelBufferWithAuxAttributes` 配置 buffe …
PiP 與介面(12)
Docs/audio-volume-page.md · app
# 音量控制頁說明
## 目的
音量控制頁用於調整直播輸出的 App 音訊與麥克風音訊,並監看 ReplayKit extension 回報的即時 RMS 音量。
此頁面同時處理兩種不同概念:
| 類型 | 對應設定 | 用途 |
| ------ | ---------- | ------ |
| 輸出音量 | `appVolume` / `micVolume` | 控制最終混音輸出比例,範圍為 `0.0...1.0` |
| 增益放大 | `appAddVolume` / `micAddVolume` …
Docs/av-pipeline.md · app
# 影音管線架構
## 總入口:`SampleHandler.processSampleBuffer`
```text
ReplayKit samples
│ CMSampleBuffer
▼
SampleHandler.processSampleBuffer(_:with:)
│
├── .video ──────────────────────────────► VideoFrameProcessor.process()
│
└── .audioApp / …
Docs/development/HOME_MODULES.md · app
# 主頁模組與維護入口
## 第一批拆分
| 檔案(liveAPP/ 下) | 責任 |
| --- | --- |
| ContentView.swift | 頂層分頁、環境注入及原本的頁面/前背景通知 |
| Navigation/AppPage.swift | 分頁識別與 PageState |
| Home/HomeView.swift | homeView 的狀態、Binding、權限提示及響應式排版 |
| Home/HomeView_Cards.swift | 擷取、串流、編碼、ReplayKit …
Docs/development/LIVE_ACTIVITY.md · app
# 即時動態管理
入口:工具 → App 設定 → 即時動態 LiveActivity。預設關閉;明確啟用後摘要每 5 分鐘更新,可選 1、5、10、15 分鐘。停用只結束即時動態,不停止直播;直播中重新啟用會嘗試建立活動,仍受系統權限限制。
計時使用固定開播時間,由系統顯示;不靠高頻 Activity.update 維持跳秒。開播、重連、恢復與結束走事件更新,週期只刷新摘要。資料過期時間為更新間隔加 60 秒;系統暫停 App 時不能保證準時更新,不能把此排程當成背景保活。
設定立即重排目前任務。取消睡眠直 …
Docs/development/PIP_KEEPALIVE.md · app
# PiP 保活更新間隔
入口:PiP 主頁,或設定中的聊天/PiP 設定。預設每 5 秒更新,可設為 1–60 秒;調整會重排已啟動的保活更新工作。
間隔只控制保活畫面。聊天室仍使用原本的閒置、活動與動畫頻率。贊助疊加期間暫時以 6 FPS 更新,結束後回到指定間隔。此設定不保證永久背景執行。
## 實作入口
- `PIPRenderPolicy`:純計算、範圍驗證與模式頻率選擇。
- `PIPKeepaliveSettingsSection`:共用設定 UI,偏好鍵 `pipKeepaliveSecon …
Docs/development/PIP_REFRESH.md · app
# PiP 刷新與次要訊息
工具 → 子母畫面 PiP → 聊天室 PiP:時間刷新可選 1/2/5 秒,預設一秒。動畫維持自動變頻;開啟「降低聊天室動畫頻率」將活動/動畫目標由 6/16 FPS 降為 3/8 FPS。保活模式仍使用原本獨立間隔。這些頻率是排程目標,不保證實際輸出或系統背景執行。
時間字串依時間分桶及時區、語系快取。靜態聊天室只保留一張圖像,內容世代或尺寸改變即重建,動畫時直接繪製,停止清空快取。時間刷新仍須合成輸出畫面,並非零 GPU/CPU 成本。
次要訊息由 isMain=false …
Docs/development/SETTINGS_NAVIGATION.md · app
# 設定與五分頁導航
## 入口與歸屬
主分頁列的「設定」分頁是全域設定入口,由 AppSettingsView 分類導覽。日誌頁選單的「日誌設定」使用同一個 LogSettingsView,以獨立 NavigationStack 呈現,並提供完成按鈕。
| 分類 | 內容 |
| --- | --- |
| 一般 | App 語言 |
| Socket 與連線 | 本機位址、端口與服務設定 |
| 音訊 | 既有音訊設定 |
| 畫面與疊加 | 疊加、GPU 旋轉、進階編碼相容選項 |
| PiP 與聊天 …
Docs/home-layout.md · app
# 主頁操作與金鑰顯示
## 排版
- 優先顯示擷取來源、工作模式與開始/停止操作,本地錄影入口保持可見。
- 可用寬度達 850 點且未使用輔助使用的大字體時採雙欄;其他情況採單欄。
- ScreenCaptureKit 選擇只錄製時,隱藏 RTMP、推流碼率與編碼設定。
- 進階編碼、ReplayKit 畫面控制與權限檢查預設收合。
- ScreenCaptureKit 顯示自己的擷取、推流與錄影狀態;ReplayKit 的暫停與方向控制不套用到 ScreenCaptureKit。
- ScreenCapt …
Docs/overlay-scene-config.md · app
# 畫面加工 Overlay 配置設計
本文整理主 App 可視化配置與 ReplayKit Extension 讀取 Overlay 設定的設計。此功能是可選加工層;用戶不啟用時,既有輸出與原本 PiP overlay 行為應保持不變。
注意:本文件中的 Overlay 指「最終推流畫布加工」,不是 PiP 子母窗口排版。PiP 應使用獨立的 `PIPLayoutSettingsView` 與現有 `PIP*` 設定 key。
## 目標
- 在主 UI 提供獨立的「畫面加工設置」頁面。
- 讓用戶控制最 …
Docs/pip-keepalive-performance.md · app
# PiP 保活模式渲染效能
## 發現與修正
- 保活目標為 0.2 FPS,但排程以 `1 / max(currentFPS, 1)` 計算,實際至少每秒喚醒一次。現在使用完整低幀率值,無覆蓋層時每 5 秒更新一次時間畫面。
- 遞迴 `asyncAfter` 沒有取消控制代次;停止後立即重啟會讓舊 callback 通過共用布林檢查,可能增加渲染迴圈。現在取消待執行工作並使舊代次失效,在主執行緒進入及離開渲染時都確認代次。
- `rescheduleRenderTimer` 原本是空函式。現在真正提前下一 …
Docs/pip-layout-config.md · app
# PIP 排版加工設計
本文整理 PiP 子母窗口排版設定。PiP 排版加工與最終推流畫布 Overlay 是兩套設定,不應共用同一份 scene config。
## 邊界
PiP 排版加工負責主 App 內的子母窗口畫面:
- 聊天室主訊息字體大小
- 次要訊息字體大小
- 贊助覆蓋字體與停留時間
- 訊息淡出速度與滾動時間
最終輸出 Overlay 負責 ReplayKit Extension 的推流畫布:
- 時間、Logo、浮水印、狀態文字
- 最終 `ODWidth x ODHeight` …
Docs/pip-performance-improvements.md · app
# PiP 性能優化 (2026-07)
## 概述
改善子母畫面(PiP)渲染管線的多項效能瓶頸:
- 移除不必要的 async hop(actor → Task → MainActor)
- 加入 dirty flag 避免無變化時仍每秒產生 pixel buffer
- 消除配置(layout)重複計算
---
## 1. 移除 PIPRenderPipeline actor
### `liveAPP/PIPService.swift` - 移除 PIPRenderPipeline actor
…
診斷與效能(17)
Docs/cooperative-queue-stack-overflow.md · app
# AsyncStream yield() 同步鏈造成 cooperative thread stack overflow (bug_type 309)
## 問題
ReplayKit extension(`ReplyKIT`)在 iOS 27 beta 上反覆出現 `bug_type: 309` crash:
```log
"bug_type":"309",
"exception":{"type":"EXC_BAD_ACCESS","signal":"SIGBUS","subtype":"KERN_PROT …
Docs/coroutine-frame-recursion.md · app
# Swift 協程幀分配器無窮遞迴
## 問題
`VideoFrameProcessor.process()` 對每幀 ReplayKit 畫面建立一個 unstructured `Task { }`。當 GPU 初次編譯 shader 管線時,`MTLComputePipelineState` 內部也使用 Swift async runtime。兩種非同步系統疊加 → Swift runtime 的 `__swift_coroFrameAllocStub` 無窮遞迴 → Stack Overflow。
# …
Docs/crash-tracing.md · app
# dSYM 崩潰追蹤工具
`crash_trace.py` 讀 Apple `.ips` crash report,把符號化、死因判定與跨執行緒死鎖分析一次做完。
**最重要的特性:它會驗證符號來源與這份 crash 是否相符,不再張冠李戴。**
## 快速使用
```bash
# 建議:指向含 dSYM 的目錄(用 crash 的 slice_uuid 挑正確的那份)
python crash_trace.py crash.ips -s "path/to/xcarchive/dSYMs"
# 單一 dS …
Docs/development/DEVICE_DIAGNOSTICS.md · app
# 設備資訊:來源管線、網路流量與報告單位
## 兩種來源的共同入口
設備資訊的 Video Pipeline/Audio Pipeline 卡片讀取 `StreamDiagnosticsModel`,同時支援 ReplayKit 與 ScreenCaptureKit。
- ReplayKit:擴展每五秒透過 Socket 傳送 `StreamDiagnosticsSnapshot`。
- ScreenCaptureKit:每五秒直接更新同一模型;推流與本地可控錄製共用 Mixer 探針,推流停止而錄製繼續時 …
Docs/development/LOG49_DIAGNOSTICS.md · app
# log-49 管線停滯與記憶體調查
## 已確認的證據
- 2026-10-07 02:24:59,ScreenCaptureKit session E92A12FA 的 RTMP 連線遭遠端重設,隨後進入重連。
- 02:25:12 至 02:36:07,混音輸出探針 delivered 固定 4257;mixed 從 4408 增加到 35100。這不是只有 UI 沒刷新,至少 Mixer 產出與輸出端接收不再一致。
- 02:36:08 開始停止,02:36:09 capture.stopEnd 之後 …
Docs/development/LOG58_DISCONNECT.md · app
# log-58 斷流與時間軸診斷
## 已知結果
本次產物為 App `f325435`、HaishinKit `7ce4304b`。2026-10-20 15:54:45 因心跳等待 5 秒無回應而主動斷線;後續四次重連皆卡在 S0S1。第五次重連期間使用者停止,不能將其視為獨立的伺服器拒絕證據。
斷線時擷取與混音仍持續。現有日誌無法區分伺服器未回應、網路中斷或客戶端接收異常,需對照 SRS 同日 15:54:35~15:56:10 的日誌或封包。
## 新增診斷
底層每次心跳探測入列及逾時記錄:
…
Docs/development/LOG_DIAGNOSTIC_EXPORT.md · app
# 時間範圍診斷日誌匯出
入口:日誌頁 → 匯出診斷日誌。支援今天、最近一小時及自訂日期時間,產生後以分享按鈕送出 UTF-8 文字檔。今天與最近一小時以按下產生時為準;檔名及文件頭包含範圍。
不改變主 log.txt。先在持久化佇列 flush、匯入擴展封存,將封存與主檔合成快照,再背景分塊讀取,避免正在追加或清空主日誌造成內容混雜。快照複製期間暫時佔用寫入佇列,檔案很大時會延後寫入;不持有整檔記憶體。單行超過 8 MiB 時明確失敗,不靜默截斷。
中文年月日與時段格式優先解析,其次嘗試目前語系與 en_U …
Docs/development/LOG_PERSISTENCE.md · app
# 長時間直播日誌保存
## 主 App
主日誌仍為 Documents/log.txt;超過約 7,000 行或 8 MiB 時,關閉 handle,將整個檔案移入 LogArchives,不再裁掉前段。下一批重新建立 log.txt。封存以時間及 UUID 命名;單次批次可略超過觸發門檻。
維持 0.5 秒/50 筆先到先寫。背景持續寫入會重用 handle,十秒閒置後才同步並關閉;回前景取消閒置關閉。系統暫停時程式無法持續執行,關檔不是保活機制,仍不能保證程序強制終止前零遺失。
成功 write 才計 …
Docs/development/METRICKIT.md · app
# MetricKit 本機效能報告
## 使用方式
設備資訊 → 系統效能報告 → MetricKit 歷史報告。可以查看收到時間、報告涵蓋期間、內容分類、指標解讀與原始 JSON,也可以分享單份報告。
主 App 啟動時由 `MetricReports.shared.start()` 訂閱一次,視窗建立與銷毀不重複註冊。使用相容舊 iOS 的 MXMetricManagerSubscriber API;新版 SDK 可能提示此 API 已被新版 MetricManager 取代。
## 資料與限制
- …
Docs/development/STREAM_DIAGNOSTICS.md · app
# 設備資訊:串流格式與 RTMP 傳輸
## 入口與更新
設備資訊頁的「串流格式與 RTMP 傳輸」提供 ReplayKit、ScreenCaptureKit 各自的展開區塊。每五秒取樣,只保存每個來源最新一筆;超過十五秒標為歷史資料。ReplayKit 由擴展經 Socket 傳入,ScreenCaptureKit 直接更新同一模型。來源 session UUID 與 socket generation 分別表示探針生命週期與連線計數世代。
## 已接入
- Mixer 實測:影像寬高、pixel Fo …
Docs/generic-specialization-recursion.md · app
# 泛型特化遞迴 (ExpressibleByIntegerLiteral)
## 問題
`ExpressibleByIntegerLiteral.init(data: Data)` 使用 `data.withUnsafeBytes { $0.pointee }`
來讀取整數值,但這個 closure 回傳型別是 `Self`(例如 `UInt32`),導致 Swift compiler
產生 `Data.withUnsafeBytes<UInt32>` 的泛型特化版本。
在特定情況下,這個 compil …
Docs/log-system-improvements.md · app
# 日誌系統改善 (2026-06)
## 概述
修復 LogManager 的多項設計問題,重點在於:
- 消除日誌丟失(data race、reentrancy drop、單封包過大)
- 將重負載移出 barrier queue,提升整體效
- 側載無 App Group 時自動強制走 Socket 轉送
- 檔案 App 可直接讀取日誌
---
## 1. Socket 傳送修復
### `ReplyKIT/Socket.swift`
| 問題 | 原因 | 修正 |
| ------ | - …
Docs/log-view.md · app
# 日誌頁顯示、歷史與搜尋
日誌頁以主 App Documents 的 `log.txt` 為準,主 App、Socket 與擴展轉送的日誌由既有 AppLogPersister 匯入主檔案。讀取與寫入共用序列佇列,讀取前先將待寫內容落盤。
## 歷史瀏覽
- 預設顯示最新 200 行,較早/較新按鈕依檔案行號分頁。
- 切頁或進入背景不清除歷史;保留目前頁面、捲動位置與篩選狀態(限本次 App 執行期間)。
- 拖曳進入歷史閱讀模式,有新內容只顯示新增數量。按「回到最新」恢復追尾。
- 只有日誌頁可見且 A …
Docs/memory-warning-removal.md · app
# 移除 MemoryWarning 監聽設計
## 2026.07.31
## 背景
App 原本監聽 `UIApplication.didReceiveMemoryWarningNotification`,收到系統記憶體壓力警告時:
1. **PIPService**:清空 `pixelBufferPool` + `cachedFormatDescription`(強制 PiP 渲染管線重建)
2. **SocketServer**:清空所有 receive/send buffer(包括在途 log p …
Docs/nw-recursion.md · app
# NWConnection 遞迴 receive 模式
## 問題
`NWConnection.receive` 的 completion handler 內部直接呼叫 `self.receive(...)` 會造成潛在的 stack overflow。
### 危險模式
```swift
// ❌ 危險:callback 內直接遞迴
private func receive() {
connection.receive(...) { data, _, _, _ in
// ... …
Docs/page-switch-crash-analysis.md · app
# 頁面切換崩潰修復:HaishinKit Buffer Overflow 導致 Swift String 記憶體損毀
## 現象
- 在日誌頁、音量頁、PIPChat 頁面之間切換時觸發崩潰
- crash 類型:`EXC_BAD_ACCESS/SIGSEGV`,`bug_type 309`
- fault address:`0x8`(nil 指標 + 8,PAC failure on ARM64e)
- 崩潰函數:`swift_isUniquelyReferenced_nonNull_native`
## …
Docs/uint32-overflow-2026.md · app
# UInt32 時間戳溢位(2026 年問題)
## 問題
`RTMPHandshake.c2packet()` 將 `Date().timeIntervalSince1970 * 1000` 轉為 `UInt32`:
```swift
// RTMPHaishinKit/Sources/RTMP/RTMPHandshake.swift:60
var ct = UInt32(Date().timeIntervalSince1970 * 1000).bigEndian
```
### 計算
| 項目 | …
Socket 與 RTMP(5)
Docs/development/EXTERNAL_LOG_TRANSPORT.md · app
# 主 App 外部日誌通道
日誌頁選「外部/全部」後可選 HTTP Web(預設)或已連線 Socket;日誌設定亦提供同一選項。此選項不變更擴展本身的設定、檔案保存與交接。HTTP 是既有 POST 傳送,並非新增 HTTP 接收服務。
## Socket 訂閱
外部工具在既有連線送出一行 JSON:
```json
{"type":"subscribeExternalLogs","enabled":true}
```
回應 `externalLogSubscription` 的 enabled 表示 …
Docs/development/RTMP_TIMELINE_DIAGNOSTICS.md · app
# RTMP 時間軸診斷接入
套件版本:`d7ece58808efc052e8b1d444888d3a3255b55b1f`。兩份 Package.resolved 須一致,實機以 BuildInfo 確認產物實際使用的 checkout。
## 取得方式
- ScreenCaptureKit:主 App 的 CaptureTransport 白名單放行 `publish timeline`,沿用 session 標記與敏感資訊遮蔽。底層約每 10 次 status 產生一筆,不額外新增計時器。
- Repl …
Docs/development/SOCKET_MODULES.md · app
# Socket 模組與維護入口
| 檔案(liveAPP/ 下) | 責任 |
| --- | --- |
| Socket.swift | listener/端口切換、連線、換行 JSON 收送及訊息分派 |
| Networking/NWListenerState_Log.swift | listener 狀態轉日誌文字;不以字串控制連線狀態 |
| Networking/SocketServer_JSONValue.swift | 保留巢狀型別名稱的 Codable/Sendable JSON 模型與轉換 …
Docs/replykit-log-socket-stability.md · app
# ReplyKIT 日誌與 Socket 穩定性改進
## 根本問題
原有 pipeline 在大量日誌時有三個連鎖缺陷:
1. **全部 flush、一次送**:`flushLocalLogs()` 把整個 buffer `joined()` 成一個巨大字串塞給 socket,單次 payload 可能數百 KB。socket 的 8KB chunking 產生 N 個 `{"type":"log"}` 排進 serial queue,最後面的 chunk 等幾十秒,30s watchdog 砍連線。
…
Docs/socket-wire-protocol.md · app
# E-Socket Wire Protocol
**Transport:** TCP, default port 9322 (configurable in the main app's Socket settings when App Group sharing is available)
**Format:** JSON, each message delimited by `0x0A` (newline)
**Server:** `liveAPP/Socket.swift` — `SocketServ …
開發與維護(10)
Docs/ChangeHistory.md · app
# 變更歷史
## 2026.11.13 AV Lag 進行中存檔與診斷檢視器
- AV Lag 在 `recentSessions` 模式新增每 60 秒的進行中 segment checkpoint,不再只在進入背景時寫一次。先前長時間推流後若 App 被中止,磁碟上的 segment 可能停在進入背景當下的少量樣本;長場次實際已累積 1,775 筆,但分享出的 JSON 只有 3 筆。
- AV Lag 的儲存任務改為依序串接,避免較舊的 checkpoint 晚於 final save 完成而覆蓋較新的 …
Docs/apple-feedback-template.md · app
# Apple Feedback Assistant 回報模板
## Title (標題)
```
iOS 27 beta (24A5370h): Swift concurrency cooperative thread stack overflow (bug_type 309) on all QoS levels — 544KB stack too small for app extension setup
```
## Description (描述)
### What happened
App ex …
Docs/build-information.md · app
# 關於與建置資訊
## 使用方式
在設定頁開啟「關於與建置資訊」。頁面顯示 App 與 HaishinKit 的來源修訂、建置時間與來源,辨識依據不依賴 MARKETING_VERSION 或 CURRENT_PROJECT_VERSION。
commit 在畫面上顯示前 12 碼;「複製完整版本資訊」與「分享版本資訊」保留完整 commit。回報問題時可以貼上這份文字。主 App 每次初始化也會將同一份資料以 `[BuildInfo]` 前綴寫入 Documents/log.txt。
## 欄位與判讀
…
Docs/design-issues.md · app
# 設計問題紀錄
## 1. Processor 初始化在 RTMP 連線之後
**檔案**: `ReplyKIT/SampleHandler.swift`
**問題**: `initProcessors()` 放在 `broadcastStarted()` 中 `await startRTMP()` 之後。由於 `startRTMP()` 內部的 `rtmpConnection?.connect()` 是非同步網路呼叫,若 RTMP 伺服器無法連線,整個 `startRTMP()` 會卡住永不返回,導致 ` …
Docs/development/CI_CONCURRENCY.md · app
# CI 新執行取代舊執行
## 行為
- 單元測試、開發索引、tag 工作:同一 workflow/ref 的新執行取消舊執行與舊等待項目;分支與 PR 的 ref 各自獨立。
- DocC **建置**按 ref 分組並可被新執行取消;Pages **部署**另用 `docc-pages-deploy` 序列化,`cancel-in-progress: false`,新部署排隊而不取消正在上傳的舊部署。
- Archive/Release:依上游 workflow_run.head_branch 分組,從測 …
Docs/github-alerts.md · app
# GitHub Alert(提示區塊)說明
GitHub Flavored Markdown 的 **alert** 語法,用 `> [!類型]` 開頭,內容接在後續的 `>` 行。
適合在文件中標示「補充說明、風險、警告」等需要醒目的內容。
## 五種類型
> [!NOTE]
> 補充說明、背景資訊。藍色。
> [!TIP]
> 建議做法、小技巧。綠色。
> [!IMPORTANT]
> 必須知道的重要資訊。紫色。
> [!WARNING]
> 需要注意的風險或限制。橘色。
> [!CAUTION …
Docs/localization.md · app
# 本地化與翻譯流程
ReplyKit 的主 app 介面逐步改用 Apple String Catalog。現階段先把新加入的「PIP 排版加工」與「輸出畫面加工」頁面接進本地化,後續再分批把舊頁面中文字串搬進同一套流程。
## 本地化文件
- 主 app UI 字串集中放在 `liveAPP/Localizable.xcstrings`。
- 專案 source language 是 `zh-Hant`,目前目標語系是 `en` 與 `ja`。
- `liveAPP.xcodeproj/project.p …
Docs/replykit-core-fixes-summary.md · app
# ReplyKit 核心修正與性能改進
## 1. Socket 日誌傳輸管線重構(滑動視窗批次傳輸)
### 問題
每 1 秒 `flushLocalLogs()` 把整個 buffer `joined()` 成一個巨大字串 → 單次 payload 可能數百 KB → 8KB chunking 產生 N 個 `{"type":"log"}` 排進 serial queue → 最後的 chunk 等幾十秒 → 30s watchdog 砍連線。
### 修正
- **Ring buffer**(`E …
Docs/workflow.md · app
# 本地建置工作流程
## 修改 Metal Shader(.metal)後的正確建置方式
`ReplyKIT/rotateNV12.metal` 使用 **Xcode File System Synchronization**(`PBXFileSystemSynchronizedRootGroup`)自動納入專案。理論上 Xcode 會自動偵測 .metal 檔案的變更並重新編譯,但**實際上有時 Metal shader cache 不會失效**,導致執行時用的仍是舊的 `default.metallib` …
TODO.md · app
# TODO 待辦事項
集中管理全專案實作進度與驗收事項。
`[x]` 表示該項描述已完成;實作與實機/CI 驗收分開記錄,避免尚待驗收被誤讀為功能尚未開發。最近部分核對:2026-11-06(PiP 分段提示/頭貼/計時列、App 圖示、RTMP 樣本、AltStore、設定備份、SCK 收尾與 CI 選機;其餘舊章節未全面重驗)。工作目錄已完成但尚未提交的實作也可標記完成,並另註驗收限制。
> 新待辦請寫在這裡,不要在各文件的角落另開 TODO 區塊;完成後改為 `[x]`(整批清理時可移除已完成項)。
…