diff --git a/packages/core/useUserMedia/demo.vue b/packages/core/useUserMedia/demo.vue index 5be0477fde9..ecfd1e619aa 100644 --- a/packages/core/useUserMedia/demo.vue +++ b/packages/core/useUserMedia/demo.vue @@ -13,7 +13,7 @@ const { videoInputs: cameras } = useDevicesList({ const video = ref() const { stream, enabled } = useUserMedia({ - videoDeviceId: currentCamera, + constraints: { video: { deviceId: currentCamera } }, }) watchEffect(() => { diff --git a/packages/core/useUserMedia/index.md b/packages/core/useUserMedia/index.md index 61618a7c335..2e7dcc628ca 100644 --- a/packages/core/useUserMedia/index.md +++ b/packages/core/useUserMedia/index.md @@ -41,7 +41,9 @@ const currentCamera = computed(() => cameras.value[0]?.deviceId) const currentMicrophone = computed(() => microphones.value[0]?.deviceId) const { stream } = useUserMedia({ - videoDeviceId: currentCamera, - audioDeviceId: currentMicrophone, + constraints: { + video: { deviceId: currentCamera }, + audio: { deviceId: currentMicrophone, } + } }) ``` diff --git a/packages/core/useUserMedia/index.ts b/packages/core/useUserMedia/index.ts index 8f2000cf8f0..92fc92fa9e2 100644 --- a/packages/core/useUserMedia/index.ts +++ b/packages/core/useUserMedia/index.ts @@ -14,7 +14,7 @@ export interface UseUserMediaOptions extends ConfigurableNavigator { */ enabled?: MaybeRef /** - * Recreate stream when the input devices id changed + * Recreate stream when deviceIds or constraints changed * * @default true */ @@ -26,6 +26,7 @@ export interface UseUserMediaOptions extends ConfigurableNavigator { * Pass `false` or "none" to disabled video input * * @default undefined + * @deprecated in favor of constraints */ videoDeviceId?: MaybeRef /** @@ -35,8 +36,16 @@ export interface UseUserMediaOptions extends ConfigurableNavigator { * Pass `false` or "none" to disabled audi input * * @default undefined + * @deprecated in favor of constraints */ audioDeviceId?: MaybeRef + /** + * MediaStreamConstraints to be applied to the requested MediaStream + * If provided, the constraints will override videoDeviceId and audioDeviceId + * + * @default {} + */ + constraints?: MaybeRef } /** @@ -50,18 +59,32 @@ export function useUserMedia(options: UseUserMediaOptions = {}) { const autoSwitch = ref(options.autoSwitch ?? true) const videoDeviceId = ref(options.videoDeviceId) const audioDeviceId = ref(options.audioDeviceId) + const constraints = ref(options.constraints) const { navigator = defaultNavigator } = options const isSupported = useSupported(() => navigator?.mediaDevices?.getUserMedia) const stream: Ref = shallowRef() - function getDeviceOptions(device: Ref) { - if (device.value === 'none' || device.value === false) - return false - if (device.value == null) - return true - return { - deviceId: device.value, + function getDeviceOptions(type: 'video' | 'audio') { + switch (type) { + case 'video': { + if (constraints.value) + return constraints.value.video || false + if (videoDeviceId.value === 'none' || videoDeviceId.value === false) + return false + if (videoDeviceId.value == null) + return true + return { deviceId: videoDeviceId.value } + } + case 'audio': { + if (constraints.value) + return constraints.value.audio || false + if (audioDeviceId.value === 'none' || audioDeviceId.value === false) + return false + if (audioDeviceId.value == null) + return true + return { deviceId: audioDeviceId.value } + } } } @@ -69,13 +92,13 @@ export function useUserMedia(options: UseUserMediaOptions = {}) { if (!isSupported.value || stream.value) return stream.value = await navigator!.mediaDevices.getUserMedia({ - video: getDeviceOptions(videoDeviceId), - audio: getDeviceOptions(audioDeviceId), + video: getDeviceOptions('video'), + audio: getDeviceOptions('audio'), }) return stream.value } - async function _stop() { + function _stop() { stream.value?.getTracks().forEach(t => t.stop()) stream.value = undefined } @@ -102,14 +125,13 @@ export function useUserMedia(options: UseUserMediaOptions = {}) { (v) => { if (v) _start() - else - _stop() + else _stop() }, { immediate: true }, ) watch( - [videoDeviceId, audioDeviceId], + [videoDeviceId, audioDeviceId, constraints], () => { if (autoSwitch.value && stream.value) restart() @@ -125,6 +147,7 @@ export function useUserMedia(options: UseUserMediaOptions = {}) { restart, videoDeviceId, audioDeviceId, + constraints, enabled, autoSwitch, }