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

如何在Agora Web SDK 4.x中同时发布摄像头与屏幕共享视频轨道?

解决Agora Web SDK 4.x同时推送摄像头与屏幕共享轨道的问题

Agora Web SDK 4.x支持同一客户端同时发布多条视频轨道,你之前的错误操作是误解了文档时序图的适用场景——该时序图仅针对「切换单视频轨道」的需求(比如只推屏幕或只推摄像头),并非强制要求取消原有摄像头轨道才能发布屏幕共享轨道。

修正后的代码实现

直接移除取消发布摄像头轨道的逻辑,同时增加屏幕共享结束后的资源清理:

async startScreenShare(id?: string): Promise<void> {
  let stream: MediaStream;
  if (!id) {
    stream = await (navigator.mediaDevices as any).getDisplayMedia({
      audio: false,
      video: true,
    });
  } else {
    const constraint = {
      audio: false,
      video: {
        mandatory: {
          chromeMediaSource: 'screen',
          chromeMediaSourceId: id,
        },
      },
    };

    stream = await navigator.mediaDevices.getUserMedia(constraint as any);
  }

  const videoTrack = stream.getTracks()[0];

  this.rtc.screenVideoTrack = AgoraRTC.createCustomVideoTrack({
    mediaStreamTrack: videoTrack,
  });

  // 移除取消发布摄像头轨道的代码
  // this.rtc.client.unpublish(this.rtc.localVideoTrack);

  // 直接发布屏幕共享轨道
  await this.rtc.client.publish(this.rtc.screenVideoTrack);

  // 监听屏幕共享结束事件,自动清理资源
  videoTrack.addEventListener('ended', () => {
    this.rtc.client.unpublish(this.rtc.screenVideoTrack);
    this.rtc.screenVideoTrack.close();
    this.rtc.screenVideoTrack = null;
  });
}

接收端区分轨道的处理

接收端需要通过轨道标识区分摄像头和屏幕共享画面,示例代码如下:

this.rtc.client.on('user-published', async (user, mediaType) => {
  await this.rtc.client.subscribe(user, mediaType);
  if (mediaType === 'video') {
    const videoTrack = user.videoTrack;
    // 屏幕共享轨道的label通常包含"screen"关键词,以此区分
    if (videoTrack.label.includes('screen')) {
      videoTrack.play('screen-container'); // 渲染到屏幕共享容器
    } else {
      videoTrack.play('camera-container'); // 渲染到摄像头画面容器
    }
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 19:20:47