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

如何在WebRTC中识别媒体流类型?能否通过SDP添加自定义信息?

区分摄像头流与屏幕共享流的方案

一、可以在SDP中添加自定义标识

当然可以通过修改发送端的SDP来注入额外信息,以此区分流类型,具体实现步骤如下:

    1. 创建Offer后,遍历SDP的媒体描述行(以m=开头的行),定位到目标视频轨道对应的媒体段
    1. 为该媒体段添加自定义属性行,比如用a=stream-type:screen标记屏幕共享流,a=stream-type:camera标记摄像头流
    1. 将修改后的SDP重新赋值给Offer,再设置到本地会话并发送给接收端
    1. 接收端解析SDP时,读取对应的自定义属性即可完成流类型区分

示例代码:

// 发送端修改SDP
pc.createOffer().then(offer => {
  // 先判断当前视频轨道是否为屏幕共享流(可通过track的label或获取流的方式判断)
  const isScreenShare = pc.getSenders().some(sender => 
    sender.track?.kind === 'video' && sender.track.label.includes('screen')
  );
  // 替换SDP,添加自定义标识
  offer.sdp = offer.sdp.replace(
    /m=video.*\r\n/,
    match => match + `${isScreenShare ? 'a=stream-type:screen\r\n' : 'a=stream-type:camera\r\n'}`
  );
  return pc.setLocalDescription(offer);
}).then(() => {
  // 发送修改后的Offer到接收端
});

// 接收端解析SDP
pc.setRemoteDescription(remoteOffer).then(() => {
  const sdpLines = remoteOffer.sdp.split('\r\n');
  let currentVideoType = '';
  for (const line of sdpLines) {
    if (line.startsWith('a=stream-type:')) {
      currentVideoType = line.split(':')[1];
      break;
    }
  }
  if (currentVideoType === 'screen') {
    // 处理屏幕共享流逻辑
  } else {
    // 处理摄像头流逻辑
  }
});

二、为什么MediaStream的label属性未生效

MediaStream的label属性属于浏览器本地属性,不会被自动映射到SDP协议字段中,因此接收端无法通过SDP或轨道信息获取到这个值,这就是你之前尝试无效的原因。

三、更兼容的替代方案

除了修改SDP,还有两种更稳妥的方式:

  • 直接标记MediaStreamTrack:在发送端为轨道添加自定义标识(注意部分浏览器可能会限制自定义属性,建议结合信令同步)
// 获取屏幕流时标记轨道
navigator.mediaDevices.getDisplayMedia({video: true}).then(stream => {
  const track = stream.getVideoTracks()[0];
  track.streamType = 'screen'; // 添加自定义属性
  pc.addTrack(track, stream);
});

// 摄像头流同理
navigator.mediaDevices.getUserMedia({video: true}).then(stream => {
  const track = stream.getVideoTracks()[0];
  track.streamType = 'camera';
  pc.addTrack(track, stream);
});
  • 信令同步轨道类型:发送SDP的同时,通过信令单独发送轨道ID与类型的映射关系,接收端根据ID匹配类型,兼容性最好
// 发送端
pc.createOffer().then(offer => pc.setLocalDescription(offer)).then(() => {
  const trackInfos = pc.getSenders()
    .filter(sender => sender.track?.kind === 'video')
    .map(sender => ({
      trackId: sender.track.id,
      type: sender.track.label.includes('screen') ? 'screen' : 'camera'
    }));
  // 通过信令发送Offer和轨道类型信息
  sendSignal({
    type: 'offer',
    sdp: pc.localDescription.sdp,
    trackInfos
  });
});

// 接收端
onSignalReceived(msg => {
  if (msg.type === 'offer') {
    pc.setRemoteDescription(new RTCSessionDescription(msg)).then(() => {
      pc.getReceivers().forEach(receiver => {
        const info = msg.trackInfos.find(item => item.trackId === receiver.track.id);
        if (info?.type === 'screen') {
          // 处理屏幕共享流
        } else {
          // 处理摄像头流
        }
      });
    });
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:57:24