Tutorial: 屏幕分享

屏幕分享

功能描述

本文主要介绍如何在 TRTC Web SDK 实现屏幕分享功能。

实现流程

  1. 【推流端】开启屏幕分享

    const trtcA = TRTC.create();
    await trtcA.enterRoom({
      scene: 'rtc',
      sdkAppId: 140000000, // 填写您的 sdkAppId
      userId: 'userA', // 填写您的 userId
      userSig: 'userA_sig', // 填写 userId 对应的 userSig
      roomId: 6969
    })
    await trtcA.startScreenShare();
    
  2. 【拉流端】播放屏幕分享

    const trtcB = TRTC.create();
    trtcB.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, ({ userId, streamType }) => {
      // 主路视频流,一般是推摄像头的那路流
      if (streamType === TRTC.TYPE.STREAM_TYPE_MAIN) {
        // 1. 在页面中放置一个 id 为 `${userId}_main` 的 div 标签,用于在 div 标签内播放主路流。业务侧可自定义 div 标签的 id,此处只是举例说明。
        // 2. 播放主路视频流
        trtcB.startRemoteVideo({ userId, streamType,  view: `${userId}_main` });
      } else {
        // 辅路视频流,一般是推屏幕分享的那路流。
        // 1. 在页面中放置一个 id 为 `${userId}_screen` 的 div 标签,用于在 div 标签内播放屏幕分享。业务侧可自定义 div 标签的 id,此处只是举例说明。
        // 2. 播放屏幕分享
        trtcB.startRemoteVideo({ userId, streamType, view: `${userId}_screen` });
      }
    });
    await trtcB.enterRoom({
      scene: 'rtc',
      sdkAppId: 140000000, // 填写您的 sdkAppId
      userId: 'userB', // 填写您的 userId
      userSig: 'userB_sig', // 填写 userId 对应的 userSig
      roomId: 6969
    })
    
  3. 同时推摄像头 + 屏幕分享

     await trtcA.startLocalVideo();
     await trtcA.startScreenShare();
    
  4. 屏幕分享 + 系统音频

    采集系统音频支持 Chrome M74+

    • 在 Windows 和 Chrome OS 上,可以采集整个系统的音频。
    • 在 Linux 和 Mac 上,只能采集某个页面的音频。
    • 其它 Chrome 版本、其它系统、其它浏览器均不支持。
     await trtcA.startScreenShare({ option: { systemAudio: true }});
    

    在弹出的对话框中勾选分享音频,系统音频会与本地麦克风混音后发布,房间内其他用户会收到 TRTC.EVENT.REMOTE_AUDIO_AVALIABLE 事件

  5. 停止屏幕分享

     // 停止屏幕分享采集及发布
     await trtcA.stopScreenShare();
     // 房间内的其他用户会收到 TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE 事件,streamType 是 TRTC.TYPE.STREAM_TYPE_SUB。
     trtcB.on(TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE, ({ userId, streamType }) => {
        if (streamType === TRTC.TYPE.STREAM_TYPE_SUB) {
        }
     })
    

    另外用户还可能会通过浏览器自带的按钮停止屏幕分享,因此屏幕分享流需要监听屏幕分享停止事件,并进行相应的处理。

    // 监听屏幕分享停止事件
    trtcA.on(TRTC.EVENT.SCREEN_SHARE_STOPPED, () => {
      console.log('screen sharing was stopped');
    });
    

注意事项

  1. 什么是主流,辅流?
  2. SDK 默认使用 1080p 参数配置来采集屏幕分享,具体参考接口:startScreenShare

常见问题

  1. Safari 屏幕分享出现报错 getDisplayMedia must be called from a user gesture handler

    这是因为 Safari 限制了 getDisplayMedia 屏幕采集的接口,必须在用户点击事件的回调函数执行的 1 秒内才可以调用。

    参考:webkit issue

    // good
    async function onClick() {
      // 建议在 onClick 执行时,先执行采集逻辑
      await trtcA.startScreenShare();
      await trtcA.enterRoom({ 
        roomId: 123123,
        sdkAppId: 140000000, // 填写您的 sdkAppId
        userId: 'userA', // 填写您的 userId
        userSig: 'userA_sig', // 填写 userId 对应的 userSig });
    });
    // bad
    async function onClick() {
      await trtcA.enterRoom({ 
        roomId: 123123,
        sdkAppId: 140000000, // 填写您的 sdkAppId
        userId: 'userA', // 填写您的 userId
        userSig: 'userA_sig', // 填写 userId 对应的 userSig });
      })
      // 进房可能耗时超过 1s,可能会采集失败
       await trtcA.startScreenShare();
    }
    
  2. Mac Chrome 在已授权屏幕录制的情况下屏幕分享失败,出现 "NotAllowedError: Permission denied by system" 或者 "NotReadableError: Could not start video source" 错误信息,Chrome bug。解决方案:打开【设置】> 点击【安全性与隐私】> 点击【隐私】> 点击【屏幕录制】> 关闭 Chrome 屏幕录制授权 > 重新打开 Chrome 屏幕录制授权 > 关闭 Chrome 浏览器 > 重新打开 Chrome 浏览器。

  3. WebRTC 屏幕分享已知问题及规避方案