如何在tmImage中切换摄像头输入设备?Google Teachable Machine开发遇摄像头切换问题
问题根因
Google Teachable Machine 官方默认的 tmImage.Webcam 类的无参setup()方法,只会调用系统优先级最高的摄像头设备,不会读取浏览器设置的默认摄像头,也没有可用设备 fallback 逻辑,这就是你无法切换输入源、卸载Iriun Webcam后页面无响应的核心原因。
修复方案
你需要先枚举系统所有可用的视频输入设备,拿到目标摄像头的设备ID后传入setup()方法,即可指定要使用的输入源,也可以新增下拉选择组件实现手动切换摄像头。
修改后完整代码
<div>Teachable Machine Image Model</div> <!-- 新增摄像头选择下拉框 --> <div> <label>选择摄像头:</label> <select id="camera-select"></select> </div> <button type="button" onclick="init()">Start</button> <div id="webcam-container"></div> <div id="label-container"></div> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@teachablemachine/image@0.8/dist/teachablemachine-image.min.js"></script> <script type="text/javascript"> const URL = "https://teachablemachine.withgoogle.com/models/sDyEbFFcX/"; let model, webcam, labelContainer, maxPredictions; const cameraSelect = document.getElementById('camera-select'); // 新增:枚举所有可用视频输入设备 async function getCameras() { const devices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = devices.filter(device => device.kind === 'videoinput'); cameraSelect.innerHTML = ''; videoDevices.forEach((device, index) => { const option = document.createElement('option'); option.value = device.deviceId; option.text = device.label || `摄像头 ${index + 1}`; cameraSelect.appendChild(option); }); } // 页面加载时先获取可用摄像头列表 window.onload = getCameras; async function init() { const modelURL = URL + "model.json"; const metadataURL = URL + "metadata.json"; model = await tmImage.load(modelURL, metadataURL); maxPredictions = model.getTotalClasses(); const flip = false; webcam = new tmImage.Webcam(1280, 720, flip); // 修改:传入选中的摄像头设备ID const selectedDeviceId = cameraSelect.value; await webcam.setup({ deviceId: selectedDeviceId }); await webcam.play(); window.requestAnimationFrame(loop); document.getElementById("webcam-container").innerHTML = ''; document.getElementById("webcam-container").appendChild(webcam.canvas); labelContainer = document.getElementById("label-container"); labelContainer.innerHTML = ''; for (let i = 0; i < maxPredictions; i++) { labelContainer.appendChild(document.createElement("div")); } } async function loop() { webcam.update(); await predict(); window.requestAnimationFrame(loop); } async function predict() { const prediction = await model.predict(webcam.canvas); for (let i = 0; i < maxPredictions; i++) { const classPrediction = prediction[i].className + ": " + prediction[i].probability.toFixed(2); labelContainer.childNodes[i].innerHTML = classPrediction; } } </script>
注意事项
- 必须在HTTPS环境或者localhost本地环境运行代码,否则浏览器会禁止枚举摄像头设备的权限。
- 切换摄像头时直接重新点击Start按钮即可加载新选中的设备。
内容的提问来源于stack exchange,提问作者ádám homonnay
相关产品推荐
相关产品推荐

