Feature: Screen Sharing #24
Labels
No labels
area:api
area:core
area:docs
area:infra
area:ux
dependencies
documentation
duplicate
good first issue
help wanted
invalid
question
rust
status:complete
status:partial
status:planned
type:bug
type:design
type:feature
type:infra
type:refactor
type:research
type:ux
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
icub3d/decentcom#24
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Migrated from GitHub issue icub3d/decentcom#24
Original Author: @icub3d
Original Date: 2026-04-15T14:15:51Z
Feature: Screen Sharing
Overview
Screen sharing allows a participant in a voice channel to share their entire screen or a specific application window as an additional video stream. Other participants see the shared screen alongside (or instead of) the sharer's camera feed. Screen sharing supports a "presenter mode" where the shared screen is displayed prominently while other participants' video tiles are minimized.
Background
The server-model doc (
docs/design/server-model.md) definesscreen_shareas a feature flag (enabled by default, requiresvoice_channelsto be enabled). Screen sharing is architecturally identical to video from the SFU's perspective — it is an additional video track on the same WebRTC peer connection. The key differences are on the client side: the source isgetDisplayMedia()instead ofgetUserMedia(), and the UI presents the shared screen differently from camera feeds.Depends on:
voice(feature #22),video(feature #23), all Phase 1 and Phase 2 features.Requirements
screen_sharefeature flagDesign
API / Interface Changes
REST endpoints (additions to voice):
/api/v1/voice/{channel_id}/screen-share/start/api/v1/voice/{channel_id}/screen-share/stopWebSocket events (additions):
VOICE_STATE_UPDATEscreen_sharingfieldSCREEN_SHARE_STARTEDSCREEN_SHARE_STOPPEDTauri IPC commands (additions):
voice_start_screen_sharegetDisplayMedia()in the WebView and adds the screen track to the peer connectionvoice_stop_screen_shareData Model Changes
Extended
voice_states(in-memory):screen_sharingExtended per-channel ephemeral state:
active_screen_share_user_idNo persistent schema changes.
Component Changes
Server (
server/):server/src/sfu/mod.rs— track which user (if any) is screen sharing per room; enforce one-at-a-time limitserver/src/sfu/session.rs— handle renegotiation for screen share track (distinct from camera track via track labels or SDP metadata)server/src/sfu/router.rs— forward screen share track with content-optimized settings (higher resolution, lower framerate)server/src/routes/voice.rs— addscreen-share/startandscreen-share/stopendpointsserver/src/gateway/events.rs— addSCREEN_SHARE_STARTEDandSCREEN_SHARE_STOPPEDeventsserver/src/config.rs— addscreen_sharefeature flag checkClient (
client/):client/src/hooks/useVoice.ts— extend withstartScreenShare()andstopScreenShare()methods; usegetDisplayMedia()to capture screenclient/src/components/VoiceControls.tsx— add screen share toggle button (disabled when another user is sharing)client/src/components/ScreenShareView.tsx— new component: large view of the shared screen with controls overlayclient/src/components/VideoGrid.tsx— modify to support presenter mode layout: screen share large + participant tiles small on the sideclient/src/stores/voiceStore.ts— extend to track screen share state, active screen sharer, and screen share MediaStreamTask List
Phase A: Server Screen Share Support
screen_sharingfield to in-memory voice state (VoiceParticipant.screen_sharing)active_screen_sharetracking inVoiceStateMap(screen_sharesmap)screen-share/startandscreen-share/stopREST endpoints (POST /api/v1/voice/{channel_id}/screen-share/{start,stop})screen_sharefeature flag checkserver/src/sfu/session.rs(deferred — SFU unresolved)server/src/sfu/router.rs(deferred)SCREEN_SHARE_STARTEDandSCREEN_SHARE_STOPPEDgateway eventsPhase B: Client Screen Share UI
client/src/hooks/useVoice.tswithstartScreenShare()usingnavigator.mediaDevices.getDisplayMedia()stopScreenShare()— remove track, notify serverclient/src/components/VoiceControls.tsxwith disabled state when someone else is sharingclient/src/components/ScreenShareView.tsx— renders the screen share stream in a large containerclient/src/components/VideoGrid.tsxto switch to presenter mode layout when a screen share is activeclient/src/stores/voiceStore.tswith screen share state trackingSCREEN_SHARE_STARTED/SCREEN_SHARE_STOPPEDevents to update the UITest List
screen_sharefeature flag is disabledOpen Questions
getDisplayMedia()can capture system audio on some platforms. Should we support sharing system audio alongside the screen? This is useful for sharing videos or presentations with sound.getDisplayMedia()? Suggested: 1080p at 5-15fps for content, with the option to switch to higher framerate for video playback.getDisplayMedia()? Some WebView implementations have restrictions on screen capture APIs. This needs verification early.