You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

WebRTC视频流断开告警实现:检测摄像头拔除或崩溃

检测WebRTC摄像头流断开的解决方案

嘿,这个问题我刚好有经验,咱们一步步来解决!你已经找到了ondevicechange这个API,但它只能告诉你设备列表发生了变化,没法直接知道当前活跃的视频流是否受到影响。其实结合MediaStreamTrack的事件监听,就能完美解决流断开的告警问题。

核心方案:监听MediaStreamTrack的状态事件

当摄像头被拔掉、硬件崩溃或者流意外终止时,对应的MediaStreamTrack会触发ended事件;如果是临时断开(比如被其他应用占用导致静音),还会触发mute/unmute事件。我们可以直接给获取到的视频轨道绑定这些事件:

navigator.mediaDevices.getUserMedia({ 
  video: { facingMode: "user" } 
}).then(function (stream) {
  const video = document.getElementById('cam-stream');
  video.srcObject = stream;

  // 遍历所有视频轨道,绑定状态监听
  stream.getVideoTracks().forEach(track => {
    // 流彻底断开时触发(比如摄像头被拔掉)
    track.addEventListener('ended', () => {
      alert('摄像头流已断开!请检查设备连接');
      // 这里可以添加自定义逻辑:比如更新页面提示、记录错误日志等
    });

    // 流临时静音时触发(比如被其他应用抢占)
    track.addEventListener('mute', () => {
      alert('摄像头流临时中断!请关闭其他占用摄像头的应用');
    });

    // 流恢复时触发
    track.addEventListener('unmute', () => {
      alert('摄像头流已恢复正常');
    });
  });
}).catch(function (error) {
  console.log("Camera Stream Error : " + error.name + " - " + error.message);
});

补充:结合ondevicechange做主动检查

ondevicechange可以在设备列表变化时(比如插拔摄像头)触发,我们可以利用它主动检查当前活跃流的状态,作为事件监听的补充:

navigator.mediaDevices.addEventListener('devicechange', () => {
  const videoElement = document.getElementById('cam-stream');
  if (!videoElement.srcObject) return;

  const activeStream = videoElement.srcObject;
  const videoTracks = activeStream.getVideoTracks();

  videoTracks.forEach(track => {
    // 检查轨道是否还处于活跃状态
    if (track.readyState !== 'live') {
      alert('检测到设备变化,当前摄像头流已断开!');
      // 可选:尝试重新获取摄像头流
      // retryGetCameraStream();
    }
  });
});

// 可选:封装重新获取流的函数
function retryGetCameraStream() {
  navigator.mediaDevices.getUserMedia({ video: { facingMode: "user" } })
    .then(newStream => {
      const video = document.getElementById('cam-stream');
      video.srcObject = newStream;
      // 别忘了给新轨道重新绑定事件
      newStream.getVideoTracks().forEach(track => {
        track.addEventListener('ended', () => alert('摄像头流再次断开'));
      });
    })
    .catch(err => console.log('重新获取流失败:', err));
}

关键细节说明

  • track.readyState:有两种状态——live表示轨道正在正常传输媒体数据,ended表示轨道已终止(比如硬件断开)。
  • enabled属性:和readyState不同,enabled是手动控制轨道是否启用(比如用户点击关闭摄像头),不是硬件断开的信号。
  • 多轨道情况:如果你的流包含多个视频轨道(比如外接多个摄像头),遍历所有轨道并监听是更稳妥的做法。

这样组合下来,既能实时响应流的状态变化,又能在设备变动时主动检查,基本覆盖了所有摄像头流断开的场景。

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

火山引擎 最新活动