Dev index

Changelog About TODO API declarations Recent changes / versions

changelogkit static export (read-only): 69 documents, 15 features.

Documents

使用指南(8)

Docs

Docs/README.md · app
# 文件索引 本目錄收錄開發/除錯/設計文件。主專案說明請見上層 [README.md](../README.md)。 - 新增**修復紀錄** → 執行 `python Scripts/change_log.py`(或雙擊 `Scripts/change_log.cmd`)開本機網頁 GUI,或直接寫進 [ChangeHistory.md](ChangeHistory.md) - 新增**主題文件** → 在下面對應分類加一行連結 ## 分類設定與靜態站規劃 根目錄 `.changelog.toml` 依 …

APP_ICON_AND_PACKAGE_SIZE

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 …

development

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`,依終端機列出的本機位址開啟 ` …

SETTINGS_BACKUP

Docs/development/SETTINGS_BACKUP.md · app
# 設定備份與側載到期資料保留 ## 使用入口 工具 → 備份與還原。設定變更後約兩秒自動檢查並備份,不需要停留在備份頁。 內容未變不重寫;進背景時補存。系統凍結或簽署到期後不能再執行備份,請查看最近成功時間。 ## 刪除 App 前先搬走 若 App 掉簽無法開啟,使用「檔案 → 我的 iPhone/iPad → 松鼠推流」,將下列資料複製至 iCloud Drive、其他 App 或電腦。 確認副本可讀後再刪除 App;存放在 App 文件裡的備份不會在刪除 App 後保留。 | 目錄 | 內容 | …

version

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 …

sponsor

Docs/sponsor.md · app
# 贊助支持說明 本專案為個人開發,致力於提供優質的直播推流應用。為了維持持續開發與更新,我們誠摯邀請您參與贊助支持。 ## 贊助管道 目前支援以下贊助方式: - **Twitch**: [https://twitch.tv/twhomegh](https://twitch.tv/twhomegh) ## 贊助用途 您的贊助將用於: - 維持開發與更新 - 或支持其他項目開發 - 提升技術研發能力 ## 感謝您的支持 感謝您對本專案的贊助,您的支持是我們持續開發的重要動力。

tts-filter-configuration

Docs/tts-filter-configuration.md · app
# TTS 過濾器 JSON 匯入與匯出 ## 使用方式 進入「TTS 朗讀 → TTS 過濾詞管理」。每條排除/替換規則旁有啟用開關,停用只略過處理,不刪除規則。替換規則依畫面順序執行,可按「編輯」拖曳調整。 - **匯出目前配置**:將完整過濾配置儲存至主 App 的 Documents,與 `log.txt` 相同目錄。完成後可按「分享最近匯出的配置」,或從檔案 App 的本機 App 目錄取用。 - **匯入 JSON**:從系統文件選擇器匯入副本,背景讀取並完整驗證後,直接在目前頁面預覽數量與衝突。 …

README

README.md · app
# 松鼠🐿️推流 適用於iOS的直播推流應用 最近註冊了 愛發電有興趣可以去看看 [愛發電 快樂大松鼠](https://ifdian.net/a/coffee0709) ![主畫面](Docs/Screenshots/Main.png) > [!WARNING] > 說明文件不即時 由於後續更新迭代多次 > > 文檔可能沒有更新 所以實際包含功能會有所區別 ## 更新紀錄 近期更新包含: - **擷取與錄影**:新增 ScreenCaptureKit 擷取路徑,保留 ReplayKit;提供本地錄 …

Developer guide(2)

AUDIO_VOLUME_METER

Docs/development/AUDIO_VOLUME_METER.md · app
# 音量控制與監測 - 輸出增益顯示 dB,0 值顯示靜音;滑桿 0–100% 是控制位置,保留既有對數映射,不代表線性振幅百分比。 - ScreenCaptureKit 的 App/Mic 來源 RMS 在混音前量測,不隨增益變化。 - 調整後 RMS 是來源振幅乘上 Mixer 已接受增益的估算,沒有分軌輸出實測保證;處理器、混音相位與不同取樣時間可能造成差異。 - 混音輸出 RMS 為混音後實測;不代表伺服器收到或遠端播放驗證。 - 音量表固定 −60 至 0 dBFS,數字保留實際值,超出範圍只截斷長條; …

DIAGNOSTIC_LOG_VIEWER

Docs/development/DIAGNOSTIC_LOG_VIEWER.md · app
# 診斷日誌檢視器 把 `diagnostic-*.txt` 依 `[Tag]`、session 與嚴重度拆開,提供可搜尋的本機網頁;日誌不會上傳,也不需要外部套件。 ## 啟動 ```bash python Scripts/diagnostic_viewer.py "E:\Video5\crash-symbols\diagnostic-20261113-0224-20261113-1458.txt" ``` 預設開 `http://127.0.0.1:8766/`,並自動開啟瀏覽器。 ```bash # …

影音與錄製(13)

bitrate_mode

Docs/bitrate_mode.md · app
# 位元率模式說明 ## 模式一覽 | 模式 | 值 | HaishinKit | 特性 | 適合 | | ------ | ---- | ------------ | ------ | ------ | | ABR | 0 | `.average` | 長期貼近目標 bitrate,允許短期波動 | **推薦** — 直播首選,穩定與畫質的平衡 | | CBR | 1 | `.constant` | 嚴格維持固定 bitrate,波動最小 | 上傳頻寬極度受限或不穩定的環境 | | VBR | 2 | `.v …

AV_LAG

Docs/development/AV_LAG.md · app
# A/V 內容延遲診斷(AVLag) ## 快速入口 - 裝置資訊頁 → **A/V Lag** → **查看目前 AV Lag 報告** - 報告頁可複製/分享 JSON,給回放 retime 工具做交叉比對;分享的是實際 `.json` 檔案,可直接交給分析工具 - 日誌關鍵字:`[AVLag]` ## 這份報告回答什麼 `videoContentAge`(介面顯示「影片內容延遲」)是「擷取回呼到達時間 - 影片來源 PTS」: ```text videoContentAge = arrival - …

COMPRESSED_VIDEO_LIBRARY

Docs/development/COMPRESSED_VIDEO_LIBRARY.md · app
# 壓縮成品與暫存管理 工具分頁與影片壓縮頁均可開啟「已壓縮影片」。清單直接掃描 Documents/CompressedVideos,支援播放、分享、多選永久刪除;刪除前確認,正在壓縮或選取項目是目前來源時禁止刪除。返回清單或 App 回前景會重新掃描。 ## 空間與清理範圍 - 成品、目前程序暫存、前次程序暫存分開計量;不是 iOS「文件與資料」總量。 - 新相簿副本與手動轉碼檔案使用 tmp/ManagedVideoWork/程序 UUID/Imports 或 Transcodes。 - 正常轉碼收尾刪 …

COMPRESSION_TEST_FIXTURE

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 內的固定影片複製到獨立暫存目錄,然後真正執行手動碼率與系統品質壓縮;不再於準備階段另啟動編碼器。樣本 …

ENCODING_CAPABILITIES

Docs/development/ENCODING_CAPABILITIES.md · app
# 編碼選項與健康指標入口 ## H.264 裝置能力 主頁 → 編碼設定,展開後查詢 VideoToolbox ProfileLevel 支援清單。清單是該尺寸與模式的編碼器回報值,不保證所有 FPS、碼率、像素格式组合均可用。沒有清單時保留原值並顯示未確認;不補入猜測選項。 - `H264EncodingProfile.resolve`:共用設定解析。舊 Baseline/Main/High 改為同 Profile 的 AutoLevel;舊 Auto 與 Constrained/Extended 名稱仍 …

RECORDING_COMPRESSION

Docs/development/RECORDING_COMPRESSION.md · app
# ScreenCaptureKit 本地錄影:錄後壓縮 ## 使用入口 主頁 → 擷取與開始 → ScreenCaptureKit → 本地錄影設定 →「錄後壓縮(SDR)」。預設關閉,設定在下次開錄時固定,與 RTMP 推流設定分開。 系統錄製編碼與錄後壓縮編碼是兩個階段。HEVC 是有損壓縮編碼,不是 MP4 容器;選用 HEVC 本身不保證檔案比 H.264 小。 | 選項 | 預設 | 用途 | | --- | --- | --- | | 完成錄影後壓縮 | 關閉 | 系統完成檔案後,才進行處理 …

SCREEN_CAPTURE_CALLBACKS

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 為略過原因 …

VIDEO_COMPRESSION

Docs/development/VIDEO_COMPRESSION.md · app
# 手動影片壓縮 ## 入口與輸出 主頁「常用工具」或「工具 → 影片工具 → 影片壓縮」可直接進入;也可使用碼率分析頁工具列「壓縮影片」,或本地錄影詳細頁「壓縮影片」。兩個入口都以頁面推入,不開臨時表單。可從相簿或檔案選取影片;分析頁目前選取的檔案也可帶入。 輸出為 MP4,存入 App 的 Documents/CompressedVideos,可從檔案 App 或文件共享取得,不依賴 App Group。名稱包含原檔名與 UUID,避免覆寫。原檔唯讀;暫存輸出在 App temporaryDirector …

haishinkit-fixes

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 …

metal-shader-optimizations

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 …

screencapturekit-integration

Docs/screencapturekit-integration.md · app
# ScreenCaptureKit 雙來源接入 ## 使用方式 在開播頁的「螢幕擷取方式」選擇 ReplayKit 或 ScreenCaptureKit。預設維持 ReplayKit;新來源標為測試中。停止直播後才能更換來源。 ScreenCaptureKit 路徑會呈現系統分享選擇器,取得使用者選擇後,依工作模式啟動推流、錄製或兩者。主 App 的「停止擷取」會關閉擷取、樣本消費端、Mixer 與 RTMP,再釋放跨程序直播鎖。取消選擇不會改用 ReplayKit。直播中更改系統分享選項會停止,請重新開始 …

video-dimensions

Docs/video-dimensions.md · app
# 影片尺寸設計:AD / OD 本文整理 ReplyKit 影片尺寸設定的語意,避免把 GPU 中間處理尺寸誤當成最終輸出解析度。 ## 欄位語意 | App Group / Socket 欄位 | Extension 狀態 | 用途 | | --- | --- | --- | | `dstW` / `dstH` | `ADWidth` / `ADHeight` | GPU 旋轉/縮放的中間處理尺寸 | | `odstW` / `odstH` | `ODWidth` / `ODHeight` | 最終畫布尺 …

video-output-pool-lifetime

Docs/video-output-pool-lifetime.md · app
# GPU 輸出 Pool 與使用期限 ## 2026-09-10 修正 原本 GPU completion 將 `ReusableOutputSet` 放回陣列,再回傳包裝同一個 pixel buffer 的 sample buffer。下游尚未讀完時,下一幀可能取出並覆寫相同儲存空間。陣列的鎖不能保護下游讀取期限。 現在每個輸出尺寸使用 `CVPixelBufferPool`,透過 `CVPixelBufferPoolCreatePixelBufferWithAuxAttributes` 配置 buffe …

PiP 與介面(12)

audio-volume-page

Docs/audio-volume-page.md · app
# 音量控制頁說明 ## 目的 音量控制頁用於調整直播輸出的 App 音訊與麥克風音訊,並監看 ReplayKit extension 回報的即時 RMS 音量。 此頁面同時處理兩種不同概念: | 類型 | 對應設定 | 用途 | | ------ | ---------- | ------ | | 輸出音量 | `appVolume` / `micVolume` | 控制最終混音輸出比例,範圍為 `0.0...1.0` | | 增益放大 | `appAddVolume` / `micAddVolume` …

av-pipeline

Docs/av-pipeline.md · app
# 影音管線架構 ## 總入口:`SampleHandler.processSampleBuffer` ```text ReplayKit samples │ CMSampleBuffer ▼ SampleHandler.processSampleBuffer(_:with:) │ ├── .video ──────────────────────────────► VideoFrameProcessor.process() │ └── .audioApp / …

HOME_MODULES

Docs/development/HOME_MODULES.md · app
# 主頁模組與維護入口 ## 第一批拆分 | 檔案(liveAPP/ 下) | 責任 | | --- | --- | | ContentView.swift | 頂層分頁、環境注入及原本的頁面/前背景通知 | | Navigation/AppPage.swift | 分頁識別與 PageState | | Home/HomeView.swift | homeView 的狀態、Binding、權限提示及響應式排版 | | Home/HomeView_Cards.swift | 擷取、串流、編碼、ReplayKit …

LIVE_ACTIVITY

Docs/development/LIVE_ACTIVITY.md · app
# 即時動態管理 入口:工具 → App 設定 → 即時動態 LiveActivity。預設關閉;明確啟用後摘要每 5 分鐘更新,可選 1、5、10、15 分鐘。停用只結束即時動態,不停止直播;直播中重新啟用會嘗試建立活動,仍受系統權限限制。 計時使用固定開播時間,由系統顯示;不靠高頻 Activity.update 維持跳秒。開播、重連、恢復與結束走事件更新,週期只刷新摘要。資料過期時間為更新間隔加 60 秒;系統暫停 App 時不能保證準時更新,不能把此排程當成背景保活。 設定立即重排目前任務。取消睡眠直 …

PIP_KEEPALIVE

Docs/development/PIP_KEEPALIVE.md · app
# PiP 保活更新間隔 入口:PiP 主頁,或設定中的聊天/PiP 設定。預設每 5 秒更新,可設為 1–60 秒;調整會重排已啟動的保活更新工作。 間隔只控制保活畫面。聊天室仍使用原本的閒置、活動與動畫頻率。贊助疊加期間暫時以 6 FPS 更新,結束後回到指定間隔。此設定不保證永久背景執行。 ## 實作入口 - `PIPRenderPolicy`:純計算、範圍驗證與模式頻率選擇。 - `PIPKeepaliveSettingsSection`:共用設定 UI,偏好鍵 `pipKeepaliveSecon …

PIP_REFRESH

Docs/development/PIP_REFRESH.md · app
# PiP 刷新與次要訊息 工具 → 子母畫面 PiP → 聊天室 PiP:時間刷新可選 1/2/5 秒,預設一秒。動畫維持自動變頻;開啟「降低聊天室動畫頻率」將活動/動畫目標由 6/16 FPS 降為 3/8 FPS。保活模式仍使用原本獨立間隔。這些頻率是排程目標,不保證實際輸出或系統背景執行。 時間字串依時間分桶及時區、語系快取。靜態聊天室只保留一張圖像,內容世代或尺寸改變即重建,動畫時直接繪製,停止清空快取。時間刷新仍須合成輸出畫面,並非零 GPU/CPU 成本。 次要訊息由 isMain=false …

SETTINGS_NAVIGATION

Docs/development/SETTINGS_NAVIGATION.md · app
# 設定與五分頁導航 ## 入口與歸屬 主分頁列的「設定」分頁是全域設定入口,由 AppSettingsView 分類導覽。日誌頁選單的「日誌設定」使用同一個 LogSettingsView,以獨立 NavigationStack 呈現,並提供完成按鈕。 | 分類 | 內容 | | --- | --- | | 一般 | App 語言 | | Socket 與連線 | 本機位址、端口與服務設定 | | 音訊 | 既有音訊設定 | | 畫面與疊加 | 疊加、GPU 旋轉、進階編碼相容選項 | | PiP 與聊天 …

home-layout

Docs/home-layout.md · app
# 主頁操作與金鑰顯示 ## 排版 - 優先顯示擷取來源、工作模式與開始/停止操作,本地錄影入口保持可見。 - 可用寬度達 850 點且未使用輔助使用的大字體時採雙欄;其他情況採單欄。 - ScreenCaptureKit 選擇只錄製時,隱藏 RTMP、推流碼率與編碼設定。 - 進階編碼、ReplayKit 畫面控制與權限檢查預設收合。 - ScreenCaptureKit 顯示自己的擷取、推流與錄影狀態;ReplayKit 的暫停與方向控制不套用到 ScreenCaptureKit。 - ScreenCapt …

overlay-scene-config

Docs/overlay-scene-config.md · app
# 畫面加工 Overlay 配置設計 本文整理主 App 可視化配置與 ReplayKit Extension 讀取 Overlay 設定的設計。此功能是可選加工層;用戶不啟用時,既有輸出與原本 PiP overlay 行為應保持不變。 注意:本文件中的 Overlay 指「最終推流畫布加工」,不是 PiP 子母窗口排版。PiP 應使用獨立的 `PIPLayoutSettingsView` 與現有 `PIP*` 設定 key。 ## 目標 - 在主 UI 提供獨立的「畫面加工設置」頁面。 - 讓用戶控制最 …

pip-keepalive-performance

Docs/pip-keepalive-performance.md · app
# PiP 保活模式渲染效能 ## 發現與修正 - 保活目標為 0.2 FPS,但排程以 `1 / max(currentFPS, 1)` 計算,實際至少每秒喚醒一次。現在使用完整低幀率值,無覆蓋層時每 5 秒更新一次時間畫面。 - 遞迴 `asyncAfter` 沒有取消控制代次;停止後立即重啟會讓舊 callback 通過共用布林檢查,可能增加渲染迴圈。現在取消待執行工作並使舊代次失效,在主執行緒進入及離開渲染時都確認代次。 - `rescheduleRenderTimer` 原本是空函式。現在真正提前下一 …

pip-layout-config

Docs/pip-layout-config.md · app
# PIP 排版加工設計 本文整理 PiP 子母窗口排版設定。PiP 排版加工與最終推流畫布 Overlay 是兩套設定,不應共用同一份 scene config。 ## 邊界 PiP 排版加工負責主 App 內的子母窗口畫面: - 聊天室主訊息字體大小 - 次要訊息字體大小 - 贊助覆蓋字體與停留時間 - 訊息淡出速度與滾動時間 最終輸出 Overlay 負責 ReplayKit Extension 的推流畫布: - 時間、Logo、浮水印、狀態文字 - 最終 `ODWidth x ODHeight` …

pip-performance-improvements

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)

cooperative-queue-stack-overflow

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 …

coroutine-frame-recursion

Docs/coroutine-frame-recursion.md · app
# Swift 協程幀分配器無窮遞迴 ## 問題 `VideoFrameProcessor.process()` 對每幀 ReplayKit 畫面建立一個 unstructured `Task { }`。當 GPU 初次編譯 shader 管線時,`MTLComputePipelineState` 內部也使用 Swift async runtime。兩種非同步系統疊加 → Swift runtime 的 `__swift_coroFrameAllocStub` 無窮遞迴 → Stack Overflow。 # …

crash-tracing

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 …

DEVICE_DIAGNOSTICS

Docs/development/DEVICE_DIAGNOSTICS.md · app
# 設備資訊:來源管線、網路流量與報告單位 ## 兩種來源的共同入口 設備資訊的 Video Pipeline/Audio Pipeline 卡片讀取 `StreamDiagnosticsModel`,同時支援 ReplayKit 與 ScreenCaptureKit。 - ReplayKit:擴展每五秒透過 Socket 傳送 `StreamDiagnosticsSnapshot`。 - ScreenCaptureKit:每五秒直接更新同一模型;推流與本地可控錄製共用 Mixer 探針,推流停止而錄製繼續時 …

LOG49_DIAGNOSTICS

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 之後 …

LOG58_DISCONNECT

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 的日誌或封包。 ## 新增診斷 底層每次心跳探測入列及逾時記錄: …

LOG_DIAGNOSTIC_EXPORT

Docs/development/LOG_DIAGNOSTIC_EXPORT.md · app
# 時間範圍診斷日誌匯出 入口:日誌頁 → 匯出診斷日誌。支援今天、最近一小時及自訂日期時間,產生後以分享按鈕送出 UTF-8 文字檔。今天與最近一小時以按下產生時為準;檔名及文件頭包含範圍。 不改變主 log.txt。先在持久化佇列 flush、匯入擴展封存,將封存與主檔合成快照,再背景分塊讀取,避免正在追加或清空主日誌造成內容混雜。快照複製期間暫時佔用寫入佇列,檔案很大時會延後寫入;不持有整檔記憶體。單行超過 8 MiB 時明確失敗,不靜默截斷。 中文年月日與時段格式優先解析,其次嘗試目前語系與 en_U …

LOG_PERSISTENCE

Docs/development/LOG_PERSISTENCE.md · app
# 長時間直播日誌保存 ## 主 App 主日誌仍為 Documents/log.txt;超過約 7,000 行或 8 MiB 時,關閉 handle,將整個檔案移入 LogArchives,不再裁掉前段。下一批重新建立 log.txt。封存以時間及 UUID 命名;單次批次可略超過觸發門檻。 維持 0.5 秒/50 筆先到先寫。背景持續寫入會重用 handle,十秒閒置後才同步並關閉;回前景取消閒置關閉。系統暫停時程式無法持續執行,關檔不是保活機制,仍不能保證程序強制終止前零遺失。 成功 write 才計 …

METRICKIT

Docs/development/METRICKIT.md · app
# MetricKit 本機效能報告 ## 使用方式 設備資訊 → 系統效能報告 → MetricKit 歷史報告。可以查看收到時間、報告涵蓋期間、內容分類、指標解讀與原始 JSON,也可以分享單份報告。 主 App 啟動時由 `MetricReports.shared.start()` 訂閱一次,視窗建立與銷毀不重複註冊。使用相容舊 iOS 的 MXMetricManagerSubscriber API;新版 SDK 可能提示此 API 已被新版 MetricManager 取代。 ## 資料與限制 - …

STREAM_DIAGNOSTICS

Docs/development/STREAM_DIAGNOSTICS.md · app
# 設備資訊:串流格式與 RTMP 傳輸 ## 入口與更新 設備資訊頁的「串流格式與 RTMP 傳輸」提供 ReplayKit、ScreenCaptureKit 各自的展開區塊。每五秒取樣,只保存每個來源最新一筆;超過十五秒標為歷史資料。ReplayKit 由擴展經 Socket 傳入,ScreenCaptureKit 直接更新同一模型。來源 session UUID 與 socket generation 分別表示探針生命週期與連線計數世代。 ## 已接入 - Mixer 實測:影像寬高、pixel Fo …

generic-specialization-recursion

Docs/generic-specialization-recursion.md · app
# 泛型特化遞迴 (ExpressibleByIntegerLiteral) ## 問題 `ExpressibleByIntegerLiteral.init(data: Data)` 使用 `data.withUnsafeBytes { $0.pointee }` 來讀取整數值,但這個 closure 回傳型別是 `Self`(例如 `UInt32`),導致 Swift compiler 產生 `Data.withUnsafeBytes<UInt32>` 的泛型特化版本。 在特定情況下,這個 compil …

log-system-improvements

Docs/log-system-improvements.md · app
# 日誌系統改善 (2026-06) ## 概述 修復 LogManager 的多項設計問題,重點在於: - 消除日誌丟失(data race、reentrancy drop、單封包過大) - 將重負載移出 barrier queue,提升整體效 - 側載無 App Group 時自動強制走 Socket 轉送 - 檔案 App 可直接讀取日誌 --- ## 1. Socket 傳送修復 ### `ReplyKIT/Socket.swift` | 問題 | 原因 | 修正 | | ------ | - …

log-view

Docs/log-view.md · app
# 日誌頁顯示、歷史與搜尋 日誌頁以主 App Documents 的 `log.txt` 為準,主 App、Socket 與擴展轉送的日誌由既有 AppLogPersister 匯入主檔案。讀取與寫入共用序列佇列,讀取前先將待寫內容落盤。 ## 歷史瀏覽 - 預設顯示最新 200 行,較早/較新按鈕依檔案行號分頁。 - 切頁或進入背景不清除歷史;保留目前頁面、捲動位置與篩選狀態(限本次 App 執行期間)。 - 拖曳進入歷史閱讀模式,有新內容只顯示新增數量。按「回到最新」恢復追尾。 - 只有日誌頁可見且 A …

memory-warning-removal

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 …

nw-recursion

Docs/nw-recursion.md · app
# NWConnection 遞迴 receive 模式 ## 問題 `NWConnection.receive` 的 completion handler 內部直接呼叫 `self.receive(...)` 會造成潛在的 stack overflow。 ### 危險模式 ```swift // ❌ 危險:callback 內直接遞迴 private func receive() { connection.receive(...) { data, _, _, _ in // ... …

page-switch-crash-analysis

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` ## …

uint32-overflow-2026

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)

EXTERNAL_LOG_TRANSPORT

Docs/development/EXTERNAL_LOG_TRANSPORT.md · app
# 主 App 外部日誌通道 日誌頁選「外部/全部」後可選 HTTP Web(預設)或已連線 Socket;日誌設定亦提供同一選項。此選項不變更擴展本身的設定、檔案保存與交接。HTTP 是既有 POST 傳送,並非新增 HTTP 接收服務。 ## Socket 訂閱 外部工具在既有連線送出一行 JSON: ```json {"type":"subscribeExternalLogs","enabled":true} ``` 回應 `externalLogSubscription` 的 enabled 表示 …

RTMP_TIMELINE_DIAGNOSTICS

Docs/development/RTMP_TIMELINE_DIAGNOSTICS.md · app
# RTMP 時間軸診斷接入 套件版本:`d7ece58808efc052e8b1d444888d3a3255b55b1f`。兩份 Package.resolved 須一致,實機以 BuildInfo 確認產物實際使用的 checkout。 ## 取得方式 - ScreenCaptureKit:主 App 的 CaptureTransport 白名單放行 `publish timeline`,沿用 session 標記與敏感資訊遮蔽。底層約每 10 次 status 產生一筆,不額外新增計時器。 - Repl …

SOCKET_MODULES

Docs/development/SOCKET_MODULES.md · app
# Socket 模組與維護入口 | 檔案(liveAPP/ 下) | 責任 | | --- | --- | | Socket.swift | listener/端口切換、連線、換行 JSON 收送及訊息分派 | | Networking/NWListenerState_Log.swift | listener 狀態轉日誌文字;不以字串控制連線狀態 | | Networking/SocketServer_JSONValue.swift | 保留巢狀型別名稱的 Codable/Sendable JSON 模型與轉換 …

replykit-log-socket-stability

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 砍連線。 …

socket-wire-protocol

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)

ChangeHistory

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 完成而覆蓋較新的 …

apple-feedback-template

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 …

build-information

Docs/build-information.md · app
# 關於與建置資訊 ## 使用方式 在設定頁開啟「關於與建置資訊」。頁面顯示 App 與 HaishinKit 的來源修訂、建置時間與來源,辨識依據不依賴 MARKETING_VERSION 或 CURRENT_PROJECT_VERSION。 commit 在畫面上顯示前 12 碼;「複製完整版本資訊」與「分享版本資訊」保留完整 commit。回報問題時可以貼上這份文字。主 App 每次初始化也會將同一份資料以 `[BuildInfo]` 前綴寫入 Documents/log.txt。 ## 欄位與判讀 …

design-issues

Docs/design-issues.md · app
# 設計問題紀錄 ## 1. Processor 初始化在 RTMP 連線之後 **檔案**: `ReplyKIT/SampleHandler.swift` **問題**: `initProcessors()` 放在 `broadcastStarted()` 中 `await startRTMP()` 之後。由於 `startRTMP()` 內部的 `rtmpConnection?.connect()` 是非同步網路呼叫,若 RTMP 伺服器無法連線,整個 `startRTMP()` 會卡住永不返回,導致 ` …

CI_CONCURRENCY

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 分組,從測 …

github-alerts

Docs/github-alerts.md · app
# GitHub Alert(提示區塊)說明 GitHub Flavored Markdown 的 **alert** 語法,用 `> [!類型]` 開頭,內容接在後續的 `>` 行。 適合在文件中標示「補充說明、風險、警告」等需要醒目的內容。 ## 五種類型 > [!NOTE] > 補充說明、背景資訊。藍色。 > [!TIP] > 建議做法、小技巧。綠色。 > [!IMPORTANT] > 必須知道的重要資訊。紫色。 > [!WARNING] > 需要注意的風險或限制。橘色。 > [!CAUTION …

localization

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 …

replykit-core-fixes-summary

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 …

workflow

Docs/workflow.md · app
# 本地建置工作流程 ## 修改 Metal Shader(.metal)後的正確建置方式 `ReplyKIT/rotateNV12.metal` 使用 **Xcode File System Synchronization**(`PBXFileSystemSynchronizedRootGroup`)自動納入專案。理論上 Xcode 會自動偵測 .metal 檔案的變更並重新編譯,但**實際上有時 Metal shader cache 不會失效**,導致執行時用的仍是舊的 `default.metallib` …

TODO

TODO.md · app
# TODO 待辦事項 集中管理全專案實作進度與驗收事項。 `[x]` 表示該項描述已完成;實作與實機/CI 驗收分開記錄,避免尚待驗收被誤讀為功能尚未開發。最近部分核對:2026-11-06(PiP 分段提示/頭貼/計時列、App 圖示、RTMP 樣本、AltStore、設定備份、SCK 收尾與 CI 選機;其餘舊章節未全面重驗)。工作目錄已完成但尚未提交的實作也可標記完成,並另註驗收限制。 > 新待辦請寫在這裡,不要在各文件的角落另開 TODO 區塊;完成後改為 `[x]`(整批清理時可移除已完成項)。 …

Other(2)

AppIcons

Artwork/AppIcons/README.md · app
# App 圖示原稿 將預計內建的替換圖示放在此資料夾,供後續整理成 Xcode 圖示資源。 此處僅保存原稿,加入圖片不會自動啟用 App 圖示切換。 ## 圖片規格 - 建議使用 1024 × 1024 像素的正方形 PNG。 - 圖片應有完整、不透明的背景,不要預先裁切圓角。 - 主體與邊緣保留適當距離,避免系統圓角遮住重要內容。 - 檔名使用簡單英文,例如 `squirrel.png`、`coffee.png`、`dark.png`。 - App 內顯示名稱可另外設定中文,不必與檔名相同。 - 請使用自 …

liveAPP

liveAPP/Documentation.docc/liveAPP.md · app
# ``liveAPP`` 直播主 App 的開發文件。 ## Overview 本 App 支援 ReplayKit 廣播擴展與 ScreenCaptureKit。功能是否接入、UI 入口及實機驗收狀態,請以專案 `Docs/development/features.json` 與本機開發索引為準;API 文件存在不代表該功能已在所有來源啟用。 新增或修改 API 時,使用 `///` 描述用途、參數、回傳值、錯誤、actor 要求與計數單位。這份文件由當次 checkout 建置,請搭配同一份產物的 r …

Features

設定備份與還原

settings.backup

共享與主 App 白名單偏好自動備份至 Documents;敏感設定選擇匯出,驗證後下次啟動還原。

雙擷取來源與工作模式

capture.backends

保留 ReplayKit;ScreenCaptureKit 支援推流、錄製及兩者並行。

AAC 推流音訊碼率

stream.audio-bitrate

共用自動/128/96/64 kbps;下次開播套用。

RTMP connect 失敗診斷

diagnostics.connect

底層 Connect diagnostic 事件包含握手、chunk 組裝、AMF 與 transaction 配對。

音訊來源、混音與 RTMP 產出

diagnostics.audio

來源 accepted、Mixer 產出與 RTMP 訊息產出是不同階段。

RTMP 傳送與 chunk 可觀測性

diagnostics.transport

底層新增 RTMPConnection.transportDiagnostics();區分本機成功完成、失敗批次、待送量與耗時。尚未更新 App 鎖定套件。

ScreenCaptureKit 推流固定左轉

capture.rotation

推流像素旋轉與原生錄影收尾方向分別控制。

影片處理負載

diagnostics.video-load

輸入/處理 FPS、GPU 耗時與丟幀用於定位效能問題。

建置產物版本資訊

build.identity

辨認實際 App 與套件 revision;不同於本機 checkout。

主頁模組入口

ui.home-modules

第一批保持行為拆檔,主頁狀態與卡片組合分開。

H.264 裝置編碼選項

stream.h264-capabilities

查詢 ProfileLevel,共用設定解析並保留未知診斷值。

Socket 資料與日誌輔助模組

socket.support-modules

Socket 純資料輔助與統一恢復決策;停止意圖、通知生命週期及端口切換分開管理。

本地錄影錄後壓縮

recording.post-compression

可選 HEVC/H.264、碼率、最長邊與 FPS 上限;與方向修正共用轉碼,失敗保留原檔。

MetricKit 本機報告

diagnostics.metrickit

主 App 單次訂閱系統報告,限量保存 JSON,可查看與分享;不是即時診斷。

可控分段錄製與即時音量

recording.segmented

Mixer 共用音量;可指定碼率與畫布寬高,分段保留晚到音訊,群組顯示並支援手動或停止後合併。