Camera-only SDK recordings cannot be saved after their source ends
メンテナーはふだん 1 日以内に返信
関連するプルリクエストがすでにマージされています。
- #2971 @AksharP5 による — マージ済み
評価
- 難易度
- 4/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 35/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 停滞
- 技術スタック
- react, typescript
調査の方向性
Read packages/sdk-recorder/src/index.ts around CapRecorder.stop() and the camera/display track handling; compare the React hook Stop path in packages/sdk-recorder/src/react/useCapRecorder.ts. Reproduce with camera mode and the microphone disabled, then verify Stop completes after the source ends during recording or pause and uploads the buffered chunks. An open linked pull request (#2971) is already addressing this issue.
索引モデルが issue の本文から書いたものです。
説明
Description
@cap/sdk-recorder cannot save a camera-only recording after its camera source ends while the microphone is disabled. The native MediaRecorder has already emitted the final video and stopped, but the SDK still reports recording or paused. Calling the SDK's Stop switches it to stopping forever. No upload begins, and destroying the recorder discards the buffered take.
CapRecorder.stop() installs its native stop listener only when called, then invokes native stop() unconditionally. An already-inactive MediaRecorder does nothing and emits no second stop event, so the new promise has no path to settle.
Expected: Stop saves the already-buffered recording and completes.
Reproduction
Use the class API or the exported React hook with:
const recorder = new CapRecorder({
publicKey,
mode: "camera",
microphone: { enabled: false },
});
await recorder.start();
- Record camera video, then end the camera source, for example by disconnecting an external webcam or revoking its permission.
- After native recording has ended, invoke
await recorder.stop(). - Observe the SDK remain in
stopping, with no upload requests or completed result. The paused case is also affected.
The source-ending transition was reproduced deterministically in Chromium by returning a real canvas.captureStream(30) from the camera-acquisition boundary, recording moving frames, ending its sole video track, waiting for native completion, then invoking public Stop. The SDK, MediaRecorder, media events, chunks and multipart client were real; camera acquisition and HTTP responses were local fixtures. A physical webcam disconnect was not exercised.
| Same short video fixture | Main | Proposed fix |
|---|---|---|
| Source ends during recording | 9,343 buffered bytes; Stop pending after 800 ms; zero HTTP calls | Stop resolves; all 9,343 bytes uploaded; phase complete |
| Source ends while paused | Same pending Stop and zero HTTP calls | Stop resolves and uploads the buffered video |
| Normal manual Stop | Completes | Completes |
The final patch was also replayed with Stop running while native final events were still pending. All six output files decode successfully as 320×180 VP9 video with 21 or 51 frames, and each upload matches all native chunks byte for byte. A 1.7 s replay preserves all 25,672 bytes, including its final 11,107-byte chunk. The baseline's otherwise-stranded artifacts were recovered from buffered chunks by the diagnostic fixture; there is no consumer-facing recovery feature.
Additional Context
- Baseline main:
1965b31796db6da107a8f859ff34397468ae9512. - Linux x86-64, Bun 1.4.1, Chromium 152.0.7977.167. The 800 ms timeout records the observed hang; the missed stop event explains why waiting longer cannot complete it.
- The focused fix observes native stop completion from recording startup, then awaits it before uploading. This handles both an event that already fired and final data/stop events that are still pending after native state becomes inactive.
- This is specific to the recording SDK. The Chrome extension uses a different recorder.
- Real authenticated upload, hardware-specific disconnect behavior, Firefox and Safari were not exercised. The already-reported paused-duration calculation and unrelated SDK typing issue #2915/#2917 are separate.
Relevant sources: Stop implementation, camera/display track handling, React hook Stop. The MediaRecorder stop algorithm specifies the inactive no-op.
- 主要言語
- Rust
- スター
- 23.7k
- フォーク
- 2.1k
- 平均マージ
- 1日 6時間
- マージ済み PR(30日)
- 661
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
CapSoftware/Cap のほかの issue
-
Web player intercepts ⌘⇧M and blocks Chrome profile-menu shortcut対応中かも @AatmanAJ が 11 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
CapSoftware/Cap#2596 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
CapSoftware/Cap#2384 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
Dashboard pagination causes full page reloads on self-hosted Cap対応中かも @Dewin が 39 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
CapSoftware/Cap#2305 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
CapSoftware/Cap#1714 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
Mobile startup network failures sign users out and delete pending recording files対応中かも @AksharP5 が今日担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 35/100
CapSoftware/Cap#3315 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
CapSoftware/Cap の issue をすべて見る
似ている issue
-
bug llm translation
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
メンテナーはふだん 1 日以内に返信
-
accounts bug decoding
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
wboayue/rust-ibapi#1088 ·
メンテナーはふだん 1 日以内に返信
-
chmod -v: missing 'could not be accessed' line for operands that can't be stat'ed対応中かも @emirmrkaljevic が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
gtk-rs/gtk-rs-core#2068 ·
メンテナーはふだん 6 日以内に返信