Repository navigation
feat: Android support for stream-video + top-level cross-platform verb (#78) - #80
Merged
Merged
Conversation
Closes #78. AndroidStreamVideoCommand serves two engines behind one flag surface: --format h264 pipes `adb exec-out screenrecord --output-format=h264 -` byte-for-byte to stdout (VFR, segment-restart loop from record-video minus the muxer; each new segment re-emits SPS/PPS, which ffplay/ffmpeg accept mid-stream), while mjpeg/raw/ffmpeg run a screencap JPEG loop with byte-identical framing to the iOS formats. The new top-level StreamVideo forwarder routes by UDID shape: bgra stays iOS-only, h264 is Android-only for now (iOS passthrough is a separate follow-up), and mismatches fail with a pointer to the right alternative. The 0.5.x agent-typo redirect shim drops stream-video from its list now that the verb is genuinely top-level. Streaming writes go through a POSIX-write stdout sink that ignores SIGPIPE and reports consumer hangup (ffplay quit, `head -c` done) as an orderly end-of-stream instead of crashing mid-summary. SIM_USE_SCREENRECORD_TIME_LIMIT=<seconds> (debug) forces short screenrecord segments so the restart path is exercisable on API >= 34 devices, where `--time-limit 0` would otherwise never restart; it applies to Android record-video and stream-video alike. Verified: 1221 unit tests green; live AndroidStreamVideoTests E2E suite (5 tests: h264 Annex B smoke, mjpeg framing, raw length prefix, forced segment restart, consumer hangup) green against emulator-5554; ffmpeg decodes the live top-level h264 stream; iOS mjpeg via top-level streams 16 frames from a booted simulator. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: onevcat <onevcat@gmail.com>
…enrecord exits, sync skill docs Three review findings: 1. --json corrupted the stream (P1): the video bytes own stdout, and the generic runner appended the JSON summary envelope to the same stream after execute(). All three stream-video surfaces (top-level, ios, android) now reject --json at validation time with a targeted error; the run summary stays on stderr. Pinned by a parse-level unit test. 2. Blind restart on abnormal screenrecord exit (P2): both segment loops restarted whenever a segment had produced bytes, so a screenrecord that repeatedly died mid-segment (dead encoder/adb) looped forever. Restart now requires a clean exit 0 (the time-limit case); a non-zero exit aborts with screenrecord's stderr — record-video still finalizes and keeps the partial MP4. 3. Bundled skill cheatsheet still said stream-video was iOS-only (P3): the namespace table and the video section now show the cross-platform verb and the Android h264/ffplay one-liner; stale five-verb iOS-only comments in IOSSimCommand and Command+BatchConvertible updated, and IOSSimStreamVideoCommand moved into the cross-platform registration group. Verified: 1222 unit tests green; live AndroidStreamVideoTests suite green post-change (forced segment restart still restarts on exit 0); --json rejection exercised on all three surfaces against a live emulator and simulator. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: onevcat <onevcat@gmail.com>
angelmic
pushed a commit
to angelmic/sim-use
that referenced
this pull request
Jul 29, 2026
…latforms + unit suites Pre-release audit of the video stack found the pure-logic core well covered (AnnexBStreamParser 98.8%, H264MuxingPipeline 89.0%, H264PassthroughRecorder 91.8%) but three blind spots: E2E: screenshot had no live suite on either platform, and Android record-video had none (stream-video landed with one in lycorp-jp#80). Added: - ScreenshotTests (iOS runner): PNG-magic file capture, --json envelope whose path is verified on disk, directory-target stamping. - AndroidScreenshotTests: bridge capture to file, `--output -` raw PNG on stdout, top-level serial routing. - AndroidRecordVideoTests: AVAsset-loadable MP4 with a video track from both the android subcommand and the top-level route, plus a forced segment restart (SIM_USE_SCREENRECORD_TIME_LIMIT=2) that must still finalize one continuous MP4. Unit: VideoOutputFile was at 0% despite being pure path logic — now 95.7% (default stamping, tilde expansion, directory targets, stale-file replacement, intermediate dirs). VideoRecordingOptions boundary pins (93.8%), VideoFrameUtilities frame processing incl. the byte-for-byte pass-through fast path (the scale path renders via NSImage.lockFocus at the host's backing scale factor, so tests pin re-encode + aspect ratio, not absolute pixels), and ProcessControl primitives (66.2%; SignalObserver left to the live SIGTERM E2E paths). H264StreamRecorder's AVAssetWriter encoder body stays E2E-only: it is reachable only through the screencap/screenshot fallbacks, which cannot be forced without breaking screenrecord. 1252 unit tests green; all 12 new/E2E cases verified live against a booted iPhone 17 Pro simulator and emulator-5554. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: onevcat <onevcat@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements #78 on top of the #79 refactor (stacked PR — merge #79 first; GitHub will retarget this to
mainwhen the base branch is deleted).stream-videobecomes a genuine cross-platform verb with the standard three-surface layout:sim-use android stream-video --format h264— nativeadb exec-out screenrecord --output-format=h264 -passthrough to stdout: variable frame rate, cheap, high quality. screenrecord's per-invocation time limit is papered over by restarting it mid-stream (the record-video segment loop, minus the muxer); each new segment re-emits SPS/PPS, which ffplay/ffmpeg accept.mjpeg/raw/ffmpeg— a screencap-per-frame JPEG loop (~7–8 FPS ceiling) with byte-identical on-the-wire framing to the iOS formats, so existing consumers work unchanged.sim-use stream-videoroutes by UDID shape.bgrastays iOS-only,h264is Android-only for now (iOS H.264 passthrough is a separate follow-up); the mismatch cases fail with a pointer to the right alternative. The 0.5.x agent-typo redirect shim dropsstream-videonow that the verb is really top-level (caught live — the shim intercepted the new verb before ArgumentParser ever saw it).Supporting pieces:
head -cdone) as an orderly end-of-stream — summary + exit 0 instead of a crash.SIM_USE_SCREENRECORD_TIME_LIMIT=<seconds>(debug): forces short screenrecord segments so the restart path can be exercised on API ≥ 34 devices, where--time-limit 0never restarts naturally. Applies to Androidrecord-videoandstream-videoalike.VideoRecordingOptions.validateStreaming) across all three surfaces.Definition of done (from #78)
--format h264plays live against an emulator, surviving a screenrecord segment restart — verified via the forced-segment E2E test and an ffmpeg live-decode of the top-level stream (headless ffplay proxy;ffplayone-liner documented in the README)mjpegworks with the same consumer contract as iOS (multipart framing;rawkeeps the 4-byte length prefix)Verification
make build+make test: 1221 tests green, zero warnings.AndroidStreamVideoTestslive E2E suite (registered intest-runner-android.sh), all 5 green againstemulator-5554: h264 Annex B smoke, mjpeg framing, raw length prefix, forced segment restart, consumer hangup.ios stream-videoAndroid-UDID redirect produce the intended errors.🤖 Generated with Claude Code