Flutter视频会议插件custom_jitsi_meet的使用
Flutter视频会议插件custom_jitsi_meet的使用
简介
custom_jitsi_meet
是一个 Flutter 插件,用于在 Flutter 应用中集成 Jitsi Meet 视频会议功能。Jitsi Meet 是一个开源的(Apache 许可证)WebRTC JavaScript 应用程序,使用 Jitsi Videobridge 提供高质量、安全且可扩展的视频会议。
更多关于 Jitsi Meet 的信息可以在这里找到:Jitsi Meet GitHub
目录
配置
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 需要访问您的摄像头以进行会议。</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) MyApp 需要访问您的麦克风以进行会议。</string>
Android
Gradle
将 build tools 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 会与你的项目冲突,特别是 application:label
字段。为了应对这一点,在 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
Jitsi 的 SDK 启用了 proguard,但如果没有 proguard-rules.pro 文件,你的发布版 apk 构建将缺少 Flutter Wrapper 以及 react-native 代码。在你的 Flutter 项目的 android/app/build.gradle
文件中添加 proguard 支持:
buildTypes {
release {
// TODO: 添加你自己的签名配置以用于发布构建。
// 当前使用调试密钥进行签名,以便 `flutter run --release` 可以工作。
signingConfig signingConfigs.debug
// 添加以下 3 行以启用 proguard
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
然后在同一目录下创建一个名为 proguard-rules.pro
的文件。参见示例应用的 proguard-rules.pro
文件以了解需要粘贴的内容。
Web
在 web 部分的 index.html
中包含 Jitsi Js 库:
<script src="https://meet.jit.si/external_api.js" type="application/javascript"></script>
示例:
<body>
<!-- 这个脚本安装 service_worker.js 以向应用程序提供 PWA 功能。更多信息,请参阅:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<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>
</html>
加入会议
_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
字段 | 是否必需 | 默认值 | 描述 |
---|---|---|---|
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] ,例如 https://someHost.com 。默认为 Jitsi Meet 的服务器。 |
userAvatarURL | 否 | none | 用户的头像 URL。 |
token | 否 | none | 用于身份验证的 JWT 令牌。 |
featureFlag | 否 | 见下文 | FeatureFlag 类的对象,用于启用/禁用 Jitsi Meet SDK 的功能并设置视频分辨率。 |
FeatureFlag
Feature flag 允许你限制视频分辨率并启用/禁用 Jitsi Meet SDK 的一些功能,如列表所示。如果你不提供任何标志给 JitsiMeetingOptions,默认值将被使用。
我们使用的是 官方的标志列表。
标志 | 默认值 (Android) | 默认值 (iOS) | 描述 |
---|---|---|---|
addPeopleEnabled | true | true | 启用蓝色按钮 “Add people”,当你是唯一的参与者时显示。要求启用 inviteEnabled 标志。 |
calendarEnabled | true | auto | 启用日历集成。 |
callIntegrationEnabled | true | true | 启用通话集成(Android 上的 ConnectionService,iOS 上的 CallKit)。 参见备注 |
closeCaptionsEnabled | true | true | 启用字幕(字幕)选项。 |
conferenceTimerEnabled | true | true | 启用会议计时器。 |
chatEnabled | true | true | 启用聊天(按钮和功能)。 |
inviteEnabled | true | true | 启用邀请选项。 |
iOSRecordingEnabled | N/A | false | 启用 iOS 录制。 |
kickOutEnabled | true | true | 启用踢出选项。 |
liveStreamingEnabled | auto | auto | 启用直播选项。 |
meetingNameEnabled | true | true | 显示会议名称。 |
meetingPasswordEnabled | true | true | 显示会议密码选项。 |
pipEnabled | auto | auto | 启用画中画模式。 |
raiseHandEnabled | true | true | 启用举手选项。 |
recordingEnabled | auto | N/A | 启用录制选项。 |
resolution | N/A | N/A | 设置本地和(最大)远程视频分辨率。接受的值为:LD_RESOLUTION 180p, MD_RESOLUTION 360p, SD_RESOLUTION 480p(SD), HD_RESOLUTION 720p(HD)。 |
serverURLChangeEnabled | true | true | 启用服务器 URL 更改。 |
tileViewEnabled | true | true | 启用平铺视图选项。 |
toolboxAlwaysVisible | true | true | 通话期间工具栏(按钮和菜单)始终可见(如果不显示,单击一次即可显示)。 |
videoShareButtonEnabled | true | true | 启用视频共享按钮。 |
welcomePageEnabled | false | false | 启用欢迎页面。“欢迎页面列出了最近的会议和日历预约,适用于独立应用程序。” |
关于通话集成的备注:Android 上的通话集成(称为 ConnectionService)由于存在许多问题,已在官方 Jitsi Meet 应用中禁用。为了避免这些问题,你也应该禁用它。
JitsiMeetingResponse
字段 | 类型 | 描述 |
---|---|---|
isSuccess | bool | 成功指示符。 |
message | String | 成功消息或错误信息。 |
error | dynamic | 可选,仅在 isSuccess 为 false 时存在。错误对象。 |
监听会议事件
支持的事件:
名称 | 描述 |
---|---|
onConferenceWillJoin | 会议正在加载。 |
onConferenceJoined | 用户已加入会议。 |
onConferenceTerminated | 用户已退出会议。 |
onPictureInPictureWillEnter | 用户进入画中画模式。 |
onPictureInPictureTerminated | 用户退出画中画模式。 |
onError | 监听会议事件时发生错误。 |
每场会议事件
要在每场会议中监听事件,传递一个 JitsiMeetingListener
到 joinMeeting
。监听器将在 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");
}));
全局会议事件
要监听全局会议事件,只需使用 JitsiMeet.addListener(myListener)
添加一个 JitsiMeetingListener
。你可以使用 JitsiMeet.removeListener(listener)
或 JitsiMeet.removeAllListeners()
移除监听器。
@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 with message: $message");
}
_onConferenceJoined({message}) {
debugPrint("_onConferenceJoined broadcasted with message: $message");
}
_onConferenceTerminated({message}) {
debugPrint("_onConferenceTerminated broadcasted with message: $message");
}
_onPictureInPictureWillEnter({message}) {
debugPrint("_onPictureInPictureWillEnter broadcasted with message: $message");
}
_onPictureInPictureTerminated({message}) {
debugPrint("_onPictureInPictureTerminated broadcasted with message: $message");
}
_onError(error) {
debugPrint("_onError broadcasted: $error");
}
程序化关闭会议
JitsiMeet.closeMeeting();
贡献
发送一个包含尽可能多的信息的 pull request,清楚地描述问题或功能。保持更改小且每次只解决一个问题。
更多关于Flutter视频会议插件custom_jitsi_meet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter视频会议插件custom_jitsi_meet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于如何在Flutter项目中使用custom_jitsi_meet
插件来实现视频会议功能,以下是一个基本的代码示例。这个示例将展示如何集成custom_jitsi_meet
插件并启动一个视频会议。
首先,确保你的Flutter项目已经创建,并且你已经安装了custom_jitsi_meet
插件。如果还没有安装,可以通过以下命令添加:
flutter pub add custom_jitsi_meet
接下来,按照以下步骤进行配置和使用:
1. 配置pubspec.yaml
确保你的pubspec.yaml
文件中已经包含了custom_jitsi_meet
的依赖项:
dependencies:
flutter:
sdk: flutter
custom_jitsi_meet: ^x.y.z # 替换为最新版本号
2. 导入插件并创建JitsiMeetView
在你的Dart文件中(例如main.dart
),导入custom_jitsi_meet
插件并创建一个JitsiMeetView
实例。
import 'package:flutter/material.dart';
import 'package:custom_jitsi_meet/custom_jitsi_meet.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Jitsi Meet Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () => startJitsiMeet(),
child: Text('Start Jitsi Meet'),
),
),
),
);
}
Future<void> startJitsiMeet() async {
final options = JitsiMeetOptions(
room: 'https://meet.jit.si/YourRoomName', // 替换为你的Jitsi Meet房间URL
userInfo: JitsiMeetUserInfo(
displayName: 'YourDisplayName', // 替换为你的显示名称
email: 'your.email@example.com', // 替换为你的邮箱
),
audioOnly: false, // 是否仅音频
chromeOptions: JitsiMeetChromeOptions(
// 可以在这里配置更多Chrome选项
),
interfaceConfig: JitsiMeetInterfaceConfig(
// 可以在这里配置更多界面选项
),
);
await JitsiMeet.launch(options);
}
}
3. 配置Android和iOS权限(如果需要)
在某些情况下,你可能需要在AndroidManifest.xml
和Info.plist
中添加额外的权限配置。通常,custom_jitsi_meet
插件会处理大部分必要的配置,但如果你遇到权限问题,请检查并添加必要的权限。
4. 运行应用
现在,你可以运行你的Flutter应用,点击按钮应该能够启动Jitsi Meet视频会议。
flutter run
注意事项
- 确保你有一个有效的Jitsi Meet服务器URL或者你可以使用Jitsi的公共服务(如
https://meet.jit.si
)。 custom_jitsi_meet
插件依赖于WebView来加载Jitsi Meet界面,因此确保你的应用有适当的WebView支持。- 你可以在
JitsiMeetOptions
中配置更多选项来定制你的视频会议体验。
这个示例提供了一个基本的框架,你可以根据需要进行扩展和自定义。