Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(android): report the clip an Android recording really captured - #2566

Open
thymikee wants to merge 3 commits into
mainfrom
t3code/fix-2551-quality-refactor
Open

fix(android): report the clip an Android recording really captured#2566
thymikee wants to merge 3 commits into
mainfrom
t3code/fix-2551-quality-refactor

Conversation

@thymikee

@thymikee thymikee commented Sep 13, 2026

Copy link
Copy Markdown
Member

Summary

Android screenrecord encodes a frame only when the screen changes, so a window that ends on an unchanged screen returns a video far shorter than the requested duration, while record stop reported only host wall-clock durationMs. record stop now also reports capturedDurationMs, measured from the pulled MP4 timelines, and warns with the clip length against a window measured on the device's own elapsed clock, because host wall clock drifts against the clock the encoder timestamps frames with. An unreadable clock or an unparseable chunk costs the claim, never the recording. iOS is unchanged.

$ agent-device record stop --json
{ "durationMs": 9139, "capturedDurationMs": 689,
  "warning": "Android screenrecord encodes a frame only when the screen changes, so this video ends at
   the last frame it encoded: it covers 0.7s of the 7.0s recording window." }

Closes #2551. 35 files, inside the recording family plus its contracts, MCP schema, help, and docs. Measuring the timeline needed an ISO-BMFF box walk, which replaces the private atom scan MP4 container detection used to do.

Validation

  • Live on emulator-5554 (Android 16), one swipe then idle: at c2c93d164c capturedDurationMs: 9733 against ffprobe duration=9.732689; at e590e8574d capturedDurationMs: 689 against ffprobe duration=0.688811 with the warning above. Sessions closed.
  • pnpm check:affected --run at e590e8574d: format, lint, typecheck, layering, fallow, build, gate-manifest, depgraph, tmpdir-leaks, coverage-model, wire-compat-model, production-exports, bundle-owner-files, fixture-cache/fallback, command-docs, agent-guidance, xctest-selection, packaged-runner-swift and maestro-conformance passed. mutation-model fails on a kernel is owned by tests that reach it indirectly (gestures.test.tsscroll-edge-state); it fails identically at merge-base ab3d11e0, so it is not this PR's. Validation is therefore not fully green.
  • Coverage failed at c2c93d164c on the ADR-0019 eager-closure probe: the container gate statically imported the box walk, so recording/video.ts evaluated 25 modules where the merge-base evaluated 24. e590e8574d moves that edge behind a function-scoped await import; scripts/__tests__/eager-closure-budgets.test.ts (594 tests) is green locally. Integration Tests passed.

Android `screenrecord` encodes a frame only when the screen changes, so a window that ends on an
unchanged screen returns a video far shorter than the requested duration, and `record stop` had
nothing to say about it: the reported `durationMs` is host wall clock from `record start` until the
export finished, which is not the length of the file that was just pulled.

`record stop` now measures the pulled MP4 timelines and reports them as `capturedDurationMs`, and
warns with the clip length against the window when the video is two or more seconds short. The
window is measured on the device's own elapsed clock, read before the stop signal and at launch,
because host wall clock drifts against the clock the encoder timestamps frames with; an unreadable
clock or a chunk that answers no duration costs the caller the claim, never the recording.

Measuring the timeline needed an ISO-BMFF box walk, which now lives in
`@agent-device/capture-kit/recording-mp4-duration` and replaces the private top-level atom scan
that MP4 container detection was doing. Stop replay through daemon recovery carries the field too,
so a completion read back from the session resource reports the same numbers it did live.
…n holds

`@agent-device/capture-kit/recording-mp4-duration` and its fixture sibling are new declared package
subpaths, so the boundary enumeration that holds every exported workspace subpath has to name them
for the layering scan to accept the Android recorder's read of a pulled clip's timeline.
@github-actions

github-actions Bot commented Sep 13, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://callstack.github.io/agent-device/pr-preview/pr-2566/

Built to branch gh-pages at 2026-09-13 18:46 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions

github-actions Bot commented Sep 13, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
Installed (including dependencies) 4.52 MB 4.52 MB +3.4 kB
Package (unpacked) 4.52 MB 4.52 MB +3.4 kB
Package (download) 1.33 MB 1.33 MB +1.1 kB

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 19.5 ms 19.4 ms -0.1 ms
CLI --help 53.3 ms 51.0 ms -2.3 ms

…ated

The Coverage job's ADR-0019 eager-closure probe failed: `recording/video.ts` evaluated 25 modules on
import where the merge-base evaluated 24, because the MP4 container gate statically imported the box
walk it now shares with the clip-duration read, and `recording/overlay.ts` grew by the same module.
An entry the merge-base already carries gets no growth budget, so the edge moves behind a
function-scoped `await import`: the scan is something recording completion asks for, and importing
this module for `waitForStableFile` or WebM detection should not evaluate a box walker.

The alternative the probe offered -- hosting the walker in a module both growing entries already
evaluate -- would have put an ISO-BMFF walk in `swift-cache.ts` or `video-webm.ts`, or made the
duration read import the Swift validator machinery that sits behind `video.ts`.
@thymikee

Copy link
Copy Markdown
Member Author

No blocking findings at e590e85. The measured duration reaches the response and recovery metadata, and the short-clip warning reaches normal CLI output. The reported Android run matches ffprobe and current checks are green. The shared MP4 reader replaces the existing scan and reasonably accounts for the size increase; ready for human review.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android screen recording stops capturing about one second after the last input, regardless of how long record stop waits

1 participant