Flutter视频会议插件jitsi_meet_fix的使用

Flutter视频会议插件jitsi_meet_fix的使用

支持我们使用我们的Patreon账户。

Jitsi Meet插件适用于Flutter。支持Android、iOS和Web平台。

“Jitsi Meet是一个开源(Apache)WebRTC JavaScript应用程序,它使用Jitsi Videobridge提供高质量、安全且可扩展的视频会议。”

更多关于Jitsi Meet的信息可以在以下链接中找到。

目录

配置

iOS

注意:示例可在XCode 12.2和Flutter 1.22.4下编译。

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) 我的应用需要访问您的摄像头进行会议。</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) 我的应用需要访问您的麦克风进行会议。</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会与您的项目冲突,特别是application:label字段。要解决这个问题,请进入android/app/src/main/AndroidManifest.xml并添加工具库和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"> <!-- 添加此 -->
    <application 
        tools:replace="android:label"  
        android:name="your.application.name"
        android:label="我的应用"
        android:icon="@mipmap/ic_launcher">
        ...
    </application>
...
</manifest>

最低SDK版本 23

在android/app/build.gradle中更新您的最低sdk版本到23。

defaultConfig {
    applicationId "com.gunschu.jitsi_meet_example"
    minSdkVersion 23 // 必须设置为23以支持Jitsi
    targetSdkVersion 28
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
}

Proguard

Jitsi的SDK启用了proguard,但如果没有任何proguard-rules.pro文件,您的发布apk构建将会缺少Flutter包装器和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文件以知道要粘贴什么内容。

注意 如果您不创建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部分的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>

注意 请参阅jitsi_meet插件中的使用示例。

加入会议

_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 N/A none 用户的头像URL。
token N/A none 用于认证的JWT令牌。
featureFlag 见下文 FeatureFlag类的对象,用于启用/禁用功能和设置Jitsi Meet SDK的视频分辨率。

FeatureFlag

特征标志允许您限制视频分辨率并启用/禁用Jitsi Meet SDK中提到的某些功能。如果您不对JitsiMeetingOptions提供任何标志,默认值将被使用。

我们使用的是从Jitsi Meet存储库中获取的官方标志列表。

标志 默认 (Android) 默认 (iOS) 描述
addPeopleEnabled true true 启用蓝色按钮"Add people",当您单独通话时显示。需要启用inviteEnabled标志才能工作。
calendarEnabled true auto 启用日历集成。
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(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 用户进入PIP模式。
onPictureInPictureTerminated 用户退出PIP模式。
onError 发生了监听会议事件的错误。

每场会议的事件

要监听每场会议的事件,请在加入会议时传递一个JitsiMeetingListener。当触发onConferenceTerminated事件时,监听器将自动移除。

await JitsiMeet.joinMeeting(options,
  listener: JitsiMeetingListener(onConferenceWillJoin: ({message}) {
    debugPrint("${options.room} 将加入会议,消息:$message");
  }, onConferenceJoined: ({message}) {
    debugPrint("${options.room} 已加入会议,消息:$message");
  }, onConferenceTerminated: ({message}) {
    debugPrint("${options.room} 终止会议,消息:$message");
  }, onPictureInPictureWillEnter: ({message}) {
    debugPrint("${options.room} 进入PIP模式,消息:$message");
  }, onPictureInPictureTerminated: ({message}) {
    debugPrint("${options.room} 退出PIP模式,消息:$message");
  }));

全局会议事件

要监听全局会议事件,只需使用JitsiMeet.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 广播");
}

_onConferenceJoined({message}) {
  debugPrint("_onConferenceJoined 广播");
}

_onConferenceTerminated({message}) {
  debugPrint("_onConferenceTerminated 广播");
}

_onPictureInPictureWillEnter({message}) {
  debugPrint("_onPictureInPictureWillEnter 广播,消息:$message");
}

_onPictureInPictureTerminated({message}) {
  debugPrint("_onPictureInPictureTerminated 广播,消息:$message");
}

_onError(error) {
  debugPrint("_onError 广播,错误:$error");
}

程序化关闭会议

JitsiMeet.closeMeeting();

更多关于Flutter视频会议插件jitsi_meet_fix的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter视频会议插件jitsi_meet_fix的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成和使用 jitsi_meet_fix 插件的一个示例。这个插件是对 jitsi_meet 插件的一个修复和优化版本,主要用于集成 Jitsi Meet 进行视频会议。

步骤 1: 添加依赖

首先,在你的 pubspec.yaml 文件中添加 jitsi_meet_fix 依赖:

dependencies:
  flutter:
    sdk: flutter
  jitsi_meet_fix: ^x.y.z  # 请替换为最新版本号

然后运行 flutter pub get 来获取依赖。

步骤 2: 导入插件

在你的 Dart 文件中导入插件:

import 'package:jitsi_meet_fix/jitsi_meet_fix.dart';

步骤 3: 配置 Jitsi Meet

在使用 Jitsi Meet 之前,你需要配置一些基本的选项,比如会议 URL、房间名称、用户信息等。以下是一个简单的示例:

void _launchJitsiMeet() async {
  final options = JitsiMeetOptions()
    ..room = "https://meet.jit.si/YourRoomName"  // Jitsi Meet URL 或房间名
    ..userName = "YourUserName"  // 可选:用户名
    ..subject = "Meeting Subject"  // 可选:会议主题
    ..audioOnly = false  // 可选:是否仅音频
    ..audioMuted = false  // 可选:是否静音
    ..videoMuted = true  // 可选:是否禁用视频
    ..token = "YourJitsiToken"  // 可选:如果你的 Jitsi 服务器需要认证 token
    ..email = "user@example.com"  // 可选:用户邮箱
    ..password = "password"  // 可选:用户密码
    ..features = [
      JitsiMeetViewOptions.TOOLBAR_BUTTONS,
    ]  // 可选:配置功能按钮,例如工具栏按钮
    ..interfaceConfig = InterfaceConfig(
      TOOLBAR_BUTTONS: [
        'microphone',
        'camera',
        'hangup',
      ],  // 可选:配置工具栏按钮
    );

  try {
    await JitsiMeetFix.launch(options);
  } catch (e) {
    print(e);
  }
}

步骤 4: 调用 Jitsi Meet

现在你可以在你的 Flutter 应用中调用 _launchJitsiMeet 函数来启动 Jitsi Meet 视频会议:

import 'package:flutter/material.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: _launchJitsiMeet,
            child: Text('Start Meeting'),
          ),
        ),
      ),
    );
  }
}

注意事项

  1. 权限:确保你的应用有访问网络和摄像头的权限。在 AndroidManifest.xmlInfo.plist 中添加必要的权限。
  2. URL 格式room 参数可以是完整的 Jitsi Meet URL,也可以是房间名称(如果你的 Jitsi 服务器配置为允许这种格式)。
  3. 错误处理:在实际应用中,你应该添加更多的错误处理逻辑来处理各种可能的异常情况,比如网络错误、认证失败等。

这个示例应该能帮助你在 Flutter 应用中集成 jitsi_meet_fix 插件并启动一个 Jitsi Meet 视频会议。如果你有更具体的需求或遇到问题,可以查阅插件的官方文档或提交 issue 到插件的 GitHub 仓库。

回到顶部