changes: Fix iphone rear camera showing

This commit is contained in:
2025-10-08 23:50:00 -06:00
parent d439640635
commit a646772976

View File

@@ -54,7 +54,7 @@ function HomePageContent() {
console.log('starting stream....')
try {
const newStream = await navigator.mediaDevices.getUserMedia({
video: { deviceId: { exact: deviceId } },
video: { deviceId: deviceId ? { ideal: deviceId } : true },
});
console.log(newStream)
@@ -80,73 +80,130 @@ function HomePageContent() {
useEffect(() => {
const initializeCamera = async () => {
try {
// Check if there's a stored preference first
// Load history first
setHistory(getHistory());
// Check if there's a stored preference
const storedDeviceId = localStorage.getItem('selectedCameraDeviceId');
let targetStream: MediaStream;
if (storedDeviceId) {
// User has a saved preference, use it
console.log('Using stored camera preference:', storedDeviceId);
targetStream = await navigator.mediaDevices.getUserMedia({
video: { deviceId: { exact: storedDeviceId } }
});
} else {
// No preference - try to use back/environment camera
console.log('No stored preference - requesting back camera (facingMode: environment)');
try {
targetStream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'environment' }
});
} catch (err) {
// Fallback: facingMode might not be supported, use default
console.log('facingMode not supported, using default camera');
targetStream = await navigator.mediaDevices.getUserMedia({ video: true });
console.log('✅ Found stored camera preference, attempting to use it...');
// Step 1: Request permission with stored device
const permissionStream = await navigator.mediaDevices.getUserMedia({ video: true });
permissionStream.getTracks().forEach(track => track.stop());
// Step 2: Enumerate devices
const devices = await navigator.mediaDevices.enumerateDevices();
const videoInputs = devices.filter(d => d.kind === 'videoinput');
console.log('📹 Available cameras:', videoInputs.map(d => ({ label: d.label, id: d.deviceId })));
setVideoDevices(videoInputs);
if (videoInputs.length === 0) {
setCameraStatus('no_devices');
return;
}
// Check if stored device still exists
const storedDevice = videoInputs.find(d => d.deviceId === storedDeviceId);
if (storedDevice) {
console.log('✅ Using stored camera:', storedDevice.label);
setSelectedDeviceId(storedDevice.deviceId);
await startStream(storedDevice.deviceId);
return;
} else {
console.log('⚠️ Stored camera not found, will search for back camera');
}
}
// Stop the stream temporarily to enumerate devices
targetStream.getTracks().forEach(track => track.stop());
// No stored preference or stored device not found - find back camera
console.log('🔍 Attempting to open back camera using facingMode: environment');
// Now enumerate devices - deviceIds will be stable after permission granted
// Step 1: Try to open back camera directly with facingMode
let backCameraStream: MediaStream;
try {
backCameraStream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'environment' }
});
console.log('✅ Got stream with facingMode: environment');
} catch (err) {
console.log('⚠️ facingMode: environment failed, trying default camera');
backCameraStream = await navigator.mediaDevices.getUserMedia({ video: true });
}
// Step 2: Get the actual device that was used
const track = backCameraStream.getVideoTracks()[0];
const settings = track.getSettings();
console.log('📸 Camera settings:', {
deviceId: settings.deviceId,
facingMode: settings.facingMode,
label: track.label
});
// Step 3: Enumerate all devices
const devices = await navigator.mediaDevices.enumerateDevices();
const videoInputs = devices.filter(d => d.kind === 'videoinput');
console.log('📹 All cameras:', videoInputs.map(d => ({ label: d.label, id: d.deviceId })));
setVideoDevices(videoInputs);
if (videoInputs.length === 0) {
backCameraStream.getTracks().forEach(track => track.stop());
setCameraStatus('no_devices');
return;
}
// Load history
setHistory(getHistory());
// Step 4: Verify if we got the back camera
let selectedDevice: MediaDeviceInfo | undefined;
// Find which camera was actually used
const activeTrack = targetStream.getVideoTracks()[0];
const activeDeviceId = activeTrack?.getSettings().deviceId;
let finalDevice: MediaDeviceInfo;
if (activeDeviceId && videoInputs.find(d => d.deviceId === activeDeviceId)) {
// Found the device that was actually used
finalDevice = videoInputs.find(d => d.deviceId === activeDeviceId)!;
console.log('Using camera:', finalDevice.label || 'Unknown');
if (settings.facingMode === 'environment') {
// Perfect! We got the environment camera
console.log('✅ Confirmed back camera by facingMode');
selectedDevice = videoInputs.find(d => d.deviceId === settings.deviceId);
} else {
// Fallback: try to find back camera by label
const backCameraKeywords = ['back', 'rear', 'trasera', 'environment', 'facing back'];
finalDevice = videoInputs.find(d =>
// We might have gotten the front camera, let's search manually
console.log('⚠️ facingMode is not "environment", searching manually...');
// Stop the current stream
backCameraStream.getTracks().forEach(track => track.stop());
// Search by label keywords
const backCameraKeywords = ['back', 'rear', 'trasera', 'environment', 'posterior'];
selectedDevice = videoInputs.find(d =>
backCameraKeywords.some(keyword => d.label.toLowerCase().includes(keyword))
) || videoInputs[0];
console.log('Fallback to camera:', finalDevice.label || 'Unknown');
);
if (!selectedDevice && videoInputs.length > 1) {
// iOS fallback: try index 1 (usually back camera)
console.log('📱 Trying camera at index 1 for iOS');
selectedDevice = videoInputs[1];
}
}
setSelectedDeviceId(finalDevice.deviceId);
localStorage.setItem('selectedCameraDeviceId', finalDevice.deviceId);
await startStream(finalDevice.deviceId);
// Fallback to first camera
if (!selectedDevice) {
selectedDevice = videoInputs[0];
console.log('⚠️ Using first camera as fallback');
}
console.log('🎯 Selected camera:', selectedDevice.label, selectedDevice.deviceId);
setSelectedDeviceId(selectedDevice.deviceId);
localStorage.setItem('selectedCameraDeviceId', selectedDevice.deviceId);
// If we still have the stream from facingMode and it matches, use it
if (settings.facingMode === 'environment' && settings.deviceId === selectedDevice.deviceId) {
console.log('♻️ Reusing existing stream');
setStream(backCameraStream);
setCameraStatus('active');
if (videoRef.current) {
videoRef.current.srcObject = backCameraStream;
}
} else {
// Start fresh stream with selected device
backCameraStream.getTracks().forEach(track => track.stop());
await startStream(selectedDevice.deviceId);
}
} catch (err) {
// Permission denied or no camera
console.error('Error accessing camera or enumerating devices:', err);
console.error('❌ Error accessing camera:', err);
setCameraStatus('denied');
}
};