Summary
When SimulatorView uses its native MJPEG <img> mode, rotating the simulator can display the fatal frame-stall overlay even though the stream endpoint is actively producing frames.
The message is:
Stream is not producing frames. The simulator may have stopped - try reconnecting.
Environment
serve-sim@0.1.44
- macOS 26.3 (25D125), Apple Silicon (Mac16,10)
- Xcode 26.5 / iOS Simulator 26.5
- iPad Air 11-inch (M4) simulator
- Node v25.5.0
- Chromium client on another machine on the LAN
Context
The default JavaScript frame-reader path was unusable because of #103, so a diagnostic patch selected the existing native MJPEG <img> path. A localhost MJPEG keepalive consumer was also attached to avoid the native startup crash described in #120. This meant the helper had multiple stream consumers.
Reproduction
- Start serve-sim with MJPEG capture.
- Render the existing native MJPEG
<img> path in SimulatorView.
- Rotate the simulator from the toolbar.
- Wait for the liveness timeout.
Actual behavior
The frame-stall overlay appears after rotation. At the same time:
- a fresh request to
/stream.mjpeg returns HTTP 200;
- the endpoint transferred about 9.4 MB in a four-second sample;
/config reflected the new orientation.
The capture service was therefore still producing frames.
Expected behavior
The native image should remain live or reconnect after the orientation/config change. A secondary stream consumer should not be able to mark the visible stream as dead while frames are still being produced.
Suspected cause
In native image mode, SimulatorView renders <img src=".../stream.mjpeg"> and starts a separate JavaScript fetch() of the same endless stream as a boundary watchdog. Either request can stall independently, so the watchdog can set the fatal error while the visible image and capture helper remain healthy.
PR #25 describes the same parallel-fetch false-positive risk and uses a plain <img> for grid mode to avoid it.
Possible direction
Use one native image stream consumer. Liveness could come from the /config frame counter, similar to the Safari support path, and the image URL could be refreshed when orientation/config changes.
Summary
When
SimulatorViewuses its native MJPEG<img>mode, rotating the simulator can display the fatal frame-stall overlay even though the stream endpoint is actively producing frames.The message is:
Environment
serve-sim@0.1.44Context
The default JavaScript frame-reader path was unusable because of #103, so a diagnostic patch selected the existing native MJPEG
<img>path. A localhost MJPEG keepalive consumer was also attached to avoid the native startup crash described in #120. This meant the helper had multiple stream consumers.Reproduction
<img>path inSimulatorView.Actual behavior
The frame-stall overlay appears after rotation. At the same time:
/stream.mjpegreturns HTTP 200;/configreflected the new orientation.The capture service was therefore still producing frames.
Expected behavior
The native image should remain live or reconnect after the orientation/config change. A secondary stream consumer should not be able to mark the visible stream as dead while frames are still being produced.
Suspected cause
In native image mode,
SimulatorViewrenders<img src=".../stream.mjpeg">and starts a separate JavaScriptfetch()of the same endless stream as a boundary watchdog. Either request can stall independently, so the watchdog can set the fatal error while the visible image and capture helper remain healthy.PR #25 describes the same parallel-fetch false-positive risk and uses a plain
<img>for grid mode to avoid it.Possible direction
Use one native image stream consumer. Liveness could come from the
/configframe counter, similar to the Safari support path, and the image URL could be refreshed when orientation/config changes.