From 96615c6df88d130021b340bad4d481bcbc19a675 Mon Sep 17 00:00:00 2001 From: Pushpam <93931528+Decoder07@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:55:28 +0530 Subject: [PATCH 01/11] FLUT-253: Moved all permissions from app to sdk (#1787) * Moved all permissions from app to sdk * Moved all permissions from app to sdk * testing permissions * testing permissions * Updated Permissions --- packages/hms_room_kit/example/pubspec.lock | 7 ++-- packages/hms_room_kit/pubspec.lock | 7 ++-- packages/hms_room_kit/pubspec.yaml | 3 +- .../android/src/main/AndroidManifest.xml | 21 ------------ .../android/app/src/main/AndroidManifest.xml | 34 ++++++------------- packages/hmssdk_flutter/example/pubspec.lock | 7 ++-- 6 files changed, 22 insertions(+), 57 deletions(-) diff --git a/packages/hms_room_kit/example/pubspec.lock b/packages/hms_room_kit/example/pubspec.lock index fbae0172b..73b282168 100644 --- a/packages/hms_room_kit/example/pubspec.lock +++ b/packages/hms_room_kit/example/pubspec.lock @@ -242,10 +242,9 @@ packages: hmssdk_flutter: dependency: transitive description: - name: hmssdk_flutter - sha256: b1c3e2e9e50bff07831f77c948e4db46ded3b582304aa74b2019e4f8750fcfe1 - url: "https://pub.dev" - source: hosted + path: "../../hmssdk_flutter" + relative: true + source: path version: "1.10.3" http: dependency: transitive diff --git a/packages/hms_room_kit/pubspec.lock b/packages/hms_room_kit/pubspec.lock index 022dd3990..3d85553ef 100644 --- a/packages/hms_room_kit/pubspec.lock +++ b/packages/hms_room_kit/pubspec.lock @@ -219,10 +219,9 @@ packages: hmssdk_flutter: dependency: "direct main" description: - name: hmssdk_flutter - sha256: b1c3e2e9e50bff07831f77c948e4db46ded3b582304aa74b2019e4f8750fcfe1 - url: "https://pub.dev" - source: hosted + path: "../hmssdk_flutter" + relative: true + source: path version: "1.10.3" http: dependency: transitive diff --git a/packages/hms_room_kit/pubspec.yaml b/packages/hms_room_kit/pubspec.yaml index 415d616a4..5711cd9c8 100644 --- a/packages/hms_room_kit/pubspec.yaml +++ b/packages/hms_room_kit/pubspec.yaml @@ -14,7 +14,8 @@ dependencies: flutter: sdk: flutter - hmssdk_flutter: 1.10.3 + hmssdk_flutter: + path: ../hmssdk_flutter intl: ^0.18.0 permission_handler: ^11.0.0 provider: ^6.0.5 diff --git a/packages/hmssdk_flutter/android/src/main/AndroidManifest.xml b/packages/hmssdk_flutter/android/src/main/AndroidManifest.xml index 2cf4b2071..7c30a00f8 100644 --- a/packages/hmssdk_flutter/android/src/main/AndroidManifest.xml +++ b/packages/hmssdk_flutter/android/src/main/AndroidManifest.xml @@ -2,28 +2,7 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/hmssdk_flutter/example/android/app/src/main/AndroidManifest.xml b/packages/hmssdk_flutter/example/android/app/src/main/AndroidManifest.xml index b62c8b15d..aa2d7433a 100644 --- a/packages/hmssdk_flutter/example/android/app/src/main/AndroidManifest.xml +++ b/packages/hmssdk_flutter/example/android/app/src/main/AndroidManifest.xml @@ -1,35 +1,23 @@ - - - - - - - - - - - + + + - - - - - - - - - - - - + + + + + + + + Date: Wed, 12 Jun 2024 18:16:45 +0530 Subject: [PATCH 02/11] =?UTF-8?q?released=20sample=20app=20version=201.5.2?= =?UTF-8?q?03=20(503)=20=F0=9F=8D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/ExampleAppChangelog.txt | 22 ++----------------- .../example/android/app/build.gradle | 4 ++-- .../example/ios/Runner/Info.plist | 4 ++-- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt index c717b3642..0d6d73268 100644 --- a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt +++ b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt @@ -1,25 +1,7 @@ Board: https://100ms.atlassian.net/jira/software/projects/FLUT/boards/34/ -- Implement Background Blur effects -https://100ms.atlassian.net/browse/FLUT-318 - -- Expose SDK APIs for Virtual Backgrounds -https://100ms.atlassian.net/browse/FLUT-319 - -- Create separate package on pub for Virtual Background -https://100ms.atlassian.net/browse/FLUT-317 - -- Hand Raise as a Layout Config -https://100ms.atlassian.net/browse/FLUT-275 - -- Empty screen scenarios on Prebuilt -https://100ms.atlassian.net/browse/FLUT-304 - -- Resolve issue where VRT is not able to subscribe to host -https://100ms.atlassian.net/browse/FLUT-329 - -- Remove use of Popup in screen share while in full screen -https://100ms.atlassian.net/browse/FLUT-326 +- Move all the permissions from app to sdk +https://100ms.atlassian.net/browse/FLUT-253 Room Kit: 1.1.3 Core SDK: 1.10.3 diff --git a/packages/hmssdk_flutter/example/android/app/build.gradle b/packages/hmssdk_flutter/example/android/app/build.gradle index 813225477..53e241146 100644 --- a/packages/hmssdk_flutter/example/android/app/build.gradle +++ b/packages/hmssdk_flutter/example/android/app/build.gradle @@ -36,8 +36,8 @@ android { applicationId "live.hms.flutter" minSdkVersion 21 targetSdkVersion 34 - versionCode 502 - versionName "1.5.202" + versionCode 503 + versionName "1.5.203" } signingConfigs { diff --git a/packages/hmssdk_flutter/example/ios/Runner/Info.plist b/packages/hmssdk_flutter/example/ios/Runner/Info.plist index 4d6b7716f..15a6a21d9 100644 --- a/packages/hmssdk_flutter/example/ios/Runner/Info.plist +++ b/packages/hmssdk_flutter/example/ios/Runner/Info.plist @@ -21,7 +21,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.5.202 + 1.5.203 CFBundleSignature ???? CFBundleURLTypes @@ -48,7 +48,7 @@ CFBundleVersion - 502 + 503 ITSAppUsesNonExemptEncryption LSApplicationCategoryType From 8889014196def1de3c5ca0d625beed4d5e5097bb Mon Sep 17 00:00:00 2001 From: Pushpam <93931528+Decoder07@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:38:06 +0530 Subject: [PATCH 03/11] Updated SDK version (#1788) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * updated sdk versions * 🤖 Automated Format and Fix --------- Co-authored-by: Decoder07 --- packages/hms_room_kit/example/pubspec.yaml | 2 +- packages/hms_room_kit/pubspec.yaml | 2 +- packages/hmssdk_flutter/example/ExampleAppChangelog.txt | 4 ++-- packages/hmssdk_flutter/example/pubspec.lock | 4 ++-- packages/hmssdk_flutter/example/pubspec.yaml | 2 +- packages/hmssdk_flutter/lib/assets/sdk-versions.json | 2 +- packages/hmssdk_flutter/pubspec.yaml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/hms_room_kit/example/pubspec.yaml b/packages/hms_room_kit/example/pubspec.yaml index d71949162..a955121b3 100644 --- a/packages/hms_room_kit/example/pubspec.yaml +++ b/packages/hms_room_kit/example/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.1.3 +version: 1.1.4 environment: sdk: ">=2.19.6 <3.0.0" diff --git a/packages/hms_room_kit/pubspec.yaml b/packages/hms_room_kit/pubspec.yaml index 5711cd9c8..ba98d378b 100644 --- a/packages/hms_room_kit/pubspec.yaml +++ b/packages/hms_room_kit/pubspec.yaml @@ -1,6 +1,6 @@ name: hms_room_kit description: 100ms Room Kit provides simple & easy to use UI components to build Live Streaming & Video Conferencing experiences in your apps. -version: 1.1.3 +version: 1.1.4 homepage: https://www.100ms.live/ repository: https://github.com/100mslive/100ms-flutter issue_tracker: https://github.com/100mslive/100ms-flutter/issues diff --git a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt index 0d6d73268..8414247b2 100644 --- a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt +++ b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt @@ -3,7 +3,7 @@ Board: https://100ms.atlassian.net/jira/software/projects/FLUT/boards/34/ - Move all the permissions from app to sdk https://100ms.atlassian.net/browse/FLUT-253 -Room Kit: 1.1.3 -Core SDK: 1.10.3 +Room Kit: 1.1.4 +Core SDK: 1.10.4 Android SDK: 2.9.59 iOS SDK: 1.12.0 \ No newline at end of file diff --git a/packages/hmssdk_flutter/example/pubspec.lock b/packages/hmssdk_flutter/example/pubspec.lock index d4e228ba0..8f6e3387c 100644 --- a/packages/hmssdk_flutter/example/pubspec.lock +++ b/packages/hmssdk_flutter/example/pubspec.lock @@ -335,14 +335,14 @@ packages: path: "../../hms_room_kit" relative: true source: path - version: "1.1.3" + version: "1.1.4" hmssdk_flutter: dependency: transitive description: path: ".." relative: true source: path - version: "1.10.3" + version: "1.10.4" http: dependency: transitive description: diff --git a/packages/hmssdk_flutter/example/pubspec.yaml b/packages/hmssdk_flutter/example/pubspec.yaml index dac9649e6..88f7d9256 100644 --- a/packages/hmssdk_flutter/example/pubspec.yaml +++ b/packages/hmssdk_flutter/example/pubspec.yaml @@ -4,7 +4,7 @@ description: Demonstrates how to use the hmssdk_flutter plugin. # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.10.3 +version: 1.10.4 environment: sdk: ">=2.16.0 <4.0.0" diff --git a/packages/hmssdk_flutter/lib/assets/sdk-versions.json b/packages/hmssdk_flutter/lib/assets/sdk-versions.json index f48853100..23e0ef9ba 100644 --- a/packages/hmssdk_flutter/lib/assets/sdk-versions.json +++ b/packages/hmssdk_flutter/lib/assets/sdk-versions.json @@ -1,5 +1,5 @@ { - "flutter": "1.10.3", + "flutter": "1.10.4", "ios": "1.12.0", "iOSBroadcastExtension": "0.0.9", "iOSHLSPlayerSDK": "0.0.2", diff --git a/packages/hmssdk_flutter/pubspec.yaml b/packages/hmssdk_flutter/pubspec.yaml index cad52cdec..7c5b6cec2 100644 --- a/packages/hmssdk_flutter/pubspec.yaml +++ b/packages/hmssdk_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: hmssdk_flutter description: Add Real Time Audio & Video calls, Interactive Live Streaming & Recording, Chat, HLS, RTMP, PiP, CallKit, VoIP, Video conferencing, Stream Player & WebRTC-based communications API -version: 1.10.3 +version: 1.10.4 homepage: https://www.100ms.live/ repository: https://github.com/100mslive/100ms-flutter issue_tracker: https://github.com/100mslive/100ms-flutter/issues From a2ec9492cb6ad3da9e5f38ad5c7596a6468e9ee4 Mon Sep 17 00:00:00 2001 From: Pushpam <93931528+Decoder07@users.noreply.github.com> Date: Thu, 13 Jun 2024 20:09:38 +0530 Subject: [PATCH 04/11] Updated room kit to v2 embedding (#1789) --- .../plugins/GeneratedPluginRegistrant.java | 23 ------------------- packages/hms_room_kit/example/pubspec.lock | 4 ++-- packages/hms_room_kit/example/pubspec.yaml | 2 +- .../ios/Runner/GeneratedPluginRegistrant.h | 19 --------------- .../ios/Runner/GeneratedPluginRegistrant.m | 14 ----------- packages/hms_room_kit/pubspec.lock | 2 +- 6 files changed, 4 insertions(+), 60 deletions(-) delete mode 100644 packages/hms_room_kit/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java delete mode 100644 packages/hms_room_kit/ios/Runner/GeneratedPluginRegistrant.h delete mode 100644 packages/hms_room_kit/ios/Runner/GeneratedPluginRegistrant.m diff --git a/packages/hms_room_kit/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/packages/hms_room_kit/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java deleted file mode 100644 index d007606a4..000000000 --- a/packages/hms_room_kit/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.flutter.plugins; - -import io.flutter.plugin.common.PluginRegistry; - -/** - * Generated file. Do not edit. - */ -public final class GeneratedPluginRegistrant { - public static void registerWith(PluginRegistry registry) { - if (alreadyRegisteredWith(registry)) { - return; - } - } - - private static boolean alreadyRegisteredWith(PluginRegistry registry) { - final String key = GeneratedPluginRegistrant.class.getCanonicalName(); - if (registry.hasPlugin(key)) { - return true; - } - registry.registrarFor(key); - return false; - } -} diff --git a/packages/hms_room_kit/example/pubspec.lock b/packages/hms_room_kit/example/pubspec.lock index 73b282168..6d95f230a 100644 --- a/packages/hms_room_kit/example/pubspec.lock +++ b/packages/hms_room_kit/example/pubspec.lock @@ -238,14 +238,14 @@ packages: path: ".." relative: true source: path - version: "1.1.3" + version: "1.1.4" hmssdk_flutter: dependency: transitive description: path: "../../hmssdk_flutter" relative: true source: path - version: "1.10.3" + version: "1.10.4" http: dependency: transitive description: diff --git a/packages/hms_room_kit/example/pubspec.yaml b/packages/hms_room_kit/example/pubspec.yaml index a955121b3..c72366a10 100644 --- a/packages/hms_room_kit/example/pubspec.yaml +++ b/packages/hms_room_kit/example/pubspec.yaml @@ -19,7 +19,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev version: 1.1.4 environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=3.0.0 <4.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions diff --git a/packages/hms_room_kit/ios/Runner/GeneratedPluginRegistrant.h b/packages/hms_room_kit/ios/Runner/GeneratedPluginRegistrant.h deleted file mode 100644 index 7a8909271..000000000 --- a/packages/hms_room_kit/ios/Runner/GeneratedPluginRegistrant.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GeneratedPluginRegistrant_h -#define GeneratedPluginRegistrant_h - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface GeneratedPluginRegistrant : NSObject -+ (void)registerWithRegistry:(NSObject*)registry; -@end - -NS_ASSUME_NONNULL_END -#endif /* GeneratedPluginRegistrant_h */ diff --git a/packages/hms_room_kit/ios/Runner/GeneratedPluginRegistrant.m b/packages/hms_room_kit/ios/Runner/GeneratedPluginRegistrant.m deleted file mode 100644 index efe65eccc..000000000 --- a/packages/hms_room_kit/ios/Runner/GeneratedPluginRegistrant.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#import "GeneratedPluginRegistrant.h" - -@implementation GeneratedPluginRegistrant - -+ (void)registerWithRegistry:(NSObject*)registry { -} - -@end diff --git a/packages/hms_room_kit/pubspec.lock b/packages/hms_room_kit/pubspec.lock index 3d85553ef..02ba44dd6 100644 --- a/packages/hms_room_kit/pubspec.lock +++ b/packages/hms_room_kit/pubspec.lock @@ -222,7 +222,7 @@ packages: path: "../hmssdk_flutter" relative: true source: path - version: "1.10.3" + version: "1.10.4" http: dependency: transitive description: From 35ffa97bee49e0132a8b3989cfa304703d5b9e6c Mon Sep 17 00:00:00 2001 From: Pushpam <93931528+Decoder07@users.noreply.github.com> Date: Fri, 28 Jun 2024 12:44:39 +0530 Subject: [PATCH 05/11] Iss 22680 (#1790) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added webrtc transcription apis * Added methods to start stop transcription * Added UI for transcription * released sample app version 1.5.204 (504) 🍀 * Fixed imports * Added dismiss timer in captions * released sample app version 1.5.205 (505) 🍀 * Updated ui for transcription * Updated fastlane * updated Example app changelog * released sample app version 1.5.206 (506) 🍀 * Added comments * Reverted android sdk version to 2.9.59 * Fixed icon issue * released sample app version 1.5.207 (507) 🍀 --------- Co-authored-by: Yogesh Singh --- .../lib/src/assets/icons/cc-filled.svg | 3 + .../hms_room_kit/lib/src/assets/icons/cc.svg | 5 + .../lib/src/meeting/meeting_page.dart | 5 + .../lib/src/meeting/meeting_store.dart | 105 +++++++++++++- .../app_utilities_bottom_sheet.dart | 93 +++++++++++- .../closed_caption_bottom_sheet.dart | 128 +++++++++++++++++ .../closed_caption_control_bottom_sheet.dart | 132 ++++++++++++++++++ .../common_widgets/transcription_view.dart | 106 ++++++++++++++ .../src/widgets/toasts/hms_toasts_type.dart | 3 +- .../toasts/hms_transcription_toast.dart | 33 +++++ .../lib/src/widgets/toasts/toast_widget.dart | 22 ++- .../hms/hmssdk_flutter/HMSRoomExtension.kt | 3 + .../hmssdk_flutter/HMSTranscriptExtension.kt | 92 ++++++++++++ .../hms/hmssdk_flutter/HmssdkFlutterPlugin.kt | 86 +++++++++--- .../PermissionParamsExtension.kt | 16 +++ .../methods/HMSTranscriptionAction.kt | 60 ++++++++ .../example/ExampleAppChangelog.txt | 9 +- .../example/android/app/build.gradle | 4 +- packages/hmssdk_flutter/example/ios/Gemfile | 2 +- .../hmssdk_flutter/example/ios/Gemfile.lock | 28 ++-- .../hmssdk_flutter/example/ios/Podfile.lock | 4 +- .../example/ios/Runner/Info.plist | 4 +- .../example/lib/qr_code_screen.dart | 111 +++++++-------- .../Actions/HMSTranscriptionAction.swift | 47 +++++++ .../Models/HMSPermissionExtension.swift | 27 +++- .../ios/Classes/Models/HMSRoomExtension.swift | 4 + .../Models/HMSTranscriptExtension.swift | 82 +++++++++++ .../Classes/SwiftHmssdkFlutterPlugin.swift | 62 +++++++- .../hmssdk_flutter/lib/hmssdk_flutter.dart | 6 + .../lib/src/common/platform_methods.dart | 26 +++- .../lib/src/enum/hms_room_update.dart | 9 ++ .../hms_transcription_listener_method.dart | 15 ++ .../lib/src/enum/hms_transcription_mode.dart | 16 +++ .../lib/src/enum/hms_transcription_state.dart | 20 +++ .../lib/src/model/hms_permissions.dart | 11 +- .../lib/src/model/hms_room.dart | 17 ++- .../src/model/platform_method_response.dart | 9 ++ .../lib/src/model/transcription.dart | 72 ++++++++++ .../hms_transcript_listener.dart | 10 ++ .../transcription/hms_transcription.dart | 35 +++++ .../hms_transcription_controller.dart | 63 +++++++++ .../hms_transcription_permission.dart | 21 +++ .../lib/src/service/platform_service.dart | 36 +++++ 43 files changed, 1533 insertions(+), 109 deletions(-) create mode 100644 packages/hms_room_kit/lib/src/assets/icons/cc-filled.svg create mode 100644 packages/hms_room_kit/lib/src/assets/icons/cc.svg create mode 100644 packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_bottom_sheet.dart create mode 100644 packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_control_bottom_sheet.dart create mode 100644 packages/hms_room_kit/lib/src/widgets/common_widgets/transcription_view.dart create mode 100644 packages/hms_room_kit/lib/src/widgets/toasts/hms_transcription_toast.dart create mode 100644 packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSTranscriptExtension.kt create mode 100644 packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSTranscriptionAction.kt create mode 100644 packages/hmssdk_flutter/ios/Classes/Actions/HMSTranscriptionAction.swift create mode 100644 packages/hmssdk_flutter/ios/Classes/Models/HMSTranscriptExtension.swift create mode 100644 packages/hmssdk_flutter/lib/src/enum/hms_transcription_listener_method.dart create mode 100644 packages/hmssdk_flutter/lib/src/enum/hms_transcription_mode.dart create mode 100644 packages/hmssdk_flutter/lib/src/enum/hms_transcription_state.dart create mode 100644 packages/hmssdk_flutter/lib/src/model/transcription.dart create mode 100644 packages/hmssdk_flutter/lib/src/model/transcription/hms_transcript_listener.dart create mode 100644 packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription.dart create mode 100644 packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription_controller.dart create mode 100644 packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription_permission.dart diff --git a/packages/hms_room_kit/lib/src/assets/icons/cc-filled.svg b/packages/hms_room_kit/lib/src/assets/icons/cc-filled.svg new file mode 100644 index 000000000..3e3dd9464 --- /dev/null +++ b/packages/hms_room_kit/lib/src/assets/icons/cc-filled.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/hms_room_kit/lib/src/assets/icons/cc.svg b/packages/hms_room_kit/lib/src/assets/icons/cc.svg new file mode 100644 index 000000000..cf20fa13f --- /dev/null +++ b/packages/hms_room_kit/lib/src/assets/icons/cc.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/hms_room_kit/lib/src/meeting/meeting_page.dart b/packages/hms_room_kit/lib/src/meeting/meeting_page.dart index 3a422284a..3d5dfc85b 100644 --- a/packages/hms_room_kit/lib/src/meeting/meeting_page.dart +++ b/packages/hms_room_kit/lib/src/meeting/meeting_page.dart @@ -26,6 +26,7 @@ import 'package:hms_room_kit/src/preview_for_role/preview_for_role_bottom_sheet. import 'package:hms_room_kit/src/preview_for_role/preview_for_role_header.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/hms_circular_avatar.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/hms_left_room_screen.dart'; +import 'package:hms_room_kit/src/widgets/common_widgets/transcription_view.dart'; ///[MeetingPage] is the main page of the meeting ///It takes the following parameters: @@ -152,6 +153,10 @@ class _MeetingPageState extends State { ], ), + ChangeNotifierProvider.value( + value: _visibilityController, + child: const TranscriptionView()), + ///This gets rendered when the previewForRole method is called ///This is used to show the preview for role component Selector< diff --git a/packages/hms_room_kit/lib/src/meeting/meeting_store.dart b/packages/hms_room_kit/lib/src/meeting/meeting_store.dart index 64fa171d2..adcf9a6eb 100644 --- a/packages/hms_room_kit/lib/src/meeting/meeting_store.dart +++ b/packages/hms_room_kit/lib/src/meeting/meeting_store.dart @@ -1,6 +1,7 @@ ///Dart imports library; +import 'dart:async'; import 'dart:convert'; import 'dart:developer'; import 'dart:io'; @@ -38,7 +39,8 @@ class MeetingStore extends ChangeNotifier HMSKeyChangeListener, HMSHLSPlaybackEventsListener, HMSPollListener, - HMSWhiteboardUpdateListener { + HMSWhiteboardUpdateListener, + HMSTranscriptListener { late HMSSDKInteractor _hmsSDKInteractor; MeetingStore({required HMSSDKInteractor hmsSDKInteractor}) { @@ -276,6 +278,13 @@ class MeetingStore extends ChangeNotifier ///variable to store whiteboard model HMSWhiteboardModel? whiteboardModel; + ///variable to store whether transcription is enabled or not + bool isTranscriptionEnabled = false; + + bool isTranscriptionDisplayed = false; + + List captions = []; + Future join(String userName, String? tokenData) async { late HMSConfig joinConfig; @@ -475,6 +484,9 @@ class MeetingStore extends ChangeNotifier case HMSToastsType.streamingErrorToast: toasts.removeWhere( (toast) => toast.hmsToastType == HMSToastsType.streamingErrorToast); + case HMSToastsType.transcriptionToast: + toasts.removeWhere( + (toast) => toast.hmsToastType == HMSToastsType.transcriptionToast); } notifyListeners(); } @@ -824,6 +836,40 @@ class MeetingStore extends ChangeNotifier notifyListeners(); } + ///This method is used to toggle the transcription + ///for the peer who has admin permissions + void toggleTranscription() async { + HMSException? result; + toasts.add(HMSToastModel( + isTranscriptionEnabled + ? "Disabling Closed Captioning for everyone" + : "Enabling Closed Captioning for everyone", + hmsToastType: HMSToastsType.transcriptionToast)); + if (isTranscriptionEnabled) { + result = await HMSTranscriptionController.stopTranscription(); + } else { + result = await HMSTranscriptionController.startTranscription(); + } + if (result == null) { + isTranscriptionEnabled = !isTranscriptionEnabled; + toggleTranscriptionDisplay(); + } else { + removeToast(HMSToastsType.transcriptionToast); + toasts.add(HMSToastModel(result, hmsToastType: HMSToastsType.errorToast)); + } + notifyListeners(); + } + + void toggleTranscriptionDisplay() { + isTranscriptionDisplayed = !isTranscriptionDisplayed; + if (isTranscriptionDisplayed) { + HMSTranscriptionController.addListener(listener: this); + } else { + HMSTranscriptionController.removeListener(); + } + notifyListeners(); + } + // Override Methods @override @@ -850,6 +896,16 @@ class MeetingStore extends ChangeNotifier streamingType["hls"] = room.hmshlsStreamingState?.state ?? HMSStreamingState.none; + int index = room.transcriptions?.indexWhere( + (element) => element.mode == HMSTranscriptionMode.caption) ?? + -1; + + if (index != -1) { + room.transcriptions?[index].state == HMSTranscriptionState.started + ? isTranscriptionEnabled = true + : isTranscriptionEnabled = false; + } + checkNoiseCancellationAvailability(); setParticipantsList(roles); toggleAlwaysScreenOn(); @@ -906,6 +962,7 @@ class MeetingStore extends ChangeNotifier notifyListeners(); fetchPollList(HMSPollState.stopped); HMSWhiteboardController.addHMSWhiteboardUpdateListener(listener: this); + HMSTranscriptionController.addListener(listener: this); if (HMSRoomLayout.roleLayoutData?.screens?.preview?.joinForm?.joinBtnType == JoinButtonType.JOIN_BTN_TYPE_JOIN_AND_GO_LIVE && @@ -1000,6 +1057,28 @@ class MeetingStore extends ChangeNotifier ? room.hmshlsStreamingState?.variants[0]?.hlsStreamUrl : null; break; + case HMSRoomUpdate.transcriptionsUpdated: + if (room.transcriptions?.isNotEmpty ?? false) { + int index = room.transcriptions?.indexWhere( + (element) => element.mode == HMSTranscriptionMode.caption) ?? + -1; + + if (index != -1) { + if (room.transcriptions?[index].state == + HMSTranscriptionState.started || + room.transcriptions?[index].state == + HMSTranscriptionState.stopped) { + removeToast(HMSToastsType.transcriptionToast); + } + if (room.transcriptions?[index].state == + HMSTranscriptionState.started) { + isTranscriptionEnabled = true; + } else { + isTranscriptionEnabled = false; + } + } + } + break; default: break; } @@ -1406,6 +1485,7 @@ class MeetingStore extends ChangeNotifier HMSHLSPlayerController.removeHMSHLSPlaybackEventsListener(this); HMSPollInteractivityCenter.removePollUpdateListener(); HMSWhiteboardController.removeHMSWhiteboardUpdateListener(); + HMSTranscriptionController.removeListener(); } ///Function to toggle screen share @@ -2676,6 +2756,29 @@ class MeetingStore extends ChangeNotifier notifyListeners(); } + bool areCaptionsEmpty = true; + Timer? transcriptionTimerObj; + + @override + void onTranscripts({required List transcriptions}) { + areCaptionsEmpty = false; + captions = transcriptions; + startTranscriptionHideTimer(); + transcriptions.forEach((element) { + log("onTranscripts -> text: ${element.transcript}"); + }); + notifyListeners(); + } + + void startTranscriptionHideTimer() { + transcriptionTimerObj?.cancel(); + transcriptionTimerObj = Timer(Duration(seconds: 4), () { + areCaptionsEmpty = true; + captions = []; + notifyListeners(); + }); + } + //Get onSuccess or onException callbacks for HMSActionResultListenerMethod @override void onSuccess( diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart index 5177fe126..ab5b3abcd 100644 --- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart +++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart @@ -4,6 +4,8 @@ library; import 'package:badges/badges.dart' as badge; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:hms_room_kit/src/widgets/bottom_sheets/closed_caption_bottom_sheet.dart'; +import 'package:hms_room_kit/src/widgets/bottom_sheets/closed_caption_control_bottom_sheet.dart'; import 'package:hmssdk_flutter/hmssdk_flutter.dart'; import 'package:provider/provider.dart'; @@ -42,7 +44,7 @@ class _AppUtilitiesBottomSheetState extends State { super.deactivate(); } - Color geWhiteboardStatusColor(MeetingStore meetingStore) { + Color getWhiteboardStatusColor(MeetingStore meetingStore) { ///If whiteboard is enabled and the local peer is the owner of the whiteboard ///we return high emphasis color since the local peer can close the whiteboard ///else we return low emphasis color since local peer can't close the whiteboard @@ -59,6 +61,15 @@ class _AppUtilitiesBottomSheetState extends State { : HMSThemeColors.onSurfaceHighEmphasis; } + bool getTranscriptionPermission(MeetingStore meetingStore) { + int? index = meetingStore.localPeer?.role.permissions.transcription + ?.indexWhere((element) => element.mode == HMSTranscriptionMode.caption); + if (index == null || index == -1) { + return false; + } + return meetingStore.localPeer!.role.permissions.transcription![index].admin; + } + @override Widget build(BuildContext context) { MeetingStore meetingStore = context.read(); @@ -414,14 +425,90 @@ class _AppUtilitiesBottomSheetState extends State { height: 20, width: 20, colorFilter: ColorFilter.mode( - geWhiteboardStatusColor(meetingStore), + getWhiteboardStatusColor(meetingStore), BlendMode.srcIn), ), - optionTextColor: geWhiteboardStatusColor(meetingStore), + optionTextColor: getWhiteboardStatusColor(meetingStore), optionText: meetingStore.isWhiteboardEnabled ? "Close Whiteboard" : "Open Whiteboard"), + ///This renders the closed captions option + ///This option is only rendered if the local peer has the permission to + ///enable/disable transcription(will see the popup to enable caption) + ///else the local peer can only see the option to Show/Hide captions + if (getTranscriptionPermission(meetingStore) || + meetingStore.isTranscriptionEnabled) + MoreOptionItem( + onTap: () async { + Navigator.pop(context); + + ///If the local peer has the permission to enable/disable transcription + ///we show the popup to enable/disable transcription + ///else we call the method to show/hide captions + (getTranscriptionPermission(meetingStore)) + ? showModalBottomSheet( + isScrollControlled: true, + backgroundColor: HMSThemeColors.surfaceDim, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16)), + ), + context: context, + builder: (ctx) => ChangeNotifierProvider.value( + value: meetingStore, + child: meetingStore.isTranscriptionEnabled + ? ClosedCaptionControlBottomSheet( + meetingStore: meetingStore, + ) + : ClosedCaptionBottomSheet( + onButtonPressed: () => meetingStore + .toggleTranscription(), + title: HMSTitleText( + text: + "Enable Closed Captions (CC) for this session?", + maxLines: 5, + textColor: HMSThemeColors + .onSecondaryHighEmphasis, + letterSpacing: 0.15, + fontSize: 20, + ), + subTitle: HMSSubheadingText( + text: + "This will enable Closed Captions for everyone in this room. You can disable it later.", + maxLines: 2, + textColor: HMSThemeColors + .onSurfaceMediumEmphasis, + ), + buttonText: "Enable for Everyone", + ), + ), + ) + : meetingStore.toggleTranscriptionDisplay(); + }, + + ///The button is active if the transcription is enabled and getting displayed + isActive: meetingStore.isTranscriptionDisplayed, + optionIcon: SvgPicture.asset( + "packages/hms_room_kit/lib/src/assets/icons/${meetingStore.isTranscriptionDisplayed ? "cc-filled" : "cc"}.svg", + height: 20, + width: 20, + colorFilter: ColorFilter.mode( + HMSThemeColors.onSurfaceHighEmphasis, + BlendMode.srcIn), + ), + optionTextColor: HMSThemeColors.onSurfaceHighEmphasis, + + ///If the local peer has the permission to enable/disable transcription + ///we show the option to enable/disable transcription + ///else we show the option to show/hide captions + optionText: getTranscriptionPermission(meetingStore) + ? "Closed Captions" + : meetingStore.isTranscriptionDisplayed + ? "Hide Captions" + : "Show Captions"), + ///Virtual background is not supported out of the box in prebuilt as of now // if (AppDebugConfig.isVirtualBackgroundEnabled && // (meetingStore.localPeer?.role.publishSettings?.allowed diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_bottom_sheet.dart new file mode 100644 index 000000000..7a5fc033d --- /dev/null +++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_bottom_sheet.dart @@ -0,0 +1,128 @@ +///Package imports +library; + +import 'package:flutter/material.dart'; + +///Project imports +import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart'; +import 'package:hms_room_kit/src/meeting/meeting_store.dart'; +import 'package:hms_room_kit/src/widgets/common_widgets/hms_cross_button.dart'; +import 'package:hms_room_kit/src/widgets/common_widgets/hms_title_text.dart'; +import 'package:provider/provider.dart'; + +///[EndServiceBottomSheet] is a bottom sheet that is used to render the bottom sheet to stop services +///It has following parameters: +///[bottomSheetTitleIcon] is the icon that is shown on the top left of the bottom sheet +/// [title] is the title of the bottom sheet +/// [subTitle] is the subtitle of the bottom sheet +/// [buttonText] is the text of the button +/// [onButtonPressed] is the function that is called when the button is pressed +/// [buttonColor] is the color of the button +class ClosedCaptionBottomSheet extends StatefulWidget { + final Widget? bottomSheetTitleIcon; + final Widget? title; + final Widget? subTitle; + final String? buttonText; + final Function? onButtonPressed; + final Color? buttonColor; + + const ClosedCaptionBottomSheet( + {super.key, + this.bottomSheetTitleIcon, + this.title, + this.subTitle, + this.buttonText, + this.onButtonPressed, + this.buttonColor}); + + @override + State createState() => + _ClosedCaptionBottomSheetState(); +} + +class _ClosedCaptionBottomSheetState extends State { + @override + void initState() { + super.initState(); + context.read().addBottomSheet(context); + } + + @override + void deactivate() { + context.read().removeBottomSheet(context); + super.deactivate(); + } + + @override + Widget build(BuildContext context) { + return FractionallySizedBox( + heightFactor: MediaQuery.of(context).orientation == Orientation.portrait + ? 0.30 + : 0.45, + child: Padding( + padding: const EdgeInsets.only(top: 16.0, left: 20, right: 20), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + widget.bottomSheetTitleIcon ?? const SizedBox(), + widget.bottomSheetTitleIcon ?? + const SizedBox( + width: 8, + ), + SizedBox( + width: MediaQuery.of(context).size.width - 100, + child: widget.title ?? const SizedBox()) + ], + ), + const Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + HMSCrossButton(), + ], + ) + ], + ), + const SizedBox( + height: 16, + ), + ElevatedButton( + style: ButtonStyle( + shadowColor: + MaterialStateProperty.all(HMSThemeColors.surfaceDim), + backgroundColor: MaterialStateProperty.all( + widget.buttonColor ?? HMSThemeColors.primaryDefault), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ))), + onPressed: () { + if (widget.onButtonPressed != null) { + widget.onButtonPressed!(); + } + Navigator.pop(context); + }, + child: SizedBox( + height: 48, + child: Center( + child: HMSTitleText( + text: widget.buttonText ?? "", + textColor: HMSThemeColors.onSurfaceHighEmphasis), + ), + )), + const SizedBox( + height: 16, + ), + widget.subTitle ?? const SizedBox(), + ], + ), + ), + ), + ); + } +} diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_control_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_control_bottom_sheet.dart new file mode 100644 index 000000000..c589f36db --- /dev/null +++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_control_bottom_sheet.dart @@ -0,0 +1,132 @@ +import 'package:flutter/material.dart'; +import 'package:hms_room_kit/hms_room_kit.dart'; +import 'package:hms_room_kit/src/meeting/meeting_store.dart'; +import 'package:hms_room_kit/src/widgets/common_widgets/hms_cross_button.dart'; +import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart'; +import 'package:provider/provider.dart'; + +class ClosedCaptionControlBottomSheet extends StatefulWidget { + final MeetingStore meetingStore; + + const ClosedCaptionControlBottomSheet( + {super.key, required this.meetingStore}); + + @override + State createState() => + _ClosedCaptionControlBottomSheetState(); +} + +class _ClosedCaptionControlBottomSheetState + extends State { + @override + void initState() { + super.initState(); + context.read().addBottomSheet(context); + } + + @override + void deactivate() { + context.read().removeBottomSheet(context); + super.deactivate(); + } + + @override + Widget build(BuildContext context) { + return FractionallySizedBox( + heightFactor: MediaQuery.of(context).orientation == Orientation.portrait + ? 0.37 + : 0.45, + child: Padding( + padding: const EdgeInsets.only(top: 16.0, left: 20, right: 20), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + HMSTitleText( + text: "Closed Captions (CC)", + textColor: HMSThemeColors.onSecondaryHighEmphasis, + letterSpacing: 0.15, + fontSize: 20, + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + const HMSCrossButton(), + ], + ) + ], + ), + const SizedBox( + height: 16, + ), + ElevatedButton( + style: ButtonStyle( + shadowColor: + MaterialStateProperty.all(HMSThemeColors.surfaceDim), + backgroundColor: MaterialStateProperty.all( + HMSThemeColors.secondaryDefault), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ))), + onPressed: () { + widget.meetingStore.toggleTranscriptionDisplay(); + Navigator.pop(context); + }, + child: SizedBox( + height: 48, + child: Center( + child: HMSTitleText( + text: + "${widget.meetingStore.isTranscriptionDisplayed ? "Hide" : "Show"} for Me", + textColor: HMSThemeColors.onSecondaryHighEmphasis), + ), + )), + const SizedBox( + height: 16, + ), + ElevatedButton( + style: ButtonStyle( + shadowColor: + MaterialStateProperty.all(HMSThemeColors.surfaceDim), + backgroundColor: MaterialStateProperty.all( + HMSThemeColors.alertErrorDefault), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ))), + onPressed: () { + widget.meetingStore.toggleTranscription(); + Navigator.pop(context); + }, + child: SizedBox( + height: 48, + child: Center( + child: HMSTitleText( + text: "Disable For Everyone", + textColor: HMSThemeColors.alertErrorBrighter), + ), + )), + const SizedBox( + height: 16, + ), + HMSSubheadingText( + text: + "This will disable Closed Captions for everyone in this room. You can enable it again.", + maxLines: 2, + textColor: HMSThemeColors.onSurfaceMediumEmphasis, + ), + ], + ), + ), + ), + ); + } +} diff --git a/packages/hms_room_kit/lib/src/widgets/common_widgets/transcription_view.dart b/packages/hms_room_kit/lib/src/widgets/common_widgets/transcription_view.dart new file mode 100644 index 000000000..5d3662e55 --- /dev/null +++ b/packages/hms_room_kit/lib/src/widgets/common_widgets/transcription_view.dart @@ -0,0 +1,106 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:hms_room_kit/hms_room_kit.dart'; +import 'package:hms_room_kit/src/meeting/meeting_navigation_visibility_controller.dart'; +import 'package:hms_room_kit/src/meeting/meeting_store.dart'; +import 'package:hmssdk_flutter/hmssdk_flutter.dart'; +import 'package:provider/provider.dart'; +import 'package:tuple/tuple.dart'; + +class TranscriptionView extends StatefulWidget { + const TranscriptionView({Key? key}) : super(key: key); + @override + State createState() => _TranscriptionViewState(); +} + +class _TranscriptionViewState extends State { + @override + Widget build(BuildContext context) { + return Selector( + selector: (_, meetingStore) => meetingStore.isTranscriptionDisplayed, + builder: (_, isTranscriptionDisplayed, __) { + return isTranscriptionDisplayed + ? Selector, int>>( + selector: (_, meetingStore) => Tuple2( + meetingStore.captions, meetingStore.captions.length), + builder: (_, data, __) { + String transcript = ""; + for (var i = 0; i < data.item2; i++) { + transcript += + "${data.item1[i].peerName}: ${data.item1[i].transcript}\n"; + } + return data.item2 > 0 + ? Selector>( + selector: (_, meetingStore) => Tuple2( + meetingStore.isOverlayChatOpened, + meetingStore.toasts.isNotEmpty), + builder: (_, isUIElementPresent, __) { + return Selector< + MeetingNavigationVisibilityController, + bool>( + selector: + (_, meetingNavigationVisibilityController) => + meetingNavigationVisibilityController + .showControls, + builder: (_, showControls, __) { + double bottomMargin = showControls + ? Platform.isIOS + ? 110 + : 90 + : Platform.isIOS + ? 80 + : 50; + + ///If toasts are present then we need to adjust the bottom margin + bottomMargin += isUIElementPresent.item2 + ? showControls + ? 40 + : 80 + : 0; + return Positioned( + ///If overlay chat is opened then we need to adjust the top margin(shift the chat to top) + ///else we keep it at the bottom + bottom: isUIElementPresent.item1 + ? null + : bottomMargin, + top: isUIElementPresent.item1 + ? showControls + ? 80 + : 50 + : null, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Container( + width: MediaQuery.of(context) + .size + .width - + 10, + padding: const EdgeInsets.all(5), + margin: const EdgeInsets.all(2), + decoration: BoxDecoration( + // color: Colors.red, + color: Colors.black + .withAlpha(64), + borderRadius: + const BorderRadius.all( + Radius.circular(10))), + child: HMSSubtitleText( + text: transcript, + maxLines: 5, + textColor: HMSThemeColors + .onSurfaceHighEmphasis)), + ], + ), + ); + }); + }) + : const SizedBox(); + }) + : const SizedBox(); + }); + } +} diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart index d617daace..de30b4679 100644 --- a/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart +++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart @@ -7,5 +7,6 @@ enum HMSToastsType { chatPauseResumeToast, errorToast, pollStartedToast, - streamingErrorToast + streamingErrorToast, + transcriptionToast } diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_transcription_toast.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_transcription_toast.dart new file mode 100644 index 000000000..5ec2c9d7e --- /dev/null +++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_transcription_toast.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:hms_room_kit/hms_room_kit.dart'; +import 'package:hms_room_kit/src/meeting/meeting_store.dart'; +import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart'; +import 'package:hms_room_kit/src/widgets/toasts/hms_toast.dart'; + +class HMSTranscriptionToast extends StatelessWidget { + final String message; + final MeetingStore meetingStore; + const HMSTranscriptionToast( + {Key? key, required this.message, required this.meetingStore}); + + @override + Widget build(BuildContext context) { + return HMSToast( + leading: SizedBox( + height: 18, + width: 18, + child: CircularProgressIndicator( + strokeWidth: 2, + color: HMSThemeColors.onSurfaceHighEmphasis, + ), + ), + subtitle: HMSSubheadingText( + text: message, + textColor: HMSThemeColors.onSurfaceHighEmphasis, + fontWeight: FontWeight.w600, + letterSpacing: 0.1, + textOverflow: TextOverflow.ellipsis, + maxLines: 2, + )); + } +} diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/toast_widget.dart b/packages/hms_room_kit/lib/src/widgets/toasts/toast_widget.dart index 2ae64da65..1b8c6ecb0 100644 --- a/packages/hms_room_kit/lib/src/widgets/toasts/toast_widget.dart +++ b/packages/hms_room_kit/lib/src/widgets/toasts/toast_widget.dart @@ -2,6 +2,9 @@ library; import 'package:flutter/material.dart'; +import 'package:hms_room_kit/src/widgets/toasts/hms_error_toast.dart'; +import 'package:hms_room_kit/src/widgets/toasts/hms_streaming_error_toast.dart'; +import 'package:hmssdk_flutter/hmssdk_flutter.dart'; import 'package:provider/provider.dart'; ///Project imports @@ -16,6 +19,7 @@ import 'package:hms_room_kit/src/widgets/toasts/hms_recording_error_toast.dart'; import 'package:hms_room_kit/src/widgets/toasts/hms_role_change_decline_toast.dart'; import 'package:hms_room_kit/src/widgets/toasts/hms_toast_model.dart'; import 'package:hms_room_kit/src/widgets/toasts/hms_toasts_type.dart'; +import 'package:hms_room_kit/src/widgets/toasts/hms_transcription_toast.dart'; ///[ToastWidget] returns toast based on the toast type class ToastWidget extends StatelessWidget { @@ -74,8 +78,24 @@ class ToastWidget extends StatelessWidget { ), ), ); + case HMSToastsType.transcriptionToast: + return HMSTranscriptionToast( + message: toast.toastData, + meetingStore: meetingStore, + ); + // default: + // return const SizedBox(); + case HMSToastsType.errorToast: + if (toast.toastData is HMSException) { + return HMSErrorToast( + error: toast.toastData, meetingStore: meetingStore); + } + return SizedBox(); + case HMSToastsType.streamingErrorToast: + return HMSStreamingErrorToast( + streamingError: toast.toastData, meetingStore: meetingStore); default: - return const SizedBox(); + return SizedBox(); } } } diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRoomExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRoomExtension.kt index bebd5bd78..93b7b68b7 100644 --- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRoomExtension.kt +++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRoomExtension.kt @@ -1,6 +1,7 @@ package live.hms.hmssdk_flutter import live.hms.video.sdk.models.HMSRoom +import live.hms.video.sdk.models.Transcriptions import live.hms.video.sdk.models.enums.HMSRoomUpdate class HMSRoomExtension { @@ -18,6 +19,7 @@ class HMSRoomExtension { args.add(HMSPeerExtension.toDictionary(it)!!) } + hashMap["transcriptions"] = HMSTranscriptExtension.getMapFromTranscriptionsList(room.transcriptions) hashMap["is_large"] = room.isLargeRoom hashMap["local_peer"] = HMSPeerExtension.toDictionary(room.localPeer) hashMap["peers"] = args @@ -44,6 +46,7 @@ class HMSRoomExtension { HMSRoomUpdate.BROWSER_RECORDING_STATE_UPDATED -> "browser_recording_state_updated" HMSRoomUpdate.HLS_RECORDING_STATE_UPDATED -> "hls_recording_state_updated" HMSRoomUpdate.ROOM_PEER_COUNT_UPDATED -> "room_peer_count_updated" + HMSRoomUpdate.TRANSCRIPTIONS_UPDATED -> "transcriptions_updated" else -> "defaultUpdate" } } diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSTranscriptExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSTranscriptExtension.kt new file mode 100644 index 000000000..f46d0e4db --- /dev/null +++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSTranscriptExtension.kt @@ -0,0 +1,92 @@ +package live.hms.hmssdk_flutter + +import live.hms.video.sdk.models.OnTranscriptionError +import live.hms.video.sdk.models.TranscriptionState +import live.hms.video.sdk.models.Transcriptions +import live.hms.video.sdk.models.TranscriptionsMode +import live.hms.video.sdk.transcripts.HmsTranscript + +class HMSTranscriptExtension { + + companion object{ + + fun toDictionary(hmsTranscript: HmsTranscript):HashMap{ + + val args = HashMap() + + args["start"] = hmsTranscript.start + args["end"] = hmsTranscript.end + args["transcript"] = hmsTranscript.transcript + args["peer_id"] = hmsTranscript.peerId + args["peer_name"] = hmsTranscript.peer?.name + args["is_final"] = hmsTranscript.isFinal + return args + } + + fun getMapFromTranscriptionsList(transcriptions : List): ArrayList>{ + + val transcriptionList = ArrayList>() + + transcriptions.forEach {_transcription -> + transcriptionList.add(getMapFromTranscription(_transcription)) + } + + return transcriptionList + } + + private fun getMapFromTranscription(transcription: Transcriptions): HashMap{ + + val args = HashMap() + + args["error"] = transcriptionErrorExtension(transcription.error) + args["started_at"] = transcription.startedAt + args["stopped_at"] = transcription.stoppedAt + args["updated_at"] = transcription.updatedAt + args["state"] = getStringFromTranscriptionState(transcription.state) + args["mode"] = getStringFromTranscriptionMode(transcription.mode) + + return args + } + + private fun transcriptionErrorExtension(onTranscriptionError: OnTranscriptionError?): HashMap?{ + onTranscriptionError?.let {_transcriptionError -> + + val args = HashMap() + + args["code"] = _transcriptionError.code + args["message"] = _transcriptionError.message + + return args + + }?: run { + return null + } + } + + private fun getStringFromTranscriptionState(transcriptionState: TranscriptionState?): String?{ + return when(transcriptionState){ + TranscriptionState.STARTED -> "started" + TranscriptionState.STOPPED -> "stopped" + TranscriptionState.INITIALIZED -> "initialized" + TranscriptionState.FAILED -> "failed" + else -> null + } + } + + fun getTranscriptionModeFromString(transcriptionMode: String): TranscriptionsMode?{ + return when(transcriptionMode){ + "caption" -> TranscriptionsMode.CAPTION + "live" -> TranscriptionsMode.LIVE + else -> null + } + } + + fun getStringFromTranscriptionMode(transcriptionMode: TranscriptionsMode?): String?{ + return when(transcriptionMode){ + TranscriptionsMode.CAPTION -> "caption" + TranscriptionsMode.LIVE -> "live" + else -> null + } + } + } +} diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt index 73b8f7db8..3d7cb5cdd 100644 --- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt +++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt @@ -45,6 +45,7 @@ import live.hms.video.sdk.models.* import live.hms.video.sdk.models.enums.* import live.hms.video.sdk.models.role.HMSRole import live.hms.video.sdk.models.trackchangerequest.HMSChangeTrackStateRequest +import live.hms.video.sdk.transcripts.HmsTranscripts import live.hms.video.sessionstore.HMSKeyChangeListener import live.hms.video.sessionstore.HmsSessionStore import live.hms.video.signal.init.* @@ -68,6 +69,7 @@ class HmssdkFlutterPlugin : var hlsPlayerChannel: EventChannel? = null private var pollsEventChannel: EventChannel? = null private var whiteboardEventChannel: EventChannel? = null + private var transcriptionEventChannel: EventChannel? = null private var eventSink: EventChannel.EventSink? = null private var previewSink: EventChannel.EventSink? = null private var logsSink: EventChannel.EventSink? = null @@ -76,6 +78,7 @@ class HmssdkFlutterPlugin : var hlsPlayerSink: EventChannel.EventSink? = null private var pollsSink: EventChannel.EventSink? = null private var whiteboardSink: EventChannel.EventSink? = null + private var transcriptionSink : EventChannel.EventSink? = null private lateinit var activity: Activity var hmssdk: HMSSDK? = null private lateinit var hmsVideoFactory: HMSVideoViewFactory @@ -121,6 +124,9 @@ class HmssdkFlutterPlugin : this.whiteboardEventChannel = EventChannel(flutterPluginBinding.binaryMessenger, "whiteboard_event_channel") + this.transcriptionEventChannel = + EventChannel(flutterPluginBinding.binaryMessenger, "transcription_event_channel") + this.meetingEventChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "Meeting event channel not found") this.channel?.setMethodCallHandler(this) ?: Log.e("Channel Error", "Event channel not found") this.previewChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "Preview channel not found") @@ -130,6 +136,7 @@ class HmssdkFlutterPlugin : this.hlsPlayerChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "HLS Player channel not found") this.pollsEventChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "polls events channel not found") this.whiteboardEventChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "whiteboard events channel not found") + this.transcriptionEventChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "transcription event channel not found") this.hmsVideoFactory = HMSVideoViewFactory(this) this.hmsHLSPlayerFactory = HMSHLSPlayerFactory(this) @@ -305,6 +312,10 @@ class HmssdkFlutterPlugin : whiteboardActions(call, result) } + "start_real_time_transcription", "stop_real_time_transcription","add_transcript_listener", "remove_transcript_listener" ->{ + transcriptionActions(call,result) + } + else -> { result.notImplemented() } @@ -500,6 +511,26 @@ class HmssdkFlutterPlugin : } } + private var isTranscriptionListenerAdded = false + private fun transcriptionActions( + call: MethodCall, + result: Result + ){ + when(call.method){ + "add_transcript_listener" -> { + isTranscriptionListenerAdded = true + result.success(null) + } + "remove_transcript_listener" -> { + isTranscriptionListenerAdded = false + result.success(null) + } + else -> hmssdk?.let { + HMSTranscriptionAction.transcriptionAction(call,result,it) + } + } + } + private fun pollActions( call: MethodCall, result: Result, @@ -531,6 +562,7 @@ class HmssdkFlutterPlugin : hlsPlayerChannel?.setStreamHandler(null) ?: Log.e("Channel Error", "HLS Player channel not found") pollsEventChannel?.setStreamHandler(null) ?: Log.e("Channel Error", "polls event channel not found") whiteboardEventChannel?.setStreamHandler(null) ?: Log.e("Channel Error", "whiteboard event channel not found") + transcriptionEventChannel?.setStreamHandler(null)?: Log.e("Channel Error", "transcription event channel not found") eventSink = null previewSink = null rtcSink = null @@ -539,6 +571,7 @@ class HmssdkFlutterPlugin : hlsPlayerSink = null pollsSink = null whiteboardSink = null + transcriptionSink = null hmssdkFlutterPlugin = null hmsBinaryMessenger = null hmsTextureRegistry = null @@ -657,22 +690,21 @@ class HmssdkFlutterPlugin : ) { val nameOfEventSink = (arguments as HashMap)["name"] - if (nameOfEventSink!! == "meeting") { - this.eventSink = events - } else if (nameOfEventSink == "preview") { - this.previewSink = events - } else if (nameOfEventSink == "logs") { - this.logsSink = events - } else if (nameOfEventSink == "rtc_stats") { - this.rtcSink = events - } else if (nameOfEventSink == "session_store") { - this.sessionStoreSink = events - } else if (nameOfEventSink == "hls_player") { - this.hlsPlayerSink = events - } else if (nameOfEventSink == "polls") { - this.pollsSink = events - } else if (nameOfEventSink == "whiteboard") { - this.whiteboardSink = events + nameOfEventSink?.let { eventSink -> + when(eventSink){ + "meeting" -> this.eventSink = events + "preview" -> this.previewSink = events + "logs" -> this.logsSink = events + "rtc_stats" -> this.rtcSink = events + "session_store" -> this.sessionStoreSink = events + "hls_player" -> this.hlsPlayerSink = events + "polls" -> this.pollsSink = events + "whiteboard" -> this.whiteboardSink = events + "transcription" -> this.transcriptionSink = events + else -> Log.e("Event Sink Error", "No sink with given name found") + } + }?:run{ + HMSErrorLogger.logError("onListen", "name of event sink is null", "NULL ERROR") } } @@ -1479,6 +1511,28 @@ class HmssdkFlutterPlugin : eventSink?.success(args) } } + + override fun onTranscripts(transcripts: HmsTranscripts) { + super.onTranscripts(transcripts) + + /** + * If transcription listener is added in the application + * then only we send data from here + */ + if(isTranscriptionListenerAdded){ + val args = HashMap() + args["event_name"] = "on_transcripts" + + val transcriptsList = ArrayList>() + transcripts.transcripts.forEach { _transcript -> + transcriptsList.add(HMSTranscriptExtension.toDictionary(_transcript)) + } + args["data"] = transcriptsList + CoroutineScope(Dispatchers.Main).launch { + transcriptionSink?.success(args) + } + } + } } private val hmsPreviewListener = diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hms_role_components/PermissionParamsExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hms_role_components/PermissionParamsExtension.kt index 5e7b9c8f7..c449bfe89 100644 --- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hms_role_components/PermissionParamsExtension.kt +++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hms_role_components/PermissionParamsExtension.kt @@ -1,5 +1,7 @@ package live.hms.hmssdk_flutter.hms_role_components +import live.hms.hmssdk_flutter.HMSTranscriptExtension +import live.hms.video.sdk.models.role.HMSTranscriptionPermissions import live.hms.video.sdk.models.role.HMSWhiteBoardPermission import live.hms.video.sdk.models.role.PermissionsParams @@ -21,6 +23,7 @@ class PermissionParamsExtension { permissionsParams.whiteboard.let { args["whiteboard_permission"] = getMapFromHMSWhiteboardPermission(it) } + args["transcription_permission"] = getMapFromHMSTranscriptionPermissionsList(permissionsParams.transcriptions) return args } @@ -33,5 +36,18 @@ class PermissionParamsExtension { return permission } + + private fun getMapFromHMSTranscriptionPermissionsList(hmsTranscriptionPermission: List): ArrayList>{ + val transcriptionPermissionList = ArrayList>() + + hmsTranscriptionPermission.forEach {transcriptionPermission -> + val transcriptionPermissionMap = HashMap() + transcriptionPermissionMap["mode"] = HMSTranscriptExtension.getStringFromTranscriptionMode(transcriptionPermission.mode) + transcriptionPermissionMap["admin"] = transcriptionPermission.admin + + transcriptionPermissionList.add(transcriptionPermissionMap) + } + return transcriptionPermissionList + } } } diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSTranscriptionAction.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSTranscriptionAction.kt new file mode 100644 index 000000000..cf6f48a84 --- /dev/null +++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSTranscriptionAction.kt @@ -0,0 +1,60 @@ +package live.hms.hmssdk_flutter.methods + +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import live.hms.hmssdk_flutter.HMSCommonAction +import live.hms.hmssdk_flutter.HMSErrorLogger +import live.hms.hmssdk_flutter.HMSTranscriptExtension +import live.hms.video.sdk.HMSSDK + +class HMSTranscriptionAction { + + companion object{ + + fun transcriptionAction(call: MethodCall, + result: MethodChannel.Result, + hmssdk: HMSSDK?){ + when(call.method){ + "start_real_time_transcription" -> { + startRealTimeTranscription(call,result,hmssdk) + } + "stop_real_time_transcription" -> { + stopRealTimeTranscription(call,result,hmssdk) + } + } + } + + /** + * [startRealTimeTranscription] starts the transcription for everyone in the room + */ + private fun startRealTimeTranscription(call: MethodCall, result: MethodChannel.Result, hmssdk: HMSSDK?){ + + val mode = call.argument("mode") as? String + + mode?.let { _mode -> + val transcriptionMode = HMSTranscriptExtension.getTranscriptionModeFromString(_mode) + transcriptionMode?.let { + hmssdk?.startRealTimeTranscription(it, HMSCommonAction.getActionListener(result)) + }?:run{ + HMSErrorLogger.logError("startRealTimeTranscription","Mode is null","NULL Error") + } + } + } + + /** + * [stopRealTimeTranscription] starts the transcription for everyone in the room + */ + private fun stopRealTimeTranscription(call: MethodCall, result: MethodChannel.Result, hmssdk: HMSSDK?){ + val mode = call.argument("mode") as? String + + mode?.let { _mode -> + val transcriptionMode = HMSTranscriptExtension.getTranscriptionModeFromString(_mode) + transcriptionMode?.let { + hmssdk?.stopRealTimeTranscription(it, HMSCommonAction.getActionListener(result)) + }?:run{ + HMSErrorLogger.returnArgumentsError("mode is a required parameter cannot be null") + } + } + } + } +} \ No newline at end of file diff --git a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt index 8414247b2..ab9d42beb 100644 --- a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt +++ b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt @@ -1,7 +1,10 @@ -Board: https://100ms.atlassian.net/jira/software/projects/FLUT/boards/34/ +Board: https://app.devrev.ai/100ms/vistas/vista-250 -- Move all the permissions from app to sdk -https://100ms.atlassian.net/browse/FLUT-253 +- Move all the permissions from app to SDK +https://app.devrev.ai/100ms/works/ISS-10106 + +- Live transcription in WebRTC mode +https://app.devrev.ai/100ms/works/ISS-22680 Room Kit: 1.1.4 Core SDK: 1.10.4 diff --git a/packages/hmssdk_flutter/example/android/app/build.gradle b/packages/hmssdk_flutter/example/android/app/build.gradle index 53e241146..acaeb6de6 100644 --- a/packages/hmssdk_flutter/example/android/app/build.gradle +++ b/packages/hmssdk_flutter/example/android/app/build.gradle @@ -36,8 +36,8 @@ android { applicationId "live.hms.flutter" minSdkVersion 21 targetSdkVersion 34 - versionCode 503 - versionName "1.5.203" + versionCode 507 + versionName "1.5.207" } signingConfigs { diff --git a/packages/hmssdk_flutter/example/ios/Gemfile b/packages/hmssdk_flutter/example/ios/Gemfile index a24614677..3e0c66695 100644 --- a/packages/hmssdk_flutter/example/ios/Gemfile +++ b/packages/hmssdk_flutter/example/ios/Gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org" -gem "fastlane", "~> 2.220.0" +gem "fastlane", "~> 2.221.0" gem "activesupport", "= 7.0.8" plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') diff --git a/packages/hmssdk_flutter/example/ios/Gemfile.lock b/packages/hmssdk_flutter/example/ios/Gemfile.lock index bac543212..09a15366e 100644 --- a/packages/hmssdk_flutter/example/ios/Gemfile.lock +++ b/packages/hmssdk_flutter/example/ios/Gemfile.lock @@ -15,17 +15,17 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.929.0) - aws-sdk-core (3.196.1) + aws-partitions (1.944.0) + aws-sdk-core (3.197.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.81.0) - aws-sdk-core (~> 3, >= 3.193.0) + aws-sdk-kms (1.85.0) + aws-sdk-core (~> 3, >= 3.197.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.151.0) - aws-sdk-core (~> 3, >= 3.194.0) + aws-sdk-s3 (1.152.3) + aws-sdk-core (~> 3, >= 3.197.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) aws-sigv4 (1.8.0) @@ -74,7 +74,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.3.1) - fastlane (2.220.0) + fastlane (2.221.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -161,16 +161,16 @@ GEM os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.0.5) + http-cookie (1.0.6) domain_name (~> 0.5) httpclient (2.8.3) i18n (1.14.5) concurrent-ruby (~> 1.0) jmespath (1.6.2) json (2.7.2) - jwt (2.8.1) + jwt (2.8.2) base64 - mini_magick (4.12.0) + mini_magick (4.13.1) mini_mime (1.1.5) minitest (5.22.3) multi_json (1.15.0) @@ -181,14 +181,15 @@ GEM optparse (0.5.0) os (1.1.4) plist (3.7.1) - public_suffix (5.0.5) + public_suffix (5.1.1) rake (13.2.1) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) retriable (3.1.2) - rexml (3.2.6) + rexml (3.2.9) + strscan rouge (2.0.7) ruby2_keywords (0.0.5) rubyzip (2.3.2) @@ -201,6 +202,7 @@ GEM simctl (1.6.10) CFPropertyList naturally + strscan (3.1.0) terminal-notifier (2.0.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) @@ -231,7 +233,7 @@ PLATFORMS DEPENDENCIES activesupport (= 7.0.8) - fastlane (~> 2.220.0) + fastlane (~> 2.221.0) fastlane-plugin-firebase_app_distribution fastlane-plugin-versioning diff --git a/packages/hmssdk_flutter/example/ios/Podfile.lock b/packages/hmssdk_flutter/example/ios/Podfile.lock index e0ed2d933..1bdbf7f5f 100644 --- a/packages/hmssdk_flutter/example/ios/Podfile.lock +++ b/packages/hmssdk_flutter/example/ios/Podfile.lock @@ -133,7 +133,7 @@ PODS: - HMSSDK (1.12.0): - HMSAnalyticsSDK (= 0.0.2) - HMSWebRTC (= 1.0.6169) - - hmssdk_flutter (1.10.3): + - hmssdk_flutter (1.10.4): - Flutter - HMSBroadcastExtensionSDK (= 0.0.9) - HMSHLSPlayerSDK (= 0.0.2) @@ -316,7 +316,7 @@ SPEC CHECKSUMS: HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3 HMSNoiseCancellationModels: a3bda1405a16015632f4bcabd46ce48f35103b02 HMSSDK: 137107663eedc276c22639b2ec941c1f14f75d23 - hmssdk_flutter: cb46ccd6b59efc2f0b9ab9548b7addc95b3002ac + hmssdk_flutter: 869c38a41e8fae0bf78d47740beb7889b4b5837a HMSWebRTC: 8f51ba33a0e505e17ebf3d7b37bcdca266751a13 image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425 MLImage: 7bb7c4264164ade9bf64f679b40fb29c8f33ee9b diff --git a/packages/hmssdk_flutter/example/ios/Runner/Info.plist b/packages/hmssdk_flutter/example/ios/Runner/Info.plist index 15a6a21d9..954370388 100644 --- a/packages/hmssdk_flutter/example/ios/Runner/Info.plist +++ b/packages/hmssdk_flutter/example/ios/Runner/Info.plist @@ -21,7 +21,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.5.203 + 1.5.207 CFBundleSignature ???? CFBundleURLTypes @@ -48,7 +48,7 @@ CFBundleVersion - 503 + 507 ITSAppUsesNonExemptEncryption LSApplicationCategoryType diff --git a/packages/hmssdk_flutter/example/lib/qr_code_screen.dart b/packages/hmssdk_flutter/example/lib/qr_code_screen.dart index 6d4c04bba..165bc8338 100644 --- a/packages/hmssdk_flutter/example/lib/qr_code_screen.dart +++ b/packages/hmssdk_flutter/example/lib/qr_code_screen.dart @@ -37,63 +37,64 @@ class _QRCodeScreenState extends State { if (barcodes.isNotEmpty) { log(barcodes[0].rawValue ?? ""); String? rawValue = barcodes[0].rawValue; - if (rawValue != null) { - FocusManager.instance.primaryFocus?.unfocus(); - - Map? endPoints; - if (rawValue.trim().contains("app.100ms.live")) { - List? roomData = RoomService.getCode(rawValue.trim()); - - //If the link is not valid then we might not get the code and whether the link is a - //PROD or QA so we return the error in this case - if (roomData == null || roomData.isEmpty) { - return; - } - - ///************************************************************************************************** */ - - ///This section can be safely commented out as it's only required for 100ms internal usage - - //qaTokenEndPoint is only required for 100ms internal testing - //It can be removed and should not affect the join method call - //For _endPoint just pass it as null - //the endPoint parameter in getAuthTokenByRoomCode can be passed as null - //Pass the layoutAPIEndPoint as null the qa endPoint is only for 100ms internal testing - - ///If you wish to set your own token end point then you can pass it in the endPoints map - ///The key for the token end point is "tokenEndPointKey" - ///The key for the init end point is "initEndPointKey" - ///The key for the layout api end point is "layoutAPIEndPointKey" - if (roomData[1] == "false") { - endPoints = RoomService.setEndPoints(); - } - - ///************************************************************************************************** */ - - Constant.roomCode = roomData[0] ?? ''; - } else { - Constant.roomCode = rawValue.trim(); + FocusManager.instance.primaryFocus?.unfocus(); + + if (rawValue == null) { + return; + } + Map? endPoints; + if (rawValue.trim().contains("app.100ms.live")) { + List? roomData = RoomService.getCode(rawValue.trim()); + + //If the link is not valid then we might not get the code and whether the link is a + //PROD or QA so we return the error in this case + if (roomData == null || roomData.isEmpty) { + return; } - Utilities.saveStringData(key: "meetingLink", value: rawValue.trim()); - await initForegroundTask(); - Navigator.of(context).pushReplacement(MaterialPageRoute( - builder: (_) => WithForegroundTask( - child: HMSPrebuilt( - roomCode: Constant.roomCode, - onLeave: stopForegroundTask, - options: HMSPrebuiltOptions( - userName: AppDebugConfig.nameChangeOnPreview - ? null - : "Flutter User", - userId: widget.uuidString, - endPoints: endPoints, - iOSScreenshareConfig: HMSIOSScreenshareConfig( - appGroup: "group.flutterhms", - preferredExtension: - "live.100ms.flutter.FlutterBroadcastUploadExtension"), - enableNoiseCancellation: true)), - ))); + + ///************************************************************************************************** */ + + ///This section can be safely commented out as it's only required for 100ms internal usage + + //qaTokenEndPoint is only required for 100ms internal testing + //It can be removed and should not affect the join method call + //For _endPoint just pass it as null + //the endPoint parameter in getAuthTokenByRoomCode can be passed as null + //Pass the layoutAPIEndPoint as null the qa endPoint is only for 100ms internal testing + + ///If you wish to set your own token end point then you can pass it in the endPoints map + ///The key for the token end point is "tokenEndPointKey" + ///The key for the init end point is "initEndPointKey" + ///The key for the layout api end point is "layoutAPIEndPointKey" + if (roomData[1] == "false") { + endPoints = RoomService.setEndPoints(); + } + + ///************************************************************************************************** */ + + Constant.roomCode = roomData[0] ?? ''; + } else { + Constant.roomCode = rawValue.trim(); } + Utilities.saveStringData(key: "meetingLink", value: rawValue.trim()); + await initForegroundTask(); + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (_) => WithForegroundTask( + child: HMSPrebuilt( + roomCode: Constant.roomCode, + onLeave: stopForegroundTask, + options: HMSPrebuiltOptions( + userName: AppDebugConfig.nameChangeOnPreview + ? null + : "Flutter User", + userId: widget.uuidString, + endPoints: endPoints, + iOSScreenshareConfig: HMSIOSScreenshareConfig( + appGroup: "group.flutterhms", + preferredExtension: + "live.100ms.flutter.FlutterBroadcastUploadExtension"), + enableNoiseCancellation: true)), + ))); } } catch (e) { log(e.toString()); diff --git a/packages/hmssdk_flutter/ios/Classes/Actions/HMSTranscriptionAction.swift b/packages/hmssdk_flutter/ios/Classes/Actions/HMSTranscriptionAction.swift new file mode 100644 index 000000000..004ca0361 --- /dev/null +++ b/packages/hmssdk_flutter/ios/Classes/Actions/HMSTranscriptionAction.swift @@ -0,0 +1,47 @@ +// +// HMSTranscriptionAction.swift +// hmssdk_flutter +// +// Created by Pushpam on 14/06/24. +// + +import Foundation +import HMSSDK + +class HMSTranscriptionAction{ + + static func transcriptionActions(_ call: FlutterMethodCall, _ result: @escaping FlutterResult, _ hmssdk: HMSSDK?){ + switch call.method{ + case "start_real_time_transcription": + startRealTimeTranscription(result, hmssdk) + case "stop_real_time_transcription": + stopRealTimeTranscription(result, hmssdk) + default: + result(FlutterMethodNotImplemented) + } + } + + private static func startRealTimeTranscription(_ result: @escaping FlutterResult, _ hmssdk: HMSSDK?){ + + hmssdk?.startTranscription(){ _, error in + if let error = error{ + result(HMSErrorExtension.toDictionary(error)) + }else{ + result(nil) + } + } + } + + + private static func stopRealTimeTranscription(_ result: @escaping FlutterResult, _ hmssdk: HMSSDK?){ + hmssdk?.stopTranscription(){_, error in + if let error = error{ + result(HMSErrorExtension.toDictionary(error)) + }else{ + result(nil) + } + } + } + + +} diff --git a/packages/hmssdk_flutter/ios/Classes/Models/HMSPermissionExtension.swift b/packages/hmssdk_flutter/ios/Classes/Models/HMSPermissionExtension.swift index 5c28102b9..009c0a2fe 100644 --- a/packages/hmssdk_flutter/ios/Classes/Models/HMSPermissionExtension.swift +++ b/packages/hmssdk_flutter/ios/Classes/Models/HMSPermissionExtension.swift @@ -22,11 +22,12 @@ class HMSPermissionExtension { "un_mute": permission.unmute ?? false, "poll_read": permission.pollRead ?? false, "poll_write": permission.pollWrite ?? false, - "whiteboard_permission": getMapFromHMSWhiteboardPermission(hmsWhiteboardPermission: permission.whiteboard) + "whiteboard_permission": getMapFromHMSWhiteboardPermission(hmsWhiteboardPermission: permission.whiteboard), + "transcription_permission": getMapFromHMSTranscriptionPermissionList(hmsTranscriptionPermissions: permission.transcriptions) ] } - static func getMapFromHMSWhiteboardPermission(hmsWhiteboardPermission: HMSWhiteboardPermissions?) -> [String: Any?]? { + private static func getMapFromHMSWhiteboardPermission(hmsWhiteboardPermission: HMSWhiteboardPermissions?) -> [String: Any?]? { guard let hmsWhiteboardPermission = hmsWhiteboardPermission else { @@ -41,5 +42,27 @@ class HMSPermissionExtension { return permission } + + private static func getMapFromHMSTranscriptionPermissionList(hmsTranscriptionPermissions: [HMSTranscriptionPermissions]?) -> [[String:Any?]]?{ + + + guard let hmsTranscriptionPermissions = hmsTranscriptionPermissions + else{ + return nil + } + + var transcriptionPermissions = [[String:Any?]]() + + hmsTranscriptionPermissions.forEach{ + var permission = [String:Any?]() + + permission["mode"] = $0.mode + permission["admin"] = $0.admin + transcriptionPermissions.append(permission) + } + + return transcriptionPermissions + } + } diff --git a/packages/hmssdk_flutter/ios/Classes/Models/HMSRoomExtension.swift b/packages/hmssdk_flutter/ios/Classes/Models/HMSRoomExtension.swift index c99622137..0e0a83b41 100644 --- a/packages/hmssdk_flutter/ios/Classes/Models/HMSRoomExtension.swift +++ b/packages/hmssdk_flutter/ios/Classes/Models/HMSRoomExtension.swift @@ -49,6 +49,8 @@ class HMSRoomExtension { dict["hls_recording_state"] = HMSStreamingStateExtension.toDictionary(hlsRecording: room.hlsRecordingState) + dict["transcriptions"] = HMSTranscriptExtension.getMapFromTranscriptionsStateList(transcriptionStates: room.transcriptionStates) + return dict } @@ -68,6 +70,8 @@ class HMSRoomExtension { return "hls_recording_state_updated" case .peerCountUpdated: return "room_peer_count_updated" + case .transcriptionStateUpdated: + return "transcriptions_updated" default: return "unknown_update" } diff --git a/packages/hmssdk_flutter/ios/Classes/Models/HMSTranscriptExtension.swift b/packages/hmssdk_flutter/ios/Classes/Models/HMSTranscriptExtension.swift new file mode 100644 index 000000000..2758ae4b6 --- /dev/null +++ b/packages/hmssdk_flutter/ios/Classes/Models/HMSTranscriptExtension.swift @@ -0,0 +1,82 @@ +// +// HMSTranscriptExtension.swift +// hmssdk_flutter +// +// Created by Pushpam on 14/06/24. +// + +import Foundation +import HMSSDK + +class HMSTranscriptExtension{ + + static func toDictionary(hmsTranscript: HMSTranscript) -> [String:Any?]{ + + var args = [String:Any?]() + + args["start"] = hmsTranscript.start + args["end"] = hmsTranscript.end + args["transcript"] = hmsTranscript.transcript + args["peer_id"] = hmsTranscript.peer.peerID + args["peer_name"] = hmsTranscript.peer.name + args["is_final"] = hmsTranscript.isFinal + + return args + } + + static func getMapFromTranscriptionsStateList(transcriptionStates: [HMSTranscriptionState]?) -> [[String:Any?]]?{ + + if let transcripts = transcriptionStates{ + var transcriptStates = [[String:Any?]]() + + transcripts.forEach{ + transcriptStates.append(getMapFromTranscriptionState(transcriptionState: $0)) + } + return transcriptStates + }else{ + return nil + } + + } + + private static func getMapFromTranscriptionState(transcriptionState: HMSTranscriptionState) -> [String:Any?]{ + + var args = [String:Any?]() + + if let startedAt = transcriptionState.startedAt{ + args["started_at"] = Int(startedAt.timeIntervalSince1970 * 1000) + } + + if let stoppedAt = transcriptionState.stoppedAt{ + args["stopped_at"] = Int(stoppedAt.timeIntervalSince1970 * 1000) + } + + if let updatedAt = transcriptionState.updatedAt{ + args["updated_at"] = Int(updatedAt.timeIntervalSince1970 * 1000) + } + + args["state"] = getStringFromTranscriptionState(transcriptionState: transcriptionState.state) + + args["mode"] = transcriptionState.mode + + return args + } + + private static func getStringFromTranscriptionState(transcriptionState: HMSTranscriptionStatus) -> String?{ + switch transcriptionState{ + case .failed: + return "failed" + case .started: + return "started" + case .stopped: + return "stopped" + case .starting: + return "initialized" + default: + return nil + } + } + + + +} diff --git a/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift b/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift index fd98f14f5..640681cde 100644 --- a/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift +++ b/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift @@ -18,7 +18,8 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene var hlsPlayerChannel: FlutterEventChannel? var pollsEventChannel: FlutterEventChannel? var whiteboardEventChannel: FlutterEventChannel? - + var transcriptionEventChannel: FlutterEventChannel? + var eventSink: FlutterEventSink? var previewSink: FlutterEventSink? var logsSink: FlutterEventSink? @@ -27,6 +28,7 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene var hlsPlayerSink: FlutterEventSink? var pollsEventSink: FlutterEventSink? var whiteboardEventSink: FlutterEventSink? + var transcriptionSink: FlutterEventSink? var roleChangeRequest: HMSRoleChangeRequest? @@ -61,7 +63,8 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene let hlsChannel = FlutterEventChannel(name: "hls_player_channel", binaryMessenger: registrar.messenger()) let pollsChannel = FlutterEventChannel(name: "polls_event_channel", binaryMessenger: registrar.messenger()) let whiteboardChannel = FlutterEventChannel(name: "whiteboard_event_channel", binaryMessenger: registrar.messenger()) - + let transcriptionChannel = FlutterEventChannel(name: "transcription_event_channel", binaryMessenger: registrar.messenger()) + let instance = SwiftHmssdkFlutterPlugin(channel: channel, meetingEventChannel: eventChannel, previewEventChannel: previewChannel, @@ -70,7 +73,8 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene sessionEventChannel: sessionChannel, hlsPlayerChannel: hlsChannel, pollsEventChannel: pollsChannel, - whiteboardEventChannel: whiteboardChannel) + whiteboardEventChannel: whiteboardChannel, + transcriptionEventChannel: transcriptionChannel) let videoViewFactory = HMSFlutterPlatformViewFactory(plugin: instance) registrar.register(videoViewFactory, withId: "HMSFlutterPlatformView") @@ -86,6 +90,7 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene hlsChannel.setStreamHandler(instance) pollsChannel.setStreamHandler(instance) whiteboardChannel.setStreamHandler(instance) + transcriptionChannel.setStreamHandler(instance) registrar.addMethodCallDelegate(instance, channel: channel) } @@ -98,7 +103,8 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene sessionEventChannel: FlutterEventChannel, hlsPlayerChannel: FlutterEventChannel, pollsEventChannel: FlutterEventChannel, - whiteboardEventChannel: FlutterEventChannel) { + whiteboardEventChannel: FlutterEventChannel, + transcriptionEventChannel: FlutterEventChannel) { self.channel = channel self.meetingEventChannel = meetingEventChannel @@ -109,6 +115,7 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene self.hlsPlayerChannel = hlsPlayerChannel self.pollsEventChannel = pollsEventChannel self.whiteboardEventChannel = whiteboardEventChannel + self.transcriptionEventChannel = transcriptionEventChannel } public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { @@ -135,6 +142,8 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene pollsEventSink = events case "whiteboard": whiteboardEventSink = events + case "transcription": + transcriptionSink = events default: return FlutterError(code: #function, message: "invalid event sink name", details: arguments) } @@ -195,6 +204,12 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene } else { print(#function, "whiteboardEventChannel not found") } + if transcriptionEventChannel != nil { + transcriptionEventChannel!.setStreamHandler(nil) + transcriptionSink = nil + } else { + print(#function, "transcriptionEventChannel not found") + } } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { @@ -345,6 +360,9 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene case "enable_virtual_background", "disable_virtual_background", "enable_blur_background", "disable_blur_background", "change_virtual_background", "is_virtual_background_supported": vbAction.performActions(call, result) + case "start_real_time_transcription", "stop_real_time_transcription","add_transcript_listener", "remove_transcript_listener": + transcriptionActions(call, result) + default: result(FlutterMethodNotImplemented) } @@ -525,6 +543,20 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene HMSWhiteboardAction.whiteboardActions(call, result, hmsSDK) } } + + private var isTranscriptionListenerAdded = false + private func transcriptionActions(_ call: FlutterMethodCall, _ result: @escaping FlutterResult){ + switch call.method{ + case "add_transcript_listener": + isTranscriptionListenerAdded = true + result(nil) + case "remove_transcript_listener": + isTranscriptionListenerAdded = false + result(nil) + default: + HMSTranscriptionAction.transcriptionActions(call, result, hmsSDK) + } + } // MARK: - Track Setting var audioMixerSourceMap = [String: HMSAudioNode]() @@ -1565,6 +1597,28 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene previewSink?(data) } } + + public func on(transcripts: HMSTranscripts){ + + /** + * If transcription listener is added in the application + * then only we send data from here + */ + if(isTranscriptionListenerAdded){ + var transcriptList = [[String:Any?]]() + + transcripts.transcripts.forEach{ + transcriptList.append(HMSTranscriptExtension.toDictionary(hmsTranscript: $0)) + } + + var data = [String:Any?]() + + data["event_name"] = "on_transcripts" + data["data"] = transcriptList + self.transcriptionSink?(data) + } + } + // MARK: - RTC Stats Listeners diff --git a/packages/hmssdk_flutter/lib/hmssdk_flutter.dart b/packages/hmssdk_flutter/lib/hmssdk_flutter.dart index 67780008a..d7ff52911 100644 --- a/packages/hmssdk_flutter/lib/hmssdk_flutter.dart +++ b/packages/hmssdk_flutter/lib/hmssdk_flutter.dart @@ -27,6 +27,8 @@ export 'src/enum/hms_peer_type.dart'; export 'src/enum/hms_hls_playlist_type.dart'; export 'src/enum/hms_whiteboard_listener_method.dart'; export 'src/enum/hms_whiteboard_state.dart'; +export 'src/enum/hms_transcription_mode.dart'; +export 'src/enum/hms_transcription_state.dart'; //EXCEPTIONS export 'src/exceptions/hms_exception.dart'; @@ -123,6 +125,10 @@ export 'src/model/whiteboard/hms_whiteboard_permission.dart'; export 'src/model/whiteboard/hms_whiteboard_update_listener.dart'; export 'src/model/hls_player/hms_hls_layer.dart'; export 'src/model/hms_video_filter.dart'; +export 'src/model/transcription/hms_transcription_permission.dart'; +export 'src/model/transcription//hms_transcript_listener.dart'; +export 'src/model/transcription/hms_transcription.dart'; +export 'src/model/transcription/hms_transcription_controller.dart'; //Views export 'src/ui/meeting/hms_texture_view.dart'; diff --git a/packages/hmssdk_flutter/lib/src/common/platform_methods.dart b/packages/hmssdk_flutter/lib/src/common/platform_methods.dart index d49355bc6..7cb9c51bf 100644 --- a/packages/hmssdk_flutter/lib/src/common/platform_methods.dart +++ b/packages/hmssdk_flutter/lib/src/common/platform_methods.dart @@ -246,7 +246,13 @@ enum PlatformMethod { changeVirtualBackground, enableBlurBackground, disableBlurBackground, - isVirtualBackgroundSupported + isVirtualBackgroundSupported, + + ///Transcription methods + startRealTimeTranscription, + stopRealTimeTranscription, + addTranscriptListener, + removeTranscriptListener } extension PlatformMethodValues on PlatformMethod { @@ -626,6 +632,15 @@ extension PlatformMethodValues on PlatformMethod { case PlatformMethod.isVirtualBackgroundSupported: return "is_virtual_background_supported"; + case PlatformMethod.startRealTimeTranscription: + return "start_real_time_transcription"; + case PlatformMethod.stopRealTimeTranscription: + return "stop_real_time_transcription"; + case PlatformMethod.addTranscriptListener: + return "add_transcript_listener"; + case PlatformMethod.removeTranscriptListener: + return "remove_transcript_listener"; + default: return 'unknown'; } @@ -1005,6 +1020,15 @@ extension PlatformMethodValues on PlatformMethod { case "is_virtual_background_supported": return PlatformMethod.isVirtualBackgroundSupported; + case "start_real_time_transcription": + return PlatformMethod.startRealTimeTranscription; + case "stop_real_time_transcription": + return PlatformMethod.stopRealTimeTranscription; + case "add_transcript_listener": + return PlatformMethod.addTranscriptListener; + case "remove_transcript_listener": + return PlatformMethod.removeTranscriptListener; + default: return PlatformMethod.unknown; } diff --git a/packages/hmssdk_flutter/lib/src/enum/hms_room_update.dart b/packages/hmssdk_flutter/lib/src/enum/hms_room_update.dart index 57e205245..c013a8801 100644 --- a/packages/hmssdk_flutter/lib/src/enum/hms_room_update.dart +++ b/packages/hmssdk_flutter/lib/src/enum/hms_room_update.dart @@ -23,6 +23,9 @@ enum HMSRoomUpdate { //When peer Count is changed roomPeerCountUpdated, + ///When transcription state is updated + transcriptionsUpdated, + ///Default Update defaultUpdate } @@ -54,6 +57,9 @@ extension HMSRoomUpdateValues on HMSRoomUpdate { case 'room_peer_count_updated': return HMSRoomUpdate.roomPeerCountUpdated; + case 'transcriptions_updated': + return HMSRoomUpdate.transcriptionsUpdated; + default: return HMSRoomUpdate.defaultUpdate; } @@ -85,6 +91,9 @@ extension HMSRoomUpdateValues on HMSRoomUpdate { case HMSRoomUpdate.roomPeerCountUpdated: return 'room_peer_count_updated'; + case HMSRoomUpdate.transcriptionsUpdated: + return 'transcriptions_updated'; + default: return 'defaultUpdate'; } diff --git a/packages/hmssdk_flutter/lib/src/enum/hms_transcription_listener_method.dart b/packages/hmssdk_flutter/lib/src/enum/hms_transcription_listener_method.dart new file mode 100644 index 000000000..aab86aade --- /dev/null +++ b/packages/hmssdk_flutter/lib/src/enum/hms_transcription_listener_method.dart @@ -0,0 +1,15 @@ +///[HMSTranscriptionListenerMethod] contains method for `HMSTranscriptionListener` +enum HMSTranscriptionListenerMethod { onTranscripts, unknown } + +extension HMSTranscriptionListenerMethodValues + on HMSTranscriptionListenerMethod { + static HMSTranscriptionListenerMethod + getHMSTranscriptionListenerMethodFromString(String transcription) { + switch (transcription) { + case "on_transcripts": + return HMSTranscriptionListenerMethod.onTranscripts; + default: + return HMSTranscriptionListenerMethod.unknown; + } + } +} diff --git a/packages/hmssdk_flutter/lib/src/enum/hms_transcription_mode.dart b/packages/hmssdk_flutter/lib/src/enum/hms_transcription_mode.dart new file mode 100644 index 000000000..0f670741b --- /dev/null +++ b/packages/hmssdk_flutter/lib/src/enum/hms_transcription_mode.dart @@ -0,0 +1,16 @@ +///[HMSTranscriptionMode] is an enum class that defines the transcription mode of the meeting. +enum HMSTranscriptionMode { caption, live, unknown } + +extension HMSTranscriptionModeValues on HMSTranscriptionMode { + static HMSTranscriptionMode getHMSTranscriptionModeFromString( + String transcription) { + switch (transcription) { + case "caption": + return HMSTranscriptionMode.caption; + case "live": + return HMSTranscriptionMode.live; + default: + return HMSTranscriptionMode.unknown; + } + } +} diff --git a/packages/hmssdk_flutter/lib/src/enum/hms_transcription_state.dart b/packages/hmssdk_flutter/lib/src/enum/hms_transcription_state.dart new file mode 100644 index 000000000..3fe4561bd --- /dev/null +++ b/packages/hmssdk_flutter/lib/src/enum/hms_transcription_state.dart @@ -0,0 +1,20 @@ +///[HMSTranscriptionState] is an enum class which defines the state of the transcription +enum HMSTranscriptionState { started, stopped, initialized, failed, unknown } + +extension HMSTranscriptionStateValues on HMSTranscriptionState { + static HMSTranscriptionState getHMSTranscriptionStateFromString( + String transcription) { + switch (transcription) { + case "started": + return HMSTranscriptionState.started; + case "stopped": + return HMSTranscriptionState.stopped; + case "initialized": + return HMSTranscriptionState.initialized; + case "failed": + return HMSTranscriptionState.failed; + default: + return HMSTranscriptionState.unknown; + } + } +} diff --git a/packages/hmssdk_flutter/lib/src/model/hms_permissions.dart b/packages/hmssdk_flutter/lib/src/model/hms_permissions.dart index 312e2a019..273a4d44b 100644 --- a/packages/hmssdk_flutter/lib/src/model/hms_permissions.dart +++ b/packages/hmssdk_flutter/lib/src/model/hms_permissions.dart @@ -1,3 +1,4 @@ +import 'package:hmssdk_flutter/src/model/transcription/hms_transcription_permission.dart'; import 'package:hmssdk_flutter/src/model/whiteboard/hms_whiteboard_permission.dart'; ///100ms HMSPermissions @@ -15,6 +16,7 @@ class HMSPermissions { final bool? pollRead; final bool? pollWrite; final HMSWhiteboardPermission? whiteboard; + final List? transcription; HMSPermissions( {this.endRoom, @@ -27,7 +29,8 @@ class HMSPermissions { this.changeRole, this.pollRead, this.pollWrite, - this.whiteboard}); + this.whiteboard, + this.transcription}); factory HMSPermissions.fromMap(Map map) { return HMSPermissions( @@ -43,6 +46,12 @@ class HMSPermissions { pollWrite: map['poll_write'], whiteboard: map['whiteboard_permission'] != null ? HMSWhiteboardPermission.fromMap(map['whiteboard_permission']) + : null, + transcription: map['transcription_permission'] != null + ? map['transcription_permission'] + .map( + (e) => HMSTranscriptionPermission.fromMap(e)) + .toList() : null); } } diff --git a/packages/hmssdk_flutter/lib/src/model/hms_room.dart b/packages/hmssdk_flutter/lib/src/model/hms_room.dart index 3671372d0..1894db43a 100644 --- a/packages/hmssdk_flutter/lib/src/model/hms_room.dart +++ b/packages/hmssdk_flutter/lib/src/model/hms_room.dart @@ -3,6 +3,7 @@ import 'package:hmssdk_flutter/hmssdk_flutter.dart'; import 'package:hmssdk_flutter/src/model/hms_browser_recording_state.dart'; import 'package:hmssdk_flutter/src/model/hms_hls_recording_state.dart'; import 'package:hmssdk_flutter/src/model/hms_server_recording_state.dart'; +import 'package:hmssdk_flutter/src/model/transcription.dart'; import 'hms_hls_streaming_state.dart'; import 'hms_rtmp_streaming_state.dart'; @@ -22,6 +23,7 @@ class HMSRoom { String? name; String? metaData; bool isLarge; + List? transcriptions; HMSBrowserRecordingState? hmsBrowserRecordingState; HMSRtmpStreamingState? hmsRtmpStreamingState; HMSServerRecordingState? hmsServerRecordingState; @@ -39,6 +41,7 @@ class HMSRoom { this.name, required this.peers, required this.isLarge, + this.transcriptions, this.metaData, this.hmsServerRecordingState, this.hmsRtmpStreamingState, @@ -62,6 +65,17 @@ class HMSRoom { } } + List? transcriptions; + + if (map["transcriptions"] != null) { + map["transcriptions"].forEach((element) { + if (transcriptions == null) { + transcriptions = []; + } + transcriptions?.add(Transcription.fromMap(element)); + }); + } + return HMSRoom( hmsBrowserRecordingState: map["browser_recording_state"] != null ? HMSBrowserRecordingState.fromMap(map["browser_recording_state"]) @@ -85,7 +99,8 @@ class HMSRoom { metaData: map['meta_data'], peerCount: map["peer_count"] != null ? map["peer_count"] : 0, startedAt: map["started_at"] != null ? map["started_at"] : 0, - sessionId: map["session_id"] != null ? map["session_id"] : ""); + sessionId: map["session_id"] != null ? map["session_id"] : "", + transcriptions: transcriptions); } @override diff --git a/packages/hmssdk_flutter/lib/src/model/platform_method_response.dart b/packages/hmssdk_flutter/lib/src/model/platform_method_response.dart index 3d2cc531b..0d94ab62d 100644 --- a/packages/hmssdk_flutter/lib/src/model/platform_method_response.dart +++ b/packages/hmssdk_flutter/lib/src/model/platform_method_response.dart @@ -3,6 +3,7 @@ import 'package:hmssdk_flutter/hmssdk_flutter.dart'; import 'package:hmssdk_flutter/src/enum/hms_hls_playback_event_method.dart'; import 'package:hmssdk_flutter/src/enum/hms_key_change_listener_method.dart'; import 'package:hmssdk_flutter/src/enum/hms_logs_update_listener.dart'; +import 'package:hmssdk_flutter/src/enum/hms_transcription_listener_method.dart'; ///PlatformMethodResponse contains all the responses sent back from the platform /// @@ -103,3 +104,11 @@ class HMSWhiteboardListenerMethodResponse { HMSWhiteboardListenerMethodResponse( {required this.method, required this.data}); } + +class HMSTranscriptionListenerMethodResponse { + final HMSTranscriptionListenerMethod method; + final List data; + + HMSTranscriptionListenerMethodResponse( + {required this.method, required this.data}); +} diff --git a/packages/hmssdk_flutter/lib/src/model/transcription.dart b/packages/hmssdk_flutter/lib/src/model/transcription.dart new file mode 100644 index 000000000..5892251ad --- /dev/null +++ b/packages/hmssdk_flutter/lib/src/model/transcription.dart @@ -0,0 +1,72 @@ +//Project imports +import 'package:hmssdk_flutter/src/enum/hms_transcription_mode.dart'; +import 'package:hmssdk_flutter/src/enum/hms_transcription_state.dart'; +import 'package:hmssdk_flutter/src/model/hms_date_extension.dart'; + +///[Transcription] is a class which includes the properties of a transcription +class Transcription { + ///[error] is the error object which contains the error code and message if any error occurs. + final TranscriptionError? error; + + ///[startedAt] is the time when the transcription started. + final DateTime? startedAt; + + ///[stoppedAt] is the time when the transcription stopped. + final DateTime? stoppedAt; + + ///[updatedAt] is the time when the transcription was last updated. + final DateTime? updatedAt; + + ///[state] is an enum of type [HMSTranscriptionState] which tells the state of the transcription. + final HMSTranscriptionState? state; + + ///[mode] is an enum of type [HMSTranscriptionMode] which tells the mode of the transcription. + final HMSTranscriptionMode? mode; + + Transcription( + {this.error, + this.startedAt, + this.stoppedAt, + this.updatedAt, + this.state, + this.mode}); + + factory Transcription.fromMap(Map map) { + return Transcription( + error: map["error"] != null + ? TranscriptionError.fromMap(map["error"]) + : null, + startedAt: map["started_at"] != null + ? HMSDateExtension.convertDateFromEpoch(map['started_at']) + : null, + stoppedAt: map["stopped_at"] != null + ? HMSDateExtension.convertDateFromEpoch(map['stopped_at']) + : null, + updatedAt: map["updated_at"] != null + ? HMSDateExtension.convertDateFromEpoch(map['updated_at']) + : null, + state: map["state"] != null + ? HMSTranscriptionStateValues.getHMSTranscriptionStateFromString( + map["state"]) + : null, + mode: map["mode"] != null + ? HMSTranscriptionModeValues.getHMSTranscriptionModeFromString( + map["mode"]) + : null); + } +} + +///[TranscriptionError] is a class which includes the properties of an error in transcription +class TranscriptionError { + ///[code] is the error code. + final int? code; + + ///[message] is the error message. + final String? message; + + TranscriptionError({required this.code, required this.message}); + + factory TranscriptionError.fromMap(Map map) { + return TranscriptionError(code: map['code'], message: map['message']); + } +} diff --git a/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcript_listener.dart b/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcript_listener.dart new file mode 100644 index 000000000..01dd4ebe4 --- /dev/null +++ b/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcript_listener.dart @@ -0,0 +1,10 @@ +//Project imports +import 'package:hmssdk_flutter/src/model/transcription/hms_transcription.dart'; + +///[HMSTranscriptListener] is the listener interface which listens to the transcription of the meeting. +/// +///Implement this listener in your class to get the transcription of the meeting. +abstract class HMSTranscriptListener { + ///[onTranscripts] is called when the transcription is received. + void onTranscripts({required List transcriptions}) {} +} diff --git a/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription.dart b/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription.dart new file mode 100644 index 000000000..df7d9b61b --- /dev/null +++ b/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription.dart @@ -0,0 +1,35 @@ +///[HMSTranscription] is a class which is used to represent a transcription. +class HMSTranscription { + final int start; + final int end; + + ///[transcript] is the text of the transcription. + final String transcript; + + ///[peerId] is the id of the speaker. + final String peerId; + + ///[peerName] is the name of the speaker. + final String? peerName; + + ///[isFinal] is a boolean which tells if the transcription is final or not. + final bool isFinal; + + HMSTranscription( + {required this.start, + required this.end, + required this.transcript, + required this.peerId, + required this.peerName, + required this.isFinal}); + + factory HMSTranscription.fromMap(Map map) { + return HMSTranscription( + start: map['start'], + end: map['end'], + transcript: map['transcript'], + peerId: map['peer_id'], + peerName: map['peer_name'], + isFinal: map['is_final']); + } +} diff --git a/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription_controller.dart b/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription_controller.dart new file mode 100644 index 000000000..4e3ef45c1 --- /dev/null +++ b/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription_controller.dart @@ -0,0 +1,63 @@ +//Project imports +import 'package:hmssdk_flutter/hmssdk_flutter.dart'; +import 'package:hmssdk_flutter/src/service/platform_service.dart'; + +///[HMSTranscriptionController] is used to control transcription in the meeting. +abstract class HMSTranscriptionController { + ///[addListener] is used to add a listener to get the transcription of the meeting. + /// **parameters**: + /// + /// **listener** - [HMSTranscriptListener] instance to be attached + /// Learn more about [addListener] [here](https://www.100ms.live/docs/flutter/v2/how-to-guides/extend-capabilities/live-captions#step-1-add-hmstranscriptlistener-to-the-class-to-start-getting-transcriptions) + static void addListener({required HMSTranscriptListener listener}) { + PlatformService.addTranscriptListener(listener); + PlatformService.invokeMethod(PlatformMethod.addTranscriptListener); + } + + ///[removeListener] is used to remove the listener that was previously added. + ///Learn more about [removeListener] [here](https://www.100ms.live/docs/flutter/v2/how-to-guides/extend-capabilities/live-captions#step-3-to-stop-getting-transcriptions-remove-hmstranscriptlistener) + static void removeListener() { + PlatformService.removeTranscriptListener(); + PlatformService.invokeMethod(PlatformMethod.removeTranscriptListener); + } + + ///[startTranscription] is used to start the transcription of the meeting. + /// + /// **parameters**: + /// + /// **mode** - [HMSTranscriptionMode] to start the transcription in the meeting. Default is [HMSTranscriptionMode.caption] + /// + /// Refer [startTranscription](https://www.100ms.live/docs/flutter/v2/how-to-guides/extend-capabilities/live-captions#start-transcription) + static Future startTranscription( + {HMSTranscriptionMode mode = HMSTranscriptionMode.caption}) async { + var result = await PlatformService.invokeMethod( + PlatformMethod.startRealTimeTranscription, + arguments: {'mode': mode.name}); + + if (result != null) { + return HMSException.fromMap(result["error"]); + } else { + return null; + } + } + + ///[stopTranscription] is used to stop the transcription of the meeting. + /// + /// **parameters**: + /// + /// **mode** - [HMSTranscriptionMode] to stop the transcription in the meeting. Default is [HMSTranscriptionMode.caption] + /// + /// Refer [stopTranscription](https://www.100ms.live/docs/flutter/v2/how-to-guides/extend-capabilities/live-captions#stop-transcription) + static Future stopTranscription( + {HMSTranscriptionMode mode = HMSTranscriptionMode.caption}) async { + var result = await PlatformService.invokeMethod( + PlatformMethod.stopRealTimeTranscription, + arguments: {'mode': mode.name}); + + if (result != null) { + return HMSException.fromMap(result["error"]); + } else { + return null; + } + } +} diff --git a/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription_permission.dart b/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription_permission.dart new file mode 100644 index 000000000..0d0af794c --- /dev/null +++ b/packages/hmssdk_flutter/lib/src/model/transcription/hms_transcription_permission.dart @@ -0,0 +1,21 @@ +//Project imports +import 'package:hmssdk_flutter/src/enum/hms_transcription_mode.dart'; + +///[HMSTranscriptionPermission] contains the permission of the user for transcription. +class HMSTranscriptionPermission { + ///[mode] is the transcription mode of the meeting. + final HMSTranscriptionMode mode; + + ///[admin] is a boolean value that defines if the user has admin permission for transcription. + ///i.e permissions to start/stop the transcription. + final bool admin; + + HMSTranscriptionPermission({required this.mode, required this.admin}); + + factory HMSTranscriptionPermission.fromMap(Map map) { + return HMSTranscriptionPermission( + mode: HMSTranscriptionModeValues.getHMSTranscriptionModeFromString( + map['mode']), + admin: map['admin']); + } +} diff --git a/packages/hmssdk_flutter/lib/src/service/platform_service.dart b/packages/hmssdk_flutter/lib/src/service/platform_service.dart index 29e51d085..701abb264 100644 --- a/packages/hmssdk_flutter/lib/src/service/platform_service.dart +++ b/packages/hmssdk_flutter/lib/src/service/platform_service.dart @@ -17,6 +17,7 @@ import 'package:hmssdk_flutter/hmssdk_flutter.dart'; import 'package:hmssdk_flutter/src/enum/hms_hls_playback_event_method.dart'; import 'package:hmssdk_flutter/src/enum/hms_key_change_listener_method.dart'; import 'package:hmssdk_flutter/src/enum/hms_logs_update_listener.dart'; +import 'package:hmssdk_flutter/src/enum/hms_transcription_listener_method.dart'; import 'package:hmssdk_flutter/src/model/hms_key_change_observer.dart'; import 'package:hmssdk_flutter/src/model/platform_method_response.dart'; @@ -55,6 +56,10 @@ abstract class PlatformService { static const EventChannel _whiteboardEventChannel = const EventChannel("whiteboard_event_channel"); + ///used to get transcription events + static const EventChannel _transcriptionEventChannel = + const EventChannel("transcription_event_channel"); + ///add meeting listeners. static List updateListeners = []; @@ -71,6 +76,8 @@ abstract class PlatformService { static HMSWhiteboardUpdateListener? _whiteboardListener; + static HMSTranscriptListener? _transcriptListener; + ///List for event Listener static List statsListeners = []; static bool isStartedListening = false; @@ -146,6 +153,14 @@ abstract class PlatformService { keyChangeObservers.add(hmsKeyChangeObserver); } + static void addTranscriptListener(HMSTranscriptListener transcriptListener) { + _transcriptListener = transcriptListener; + } + + static void removeTranscriptListener() { + _transcriptListener = null; + } + static Future removeKeyChangeObserver( HMSKeyChangeListener hmsKeyChangeListener) async { int index = keyChangeObservers.indexWhere((observer) => @@ -626,6 +641,27 @@ abstract class PlatformService { break; } }); + + _transcriptionEventChannel + .receiveBroadcastStream({'name': 'transcription'}).map((event) { + HMSTranscriptionListenerMethod method = + HMSTranscriptionListenerMethodValues + .getHMSTranscriptionListenerMethodFromString(event['event_name']); + var data = event['data']; + return HMSTranscriptionListenerMethodResponse(method: method, data: data); + }).listen((event) { + HMSTranscriptionListenerMethod method = event.method; + switch (method) { + case HMSTranscriptionListenerMethod.onTranscripts: + _transcriptListener?.onTranscripts( + transcriptions: (event.data) + .map((e) => HMSTranscription.fromMap(e)) + .toList()); + break; + case HMSTranscriptionListenerMethod.unknown: + break; + } + }); } static void notifyLogsUpdateListeners( From 61946dd41b0c21a8774c8bd52876badb37015f74 Mon Sep 17 00:00:00 2001 From: Pushpam <93931528+Decoder07@users.noreply.github.com> Date: Fri, 28 Jun 2024 17:20:47 +0530 Subject: [PATCH 06/11] Added release notes for 1.10.4 (#1791) --- packages/hms_room_kit/CHANGELOG.md | 16 ++++++++++++++++ packages/hmssdk_flutter/CHANGELOG.md | 23 +++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/packages/hms_room_kit/CHANGELOG.md b/packages/hms_room_kit/CHANGELOG.md index 89c1b13d3..ad7949201 100644 --- a/packages/hms_room_kit/CHANGELOG.md +++ b/packages/hms_room_kit/CHANGELOG.md @@ -5,12 +5,28 @@ | hms_room_kit | [![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit) | | hmssdk_flutter | [![Pub Version](https://img.shields.io/pub/v/hmssdk_flutter)](https://pub.dev/packages/hmssdk_flutter) | +## 1.1.4 - 2024-06-28 + +| Package | Version | +| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| hms_room_kit | 1.1.4 | +| hmssdk_flutter | 1.10.4 | + +### 🚀 Added + +- Introducing live transcription options in prebuilt + + Prebuilt now supports live transcription for better accessibility. Users can enable or disable live transcription from the prebuilt interface. + +Uses `hmssdk_flutter` package version 1.10.4 + ## 1.1.3 - 2024-06-12 | Package | Version | | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | hms_room_kit | 1.1.3 | | hmssdk_flutter | 1.10.3 | +| hms_video_plugin | 0.0.1 | ### 🚀 Added diff --git a/packages/hmssdk_flutter/CHANGELOG.md b/packages/hmssdk_flutter/CHANGELOG.md index 7b5330613..6a8ea4edf 100644 --- a/packages/hmssdk_flutter/CHANGELOG.md +++ b/packages/hmssdk_flutter/CHANGELOG.md @@ -5,6 +5,29 @@ | hms_room_kit | [![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit) | | hmssdk_flutter | [![Pub Version](https://img.shields.io/pub/v/hmssdk_flutter)](https://pub.dev/packages/hmssdk_flutter) | +# 1.10.4 - 2024-06-28 + +| Package | Version | +| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| hms_room_kit | 1.1.4 | +| hmssdk_flutter | 1.10.4 | +| hms_video_plugin | 0.0.1 | + +### ✨ Added + +- Live Transcription in webRTC calls + + HMSSDK now provides support for transcription in webRTC calls. You can now start/stop transcription using `HMSTranscriptionController` methods. HMSSDK provides also provides callbacks for transcription start/stop events. Learn more about it [here](https://www.100ms.live/docs/flutter/v2/how-to-guides/extend-capabilities/live-captions) + +### 🛠️ Changed + +- Applications no longer need to request permissions for camera, microphone etc. HMSSDK handles the permissions internally.Checkout the [permissions guide](https://www.100ms.live/docs/flutter/v2/quickstart/quickstart#add-permissions) + +Uses Android SDK 2.9.59 & iOS SDK 1.12.0 + +**Full Changelog**: [1.10.3...1.10.4](https://github.com/100mslive/100ms-flutter/compare/1.10.3...1.10.4) + + # 1.10.3 - 2024-06-12 | Package | Version | From 826c17e4632bf58f3d7ba387d1e06ed14a265a67 Mon Sep 17 00:00:00 2001 From: Decoder07 Date: Mon, 1 Jul 2024 12:19:14 +0530 Subject: [PATCH 07/11] Addd transcription view --- .../widgets/common_widgets/transcription_view.dart | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/hms_room_kit/lib/src/widgets/common_widgets/transcription_view.dart b/packages/hms_room_kit/lib/src/widgets/common_widgets/transcription_view.dart index 5d3662e55..500fa8558 100644 --- a/packages/hms_room_kit/lib/src/widgets/common_widgets/transcription_view.dart +++ b/packages/hms_room_kit/lib/src/widgets/common_widgets/transcription_view.dart @@ -1,13 +1,20 @@ +library; + +///Dart imports import 'dart:io'; +///Package imports import 'package:flutter/material.dart'; -import 'package:hms_room_kit/hms_room_kit.dart'; -import 'package:hms_room_kit/src/meeting/meeting_navigation_visibility_controller.dart'; -import 'package:hms_room_kit/src/meeting/meeting_store.dart'; import 'package:hmssdk_flutter/hmssdk_flutter.dart'; import 'package:provider/provider.dart'; import 'package:tuple/tuple.dart'; +///Project imports +import 'package:hms_room_kit/hms_room_kit.dart'; +import 'package:hms_room_kit/src/meeting/meeting_navigation_visibility_controller.dart'; +import 'package:hms_room_kit/src/meeting/meeting_store.dart'; + +///[TranscriptionView] is a widget that displays the transcription of the meeting class TranscriptionView extends StatefulWidget { const TranscriptionView({Key? key}) : super(key: key); @override From e930dec7023d9d267ca006c616775d340bf5c37c Mon Sep 17 00:00:00 2001 From: Decoder07 Date: Mon, 1 Jul 2024 12:22:20 +0530 Subject: [PATCH 08/11] Added library annotation --- .../closed_caption_control_bottom_sheet.dart | 8 +++++++- .../lib/src/widgets/toasts/hms_toasts_type.dart | 2 ++ .../lib/src/widgets/toasts/hms_transcription_toast.dart | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_control_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_control_bottom_sheet.dart index c589f36db..943971cf7 100644 --- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_control_bottom_sheet.dart +++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/closed_caption_control_bottom_sheet.dart @@ -1,10 +1,16 @@ +library; + +///Package imports import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +///Project imports import 'package:hms_room_kit/hms_room_kit.dart'; import 'package:hms_room_kit/src/meeting/meeting_store.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/hms_cross_button.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart'; -import 'package:provider/provider.dart'; +///[ClosedCaptionControlBottomSheet] is a widget that displays the closed caption control bottom sheet class ClosedCaptionControlBottomSheet extends StatefulWidget { final MeetingStore meetingStore; diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart index de30b4679..39c1040f0 100644 --- a/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart +++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart @@ -1,3 +1,5 @@ +library; + ///[HMSToastsType] is used to define the type of toast to be shown. enum HMSToastsType { roleChangeToast, diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_transcription_toast.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_transcription_toast.dart index 5ec2c9d7e..8ad1d5bc5 100644 --- a/packages/hms_room_kit/lib/src/widgets/toasts/hms_transcription_toast.dart +++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_transcription_toast.dart @@ -1,9 +1,15 @@ +library; + +///Package imports import 'package:flutter/material.dart'; + +///Project imports import 'package:hms_room_kit/hms_room_kit.dart'; import 'package:hms_room_kit/src/meeting/meeting_store.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart'; import 'package:hms_room_kit/src/widgets/toasts/hms_toast.dart'; +///[HMSTranscriptionToast] is a widget that displays the transcription toast class HMSTranscriptionToast extends StatelessWidget { final String message; final MeetingStore meetingStore; From 12fc7a727de015bac461e82d08179f7a7467b850 Mon Sep 17 00:00:00 2001 From: Decoder07 Date: Mon, 1 Jul 2024 12:36:40 +0530 Subject: [PATCH 09/11] Updated date --- packages/hms_room_kit/CHANGELOG.md | 2 +- packages/hmssdk_flutter/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hms_room_kit/CHANGELOG.md b/packages/hms_room_kit/CHANGELOG.md index ad7949201..96c3d1150 100644 --- a/packages/hms_room_kit/CHANGELOG.md +++ b/packages/hms_room_kit/CHANGELOG.md @@ -5,7 +5,7 @@ | hms_room_kit | [![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit) | | hmssdk_flutter | [![Pub Version](https://img.shields.io/pub/v/hmssdk_flutter)](https://pub.dev/packages/hmssdk_flutter) | -## 1.1.4 - 2024-06-28 +## 1.1.4 - 2024-07-01 | Package | Version | | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/packages/hmssdk_flutter/CHANGELOG.md b/packages/hmssdk_flutter/CHANGELOG.md index 6a8ea4edf..310ae0763 100644 --- a/packages/hmssdk_flutter/CHANGELOG.md +++ b/packages/hmssdk_flutter/CHANGELOG.md @@ -5,7 +5,7 @@ | hms_room_kit | [![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit) | | hmssdk_flutter | [![Pub Version](https://img.shields.io/pub/v/hmssdk_flutter)](https://pub.dev/packages/hmssdk_flutter) | -# 1.10.4 - 2024-06-28 +# 1.10.4 - 2024-07-01 | Package | Version | | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | From 3eb63e0130cd262b23b7bd984c127684b7852481 Mon Sep 17 00:00:00 2001 From: Decoder07 Date: Mon, 1 Jul 2024 13:00:26 +0530 Subject: [PATCH 10/11] Updated spacing package versions --- packages/hmssdk_flutter/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hmssdk_flutter/CHANGELOG.md b/packages/hmssdk_flutter/CHANGELOG.md index 310ae0763..2e785212d 100644 --- a/packages/hmssdk_flutter/CHANGELOG.md +++ b/packages/hmssdk_flutter/CHANGELOG.md @@ -11,7 +11,7 @@ | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | hms_room_kit | 1.1.4 | | hmssdk_flutter | 1.10.4 | -| hms_video_plugin | 0.0.1 | +| hms_video_plugin | 0.0.1 | ### ✨ Added From 5cf6fa8e0f391411ba6fabaeb8069cf98f9c2b6f Mon Sep 17 00:00:00 2001 From: Decoder07 Date: Mon, 1 Jul 2024 13:08:30 +0530 Subject: [PATCH 11/11] Updated hmssdk_flutter version to 1.10.4 --- packages/hms_room_kit/CHANGELOG.md | 1 + packages/hms_room_kit/example/pubspec.lock | 7 ++++--- packages/hms_room_kit/pubspec.lock | 7 ++++--- packages/hms_room_kit/pubspec.yaml | 3 +-- packages/hmssdk_flutter/CHANGELOG.md | 4 +++- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/hms_room_kit/CHANGELOG.md b/packages/hms_room_kit/CHANGELOG.md index 96c3d1150..38c5d1c49 100644 --- a/packages/hms_room_kit/CHANGELOG.md +++ b/packages/hms_room_kit/CHANGELOG.md @@ -11,6 +11,7 @@ | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | hms_room_kit | 1.1.4 | | hmssdk_flutter | 1.10.4 | +| hms_video_plugin | 0.0.2 | ### 🚀 Added diff --git a/packages/hms_room_kit/example/pubspec.lock b/packages/hms_room_kit/example/pubspec.lock index 6d95f230a..b258c3089 100644 --- a/packages/hms_room_kit/example/pubspec.lock +++ b/packages/hms_room_kit/example/pubspec.lock @@ -242,9 +242,10 @@ packages: hmssdk_flutter: dependency: transitive description: - path: "../../hmssdk_flutter" - relative: true - source: path + name: hmssdk_flutter + sha256: c91a6409939487c5322b950cf23a5ebe3f40ab839163b06977d51545a3cceb13 + url: "https://pub.dev" + source: hosted version: "1.10.4" http: dependency: transitive diff --git a/packages/hms_room_kit/pubspec.lock b/packages/hms_room_kit/pubspec.lock index 02ba44dd6..8ad5ed950 100644 --- a/packages/hms_room_kit/pubspec.lock +++ b/packages/hms_room_kit/pubspec.lock @@ -219,9 +219,10 @@ packages: hmssdk_flutter: dependency: "direct main" description: - path: "../hmssdk_flutter" - relative: true - source: path + name: hmssdk_flutter + sha256: c91a6409939487c5322b950cf23a5ebe3f40ab839163b06977d51545a3cceb13 + url: "https://pub.dev" + source: hosted version: "1.10.4" http: dependency: transitive diff --git a/packages/hms_room_kit/pubspec.yaml b/packages/hms_room_kit/pubspec.yaml index ba98d378b..6bf96d141 100644 --- a/packages/hms_room_kit/pubspec.yaml +++ b/packages/hms_room_kit/pubspec.yaml @@ -14,8 +14,7 @@ dependencies: flutter: sdk: flutter - hmssdk_flutter: - path: ../hmssdk_flutter + hmssdk_flutter: 1.10.4 intl: ^0.18.0 permission_handler: ^11.0.0 provider: ^6.0.5 diff --git a/packages/hmssdk_flutter/CHANGELOG.md b/packages/hmssdk_flutter/CHANGELOG.md index 2e785212d..8ad0d50e1 100644 --- a/packages/hmssdk_flutter/CHANGELOG.md +++ b/packages/hmssdk_flutter/CHANGELOG.md @@ -11,7 +11,7 @@ | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | hms_room_kit | 1.1.4 | | hmssdk_flutter | 1.10.4 | -| hms_video_plugin | 0.0.1 | +| hms_video_plugin | 0.0.2 | ### ✨ Added @@ -34,6 +34,8 @@ Uses Android SDK 2.9.59 & iOS SDK 1.12.0 | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | hms_room_kit | 1.1.3 | | hmssdk_flutter | 1.10.3 | +| hms_video_plugin | 0.0.1 | + Uses Android SDK 2.9.59 & iOS SDK 1.12.0