Skip to content

feat(call): local self-view in video calls - #31

Merged
schnsrw merged 1 commit into
mainfrom
feat/call-selfview
Jul 25, 2026
Merged

feat(call): local self-view in video calls#31
schnsrw merged 1 commit into
mainfrom
feat/call-selfview

Conversation

@schnsrw

@schnsrw schnsrw commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Adds a self-view to video calls — you see your own camera, like every call app.

How (no second camera open)

The macOS camera pump already captures + VP9-encodes your camera once per frame. It now emits each encoded frame two places:

  • to the peer (as before), and

  • to our own webview over a new call-selfvideo event — the same encoded bytes, so there's no second camera open and no device-contention.

  • call.rs: factored the RCFG+RAS1 blob emit into emit_video_frame(app, event, frame, configured); forward_call_video uses it for the peer render, and the camera pump feeds it for the self-view. start_camera_egress/camera_pump take the AppHandle.

  • viewer.js already exposed feed()/resetSink() (decode pushed blobs without a connect) from the video-call PR — reused as-is.

  • shell: a <canvas> inside the existing .selfview box; shell.js renders call-selfvideo through the shared viewer and clears it on call end; CSS mirrors it (scaleX(-1), object-fit:cover).

Security (unchanged)

Self-view frames are the same live camera bytes — live-only, never recorded, torn down on hangup/emergency-stop (Inv 4/12); no pixel logged (Inv 8).

Verification

App cargo check + clippy -D warnings + fmt; node --check shell.js. On-device (a real camera self-view) pending hardware.

… frames)

Show your own camera during a video call. The camera is opened once: the
macOS camera pump now emits each encoded VP9 frame two places — to the peer
(as before) and to our own webview over a new call-selfvideo event, reusing
the exact same bytes (no second camera open, no device conflict).

- call.rs: factor the RCFG+RAS1 blob emit into emit_video_frame(app, event,
  frame, configured); forward_call_video uses it for the peer render; the
  camera pump also feeds it for the self-view. start_camera_egress/camera_pump
  take the AppHandle.
- viewer.js already supports feed()/resetSink() (pushed-blob decode, no connect).
- shell: a canvas inside the existing .selfview box; shell.js renders
  call-selfvideo through the shared viewer and clears it on call end; CSS
  mirrors it (scaleX(-1), object-fit:cover) like every call app.

Security unchanged: self-view frames are the same live camera bytes, live-only
never recorded, torn down on hangup (Inv 4/12); no pixel logged (Inv 8).

Verified: app cargo check + clippy -D warnings + fmt; node --check shell.js.
On-device (a real camera self-view) pending hardware.

Author: sachin sarwa
@schnsrw
schnsrw merged commit 705267b into main Jul 25, 2026
8 checks passed
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.

1 participant