​屏幕共享

​屏幕共享 SDK 从 5.1.8 版本开始支持。
发布时间: 2021-11-22 19:03

回答:

屏幕共享{#official}

在融云音视频会议中, 你可以使用屏幕共享功能, 将当前正在观看的内容共享给会议中其他的用户.

集成条件{#intergrate}

音视频会议场景库: RTCLib sdk版本要求: 大于等于5.1.8

功能介绍{#description}

融云音视频会议SDK, 支持屏幕共享. 在音视频会议时, 您可以通过融云音视频SDK进行屏幕视频数据的抓取,并将其以单独视频流的形式发送到会议中. 这样会议中的其他用户就可以拉取该视频流, 观看你当前屏幕的内容.该功能也适用于低延迟直播场景.

注意: 音视频通话场景暂不支持该功能,即集成callkit或calllib的应用场景中暂不支持此功能.

功能使用说明{#instruction}

屏幕共享使用主要分为两部分: 1. 发布端分享屏幕, 2. 观众端拉取屏幕共享流

发布端分享屏幕

在发布共享屏幕数据时, 你需要注意三个过程:

  • 开启屏幕抓取

  • 发布屏幕共享视频流

  • 防止应用后台被强杀

开启屏幕抓取

在此过程中您需要注意以下三点:

  1. 添加Activity. 在 manifest 文件中粘贴如下 activity

     <activity android:name="cn.rongcloud.rtc.api.stream.RCRTCScreenShareActivity"></activity>
  2. 设置视频编码参数: 你可以通过RCRTCEngine.getInstance().getScreenShareVideoStream()获取用于屏幕共享的视频流. 然后进行编码参数的设置.

    注意: 默认屏幕共享流的分辨率为: 720x960, 帧率为:15fps

    RCRTCVideoStreamConfig.Builder builder = Builder.create();
    //设置帧率
    builder.setVideoFps(RCRTCVideoFps.Fps_15);
    //设置分辨率
    builder.setVideoResolution(RCRTCVideoResolution.RESOLUTION_720_1280);
    //设置最大码率
    builder.setMaxRate(2500);
    RCRTCEngine.getInstance().getScreenShareVideoStream().setVideoConfig(builder.build());
  3. 开启屏幕抓取:

    注意: 你需要在RCRTCEngine.getInstance().init()即融云音视频引擎初始化之后才可开启屏幕抓取 ``` RCRTCEngine.getInstance().getScreenShareVideoStream().startCaptureScreen( new IRCRTCResultCallback() { @Override public void onSuccess() {

     //todo 屏幕抓取开启成功

    }

    @Override public void onFailed(RTCErrorCode errorCode) {

     //todo 屏幕抓取开启失败

    } }); ```

  4. 关闭屏幕抓取:当用户不需要屏幕抓取时,需要调用stopCaptureScreen()关闭屏幕抓取.

RCRTCEngine.getInstance().getScreenShareVideoStream().stopCaptureScreen();
  • 屏幕共享流预览: 你也可以对本端屏幕共享流进行预览.

    //用于本地预览的视图
    RCRTCVideoView videoView = new RCRTCVideoView(getApplicationContext());
    RCRTCEngine.getInstance().getScreenShareVideoStream().setVideoView(videoView);

发布屏幕共享视频流

注意: 你需要在RCRTCEngine.getInstance().joinRoom()成功之后才可以发布屏幕共享流. 通过本地用户将屏幕共享流发布出去 ``` RCRTCEngine.getInstance().joinRoom("yourRoomId", new IRCRTCResultDataCallback() {            @Override            public void onSuccess(RCRTCRoom room) {                room.getLocalUser().publishStream(                    RCRTCEngine.getInstance().getScreenShareVideoStream(),                    new IRCRTCResultCallback() {                        @Override                        public void onSuccess() {                            //todo 发布成功                        }

                    @Override
                    public void onFailed(RTCErrorCode errorCode) {
                        //todo 发布失败
                    }
                });
        }

        @Override
        public void onFailed(RTCErrorCode errorCode) {

        }
    });
你也可以通过 localUser.publishStreams(streamList) 方法将屏幕共享流和其他音视频流一起发布到房间中.

* 取消发布屏幕共享视屏流: 当用户不需要进行屏幕共享时, 可以通过unpublishStream进行取消屏幕共享.

mRoom.getLocalUser().unpublishStream(RCRTCEngine.getInstance().getScreenShareVideoStream(), new IRCRTCResultCallback() {            @Override            public void onSuccess() {            }

        @Override
        public void onFailed(RTCErrorCode errorCode) {
        }
    });
#### 防止应用后台被强杀
从 Android 7.0 系统开始,切入到后台运行的普通 App 进程,但凡有 CPU 活动,都很容易会被系统强杀掉。融云提供的方案是:启动前台service. 当App切入后台进行屏幕共享时,由于启动了前台service就可以避免被系统强制杀掉.同时service中也会弹出通知消息. 告知用户当前应用正在屏幕共享.此方案是以技术方案的形式提供, 在融云<a src="https://github.com/rongcloud/rtc-quickdemo-android">rtc-quickdemo</a>中有实现. 

1. 注册service. ScreenCastService具体实现可参考<a src="https://github.com/rongcloud/rtc-quickdemo-android">rtc-quickdemo</a>中的相关代码.

2. 你可以在开启屏幕抓取成功后, 启动service.

private void bindScreenShareService() {        Intent service = new Intent(this, ScreenCastService.class);        serviceConnection = new ServiceConnection() {            @Override            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d(TAG, "onServiceDisconnected: ");
        }
    };
    bindService(service, serviceConnection, BIND_AUTO_CREATE);
    isBindDesktopShareService = true;

}
#### 观众端拉取屏幕共享流
当房间中有用户成功发布了共享流时,此房间的其他用户会通过IRCRTCRoomEventsListener中的onRemoteUserPublishResource事件获得通知.用户可以根据屏幕共享流的tag为RongCloudScreenShare来区分当前视频流是否为屏幕共享流, 一次的来处理屏幕共享流相关逻辑. 远端用户需要以拉取远端视频流的方法进行拉去该视频流, 然后添加videoView进行渲染.

/**

  • 远端用户发布资源通知 *

  • @param remoteUser 远端用户

  • @param streams    发布的资源 */ @Override public void onRemoteUserPublishResource(RCRTCRemoteUser remoteUser,

                                     List<RCRTCInputStream> streams) {

    for (RCRTCInputStream inputStream : streams) {

     if (inputStream.getMediaType() == RCRTCMediaType.VIDEO) {
         if (inputStream.getTag().equals(RCRTCStream.TAG_SCREEN_SHARE)){
             //todo 屏幕共享视频流
         }
         // 选择订阅大流或是小流。默认小流
         ((RCRTCVideoInputStream) inputStream).setStreamType(RCRTCStreamType.NORMAL);
         // 创建VideoView并设置到stream
         VideoViewWrapper videoViewWrapper =
                 createVideoViewByStreamId(inputStream.getStreamId(),
                         remoteUser.getUserId());
         ((RCRTCVideoInputStream) inputStream).setVideoView(videoViewWrapper.getRCRTCVideoView());
         // 将远端视图添加至布局
         addVideoViewToList(videoViewWrapper);
         onShowVideoViewChange(mVideoViewList);
     }

    } mRoom.getLocalUser().subscribeStreams(streams

         , new IRCRTCResultCallback() {
             @Override
             public void onSuccess() {
                 Log.d(TAG, "subscribeStreams:onSuccess: ");
             }
    
             @Override
             public void onFailed(RTCErrorCode rtcErrorCode) {
                 Log.d(TAG, "subscribeStreams:onFailed: " + rtcErrorCode.getReason());
             }
         });

    } ```