Flutter视频会议插件jitsi_meet_pro的使用

Flutter视频会议插件jitsi_meet_pro的使用

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

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

更多关于 Jitsi Meet 的信息可以在这里找到。

目录

配置

iOS

注意:示例在 XCode 14 和 Flutter 3 下编译成功。

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

将构建工具的 gradle 依赖设置为最低 3.6.3:

dependencies {
    classpath 'com.android.tools.build:gradle:3.6.3' <!-- 升级此 -->
    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 <!-- 升级此 -->
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="My Application"
        android:icon="@mipmap/ic_launcher">
        ...
    </application>
...
</manifest>
最低 SDK 版本 23

android/app/build.gradle 文件中更新您的最低 SDK 版本到 23。

defaultConfig {
    applicationId "com.gaurav.jitsi_meet_pro_example"
    minSdkVersion 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
        
        // 添加以下三行用于 proguard
        minifyEnabled true
        useProguard true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

然后在同一目录下创建一个名为 proguard-rules.pro 的文件。参见示例应用的 proguard-rules.pro 文件以了解需要粘贴的内容。

注意

如果您不创建 proguard-rules.pro 文件,则当您尝试加入会议或会议屏幕尝试打开时,应用程序将崩溃。您将在日志中看到以下错误之一。

## 应用崩溃 ##
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 会议名称显示在会议顶部。如果为 null,则默认为房间名称,其中破折号和下划线替换为空格,首字母大写。
userDisplayName “Fellow Jitster” 用户的显示名称。
userEmail none 用户的电子邮件地址。
audioOnly false 开始会议时不使用视频。可以在会议中启用。
audioMuted false 开始会议时音频静音。可以在会议中启用。
videoMuted false 开始会议时视频静音。可以在会议中启用。
serverURL meet.jitsi.si 指定您自己的托管服务器。必须是格式为 <scheme>://<host>[/path] 的有效绝对 URL,例如 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 发生了错误。

每场会议的事件

为了按会议监听事件,在 joinMeeting 中传递 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 广播");
}

程序化关闭会议

JitsiMeet.closeMeeting();

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

1 回复

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


jitsi_meet_pro 是一个用于在 Flutter 应用中集成 Jitsi Meet 视频会议的插件。Jitsi Meet 是一个开源的视频会议解决方案,支持高质量的音频和视频通话。使用 jitsi_meet_pro 插件,你可以轻松地在 Flutter 应用中嵌入 Jitsi Meet 视频会议功能。

安装步骤

  1. 添加依赖: 在 pubspec.yaml 文件中添加 jitsi_meet_pro 插件的依赖:

    dependencies:
      flutter:
        sdk: flutter
      jitsi_meet_pro: ^0.1.0
    

    然后运行 flutter pub get 来安装依赖。

  2. 配置项目

    • Android: 在 android/app/src/main/AndroidManifest.xml 文件中添加以下权限:

      <uses-permission android:name="android.permission.INTERNET"/>
      <uses-permission android:name="android.permission.CAMERA"/>
      <uses-permission android:name="android.permission.RECORD_AUDIO"/>
      <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
      

      确保你的 minSdkVersion 至少为 21:

      <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>
      
    • iOS: 在 ios/Runner/Info.plist 文件中添加以下权限:

      <key>NSCameraUsageDescription</key>
      <string>We need access to your camera for video calls</string>
      <key>NSMicrophoneUsageDescription</key>
      <string>We need access to your microphone for audio calls</string>
      
  3. 使用插件: 在 Flutter 代码中引入 jitsi_meet_pro 插件,并启动视频会议。

    import 'package:flutter/material.dart';
    import 'package:jitsi_meet_pro/jitsi_meet_pro.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      [@override](/user/override)
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Jitsi Meet Example'),
            ),
            body: Center(
              child: ElevatedButton(
                onPressed: () {
                  joinMeeting();
                },
                child: Text('Join Meeting'),
              ),
            ),
          ),
        );
      }
    
      void joinMeeting() async {
        var options = JitsiMeetingOptions(
          roomName: 'YourRoomName',
          userDisplayName: 'YourName',
          userEmail: 'your.email@example.com',
          audioOnly: false,
          audioMuted: false,
          videoMuted: false,
          serverURL: 'https://meet.jit.si', // 你可以使用自定义的 Jitsi 服务器
        );
    
        await JitsiMeetPro.joinMeeting(options);
      }
    }
    

参数说明

  • roomName: 会议室的名称,可以是任意字符串。
  • userDisplayName: 用户在会议中显示的名称。
  • userEmail: 用户的电子邮件地址。
  • audioOnly: 是否仅使用音频模式。
  • audioMuted: 是否静音。
  • videoMuted: 是否关闭视频。
  • serverURL: Jitsi Meet 服务器的 URL,默认是 https://meet.jit.si,你可以使用自定义的 Jitsi 服务器。

处理会议事件

你可以监听会议事件,例如会议开始、结束等:

JitsiMeetPro.addListener(
  JitsiMeetingListener(
    onConferenceWillJoin: (url) {
      print("Conference will join with url: $url");
    },
    onConferenceJoined: (url) {
      print("Conference joined with url: $url");
    },
    onConferenceTerminated: (url) {
      print("Conference terminated with url: $url");
    },
  ),
);

清理资源

dispose 方法中移除监听器:

[@override](/user/override)
void dispose() {
  JitsiMeetPro.removeAllListeners();
  super.dispose();
}
回到顶部