TCIC Client 是一个包含 LCIC 所有功能的 Flutter 插件,你可以通过该插件快速集成 LCIC 功能,实现互动直播、互动白板、音视频连麦等核心能力。
一、支持平台
·Android:API 21+ (Android 5.0 及以上)
·iOS:12.0+
三、Flutter 环境
·Flutter SDK:^3.7.0
·Dart SDK:≥ 1.17.0
四、Android 环境
·Android SDK:API 21+
·NDK:27.0.12077973+
·Java:11+
·Kotlin:支持
五、iOS 环境
·iOS:12.0+
·Xcode:14.0+
·CocoaPods:1.12.0+
注意:说明:
注意:在线 DEMO 体验,可单击查看 TCIC Flutter Simple Demo。
七、1. 安装依赖
在你的 Flutter 项目根目录下执行以下命令安装依赖:
flutter pub add tcic_client_ui
八、2. 权限相关配置
在教学场景中,通常需要使用音视频互动、屏幕共享等功能,因此需在原生工程中配置对应权限。
九、Android 端配置
1. 权限配置
在 android/app/src/main/AndroidManifest.xml 中添加以下权限:
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera.autofocus" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
2. 屏幕录制配置
同样在 AndroidManifest.xml 中添加屏幕录制辅助 Activity 及画中画支持:
<activity android:name=".MainActivity" android:supportsPictureInPicture="true" /> <!– 画中画功能 –> <activity android:name="com.tencent.rtmp.video.TXScreenCapture$TXScreenCaptureAssistantActivity" android:theme="@android:style/Theme.Translucent"/>
3. build.gradle 配置
在 android/app/build.gradle.kts 中进行如下配置:
android { namespace = "com.tencent.tcic" compileSdk = flutter.compileSdkVersion ndkVersion = "27.0.12077973" // 指定 NDK 版本 compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { jvmTarget = JavaVersion.VERSION_11.toString() } defaultConfig { applicationId = "com.tencent.tcic" minSdk = flutter.minSdkVersion targetSdk = flutter.targetSdkVersion } // 解决重复 so 文件冲突 packagingOptions { pickFirst("lib/arm64-v8a/libliteavsdk.so") pickFirst("lib/armeabi-v7a/libliteavsdk.so") pickFirst("lib/x86/libliteavsdk.so") pickFirst("lib/x86_64/libliteavsdk.so") }}
4. 混淆配置
在 android/app/proguard-rules.pro 中添加:
# 腾讯云 SDK 混淆配置-keep class com.tencent.** { *; }-keep class com.tencent.rtc.** { *; }-keep class com.tencent.liteav.** { *; }-keep class com.tencent.trtc.** { *; }-keep class com.tencent.imsdk.** { *; }-keep class com.tencent.tls.** { *; }-dontwarn com.tencentcloudapi.cls.android.producer.**# Flutter 相关-keep class io.flutter.** { *; }-keep class io.flutter.plugins.** { *; }
十、iOS 端配置
权限配置
在 ios/Runner/Info.plist 中添加以下权限描述:
<!– 相机权限 –><key>NSCameraUsageDescription</key><string>互动课堂需要访问你的相机以进行视频通话。</string><!– 麦克风权限 –><key>NSMicrophoneUsageDescription</key><string>互动课堂需要访问你的麦克风以进行语音通话。</string><!– 网络配置 –><key>NSAppTransportSecurity</key><dict> <key>NSAllowsArbitraryLoads</key> <true/></dict><!– 后台模式 –><key>UIBackgroundModes</key><array> <string>audio</string> <string>fetch</string> <string>picture-in-picture</string> <string>processing</string></array><!– 屏幕录制扩展 App Group –><key>com.apple.security.application-groups</key><array> <string>group.com.tencent.comm.tcic.sharescreen</string></array>
十一、3. 跑通代码
配置完权限后,将通过 接入准备 中获取的 classId、userId、token 传入组件即可启动课堂。
import 'package:tcic_client_ui/tcic_client_ui.dart';import 'package:tcic_client_ui/controller/tcic_contoller.dart';import 'package:tcic_client_ui/utils/model/enum/role_enum.dart';import 'package:tcic_client_ui/utils/model/tcic_cofig_model.dart';// 1. 创建控制器final controller = TCICController();// 2. 配置参数final config = TCICConfig( userId: 'user123', // 替换为你的 userId classId: 'class456', // 替换为你的 classId role: RoleEnum.student, // 设置角色 token: 'your_token_here', // 替换为你的 token);// 3. 跳转到课堂页面Navigator.push( context, MaterialPageRoute( builder: (context) => TCICView( controller: controller, config: config, ), ),);
十二、跨应用屏幕共享 (iOS 专属)
iOS 系统上的跨应用屏幕分享,需要增加 Extension 录屏进程以配合主 App 进程进行推流。Extension 录屏进程由系统在需要录屏时创建,负责接收系统采集到的屏幕图像。
十三、步骤1:创建 App Group
使用你的账号登录 Apple Developer,按以下步骤操作(完成后需重新下载 Provisioning Profile):
1. 单击左侧的 Certificates, IDs & Profiles。
2. 在右侧界面中单击 + 号。
3. 选择 App Groups,单击 Continue。
4. 填写 Description 和 Identifier(Identifier 需传入接口中的 AppGroup 参数),单击 Continue。
5. 回到 Identifier 页面,选择 App IDs,单击你的 App ID(主 App 与 Extension 需进行相同配置)。
6. 选中 App Groups 并单击 Edit。
7. 选择刚创建的 App Group,保存配置。
8. 重新下载 Provisioning Profile 并配置到 Xcode 中。
十四、步骤2:创建 Broadcast Upload Extension
1. 在 Xcode 菜单依次单击 File > New > Target…,选择 Broadcast Upload Extension。
2. 填写相关信息(无需勾选 Include UI Extension),单击 Finish。
3. 获取定制的 TXLiteAVSDK_ReplayKitExt.xcframework,将其拖入工程并勾选刚创建的 Target。
4. 选中新 Target,单击 + Capability,双击 App Groups。
5. 在生成的 Target.entitlements 文件中填写上述创建的 App Group Identifier。
6. 对主 App 的 Target 执行相同的 App Group 配置。
7. 在新 Target 中,将自动生成的 SampleHandler.swift 文件内容替换为以下代码(请将 APPGROUP 替换为你自己的 Identifier):
import ReplayKitimport TXLiteAVSDK_ReplayKitExt// 替换为你自己的 App Group Identifierlet APPGROUP = "group.com.tencent.comm.tcic.sharescreen"class SampleHandler: RPBroadcastSampleHandler, TXReplayKitExtDelegate { let recordScreenKey = Notification.Name.init("TRTCRecordScreenKey") override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) { TXReplayKitExt.sharedInstance().setup(withAppGroup: APPGROUP, delegate: self) } override func broadcastPaused() { // 用户已请求暂停直播 } override func broadcastResumed() { // 用户已请求恢复直播 } override func broadcastFinished() { TXReplayKitExt.sharedInstance().finishBroadcast() } func broadcastFinished(_ broadcast: TXReplayKitExt, reason: TXReplayKitExtReason) { var tip = "" switch reason { case TXReplayKitExtReason.requestedByMain: tip = "屏幕共享已结束" case TXReplayKitExtReason.disconnected: tip = "应用断开" case TXReplayKitExtReason.versionMismatch: tip = "集成错误(SDK 版本号不相符合)" default: break } let error = NSError(domain: NSStringFromClass(self.classForCoder), code: 0, userInfo: [NSLocalizedFailureReasonErrorKey:tip]) finishBroadcastWithError(error) } override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) { switch sampleBufferType { case RPSampleBufferType.video: TXReplayKitExt.sharedInstance().sendVideoSampleBuffer(sampleBuffer) case RPSampleBufferType.audioApp: // 处理应用程序音频 break case RPSampleBufferType.audioMic: // 处理麦克风音频 break @unknown default: fatalError("未知类型") } }}
十六、TCICView 组件参数
| 参数名 | 类型 | 是否必填 | 描述 |
| controller | TCICController | 是 | 控制器实例。 |
| config | TCICConfig | 是 | 核心配置信息。 |
| callback | TCICCallback | 否 | 课堂事件回调函数。 |
十七、TCICConfig 核心配置
| 字段名 | 类型 | 是否必填 | 描述 |
| userId | String | 是 | 用户 ID。 |
| classId | String | 是 | 课堂 ID。 |
| token | String | 是 | 认证令牌。 |
| role | RoleEnum | 否 | 用户角色(学生/老师等)。 |
| langConfig | TCICLangConfig | 否 | 语言配置。 |
| nameConfig | TCICNameConfig | 否 | 角色名称自定义配置。 |
| fontConfig | TCICFontConfig | 否 | 字体配置。 |
| liveplayerConfig | TCICLivePlayerConfig | 否 | 直播播放器配置。 |
| isLatestBackend | bool | 否 | 是否使用最新后端。 |
| isTestBackend | bool | 否 | 是否使用测试后端。 |
| componentConfig | List<TCICComponentConfig> | 否 | UI 组件自定义配置列表。 |
十八、UI 组件配置 (TCICComponentConfig)
TCICComponentConfig 是一个抽象类,用于配置课堂界面中的各个 UI 组件。
使用示例:
final config = TCICConfig( userId: 'user123', classId: 'class456', role: RoleEnum.student, token: 'your_token_here', componentConfig: [ HeaderComponentConfig( isShow: true, enableHandsUp: true, iconConfig: HeaderIconConfig( micIcon: 'custom_mic_icon.png', cameraIcon: 'custom_camera_icon.png', ), ), MemebersComponentConfig(enableStageUpDownAction: true), MessageComponentConfig(), SetttingComponentConfig(), VideoComponentConfig(), WhiteboardComponentConfig(), ],);
十九、HeaderComponentConfig (头部组件)
| 字段名 | 类型 | 描述 |
| isShow | bool | 是否显示头部组件(默认 true)。 |
| enableHandsUp | bool | 是否显示举手(默认 true)。 |
| enableScreenShare | bool | 是否显示屏幕共享(默认 true)。 |
| enableMessage | bool | 是否显示消息(默认 true)。 |
| enableCourseware | bool | 是否显示课件(默认 true)。 |
| enableSetting | bool | 是否显示设置(默认 true)。 |
| enableMemberList | bool | 是否显示花名册(默认 true)。 |
| showClassStatus | bool | 是否显示课程状态(默认 true)。 |
| showClassTime | bool | 是否显示课程时间(默认 true)。 |
| showOnlineMemberCount | bool | 是否显示在线成员数量(默认 true)。 |
| showQuitButton | bool | 是否显示退出按钮(默认 true)。 |
| iconConfig | HeaderIconConfig | 自定义头部组件图标配置。 |
| headerBuilder | Widget Function() | 自定义整个头部组件。 |
20、SettingComponentConfig (设置组件)
| 字段名 | 类型 | 描述 |
| enableAudioSetting | bool | 是否启用音频设置(默认 true)。 |
| enableVideoSetting | bool | 是否启用视频设置(默认 true)。 |
| enableGeneralSetting | bool | 是否启用通用设置(默认 true)。 |
| showMemberJoinExitInfo | bool | 是否显示成员加入/退出提示(默认 true)。 |
21、WhiteboardComponentConfig (白板组件)
| 字段名 | 类型 | 描述 |
| enableCreateBoard | bool | 是否启用创建白板(默认 true)。 |
| enableBoardList | bool | 是否启用白板列表(默认 true)。 |
| enableSwitchPage | bool | 是否允许 PPT 课件翻页(默认 true)。 |
注意:说明:
注意:其他组件如 MessageComponentConfig、VideoComponentConfig 均支持通过 Builder 函数进行高度自定义。
22、回调函数 (TCICCallback)
通过传入 TCICCallback,你可以监听课堂内的各类核心事件:
| 回调方法 | 触发时机 | 备注 |
| onJoinedClassSuccess | 加入课堂成功时 | – |
| onJoinedClassFailed | 加入课堂失败时 | – |
| beforeExitedClass | 退出课堂前 | 返回 false 可拦截/取消退出操作。 |
| afterExitedClass | 退出课堂后 | – |
| onKickedOffClass | 被踢出课堂时 | – |
| onMemberJoinedClass | 其他成员加入课堂时 | – |
| onMemberLeaveClass | 其他成员离开课堂时 | – |
| onReceivedMessage | 收到聊天消息时 | – |
| beforeRenderMessage | 渲染消息前 | 返回 false 可拦截该消息的 UI 渲染。 |
24、1. 权限问题
·Android 权限被拒绝:
·检查 AndroidManifest.xml 中是否已添加相应权限。
·确保在代码中动态申请了运行时权限。
·iOS 权限被拒绝:
·检查 Info.plist 中是否已添加权限描述文本。
·确保权限描述文本清晰明了,否则可能被 App Store 拒绝。
25、2. 音视频问题
·无法听到声音:
检查设备音量设置及麦克风权限是否已授权。
·无法看到视频:
检查相机权限是否已授权,确认设备相机硬件功能正常。
26、3. 网络与连接问题
·连接失败:
·验证 SDKAppId 和 token 是否正确且未过期。
·检查设备网络连接及防火墙设置。
·音视频卡顿:
检查网络带宽是否充足,考虑在设置中降低音视频质量。
27、4. 白板问题
·白板无法加载:
检查网络连接状态,验证白板配置参数是否合法。
·白板操作无响应:
确认当前用户的角色权限(如观众角色默认无白板操作权限)。