Simplify GumVideoCapturer

This commit is contained in:
Fedor Indutny
2025-11-06 12:04:06 -08:00
committed by GitHub
parent 7998e6c8bd
commit a0fc414361
2 changed files with 9 additions and 28 deletions

View File

@@ -3,7 +3,6 @@
/* eslint-disable max-classes-per-file */ /* eslint-disable max-classes-per-file */
/* eslint-disable no-restricted-syntax */ /* eslint-disable no-restricted-syntax */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
import { videoPixelFormatToEnum } from '@signalapp/ringrtc'; import { videoPixelFormatToEnum } from '@signalapp/ringrtc';
@@ -38,13 +37,12 @@ type GumTrackConstraintSet = {
export class GumVideoCapturer { export class GumVideoCapturer {
private defaultCaptureOptions: GumVideoCaptureOptions; private defaultCaptureOptions: GumVideoCaptureOptions;
private localPreview?: RefObject<HTMLVideoElement>; private localPreview?: HTMLVideoElement;
private captureOptions?: GumVideoCaptureOptions; private captureOptions?: GumVideoCaptureOptions;
private sender?: VideoFrameSender; private sender?: VideoFrameSender;
private mediaStream?: MediaStream; private mediaStream?: MediaStream;
private spawnedSenderRunning = false; private spawnedSenderRunning = false;
private preferredDeviceId?: string; private preferredDeviceId?: string;
private updateLocalPreviewIntervalId?: any;
constructor(defaultCaptureOptions: GumVideoCaptureOptions) { constructor(defaultCaptureOptions: GumVideoCaptureOptions) {
this.defaultCaptureOptions = defaultCaptureOptions; this.defaultCaptureOptions = defaultCaptureOptions;
@@ -54,8 +52,8 @@ export class GumVideoCapturer {
return this.captureOptions !== undefined; return this.captureOptions !== undefined;
} }
setLocalPreview(localPreview: RefObject<HTMLVideoElement> | undefined): void { setLocalPreview(localPreview: HTMLVideoElement | undefined): void {
const oldLocalPreview = this.localPreview?.current; const oldLocalPreview = this.localPreview;
if (oldLocalPreview) { if (oldLocalPreview) {
oldLocalPreview.srcObject = null; oldLocalPreview.srcObject = null;
} }
@@ -63,18 +61,6 @@ export class GumVideoCapturer {
this.localPreview = localPreview; this.localPreview = localPreview;
this.updateLocalPreviewSourceObject(); this.updateLocalPreviewSourceObject();
// This is a dumb hack around the fact that sometimes the
// this.localPreview.current is updated without a call
// to setLocalPreview, in which case the local preview
// won't be rendered.
if (this.updateLocalPreviewIntervalId !== undefined) {
clearInterval(this.updateLocalPreviewIntervalId);
}
this.updateLocalPreviewIntervalId = setInterval(
this.updateLocalPreviewSourceObject.bind(this),
1000
);
} }
async enableCapture(options?: GumVideoCaptureOptions): Promise<void> { async enableCapture(options?: GumVideoCaptureOptions): Promise<void> {
@@ -98,11 +84,6 @@ export class GumVideoCapturer {
disable(): void { disable(): void {
this.stopCapturing(); this.stopCapturing();
this.stopSending(); this.stopSending();
if (this.updateLocalPreviewIntervalId !== undefined) {
clearInterval(this.updateLocalPreviewIntervalId);
}
this.updateLocalPreviewIntervalId = undefined;
} }
async setPreferredDevice(deviceId: string): Promise<void> { async setPreferredDevice(deviceId: string): Promise<void> {
@@ -361,11 +342,9 @@ export class GumVideoCapturer {
} }
private updateLocalPreviewSourceObject(): void { private updateLocalPreviewSourceObject(): void {
if (!this.localPreview) { const { localPreview } = this;
return;
}
const localPreview = this.localPreview.current;
if (!localPreview) { if (!localPreview) {
log.warn('No local preview to update');
return; return;
} }
@@ -376,6 +355,7 @@ export class GumVideoCapturer {
} }
if (mediaStream && this.captureOptions) { if (mediaStream && this.captureOptions) {
log.warn('Enabling local preview');
localPreview.srcObject = mediaStream; localPreview.srcObject = mediaStream;
if (localPreview.width === 0) { if (localPreview.width === 0) {
localPreview.width = this.captureOptions.maxWidth; localPreview.width = this.captureOptions.maxWidth;
@@ -384,6 +364,7 @@ export class GumVideoCapturer {
localPreview.height = this.captureOptions.maxHeight; localPreview.height = this.captureOptions.maxHeight;
} }
} else { } else {
log.warn('Disabling local preview');
localPreview.srcObject = null; localPreview.srcObject = null;
} }
} }
@@ -400,7 +381,7 @@ export class CanvasVideoRenderer {
private buffer: Uint8Array; private buffer: Uint8Array;
private imageData?: ImageData; private imageData?: ImageData;
private source?: VideoFrameSource; private source?: VideoFrameSource;
private rafId?: any; private rafId?: ReturnType<typeof requestAnimationFrame>;
constructor() { constructor() {
this.buffer = new Uint8Array(MAX_VIDEO_CAPTURE_BUFFER_SIZE); this.buffer = new Uint8Array(MAX_VIDEO_CAPTURE_BUFFER_SIZE);

View File

@@ -1193,7 +1193,7 @@ export class CallingClass {
if (this.#localPreview == null) { if (this.#localPreview == null) {
this.#localPreview = document.createElement('video'); this.#localPreview = document.createElement('video');
this.#localPreview.autoplay = true; this.#localPreview.autoplay = true;
this.#videoCapturer.setLocalPreview({ current: this.#localPreview }); this.#videoCapturer.setLocalPreview(this.#localPreview);
} }
this.#localPreviewContainer?.removeChild(this.#localPreview); this.#localPreviewContainer?.removeChild(this.#localPreview);