本文档主要介绍如何使用屏幕分享,目前一个 TRTC 音视频房间只能有一路屏幕分享。
调用指引
开启屏幕分享
步骤1:添加 Activity
在 manifest 文件中粘贴如下 activity(若项目代码中存在则不需要添加)。
<activityandroid:name="com.tencent.rtmp.video.TXScreenCapture$TXScreenCaptureAssistantActivity"android:theme="@android:style/Theme.Translucent"/>
步骤2: 启动屏幕分享
通过设置 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)是指画面在剧烈变化时的最高输出码率,如果屏幕内容变化较少,实际编码码率会比较低。
步骤3:弹出悬浮窗防止应用被强杀(可选)
从 Android 7.0 系统开始,切入到后台运行的普通 App 进程,但凡有 CPU 活动,都很容易会被系统强杀掉。 所以当 App 在切入到后台默默进行屏幕分享时,通过弹出悬浮窗的方案,可以避免被系统强杀掉。 同时,在手机屏幕上显示悬浮窗也有利于告知用户当前正在做屏幕分享,避免用户泄露个人隐私。
public void showView(View view, int width, int height) {mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);int type = WindowManager.LayoutParams.TYPE_TOAST;//TYPE_TOAST仅适用于4.4+系统,假如要支持更低版本使用TYPE_SYSTEM_ALERT(需要在manifest中声明权限)//7.1(包含)及以上系统对TYPE_TOAST做了限制if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;} else 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);}
观看屏幕分享
观看 Mac / Windows 屏幕分享
当房间里有一个 Mac / Windows 用户启动了屏幕分享,会通过辅流进行分享。房间里的其他用户会通过 TRTCCloudListener 中的 onUserSubStreamAvailable 事件获得这个通知。
观看 Android / iOS 屏幕分享
若用户通过 Android / iOS 进行屏幕分享,会通过主流进行分享。房间里的其他用户会通过 TRTCCloudListener 中的 onUserVideoAvailable 事件获得这个通知。
常见问题
1、提示错误码-3343是什么问题?
如果使用屏幕分享过程中接收到
-3343
错误码,是因为网络连接问题导致的报错,需检查用户网络。2、Android 10以上版本使用 LiteAVSDK 录屏/屏幕共享功能时 crash 是什么问题?
由于 Android 系统隐私策略的更改,在 Android 10 及以上版本 App 若使用录屏等功能需要在前台 Service 中进行,否则录屏/屏幕共享时系统将报错或 App 被系统终止。如果您的项目 targetSdkVersion 设置大于 29,使用录屏/屏幕共享时,您可以参考如下步骤进行处理。
第一步,创建一个 Service ,并绑定一个 Notification 使其作为前台 Service。
public class MediaService extends Service {private final String NOTIFICATION_CHANNEL_ID="com.tencent.trtc.apiexample.MediaService";private final String NOTIFICATION_CHANNEL_NAME="com.tencent.trtc.apiexample.channel_name";private final String NOTIFICATION_CHANNEL_DESC="com.tencent.trtc.apiexample.channel_desc";public MediaService() {}@Overridepublic void onCreate() {super.onCreate();startNotification();}public void startNotification() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//Call Start foreground with notificationIntent notificationIntent = new Intent(this, MediaService.class);PendingIntent pendingIntent;if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);} else {pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);}NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID).setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground)).setSmallIcon(R.drawable.ic_launcher_foreground).setContentTitle("Starting Service").setContentText("Starting monitoring service").setContentIntent(pendingIntent);Notification notification = notificationBuilder.build();NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);channel.setDescription(NOTIFICATION_CHANNEL_DESC);NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);notificationManager.createNotificationChannel(channel);startForeground(1, notification); //必须使用此方法显示通知,不能使用notificationManager.notify,否则还是会报上面的错误}}@Overridepublic IBinder onBind(Intent intent) {throw new UnsupportedOperationException("Not yet implemented");}}
第二步,在 AndroidManifest.xml 中配置加入以下权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
指定 Service 的 android:foregroundServiceType="mediaProjection"。
<serviceandroid:name=".MediaService"android:enabled="true"android:foregroundServiceType="mediaProjection"android:exported="true"/>
第三步:在录屏前启动 Service。
public class TRTCApplication extends Application {@Overrideprotected void attachBaseContext(Context base) {super.attachBaseContext(base);MultiDex.install(this);startService(new Intent(this,MediaService.class));}}