如何将getUserMedia摄像头选择功能集成到say-cheese.js实现后置摄像头切换
Hey there! Let's break down exactly how to add camera selection (front/back support) to your SayCheese.js setup, since you're comfortable with jQuery and just need to integrate that device detection logic you found. Here's a step-by-step guide tailored to your needs:
1. Confirm Your HTML Structure
First, make sure your camera container and selection dropdown are properly placed in your page:
<!-- Container where SayCheese will render the camera feed --> <div id="camera-container"></div> <!-- Your existing camera selector --> <select id="videoSource"> <option selected>Default Camera</option> </select>
2. Add Device Detection with jQuery
We'll create a function to fetch all available video cameras and populate your dropdown. Since you use jQuery, this will feel familiar:
// Populate the camera dropdown with available devices function populateCameraOptions() { // Check if browser supports device enumeration if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { alert("Sorry, your browser doesn't support camera selection."); return; } navigator.mediaDevices.enumerateDevices() .then(deviceInfos => { const $videoSelect = $('#videoSource'); // Clear existing options except the default $videoSelect.find('option:not(:first)').remove(); deviceInfos.forEach(deviceInfo => { // Only care about video input devices if (deviceInfo.kind === 'videoinput') { // Use device label if available, otherwise generate a name const label = deviceInfo.label || `Camera ${$videoSelect.find('option').length + 1}`; $videoSelect.append($('<option>').val(deviceInfo.deviceId).text(label)); } }); }) .catch(err => console.error('Error fetching cameras:', err)); } // Run this when the page loads $(document).ready(() => { populateCameraOptions(); });
3. Modify SayCheese.js for Camera Switching
Next, we'll update the SayCheese library to accept a camera source ID and support switching cameras. Here's how to adjust the code you provided:
// Keep your existing getUserMedia fallback navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; SayCheese = function SayCheese(element, options) { this.snapshots = []; this.video = null; this.events = {}; this.stream = null; // Merge default options with user-provided ones (using jQuery's extend for familiarity) this.options = $.extend({ videoSource: null, snapshots: true, audio: false, width: 320 }, options || {}); const that = this; // Helper function to initialize/switch camera stream function initStream(sourceId) { // Stop existing stream if it exists to free up the camera if (that.stream) { that.stream.getTracks().forEach(track => track.stop()); } // Build media constraints with the selected camera source const constraints = { audio: that.options.audio, video: { optional: sourceId ? [{ sourceId: sourceId }] : [] } }; // Request access to the camera navigator.getUserMedia(constraints, stream => { that.stream = stream; // Attach stream to the video element (update this if SayCheese uses a different method) that.video.srcObject = stream; that.video.play(); }, err => console.error('Error accessing camera:', err)); } // Initialize with the default or provided camera initStream(this.options.videoSource); // Expose a method to switch cameras from outside the library this.switchCamera = function(sourceId) { initStream(sourceId); }; // Keep the rest of SayCheese's original logic here... return this; };
4. Add Dropdown Change Handler
Finally, link the dropdown to the SayCheese instance so selecting a new camera triggers a switch:
$(document).ready(() => { populateCameraOptions(); // Initialize your SayCheese instance (adjust the selector to match your container) const sayCheese = new SayCheese('#camera-container'); // Handle camera selection change $('#videoSource').on('change', function() { const selectedCameraId = $(this).val(); sayCheese.switchCamera(selectedCameraId); }); });
Key Notes to Keep in Mind
- Browser Support: Most modern browsers support
navigator.mediaDevices.enumerateDevices(), but older ones might not—add a fallback message like we did if needed. - Stream Cleanup: Always stop the old camera stream before switching to a new one, otherwise the browser might keep the first camera locked.
- Video Element Binding: If SayCheese.js uses an older method to attach the stream (like
URL.createObjectURL(stream)), replace that withsrcObjectfor modern compatibility.
内容的提问来源于stack exchange,提问作者Björn C

