You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js/Socket.io实现视频聊天时部分设备摄像头无法启动

问题背景
  • 技术栈:nextjs@10、socket.io@4、socket.io-client@4、express
  • 开发场景:在现有Next.js应用中新增视频聊天功能,参考开源项目video-chat-webrtc做了适配Next.js后端特性的自定义修改
  • 本地测试表现:localhost环境下所有功能运行正常
  • 部署环境:搭载AWS ELB的测试服务器
故障表现

所有场景下音频、聊天消息传输均正常,用户已按弹窗提示授予媒体权限,仅摄像头采集环节异常,控制台固定报错:

Error getting userMedia: DOMException: Starting videoinput failed

具体异常场景:

  • 创建支持视频、音频、聊天的房间后,加拿大地区Chrome用户加入房间,可以看到房主画面,但自身摄像头未启动,音频、聊天功能正常
  • 手机端加入房间所有功能正常;另一台笔记本加入时,Chrome环境下整体功能正常但笔记本摄像头画面无传输,Firefox环境下无任何视频传输,仅聊天、音频功能正常
问题相关核心代码

音视频采集逻辑代码如下:

useEffect(() => {
    navigator.mediaDevices.getUserMedia({
        video: {
            width: 1280,
            height: 720
        },
        audio: true
    }).then(stream => {
        console.log('STREAM OBJECT: ', stream);
        localMediaStream.current = stream;
        addNewClient(LOCAL_VIDEO, () => {
            const localVideoElement = peerMediaElements.current[LOCAL_VIDEO];
    
            if (localVideoElement) {
                localVideoElement.volume = 0; // 关闭本地麦克风回放
                localVideoElement.srcObject = stream;
            }
        });
        socket.emit(SOCKET_ACTIONS.JOIN_ROOM, {room: roomID});
    }).catch(e => {
        console.warn('Error getting userMedia:', e);
        socket.emit(SOCKET_ACTIONS.JOIN_ROOM, {room: roomID})
    });
}, []);
问题根因

核心问题是代码中硬编码了强制1280*720的精确视频采集分辨率:

  1. getUserMedia约束中直接写死width:1280、height:720属于强制值要求,浏览器不会自动做分辨率降级,只要当前设备摄像头不支持精确输出该分辨率,就会直接抛出Starting videoinput failed错误,导致视频轨道采集失败
  2. 本地开发机摄像头刚好支持1280*720采集,所以localhost测试无异常;手机摄像头普遍原生支持720P采集,所以手机端功能正常;部分老旧笔记本、外接摄像头、不同地区用户的设备可能不支持强制720P输出,就会触发采集失败
  3. Firefox对媒体采集约束的校验比Chrome更严格,只要参数不匹配就直接拒绝视频采集请求,所以会出现Firefox全量视频传输失败的表现
  4. 现有catch块逻辑存在缺陷:视频采集失败后没有任何用户提示,直接执行加入房间逻辑,导致用户进房后只有音频、聊天正常,没有本地视频画面,也不知道视频采集失败的原因
修复方案
  1. 调整视频采集约束,将强制分辨率改为理想值,给浏览器预留自动降级空间,修改后的采集参数示例:
    navigator.mediaDevices.getUserMedia({
        video: {
            width: { ideal: 1280 }, // 优先匹配1280宽度,不支持自动降级
            height: { ideal: 720 }
        },
        audio: true
    })
    
    如果要兼容更老的设备,可以再加一层降级逻辑:先尝试采集720P流,采集失败就自动降级为480P甚至默认分辨率(video: true),不要因为参数不匹配直接阻断视频功能
  2. 优化错误处理逻辑:采集失败时不要静默执行进房操作,要给用户弹出明确提示,告知是摄像头设备不支持/被占用导致视频功能不可用,避免用户无感知进房
  3. 额外适配:可以在采集前通过navigator.mediaDevices.enumerateDevices()先获取用户的摄像头设备信息,针对不同设备做更灵活的参数适配,进一步降低采集失败概率

内容的提问来源于stack exchange,提问作者Roman Nozhenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 18:24:41