如何修复NotReadableError:无法启动视频源(摄像头切换异常)
Hey there, I see your problem—first camera launch works perfectly, but switching between front/back cameras triggers that annoying NotReadableError: Could not start video source. The core issue here is you're not releasing the existing media stream before requesting access to the new camera. Camera hardware is an exclusive resource; if the old stream is still holding onto it, the new request can't grab control.
Let's fix this step by step:
1. Critical Fix: Close the Previous Media Stream
Before making a new getUserMedia call, you need to stop all tracks in the current active stream. This tells the browser to release the camera/audio hardware so the new request can use it.
2. Clean Up Your Code
- Ditch
eval()—it's unsafe and totally unnecessary here. We can create the facingMode object directly. - Double-check
videoHeightandvideoWidth—you might have swapped them (width typically comes first in constraints). - Fix the escaped quotes (
") in your alert/console log for readability.
Modified Working Code
function StartVideoCamera(obj) { var id = $(obj).attr('id'); var camNode = $(obj).attr('cammode'); // Set facingMode safely without eval var facingMode = camNode === 'user' ? 'user' : { exact: 'environment' }; var video = document.querySelector('#video' + id); var constraints = { audio: true, video: { width: videoWidth, // Ensure these variables are defined correctly in your code height: videoHeight, facingMode: facingMode } }; // Step 1: Release existing stream if it exists if (window.stream) { window.stream.getTracks().forEach(track => { track.stop(); // Stop each track to free up hardware }); window.stream = null; // Clear the reference to avoid leftovers } navigator.mediaDevices.getUserMedia(constraints) .then(function(mediaStream) { window.stream = mediaStream; video.srcObject = mediaStream; recordButton.disabled = false; // Make sure recordButton is in scope video.onloadedmetadata = function(e) { video.play(); }; }) .catch(function(err) { alert(`${err.name}: ${err.message}`); console.error(err.name + ": " + err.message); }); }
Key Explanations
- Stopping Tracks:
stream.getTracks()fetches all audio/video tracks in the current stream. Callingtrack.stop()on each one releases the hardware resources tied to that track. - No More Eval: Replaced the eval call with a simple ternary operator to set
facingMode—this is safer, faster, and easier to maintain. - Stream Cleanup: Clearing the
window.streamreference after stopping tracks ensures there are no leftover connections to the hardware.
Give this a test—switching between front and back cameras should now work without hitting the NotReadableError.
内容的提问来源于stack exchange,提问作者santosh

