配置
IOS
- 注意:示例可通过XCode 12.2和Flutter 1.22.4编译。
Podfile
确保在你的Podfile中有如下声明ios11.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
将NSCameraUsageDescription和NSMicrophoneUsageDescription添加到Info.plist中。
<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
设置编译依赖的版本不小于 3.6.3:
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3' <!-- Upgrade this -->
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
将发行版gradle包装器设置为最小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 <!-- Upgrade this -->
AndroidManifest.xml
Jitsi Meet的SDK AndroidManifest.xml将与您的项目冲突,即应用程序:标签字段。为了解决这个问题,进入android/app/src/main/AndroidManifest.xml,将tools库和tools:replace="android:label"添加到application标签中。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="yourpackage.com"
xmlns:tools="http://schemas.android.com/tools"> <!-- Add this -->
<application
tools:replace="android:label"
android:name="your.application.name"
android:label="My Application"
android:icon="@mipmap/ic_launcher">
...
</application>
...
</manifest>
Minimum SDK Version 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规则。profile文件,你的版本apk构建将会缺少Flutter Wrapper以及响应本地代码。在你的Flutter项目的android/app/build中。Gradle文件,添加proguard支持
buildTypes {
release {
// 待办事项:为发布版本添加您自己的签名配置。
// 现在使用调试密钥进行签名,因此“flutter run—release”可以工作。
signingConfig signingConfigs.debug
// 为proguard添加以下3行代码
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
然后在同一个目录中添加一个名为proguard-rules.pro的文件。参见示例应用程序的proguard-rules。专业文件知道粘贴什么。
注意:如果不创建proguard-rules。Pro文件,当你试图加入一个会议或会议屏幕试图打开但立即关闭时,应用程序将崩溃。您将在logcat中看到以下错误之一。
## App crashes ##
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)
.....
## Meeting won't open and you go to previous screen ##
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部分的index.html中包含Jitsi Js库
<script src="https://meet.jit.si/external_api.js" type="application/javascript"></script>
示例
<body>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
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>
注意看jitsi_meet plugin中的用法示例
参加一个会议
_joinMeeting() async {
try {
FeatureFlag featureFlag = FeatureFlag();
featureFlag.welcomePageEnabled = false;
featureFlag.resolution = FeatureFlagVideoResolution.MD_RESOLUTION; //限制视频分辨率为360p
var options = JitsiMeetingOptions()
..room = "myroom" // Required, spaces will be trimmed
..serverURL = "https://someHost.com"
..subject = "Meeting with Gunschu"
..userDisplayName = "My Name"
..userEmail = "myemail@email.com"
..userAvatarURL = "https://someimageurl.com/image.jpg" // or .png
..audioOnly = true
..audioMuted = true
..videoMuted = true
..featureFlag = featureFlag;
await JitsiMeet.joinMeeting(options);
} catch (error) {
debugPrint("error: $error");
}
}
JitsiMeetingOptions
字段 | 必要的 | 默认值 | 说明 |
room | Yes | N/A | 将被附加到serverURL的唯一房间名称。有效字符:字母数字、破折号和下划线。 |
subject | No | $room | 会议名称显示在会议上方。如果为空,默认为房间名称,其中破折号和下划线被空格替换,第一个字符大写。 |
userDisplayName | No | "Fellow Jitster" | 用户的显示名称。 |
userEmail | No | none | 用户的电子邮件地址。 |
audioOnly | No | false | 会议仅使用音频,可以在会议中打开。 |
audioMuted | No | false | 开始会议时静音。可以在会议中打开。 |
videoMuted | No | false | 开始会议时视频静音。可以在会议中打开。 |
serverURL | No | meet.jitsi.si | 指定您自己的托管服务器。必须是一个有效的绝对URL格式 ://[/path] , i.e. https://someHost.com. Defaults to Jitsi Meet's servers. |
userAvatarURL | N/A | none | 用户头像地址 |
token | N/A | none | 用于身份验证的JWT令牌。 |
featureFlag | No | see below | FeatureFlag Object,用于启用/禁用Jitsi Meet SDK的特性和设置视频分辨率。 |
FeatureFlag
Feature flag 允许你限制视频分辨率和启用/禁用Jitsi Meet SDK的一些特性,在下面列表中提到。如果没有为JitsiMeetingOptions提供任何标志,将使用默认值。
我们使用的是来自 Jitsi Meet存储库的官方标志列表
配置项 | 默认值 (Android) | 默认值 (iOS) | 说明 |
addPeopleEnabled | true | true | 启用蓝色按钮“添加用户”,当您单独通话时显示,需要配置inviteEnabled 时才生效。 |
calendarEnabled | true | auto | 启用日历 calendar integration. |
callIntegrationEnabled | true | true | 启用呼叫集成(iOS上的CallKit, Android上的ConnectionService)。 请参见下面的评论 |
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 | 在菜单中启用录音选项。 |
resoulution | N/A | N/A | 设置本地和(最大)远程视频分辨率。覆盖服务器配置。可接受的值为:LD_RESOLUTION for 180p, MD_RESOLUTION for 360p, SD_RESOLUTION for 480p(SD), HD_RESOLUTION for 720p(HD)。 |
serverURLChangeEnabled | true | true | 启用服务器URL更改。 |
tileViewEnabled | true | true | 启用菜单中的平铺视图选项。 |
toolboxAlwaysVisible | true | true | “工具箱”(按钮和菜单)在调用期间总是可见的(如果不可见,只需轻按即可显示)。 |
videoShareButtonEnabled | true | true | 开启视频共享按钮。 |
welcomePageEnabled | false | false | 启用欢迎页面。“欢迎页面列出了最近的会议和日程安排,它是为独立应用程序使用的。” |
关于 Call integration 的备注 在官方的Jitsi Meet应用程序上,已经禁用了Android上的呼叫集成(称为ConnectionService),因为它会产生很多问题。您也应该禁用它以避免这些问题。
JitsiMeetingResponse
字段 | 类型 | 说明 |
isSuccess | bool | 成功的指标。 |
message | String | 是否成功 |
error | dynamic | 可选,仅当isSuccess为false时存在。错误对象。 |
Listening to Meeting Events 聆听会议活动
Events supported 事件支持
名称 | 说明 |
onConferenceWillJoin | 会议以加载。 |
onConferenceJoined | 用户已加入会议。 |
onConferenceTerminated | 用户退出会议。 |
onPictureInPictureWillEnter | 用户进入画中画模式 |
onPictureInPictureTerminated | 用户退出画中画模式 |
onError | 在监听会议事件时发生错误. |
Per Meeting Events 每个会议事件
To listen to meeting events per meeting, pass in a JitsiMeetingListener in joinMeeting. The listener will automatically be removed when anonConferenceTerminated event is fired.‘
要侦听每次会议的会议事件,请在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");
}));
Global Meeting Events 全局会议事件
To listen to global meeting events, simply add a JitsiMeetListener withJitsiMeet.addListener(myListener). You can remove listeners usingJitsiMeet.removeListener(listener) or JitsiMeet.removeAllListeners().
要侦听全局会议事件,只需使用jitsimeeting . addlistener (myListener)添加一个JitsiMeetListener。您可以使用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");
}
_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();
贡献
Send a pull request with as much information as possible clearly describing the issue or feature. Keep changes small and for one issue at a time.