Fix calling video device selection by using getUserMedia deviceId.exact

This commit is contained in:
ayumi-signal
2025-09-08 17:10:04 -07:00
committed by GitHub
parent b92c0e95e8
commit fb3f281c45

View File

@@ -23,10 +23,6 @@ export class GumVideoCaptureOptions {
onEnded?: () => void;
}
interface GumConstraints extends MediaStreamConstraints {
video?: boolean | GumTrackConstraints;
}
interface GumTrackConstraints extends MediaTrackConstraints {
mandatory?: GumTrackConstraintSet;
}
@@ -135,10 +131,29 @@ export class GumVideoCapturer {
return options.mediaStream;
}
const constraints: GumConstraints = {
if (options.screenShareSourceId !== undefined) {
const screenshareConstraints: GumTrackConstraints = {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: options.screenShareSourceId,
maxWidth: options.maxWidth,
maxHeight: options.maxHeight,
minFrameRate: 1,
maxFrameRate: options.maxFramerate,
},
};
return navigator.mediaDevices.getUserMedia({
audio: false,
video: {
deviceId: options.preferredDeviceId ?? this.preferredDeviceId,
video: screenshareConstraints,
});
}
const preferredDeviceId =
options.preferredDeviceId ?? this.preferredDeviceId;
const videoConstraints: GumTrackConstraints = {
deviceId: {
exact: preferredDeviceId,
},
width: {
max: options.maxWidth,
ideal: options.maxWidth,
@@ -151,21 +166,29 @@ export class GumVideoCapturer {
max: options.maxFramerate,
ideal: options.maxFramerate,
},
},
};
if (options.screenShareSourceId !== undefined) {
constraints.video = {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: options.screenShareSourceId,
maxWidth: options.maxWidth,
maxHeight: options.maxHeight,
minFrameRate: 1,
maxFrameRate: options.maxFramerate,
},
};
try {
const exactStream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: videoConstraints,
});
if (exactStream) {
return exactStream;
}
return window.navigator.mediaDevices.getUserMedia(constraints);
} catch (e) {
log.warn(
`getUserMedia(): Failed with exact constraints: ${e}. Falling back to loose constraints.`
);
}
return navigator.mediaDevices.getUserMedia({
audio: false,
video: {
...videoConstraints,
deviceId: preferredDeviceId,
},
});
}
private async startCapturing(options: GumVideoCaptureOptions): Promise<void> {