Flutter视频会议插件custom_jitsi_meet_new的使用
简介
Jitsi Meet 插件为 Flutter 提供了支持,可以在 Android、iOS 和 Web 平台上进行视频会议。Jitsi Meet 是一个开源的(Apache 许可证)WebRTC JavaScript 应用程序,它使用 Jitsi Videobridge 来提供高质量、安全且可扩展的视频会议。
更多信息可以查看 Jitsi Meet 官方仓库。
目录
配置
iOS
Podfile
确保在您的 Podfile 中添加以下内容,声明平台为 11.0 或更高版本,并禁用 BITCODE:
platform :ios, '11.0'
...
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
Info.plist
在 Info.plist 中添加 NSCameraUsageDescription
和 NSMicrophoneUsageDescription
:
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) MyApp needs access to your camera for meetings.</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) MyApp needs access to your microphone for meetings.</string>
Android
Gradle
将构建工具的 Gradle 版本设置为至少 3.6.3:
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3' <!-- 升级此版本 -->
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
设置 Gradle Wrapper 的版本为至少 5.6.4:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip <!-- 升级此版本 -->
AndroidManifest.xml
解决 Jitsi Meet SDK 的 AndroidManifest.xml 与项目冲突问题,编辑 android/app/src/main/AndroidManifest.xml
,添加 tools
命名空间并设置 tools:replace="android:label"
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="yourpackage.com"
xmlns:tools="http://schemas.android.com/tools"> <!-- 添加此行 -->
<application
tools:replace="android:label"
android:name="your.application.name"
android:label="My Application"
android:icon="@mipmap/ic_launcher">
...
</application>
...
</manifest>
最低SDK版本 23
在 android/app/build.gradle
中将最低 SDK 版本更新为 23:
defaultConfig {
applicationId "com.gunschu.jitsi_meet_example"
minSdkVersion 23 // 必须为 Jitsi 设置
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
ProGuard
启用 ProGuard 后,如果没有 proguard-rules.pro
文件,发布 APK 将缺少 Flutter Wrapper 和 React Native 代码。在 android/app/build.gradle
中添加 ProGuard 支持:
buildTypes {
release {
// TODO: 添加自己的签名配置以支持发布构建
// 当前使用调试密钥,以便 `flutter run --release` 可用
signingConfig signingConfigs.debug
// 添加以下三行以启用 ProGuard
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
然后在同一目录下创建一个名为 proguard-rules.pro
的文件,并参考示例应用中的 proguard-rules.pro
文件内容。
注意:
如果未创建 proguard-rules.pro
文件,尝试加入会议或打开会议屏幕时应用可能会崩溃。您会在 Logcat 中看到以下错误之一:
## 应用崩溃 ##
java.lang.RuntimeException: Parcel android.os.Parcel@8530c57: Unmarshalling unknown type code 7536745 at offset 104
at android.os.Parcel.readValue(Parcel.java:2747)
at android.os.Parcel.readSparseArrayInternal(Parcel.java:3118)
at android.os.Parcel.readSparseArray(Parcel.java:2351)
.....
## 会议无法打开,返回上一页 ##
W/unknown:ViewManagerPropertyUpdater: Could not find generated setter for class com.BV.LinearGradient.LinearGradientManager
W/unknown:ViewManagerPropertyUpdater: Could not find generated setter for class com.facebook.react.uimanager.g
W/unknown:ViewManagerPropertyUpdater: Could not find generated setter for class com.facebook.react.views.art.ARTGroupViewManager
W/unknown:ViewManagerPropertyUpdater: Could not find generated setter for class com.facebook.react.views.art.a
.....
Web
要在 Web 上实现,请在 web/index.html
中包含 Jitsi 的 JavaScript 库:
<script src="https://meet.jit.si/external_api.js" type="application/javascript"></script>
示例代码:
<body>
<!-- 此脚本安装 service_worker.js 以提供 PWA 功能 -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/flutter_service_worker.js');
});
}
</script>
<script src="https://meet.jit.si/external_api.js" type="application/javascript"></script>
<script src="main.dart.js" type="application/javascript"></script>
</body>
加入会议
通过以下代码加入会议:
_joinMeeting() async {
try {
FeatureFlag featureFlag = FeatureFlag();
featureFlag.welcomePageEnabled = false;
featureFlag.resolution = FeatureFlagVideoResolution.MD_RESOLUTION; // 限制视频分辨率为 360p
var options = JitsiMeetingOptions()
..room = "myroom" // 必填,空格会被删除
..serverURL = "https://someHost.com"
..subject = "Meeting with Gunschu"
..userDisplayName = "My Name"
..userEmail = "myemail@email.com"
..userAvatarURL = "https://someimageurl.com/image.jpg" // 或者 .png
..audioOnly = true
..audioMuted = true
..videoMuted = true
..featureFlag = featureFlag;
await JitsiMeet.joinMeeting(options);
} catch (error) {
debugPrint("error: $error");
}
}
JitsiMeetingOptions
以下是 JitsiMeetingOptions
的字段说明:
字段 | 是否必填 | 默认值 | 描述 |
---|---|---|---|
room | 是 | N/A | 唯一的房间名称,会附加到 serverURL。有效字符:字母数字、连字符和下划线。 |
subject | 否 | $room | 会议名称显示在会议顶部。如果为空,默认为房间名称,连字符和下划线替换为空格并首字母大写。 |
userDisplayName | 否 | Fellow Jitster | 用户显示名称。 |
userEmail | 否 | none | 用户电子邮件地址。 |
audioOnly | 否 | false | 是否仅音频会议。可以随时在会议中启用视频。 |
audioMuted | 否 | false | 是否开始会议时静音。可以在会议中解除静音。 |
videoMuted | 否 | false | 是否开始会议时关闭视频。可以在会议中启用视频。 |
serverURL | 否 | meet.jitsi.si | 指定自定义服务器。必须是一个有效的绝对 URL,格式为 <scheme>://<host>[/<path>] 。默认为 Jitsi 的服务器。 |
userAvatarURL | N/A | none | 用户头像 URL。 |
token | N/A | none | JWT 令牌用于身份验证。 |
featureFlag | 否 | 见下文 | FeatureFlag 类的对象,用于启用/禁用功能并设置 Jitsi Meet SDK 的视频分辨率。 |
FeatureFlag
FeatureFlag 允许您限制视频分辨率并启用/禁用 Jitsi Meet SDK 的某些功能。如果未提供任何标志,则使用默认值。
标志 | Android 默认值 | iOS 默认值 | 描述 |
---|---|---|---|
addPeopleEnabled | true | true | 启用蓝色按钮“Add People”,当您单独通话时显示。需启用 inviteEnabled。 |
calendarEnabled | true | auto | 启用日历集成。 |
callIntegrationEnabled | true | true | 启用通话集成(iOS 上的 CallKit,Android 上的 ConnectionService)。 |
closeCaptionsEnabled | true | true | 启用菜单中的字幕选项。 |
… | … | … | … |
JitsiMeetingResponse
以下是 JitsiMeetingResponse
的字段说明:
字段 | 类型 | 描述 |
---|---|---|
isSuccess | bool | 成功指示符。 |
message | String | 成功消息或错误信息。 |
error | dynamic | 可选,仅在 isSuccess 为 false 时存在。错误对象。 |
监听会议事件
每场会议的事件
通过在 joinMeeting
中传递 JitsiMeetingListener
来监听每场会议的事件。监听器会在触发 onConferenceTerminated
事件时自动移除。
await JitsiMeet.joinMeeting(options,
listener: JitsiMeetingListener(onConferenceWillJoin: ({message}) {
debugPrint("${options.room} will join with message: $message");
}, onConferenceJoined: ({message}) {
debugPrint("${options.room} joined with message: $message");
}, onConferenceTerminated: ({message}) {
debugPrint("${options.room} terminated with message: $message");
}, onPictureInPictureWillEnter: ({message}) {
debugPrint("${options.room} entered PIP mode with message: $message");
}, onPictureInPictureTerminated: ({message}) {
debugPrint("${options.room} exited PIP mode with message: $message");
}));
全局会议事件
通过添加 JitsiMeetListener
来监听全局会议事件:
@override
void initState() {
super.initState();
JitsiMeet.addListener(JitsiMeetingListener(
onConferenceWillJoin: _onConferenceWillJoin,
onConferenceJoined: _onConferenceJoined,
onConferenceTerminated: _onConferenceTerminated,
onPictureInPictureWillEnter: _onPictureInPictureWillEnter,
onPictureInPictureTerminated: _onPictureInPictureTerminated,
onError: _onError));
}
@override
void dispose() {
super.dispose();
JitsiMeet.removeAllListeners();
}
_onConferenceWillJoin({message}) {
debugPrint("_onConferenceWillJoin broadcasted");
}
_onConferenceJoined({message}) {
debugPrint("_onConferenceJoined broadcasted");
}
_onConferenceTerminated({message}) {
debugPrint("_onConferenceTerminated broadcasted");
}
_onPictureInPictureWillEnter({message}) {
debugPrint("_onPictureInPictureWillEnter broadcasted with message: $message");
}
_onPictureInPictureTerminated({message}) {
debugPrint("_onPictureInPictureTerminated broadcasted with message: $message");
}
_onError(error) {
debugPrint("_onError broadcasted");
}
程序化关闭会议
通过以下代码程序化关闭会议:
JitsiMeet.closeMeeting();
更多关于Flutter视频会议插件custom_jitsi_meet_new的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
custom_jitsi_meet_new
是一个用于在 Flutter 应用中集成 Jitsi Meet 视频会议功能的插件。它允许你在应用中嵌入视频会议功能,并且可以自定义一些 UI 和行为。
1. 安装插件
首先,你需要在 pubspec.yaml
文件中添加 custom_jitsi_meet_new
插件的依赖:
dependencies:
flutter:
sdk: flutter
custom_jitsi_meet_new: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装插件。
2. 初始化插件
在你的 Dart 文件中导入插件并初始化:
import 'package:custom_jitsi_meet_new/custom_jitsi_meet.dart';
3. 配置 Jitsi Meet
在调用 Jitsi Meet 之前,你需要配置一些参数,例如房间名称、用户信息等。
void joinMeeting() async {
try {
var options = CustomJitsiMeetOptions(
roomName: "your_room_name", // 会议房间名称
userDisplayName: "Your Name", // 用户显示名称
userEmail: "your_email@example.com", // 用户邮箱
userAvatarURL: "https://your_avatar_url.com", // 用户头像 URL
serverURL: "https://meet.jit.si", // Jitsi Meet 服务器 URL
isAudioMuted: false, // 是否静音
isVideoMuted: false, // 是否关闭视频
featureFlags: {
"welcomepage.enabled": false, // 禁用欢迎页面
"invite.enabled": false, // 禁用邀请功能
},
);
await CustomJitsiMeet.joinMeeting(options);
} catch (error) {
print("Error: $error");
}
}
4. 监听会议事件
你可以监听会议的开始和结束事件,以便在会议结束时执行一些操作。
void joinMeeting() async {
try {
var options = CustomJitsiMeetOptions(
roomName: "your_room_name",
userDisplayName: "Your Name",
userEmail: "your_email@example.com",
userAvatarURL: "https://your_avatar_url.com",
serverURL: "https://meet.jit.si",
isAudioMuted: false,
isVideoMuted: false,
);
await CustomJitsiMeet.joinMeeting(options);
CustomJitsiMeet.addListener(
onConferenceWillJoin: (url) {
print("Conference will join with url: $url");
},
onConferenceJoined: (url) {
print("Conference joined with url: $url");
},
onConferenceTerminated: (url, error) {
print("Conference terminated with url: $url, error: $error");
},
);
} catch (error) {
print("Error: $error");
}
}
5. 清理监听器
在页面销毁时,记得清理监听器以避免内存泄漏。
@override
void dispose() {
CustomJitsiMeet.removeAllListeners();
super.dispose();
}
6. 运行应用
现在你可以运行你的 Flutter 应用,并调用 joinMeeting()
方法来启动 Jitsi Meet 视频会议。
7. 其他注意事项
- iOS: 你可能需要在
Info.plist
中添加相机和麦克风权限。 - Android: 确保在
AndroidManifest.xml
中添加相机和麦克风权限。
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />