首页 > 其他分享 >如何实现视频中两台电脑的实时屏幕共享

如何实现视频中两台电脑的实时屏幕共享

时间:2023-05-06 17:00:43浏览次数:37  
标签:创建 MediaProjection ZEGO 屏幕 共享 两台 SDK

1 屏幕共享功能介绍

屏幕共享是指在视频通话或互动直播过程中将屏幕内容以视频的方式分享给其他的观众,以增强互动体验,提高沟通效率。屏幕共享解决方案提升了用户实时视频通话的沟通效率。

屏幕共享在如下场景中应用广泛:

  • 视频会议场景中,屏幕共享可以将讲话者本地的文件、数据、网页、PPT 等画面分享给其他与会人;
  • 在线课堂场景中,屏幕共享可以将老师的课件、笔记、讲课内容等画面展示给学生观看。

如何实现视频中两台电脑的实时屏幕共享_视频共享

2 屏幕共享示例源码下载

请参考 下载示例源码 获取源码。

相关源码请查看 “/ZegoExpressExample/Others/src/main/java/com/example/others/screensharing” 目录下的文件。

others
...
├── screensharing
│   ├── CaptureScreenService.java //此文件实现了系统 Service 接口
│   ├── ScreenSharingActivity.java // 此文件主要完成了通过 ZegoExpress SDK 将屏幕画面数据流推送到远端的工作
│   ├── VideoCaptureScreen.java //此文件用于通过安卓系统接口创建 VirtualDisplay 实例,获取屏幕数据,并发送给 ZEGO Express SDK
│   └── ZegoVideoCaptureCallback.java //此文件实现了 ZegoExpress 的 IZegoCustomVideoCaptureHandler
...

3 屏幕共享功能实现准备工作-集成屏幕共享SDK

在实现屏幕共享功能之前,请确保:

4 屏幕共享实现流程-即构屏幕共享SDK

我们需要结合 Android 系统 API 和 ZEGO Express SDK 的自定义视频采集来进行屏幕分享。

下图展示了 Android 平台实现屏幕共享的数据流转:

如何实现视频中两台电脑的实时屏幕共享_视频共享_02

4.1 获取用户录制屏幕授权

在录制屏幕前需要获取用户的授权,不同版本下需要获取的权限如下:

  • Android 4.4 及之前版本必须获取到 root 权限后才能实现屏幕录制,由于目前大部分设备的系统版本都高于 4.4,该场景此处不做赘述。
  • Android 5.0 及以上版本,可以使用系统提供的 MediaProjection 和 MediaProjectionManager 进行屏幕录制。该版本下可以不获取 root 权限,但会弹窗提示用户是否允许应用录制屏幕,需要用户授权。
  • Android 10.0 及以上版本,屏幕录制使用系统 API 时需要用到前台服务,详情请参考 官方文档
public static MediaProjectionManager mMediaProjectionManager;
if (Build.VERSION.SDK_INT < 21) {
    Toast.makeText(ZGVideoCaptureOriginUI.this, getString(R.string.record_request), Toast.LENGTH_SHORT).show();
    finish();
} else {
    // 5.0及以上版本
    // 请求录屏权限,等待用户授权
   mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
   startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
    }

4.2 屏幕共享SDK-创建 MediaProjection 实例

  1. 在 AndroidManifest.xml 中添加相关配置。

为实现 Android 10.0 及以上版本应用的屏幕录制,需要在代码中开启前台服务,并在 AndroidManifest.xml 中注册 Service,添加 foregroundServiceType 属性。

<application>
 <activity android:name="im.zego.videocapture.ui.ZGVideoCaptureDemoUI" />
 <activity android:name="im.zego.videocapture.ui.ZGVideoCaptureOriginUI"></activity>
 <service android:name=".service.CaptureScreenService"
     android:enabled="true"
     android:foregroundServiceType="mediaProjection"/>
</application>
  1. 用户授权后创建 MediaProjection 实例。
  • 对于 Android 10.0 以下版,直接在授权成功后获取 MediaProjection
  • 对于 Android 10.0 及以上版本,MediaProjection 实例的创建需要在前台服务的 onStartCommand 方法中执行。
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       super.onActivityResult(requestCode, resultCode, data);
       if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
           if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.Q){
               //Target版本高于等于10.0需要使用前台服务,并在前台服务的onStartCommand方法中创建MediaProjection
               service=new Intent(ZGVideoCaptureOriginUI.this, CaptureScreenService.class);
               service.putExtra("code",resultCode);
               service.putExtra("data",data);
               startForegroundService(service);
           }else {
               //Target版本低于10.0直接获取MediaProjection
               mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);
           }
       }
   }

创建一个类,实现 Service 接口,在 onStartCommand 中创建 MediaProjection 实例。

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class CaptureScreenService extends Service {
    ...

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ···
        //在这里获取MediaProjection
        ZGVideoCaptureOriginUI.mMediaProjection = ZGVideoCaptureOriginUI.mMediaProjectionManager.getMediaProjection(mResultCode, Objects.requireNonNull(mResultData));
        return super.onStartCommand(intent, flags, startId);
    }
   ··· 
}

4.3 屏幕共享SDK-开启 ZegoExpress SDK 的自定义视频采集功能

调用 ZegoExpress SDK 的 enableCustomVideoCapture 开启自定义采集功能,详情请参考 自定义视频采集

//VideoCaptureScreen继承IZegoCustomVideoCaptureHandler,用于监听自定义采集onStart和onStop回调
VideoCaptureScreen videoCapture = new VideoCaptureScreen(ZGVideoCaptureOriginUI.mMediaProjection, DEFAULT_VIDEO_WIDTH, DEFAULT_VIDEO_HEIGHT, mSDKEngine);
//监听自定义采集开始停止回调
mSDKEngine.setCustomVideoCaptureHandler(videoCapture);  
ZegoCustomVideoCaptureConfig videoCaptureConfig=new ZegoCustomVideoCaptureConfig();
//使用SurfaceTexture类型进行自定义采集
videoCaptureConfig.bufferType=ZegoVideoBufferType.SURFACE_TEXTURE;
//开始自定义采集
mSDKEngine.enableCustomVideoCapture(true, videoCaptureConfig, ZegoPublishChannel.MAIN);

4.4 屏幕共享SDK-登录房间并开始推流

调用 loginRoom 接口,传入房间 ID 参数 “roomID” 和用户参数 “user”,登录房间。

调用 startPublishingStream 接口,传入流 ID 参数 “streamID”,向远端用户发送本端的音视频流。

/** 创建用户 */
ZegoUser user = new ZegoUser("user1");

/** 开始登录房间 */
mSDKEngine.loginRoom("room1", user);  
/** 开始推流 */
mSDKEngine.startPublishingStream("stream1");

4.5 创建 VirtualDisplay 并给 ZEGO Express SDK 发送屏幕数据-

1、创建 ZegoVideoCaptureCallback 类继承 IZegoCustomVideoCaptureHandler。

2、创建 VideoCaptureScreen 类继承 ZegoVideoCaptureCallback。

当收到 onStart 回调后,开发者可以通过 MediaProjection 创建 VirtualDisplay 实例,用于获取屏幕数据,并发送给 ZEGO Express SDK。

3、通过 createVirtualDisplay 系统 API 将虚拟显示器的内容渲染到 Surface。

//ZegoVideoCaptureCallback继承于IZegoCustomVideoCaptureHandler
class VideoCaptureScreen extends ZegoVideoCaptureCallback {
    @Override
    //当收到onStart回调后,就可以通过MediaProjection创建VirtualDisplay,并给ZEGO SDK塞屏幕数据
    public void onStart(ZegoPublishChannel channel) {
        if (mZegoEngine != null && !mIsCapturing && mMediaProjection != null) {
            mIsCapturing = true;
            //通过ZEGO API getCustomVideoCaptureSurfaceTexture获取SurfaceTexture,该接口默认使用主路通道进行推流
            SurfaceTexture texture = mZegoEngine.getCustomVideoCaptureSurfaceTexture();
            texture.setDefaultBufferSize(mCaptureWidth, mCaptureHeight);
            //通过获取的SurfaceTexture创建Surface
            mSurface = new Surface(texture);
            //通过mSurface,完成将录屏数据塞给ZEGO SDK
            mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCapture",
                    mCaptureWidth, mCaptureHeight, 1,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC, mSurface, null, mHandler);
        }
    }
}

至此,我们已完成采集屏幕数据并通过 ZegoExpress SDK 分享到远端的操作。

5 观看远端屏幕共享-远程控制

完成以上步骤之后,其他用户可以使用 startPlayingStream 接口拉取屏幕共享流,详细步骤可以参考 快速开始

// 同样的,拉流播放的用户首先需要初始化 SDK 并登陆同一个房间 
...
...

// 拉流播放,需传入发起屏幕共享的用户推流时所用的 streamID
mSDKEngine.startPlayingStream(streamID, new ZegoCanvas(playView));

综上所述,如果你的业务需要一款全面强大的屏幕共享服务,可以试试即构音视频+屏幕共享服务。点击跳转即构实时音视频云,了解更多(https://doc-zh.zego.im/article/9217?source=51cto&article20)


标签:创建,MediaProjection,ZEGO,屏幕,共享,两台,SDK
From: https://blog.51cto.com/u_15870111/6243436

相关文章

  • 系统集成09-Samba文件共享服务器管理
    系统集成09-Samba文件共享服务器管理1Samba文件共享服务器搭建Samba文件共享服务介绍Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件,SMB(ServerMessageBlock)服务器消息块。Samba最大的功能是可以用于Linux与windows系统直接的文件共享和打印共享,既可以用于Window......
  • ICT实战系统集成-LAB9-Samba文件共享服务器管理
    ICT实战系统集成-LAB9-Samba文件共享服务器管理实验步骤1安装samba服务端安装samba、samba-common、samba-clientyuminstallsambasamba-commonsamba-client启动samba:ststemctlstartsmb.service查看samba状态2添加系统组share,添加系统账号xiaoming、hanmeimei......
  • android 获取屏幕高度和宽度 的方法
    Android 获取屏幕高度和宽度的方法  我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸   下面的代码即可获取屏幕的尺寸。    在一个Activity的onCreate方法中,写入如下代码:[java] vi......
  • Android 屏幕适配
    一、概念1.1屏幕像素密度PPI、DPIPPI(PixelsPerInch)屏幕每英寸容纳多少个像素点,DPI(DotsPerInch)这个“点”是根据屏幕物理概念产生的一个软件概念,在不同行业有不同理解,印刷行业每英寸打印多少个墨点,鼠标移动一英寸光标移动多少像素点,在Android中被用来表示屏幕每英寸显示多......
  • linux 通过命令行(包括ssh)关闭屏幕
    题外话:不得不说现在百度的搜索真的烂,除了广告,有用的信息一点也搜不到,bing倒是广告少,照样也搜不到有用信息,谷歌虽然作恶不少,某些技术还是可以的,但是国内不通过特殊方法又使用不了,解决方法:1.找谷歌的镜像站,但是不好找,就算找到了,可能过几天就失效了;2.找一些小众的搜索......
  • Redis--分布式中实现Session共享(一)
    上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享"。这篇文章将会介绍如何使用Redis,下一篇在此基础上实现Session。这里特别说明一下,其实没有必要使用Redis来解决Session共享。Asp.net提供了StateServer模......
  • pytes中fixture的scope: 决定可以在什么范围内共享fixture
    1fixture的scope在@pytest.fixture(scope='xxx')中,scope的可选值有5个,以下是官网的描述2function级别的scope添加如下代码到pytest.ini,便于输出日志新建conftest.py文件,把fixture函数写入其中,便于后面fixture可以在多个py文件中的test函数中引用conftest.pypytest的fix......
  • C# 获取本地共享目录和网络共享目录
    1.在工程添加对应的cs文件usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.IO;usingSystem.Linq;usingSystem.Net;usingSystem.Runtime.InteropServices;usingSystem.Text;usingSystem.Web;......
  • Win10更新KB5007186后共享打印机无法使用
         卸载大概10几分钟,卸载完之后会提示重启电脑,耐心等待重启,重启完成即可正常打印。为防止电脑的继续更新导致又出现这个问题,目前只能通过延迟win10的自动更新   ......
  • ADB更改Android设备屏幕显示方向
    adbshellsettingsputsystemaccelerometer_rotation0 关闭自动旋转屏幕 adbshellsettingsputsystemuser_rotation3 调整显示方向 可选0123 user_rotationValues:0#Protrait1#Landscape2#ProtraitReversed3......