网页调用摄像头:srcObject与src属性设置报错问题求助
摄像头调用问题排查与解决
问题背景
尝试通过HTML/JS调用摄像头显示画面,编写了如下代码:
HTML代码
<html lang="fr"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=1024 initial-scale=1"> <!--JS--> <script src="script.js"></script> </head> <body> <main> <p>just a webpage to insert JS and see console returns</p> <video id="retourUtilisateur" autoplay playsinline></video> </main> </body> </html>
JS代码
const contraintes = { video: { width: { min: 1280, ideal: 1920, max: 2560, }, height: { min: 720, ideal: 1080, max: 1440 }, } }; //is getUserMedia available ? if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) { console.log("Fonctionalités logicielles disponibles") } else(console.log("Fonctionalités logicielles indisponibles")) //asking for camera access try { const stream = navigator.mediaDevices.getUserMedia(contraintes); console.log("cam connected"); // Utiliser le stream ici // Affichage du stream document.addEventListener("DOMContentLoaded", function() { const video = document.getElementById("retourUtilisateur"); video.srcObject = stream; }) } catch (e) { console.log("Impossible d'accéder à la caméra", e); }
运行后遇到两个错误:
caught TypeError: Failed to set the 'srcObject' property on 'HTMLMediaElement': The provided value is not of type '(MediaSourceHandle or MediaStream)'- 改用
src属性后出现404:GET http://127.0.0.1:5500/%5Bobject%20Promise%5D 404 (Not Found)
错误原因解析
- Promise类型错误:
navigator.mediaDevices.getUserMedia()返回的是一个Promise对象,而非直接的MediaStream。直接把Promise赋值给video.srcObject,不符合属性要求的类型,触发第一个错误。 - src属性的误用:改用
src时,浏览器会把Promise对象转换成字符串[object Promise]并当作URL请求,因此出现404错误。 - 关于srcObject的误解:
HTMLMediaElement确实拥有srcObject属性,专门用于设置MediaStream、MediaSource等媒体源,你应该是看错了文档内容。
修复后的代码
处理Promise有两种方式:async/await或.then(),这里推荐更直观的async/await写法:
const contraintes = { video: { width: { min: 1280, ideal: 1920, max: 2560, }, height: { min: 720, ideal: 1080, max: 1440 }, } }; // 检查API可用性 if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) { console.log("Fonctionalités logicielles disponibles") } else { console.log("Fonctionalités logicielles indisponibles") } // 等待DOM加载完成后再执行 document.addEventListener("DOMContentLoaded", async function() { try { // 等待Promise解析,获取真正的MediaStream const stream = await navigator.mediaDevices.getUserMedia(contraintes); console.log("cam connected"); const video = document.getElementById("retourUtilisateur"); video.srcObject = stream; } catch (e) { console.log("Impossible d'accéder à la caméra", e); } });
关键修改点
- 将摄像头请求逻辑放到
DOMContentLoaded事件回调中,确保video元素已存在于DOM中 - 用
async标记回调函数,通过await等待getUserMedia()的Promise完成,获取真实的MediaStream - 直接将MediaStream赋值给
video.srcObject,匹配属性要求的类型
总结
官方示例能正常运行,是因为它们正确处理了getUserMedia()返回的Promise——要么用.then()链式调用,要么用async/await等待结果。你之前的代码忽略了Promise的异步特性,直接使用未解析的Promise对象才导致错误。
内容的提问来源于stack exchange,提问作者Tsu'Na
相关产品推荐
相关产品推荐

