TRTC Android端开发接入学习之实现实时屏幕分享(四)
前言
在完成上一篇文章中我们知道了如何集成到项目中,本节我们来实现其中比较简单的一个功能,熟悉SDK的用法。屏幕分享代码在DEMO->trtcmeetingdemo module中
腾讯云 TRTC 在 Android 系统上支持屏幕分享,即将当前系统的屏幕内容通过 TRTC SDK 分享给房间里的其他用户。关于此功能,有两点需要注意:
TRTC Android 版本的屏幕分享并不像桌面端版本一样支持“辅路分享”,因此在启动屏幕分享时,摄像头的采集需要先被停止,否则会相互冲突。
当一个 Android 系统上的后台 App 在持续使用 CPU 时,很容易会被系统强行杀掉,而且屏幕分享本身又必然会消耗 CPU。要解决这个看似矛盾的冲突,我们需要在 App 启动屏幕分享的同时,在 Android 系统上弹出悬浮窗。由于 Android 不会强杀包含前台 UI 的 App 进程,因此该种方案可以让您的 App 可以持续进行屏幕分享而不被系统自动回收。如下图所示:
支持的平台
iOS |
Android |
Mac OS |
Windows |
Electron |
微信小程序 |
Chrome 浏览器 |
---|---|---|---|---|---|---|
✓ |
✓ |
✓ |
✓ |
✓ |
× |
✓ |
启动屏幕分享
要开启 Android 端的屏幕分享,只需调用 TRTCCloud 中的 startScreenCapture() 接口即可。
/**
* 启动屏幕分享
*
* Android 手机的屏幕分享的推荐配置参数:
* - 分辨率(videoResolution):1280 x 720
* - 帧率(videoFps):10 FPS
* - 码率(videoBitrate):1200 kbps
* - 分辨率自适应(enableAdjustRes):false
*
* @param encParams 设置屏幕分享时的编码参数,推荐采用上述推荐配置,如果您指定 encParams 为 null,则使用您调用 startScreenCapture 之前的编码参数设置。
* @param screenShareParams 设置屏幕分享的特殊配置,其中推荐设置 floatingView,windowManager也可以达到同样的 效果
*/
public abstract void startScreenCapture(TRTCCloudDef.TRTCVideoEncParam encParams, TRTCCloudDef.TRTCScreenShareParams screenShareParams);
但如果要达到稳定和清晰的分享效果,您需要关注如下两个问题:
设定视频编码参数
通过设置 startScreenCapture() 中的首个参数 encParams ,您可以指定屏幕分享的编码质量。如果您指定 encParams 为 null,SDK 会自动使用之前设定的编码参数,我们推荐的参数设定如下:
参数项 |
参数名称 |
常规推荐值 |
文字教学场景 |
---|---|---|---|
分辨率 |
videoResolution |
1280 × 720 |
1920 × 1080 |
帧率 |
videoFps |
10 FPS |
8 FPS |
最高码率 |
videoBitrate |
1600 kbps |
2000 kbps |
分辨率自适应 |
enableAdjustRes |
NO |
NO |
由于屏幕分享的内容一般不会剧烈变动,所以设置较高的 FPS 并不经济,推荐10 FPS即可。
如果您要分享的屏幕内容包含大量文字,可以适当提高分辨率和码率设置。
最高码率(videoBitrate)是指画面在剧烈变化时的最高输出码率,如果屏幕内容变化较少,实际编码码率会比较低。
弹出悬浮窗以避免被强杀
从 Android 7.0 系统开始,切入到后台运行的普通 App 进程,但凡有 CPU 活动,都很容易会被系统强杀掉。 所以当 App 在切入到后台默默进行屏幕分享时,通过弹出悬浮窗的方案,可以避免被系统强杀掉。 同时,在手机屏幕上显示悬浮窗也有利于告知用户当前正在做屏幕分享,避免用户泄漏个人隐私。
方案1:弹出普通的悬浮窗 要弹出类似“腾讯会议”的迷你悬浮窗,您只需要参考示例代码 FloatingView.java 中的实现即可:
public void showView(View view, int width, int height) {
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
//TYPE_TOAST仅适用于4.4+系统,假如要支持更低版本使用TYPE_SYSTEM_ALERT(需要在manifest中声明权限)
//7.1(包含)及以上系统对TYPE_TOAST做了限制
int type = WindowManager.LayoutParams.TYPE_TOAST;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
type = WindowManager.LayoutParams.TYPE_PHONE;
}
mLayoutParams = new WindowManager.LayoutParams(type);
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
mLayoutParams.flags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
mLayoutParams.width = width;
mLayoutParams.height = height;
mLayoutParams.format = PixelFormat.TRANSLUCENT;
mWindowManager.addView(view, mLayoutParams);
}
方案2:弹出摄像头预览窗 由于 TRTC Android 版本的屏幕分享并不像桌面端版本一样支持“辅路分享”,因此在启动屏幕分享时,摄像头这一路的视频数据无法上行,否则会相互冲突。 那要如何才能做到同时分享屏幕和摄像头画面呢? 答案很简单:只需要在屏幕上悬浮一个摄像头画面即可,这样一来,TRTC 在采集屏幕画面的同时也会将摄像头画面一并分享出去。
观看屏幕分享
当房间里有一个用户启动了屏幕分享,房间里的其他用户会通过 TRTCCloudListener 中的 onUserSubStreamAvailable 事件 获得这个通知。 希望观看屏幕分享的用户可以通过 startRemoteSubStreamView 接口来启动渲染远端用户辅流画面。
//第一步回调收到消息
@Override
public void onUserSubStreamAvailable(String userId, boolean available) {
if (mDelegate != null) {
mDelegate.onTRTCSubStreamAvailable(userId, available);
}
}
//第二步 TrtcMeeting中接口收到消息
TrtcMeetingImpl.onTrtcSubStreamAvailable
//第三步 通知用户进入
TRTCMeetingDelegate.onUserVideoAvailable
//第四步 AdapterNotify
mMemberListAdapter.notifyItemChange
//第五步 统一处理
public void startRemoteView(final String userId, final TXCloudVideoView view, final TRTCMeetingCallback.ActionCallback callback) {
runOnMainThread(new Runnable() {
@Override
public void run() {
//判断是否辅流播放
String realUserId = mSubStreamMap.get(userId);
if (realUserId != null) {
//播放辅流
TXTRTCMeeting.getInstance().startPlaySubStream(realUserId, view, new TXCallback() {
@Override
public void onCallback(int code, String msg) {
if (callback != null) {
callback.onCallback(code, msg);
}
}
});
return;
}
TXTRTCMeeting.getInstance().startPlay(userId, view, new TXCallback() {
@Override
public void onCallback(int code, String msg) {
if (callback != null) {
callback.onCallback(code, msg);
}
}
});
}
});
}
- SQL SERVER修改函数名引起的问题
- SQL Server安全(1/11):SQL Server安全概述
- SQL Server安全(2/11):身份验证(Authentication)
- SQL Server安全(3/11):主体和安全对象(Principals and Securables)
- 在SQL Server里如何进行页级别的恢复
- 你可能不知道的字符比较中的“秘密”
- c++实现简单计算器
- re模块(正则表达式)
- Python学习——collections系列
- 为stackGan一个工程创建一个虚拟环境,python 2.7 tensorflow0.12-tensorflow 1.01
- linux 普通操作,查看资源使用情况
- Python 函数使用记录,join函数和os.path.join用法
- 01.SQLServer性能优化之----强大的文件组----分盘存储
- stackGan实验
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Yii框架参数配置文件params用法实例分析
- 使用Kotlin实现文字渐变TextView的代码
- thinkPHP5框架路由常用知识点汇总
- PHP实现一个限制实例化次数的类示例
- AndroidStudio中重载方法@Override的使用详解
- mysqli扩展无法在PHP7下升级问题的解决
- PHP通过文件保存和更新信息的方法分析
- PHP中将一个字符串部分字符用星号*替代隐藏的实现代码
- PHP创建XML的方法示例【基于DOMDocument类及SimpleXMLElement类】
- android之json数据过长打印不全问题的解决
- PHP实现时间日期友好显示实现代码
- AndroidStudio插件GsonFormat之Json快速转换JavaBean教程
- android studio错误: 常量字符串过长的解决方式
- Android Shader着色器/渲染器的用法解析
- PHP实现的文件浏览器功能简单示例