fix: improve front camera detection on macOS by checking video track label

This commit is contained in:
2026-02-28 18:04:28 +00:00
parent 4d572b55ca
commit 616f615d7c

View File

@@ -8,7 +8,7 @@ const scannedCodes = ref([])
const hasMultipleCameras = ref(false)
const isFullscreen = ref(false)
const videoAspect = ref(1)
const isFront = computed(() => facingMode.value === 'user')
const isMirrored = ref(false)
const wrapperRef = ref(null)
const bgCanvas = ref(null)
let bgRafId = null
@@ -65,7 +65,7 @@ const paintDetections = (codes) => {
}
const scale = drawWidth / vw
const isMirrored = isFront.value
// Canvas is mirrored via CSS if isMirrored is true, so no manual coordinate mirroring needed
// Styles
const styles = getComputedStyle(document.documentElement)
@@ -84,10 +84,6 @@ const paintDetections = (codes) => {
const transform = (p) => {
let x = p.x * scale + startX
let y = p.y * scale + startY
if (isMirrored) {
x = width - x
}
return { x, y }
}
@@ -203,6 +199,23 @@ const startScan = async () => {
stream = await navigator.mediaDevices.getUserMedia(constraints)
// Detect actual facing mode to mirror front camera correctly
const videoTrack = stream.getVideoTracks()[0]
if (videoTrack) {
const settings = videoTrack.getSettings()
if (settings.facingMode) {
isMirrored.value = settings.facingMode === 'user'
} else {
// Fallback: check label for desktop cameras or assume requested mode
const label = videoTrack.label ? videoTrack.label.toLowerCase() : ''
if (label.includes('front') || label.includes('facetime') || label.includes('macbook')) {
isMirrored.value = true
} else {
isMirrored.value = facingMode.value === 'user'
}
}
}
if (videoRef.value) {
videoRef.value.srcObject = stream
// Wait for metadata to play
@@ -464,7 +477,7 @@ const isUrl = (string) => {
<div
class="camera-wrapper"
:class="{ 'clickable': !isFullscreen, 'is-front': isFront }"
:class="{ 'clickable': !isFullscreen, 'is-mirrored': isMirrored }"
:style="desktopFullscreenStyle"
ref="wrapperRef"
@click="!isFullscreen && toggleFullscreen()"
@@ -472,13 +485,13 @@ const isUrl = (string) => {
<video
ref="videoRef"
class="camera-feed"
:class="{ 'is-front': isFront }"
:class="{ 'is-mirrored': isMirrored }"
autoplay
playsinline
muted
></video>
<canvas ref="overlayCanvas" class="scan-overlay-canvas"></canvas>
<canvas ref="overlayCanvas" class="scan-overlay-canvas" :class="{ 'is-mirrored': isMirrored }"></canvas>
<div v-if="error" class="error-overlay">
<p>{{ error }}</p>
@@ -632,7 +645,7 @@ const isUrl = (string) => {
display: block;
}
.camera-feed.is-front {
.camera-feed.is-mirrored {
transform: scaleX(-1);
}
@@ -646,6 +659,10 @@ const isUrl = (string) => {
z-index: 5;
}
.scan-overlay-canvas.is-mirrored {
transform: scaleX(-1);
}
/* front mirror canvas removed */
.error-overlay {