feat: Add webcam basic support

This commit is contained in:
2026-03-30 03:10:44 +02:00
parent 727059fb52
commit b7d4bf20e3
40 changed files with 1042 additions and 296 deletions

View File

@@ -58,6 +58,7 @@ export class WebRTCService implements OnDestroy {
readonly connectedPeers = this.state.connectedPeers;
readonly isMuted = this.state.isMuted;
readonly isDeafened = this.state.isDeafened;
readonly isCameraEnabled = this.state.isCameraEnabled;
readonly isScreenSharing = this.state.isScreenSharing;
readonly isNoiseReductionEnabled = this.state.isNoiseReductionEnabled;
readonly screenStream = this.state.screenStream;
@@ -149,7 +150,8 @@ export class WebRTCService implements OnDestroy {
getVoiceStateSnapshot: (): VoiceStateSnapshot => this.voiceSessionController.getCurrentVoiceState(),
getIdentifyCredentials: () => this.signalingTransportHandler.getIdentifyCredentials(),
getLocalPeerId: (): string => this.state.getLocalPeerId(),
isScreenSharingActive: (): boolean => this.state.isScreenSharingActive()
isScreenSharingActive: (): boolean => this.state.isScreenSharingActive(),
isCameraEnabled: (): boolean => this.state.isCameraEnabledActive()
});
this.mediaManager.setCallbacks({
@@ -157,7 +159,8 @@ export class WebRTCService implements OnDestroy {
renegotiate: (peerId: string): Promise<void> => this.peerMediaFacade.renegotiate(peerId),
broadcastMessage: (event: ChatEvent): void => this.peerMediaFacade.broadcastMessage(event),
getIdentifyOderId: (): string => this.signalingTransportHandler.getIdentifyOderId(),
getIdentifyDisplayName: (): string => this.signalingTransportHandler.getIdentifyDisplayName()
getIdentifyDisplayName: (): string => this.signalingTransportHandler.getIdentifyDisplayName(),
setCameraEnabled: (enabled: boolean): void => this.state.setCameraEnabled(enabled)
});
this.screenShareManager.setCallbacks({
@@ -434,6 +437,16 @@ export class WebRTCService implements OnDestroy {
return this.peerMediaFacade.getRemoteVoiceStream(peerId);
}
/**
* Get the remote camera stream for a connected peer.
*
* @param peerId - The remote peer whose camera stream to retrieve.
* @returns The stream, or `null` if the peer has no active camera video.
*/
getRemoteCameraStream(peerId: string): MediaStream | null {
return this.peerMediaFacade.getRemoteCameraStream(peerId);
}
/**
* Get the remote screen-share stream for a connected peer.
*
@@ -456,6 +469,15 @@ export class WebRTCService implements OnDestroy {
return this.peerMediaFacade.getLocalStream();
}
/**
* Get the current local camera stream.
*
* @returns The local camera {@link MediaStream}, or `null` if the camera is disabled.
*/
getLocalCameraStream(): MediaStream | null {
return this.peerMediaFacade.getLocalCameraStream();
}
/**
* Get the raw local microphone stream before gain / RNNoise processing.
*
@@ -477,6 +499,25 @@ export class WebRTCService implements OnDestroy {
/** Stop local voice capture and remove audio senders from peers. */
disableVoice(): void {
this.voiceSessionController.disableVoice();
this.state.setCameraEnabled(false);
}
/**
* Start sharing the local camera video with peers in the active voice channel.
*
* @returns The camera {@link MediaStream}.
*/
async enableCamera(): Promise<MediaStream> {
const stream = await this.mediaManager.enableCamera();
this.state.setCameraEnabled(this.mediaManager.getIsCameraActive());
return stream;
}
/** Stop local camera capture and remove camera tracks from peers. */
disableCamera(): void {
this.mediaManager.disableCamera();
this.state.setCameraEnabled(this.mediaManager.getIsCameraActive());
}
/**
@@ -614,6 +655,7 @@ export class WebRTCService implements OnDestroy {
this.peerMediaFacade.closeAllPeers();
this.state.clearPeerViewState();
this.voiceSessionController.resetVoiceSession();
this.state.setCameraEnabled(false);
this.peerMediaFacade.stopScreenShare();
this.state.clearScreenShareState();
}