Skip to content

Add device screen streaming via WebSocket#328

Draft
gabrieldonadel wants to merge 6 commits intomainfrom
claude/stream-emulator-orbit-YemlX
Draft

Add device screen streaming via WebSocket#328
gabrieldonadel wants to merge 6 commits intomainfrom
claude/stream-emulator-orbit-YemlX

Conversation

@gabrieldonadel
Copy link
Copy Markdown
Member

Summary

This PR adds real-time device screen streaming capabilities to the Electron menu bar app, allowing users to view live streams from booted iOS simulators and Android emulators through a web-based viewer.

Key Changes

  • New StreamManager class (StreamManager.ts): Manages streaming sessions for multiple devices

    • Spawns platform-specific capture processes (xcrun for iOS, adb for Android)
    • Handles frame buffering and broadcasting to connected WebSocket clients
    • Supports multiple concurrent clients per device
    • iOS: Captures JPEG frames via xcrun simctl with length-prefixed framing
    • Android: Streams H.264 video via adb screenrecord
  • Stream viewer UI (stream.html): New static HTML page for viewing device streams

    • Device selection dropdown with auto-refresh capability
    • Real-time FPS counter overlay
    • iOS: Uses Canvas API with ImageBitmap for JPEG rendering
    • Android: Uses WebCodecs API (VideoDecoder) for H.264 decoding
    • Status indicator showing connection and streaming state
    • Responsive design with dark theme
  • WebSocket server integration (LocalServer.ts):

    • Added WebSocket server at /orbit/ws for bidirectional streaming communication
    • New /orbit/devices endpoint to list booted simulators/emulators
    • New /orbit/stream endpoint to serve the viewer page
    • Message protocol: start (begin streaming), stop (end streaming)
  • Build configuration (vite.main.config.mts): Added vite-plugin-static-copy to bundle static HTML assets

  • Dependencies: Added @types/ws for WebSocket TypeScript support

Implementation Details

  • Frame synchronization uses 8-character hex length prefixes for iOS JPEG frames
  • H.264 NAL unit type detection identifies keyframes for proper WebCodecs chunk typing
  • Graceful fallback for browsers without WebCodecs API support
  • Automatic cleanup of streaming sessions when all clients disconnect
  • Supports multiple simultaneous viewers for the same device

https://claude.ai/code/session_01RYPF9YAuXf4XrPEg8XASRi

@gabrieldonadel gabrieldonadel changed the base branch from main to @gabrieldonadel/add-list-devices-route March 31, 2026 21:47
@gabrieldonadel gabrieldonadel force-pushed the @gabrieldonadel/add-list-devices-route branch from 37466d1 to 4f2ac16 Compare March 31, 2026 21:49
@gabrieldonadel gabrieldonadel changed the base branch from @gabrieldonadel/add-list-devices-route to main March 31, 2026 22:25
claude added 2 commits April 1, 2026 02:08
Extends the Orbit local server with WebSocket support for streaming
iOS simulator and Android emulator screens to a browser-based viewer.

- Add StreamManager for managing capture sessions per device
- Add WebSocket server on /orbit/ws for real-time frame delivery
- Add /orbit/devices endpoint for listing booted devices
- Add /orbit/stream endpoint serving a built-in HTML viewer
- iOS capture via xcrun simctl io (JPEG frames)
- Android capture via adb screenrecord (h264 stream)
- Web client supports JPEG canvas rendering and WebCodecs h264 decoding

https://claude.ai/code/session_01RYPF9YAuXf4XrPEg8XASRi
Adds a Swift CLI helper that captures iOS Simulator windows using
ScreenCaptureKit (hardware-accelerated, 30-60fps on macOS 12.3+)
with automatic fallback to CoreGraphics window capture.

- Swift Package at helpers/simulator-stream/ with build.sh
- ScreenCaptureKit: low-latency, GPU-accelerated frame capture
- CoreGraphics fallback: CGWindowListCreateImage for older macOS
- Outputs length-prefixed JPEG frames to stdout (same protocol)
- StreamManager auto-detects native binary, falls back to xcrun
- Build integration: macOS build.sh compiles helper, Vite bundles it

https://claude.ai/code/session_01RYPF9YAuXf4XrPEg8XASRi
@gabrieldonadel gabrieldonadel force-pushed the claude/stream-emulator-orbit-YemlX branch from 201508b to 4f38c8c Compare April 1, 2026 02:08
claude added 4 commits April 1, 2026 02:37
- Add MJPEG capture mode for Android using adb screencap (~10-15fps)
  with length-prefixed PNG frames, universal browser compatibility
- Improve h264 mode with auto-restart to handle screenrecord's
  3-minute recording limit
- Add capture mode selection (auto/mjpeg/h264) to WebSocket protocol
  and stream viewer UI
- Add proper Annex B NAL unit parsing in the web client for h264
- Web viewer now shows active mode badge, disables h264 for iOS,
  handles device list format from upstream /orbit/devices endpoint
- Server reports resolved captureMode back to client on stream start

https://claude.ai/code/session_01RYPF9YAuXf4XrPEg8XASRi
bufferutil and utf-8-validate are optional native dependencies of
the ws package. Vite fails to bundle them since they're not installed.
Mark them as external so Vite skips them — ws works fine without them.

https://claude.ai/code/session_01RYPF9YAuXf4XrPEg8XASRi
Simple debug page with manual WS controls, REST endpoint buttons,
raw message sending, log output, and a canvas preview for frames.

https://claude.ai/code/session_01RYPF9YAuXf4XrPEg8XASRi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants