flutter_zoom_sdk

Creator: coderz1093

Last updated:

Add to Cart

Description:

flutter zoom sdk

Flutter Zoom SDK #


A Flutter plugin for the Zoom SDK With all features and null safety support.
Note: This plugin is still under active development, and some Zoom features might not be available yet. We are working to add more features.
Feedback, Pull Requests are always welcome.
Note: For Android and iOS Build import.
import 'package:flutter_zoom_sdk/zoom_options.dart';
copied to clipboard
Note: For Web Build import.
import 'package:flutter_zoom_sdk/flutter_zoom_web.dart';
copied to clipboard
Features #

✅ Updated Zoom SDK to latest.
✅ Null Safety.
✅ Stream meeting status.
✅ Join meeting.
✅ Start an instant meeting for Login user.
✅ Start an meeting for Login user with Meeeting ID.
✅ Login Error with proper Error codes.
✅ Hide Title bar or Hide Meeting info (Useful for e-learning platform).
✅ Change Meeting Notification App Name & Zoom Notification Icon Removed.
✅ iOS Support.
✅ Web Support.

Zoom SDK Versions #
Note: Updated to new sdk with new features.
Installation #
First, add flutter_zoom_sdk: ^1.1.0+4 as a dependency in your pubspec.yaml file.
After running pub get, you must run the follow script to get Zoom SDK for the first time:
flutter pub run flutter_zoom_sdk:unzip_zoom_sdk
copied to clipboard
iOS #
Note: correct login ID and Password needed at first attempt or need to reload app.
Note: There is no error message for login failure like android.
Add two rows to the ios/Runner/Info.plist:

one with the key Privacy - Camera Usage Description and a usage description.
and one with the key Privacy - Microphone Usage Description and a usage description.

Or in text format add the key:
<key>NSCameraUsageDescription</key>
<string>Need to use the camera for call</string>
<key>NSMicrophoneUsageDescription</key>
<string>Need to use the microphone for call</string>
copied to clipboard
Disable BITCODE in the ios/Podfile:
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
copied to clipboard
NOTE for testing on the iOS simulator
If you want to use the iOS Simulator to test your app, you will need to ensure you have the iOS Dev Zoom SDK as a dependency.
To use the Dev Zoom SDK, run the following
flutter pub run flutter_zoom_sdk:unzip_zoom_sdk dev
copied to clipboard
To switch back to the normal Zoom SDK, simply run
flutter pub run flutter_zoom_sdk:unzip_zoom_sdk
copied to clipboard
Android #
Change the minimum Android sdk version to at the minimum 21 in your android/app/build.gradle file.
minSdkVersion 21
copied to clipboard
To Change the Notification name copy the below code to android/app/src/main/res/values/strings.xml file
<string name="app_name_zoom_local" >Your App Name</string> // Put your app name in here for notification.
copied to clipboard
Disable shrinkResources for release buid
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
shrinkResources false
minifyEnabled false
}
}
copied to clipboard
Error Codes #
NOTE ZoomError class has all the codes for comparison



Error Response
Error Reference




LOGIN ERROR - 1
EMAIL_LOGIN_DISABLE


LOGIN ERROR - 2
ERROR_USER_NOT_EXIST


LOGIN ERROR - 3
ERROR_WRONG_PASSWORD


LOGIN ERROR - 4
ERROR_WRONG_ACCOUNTLOCKED


LOGIN ERROR - 5
ERROR_WRONG_SDKNEEDUPDATE


LOGIN ERROR - 6
ERROR_WRONG_TOOMANY_FAILED_ATTEMPTS


LOGIN ERROR - 7
ERROR_WRONG_SMSCODEERROR


LOGIN ERROR - 8
ERROR_WRONG_SMSCODEEXPIRED


LOGIN ERROR - 9
ERROR_WRONG_PHONENUMBERFORMATINVALID


LOGIN ERROR - 10
ERROR_LOGINTOKENINVALID


LOGIN ERROR - 11
ERROR_UserDisagreeLoginDisclaimer


LOGIN ERROR - 100
ERROR_WRONG_OTHER_ISSUE


SDK ERROR - 001
ERROR_SDK_NOT_INITIALIZED



Web #
NOTE for using on Web
You cannot get meeting ID and Password after start meeting
Only user whose JWT credentials is provided inside the app can start the meeting
Add stylesheet to the head of index.html
<link type="text/css" rel="stylesheet" href="https://source.zoom.us/1.9.9/css/bootstrap.css" />
<link type="text/css" rel="stylesheet" href="https://source.zoom.us/1.9.9/css/react-select.css" />
copied to clipboard
Import ZoomMtg dependencies to the body of index.html
<!-- import ZoomMtg dependencies -->
<script src="https://source.zoom.us/1.9.9/lib/vendor/react.min.js"></script>
<script src="https://source.zoom.us/1.9.9/lib/vendor/react-dom.min.js"></script>
<script src="https://source.zoom.us/1.9.9/lib/vendor/redux.min.js"></script>
<script src="https://source.zoom.us/1.9.9/lib/vendor/redux-thunk.min.js"></script>
<script src="https://source.zoom.us/1.9.9/lib/vendor/lodash.min.js"></script>
<script src="https://source.zoom.us/1.9.9/lib/av/1502_js_media.min.js"></script>

<!-- import ZoomMtg -->
<script src="https://source.zoom.us/zoom-meeting-1.9.9.min.js"></script>

<script src="main.dart.js" type="application/javascript"></script>
copied to clipboard
You need to obtain the User Token and Zoom Access Token (ZAK) in order to start meetings for a web user. They are unique authentication tokens required to host a meeting on behalf of another user.
Example of getting User Token and ZAK here
More info about the User Token and Zoom Access Token here.
To get personal meeting id and passcode follow https://zoom.us/meeting#/ and navigate to Personal Room tab
Examples #
Meeting status #
There are 2 ways to obtains the Zoom meeting status

Listen to Zoom Status Event stream, or
Polling the Zoom status using a Timer

The plugin emits the following Zoom meeting events:
For iOS:

MEETING_STATUS_IDLE
MEETING_STATUS_CONNECTING
MEETING_STATUS_INMEETING
MEETING_STATUS_WEBINAR_PROMOTE
MEETING_STATUS_WEBINAR_DEPROMOTE
MEETING_STATUS_UNKNOWN

For Android:

MEETING_STATUS_IDLE
MEETING_STATUS_CONNECTING
MEETING_STATUS_INMEETING
MEETING_STATUS_WEBINAR_PROMOTE
MEETING_STATUS_WEBINAR_DEPROMOTE
MEETING_STATUS_UNKNOWN
MEETING_STATUS_DISCONNECTING
MEETING_STATUS_FAILED
MEETING_STATUS_IN_WAITING_ROOM
MEETING_STATUS_RECONNECTING
MEETING_STATUS_WAITINGFORHOST

Join Meeting #
joinMeeting(BuildContext context) {
bool _isMeetingEnded(String status) {
var result = false;

if (Platform.isAndroid)
result = status == "MEETING_STATUS_DISCONNECTING" || status == "MEETING_STATUS_FAILED";
else
result = status == "MEETING_STATUS_IDLE";

return result;
}
if(meetingIdController.text.isNotEmpty && meetingPasswordController.text.isNotEmpty){
ZoomOptions zoomOptions = new ZoomOptions(
domain: "zoom.us",
appKey: "", //API KEY FROM ZOOM - Sdk API Key
appSecret: "", //API SECRET FROM ZOOM - Sdk API Secret
);
var meetingOptions = new ZoomMeetingOptions(
userId: 'username', //pass username for join meeting only --- Any name eg:- EVILRATT.
meetingId: '', //pass meeting id for join meeting only
meetingPassword: '', //pass meeting password for join meeting only
disableDialIn: "true",
disableDrive: "true",
disableInvite: "true",
disableShare: "true",
disableTitlebar: "false",
viewOptions: "true",
noAudio: "false",
noDisconnectAudio: "false"
);

var zoom = ZoomView();
zoom.initZoom(zoomOptions).then((results) {
if(results[0] == 0) {
zoom.onMeetingStatus().listen((status) {
print("[Meeting Status Stream] : " + status[0] + " - " + status[1]);
if (_isMeetingEnded(status[0])) {
print("[Meeting Status] :- Ended");
timer.cancel();
}
});
print("listen on event channel");
zoom.joinMeeting(meetingOptions).then((joinMeetingResult) {
timer = Timer.periodic(new Duration(seconds: 2), (timer) {
zoom.meetingStatus(meetingOptions.meetingId!)
.then((status) {
print("[Meeting Status Polling] : " + status[0] + " - " + status[1]);
});
});
});
}
}).catchError((error) {
print("[Error Generated] : " + error);
});
}else{
if(meetingIdController.text.isEmpty){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Enter a valid meeting id to continue."),
));
}
else if(meetingPasswordController.text.isEmpty){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Enter a meeting password to start."),
));
}
}

}
copied to clipboard
Join Meeting - For Web (JWT Required) #

Pass the Jwt API Key as api key for web & Jwt API Secret as appSecret
Role must be passed as 0 inside generateSignature for join a meeting

joinMeetingWeb(BuildContext context) {
ZoomOptions zoomOptions = new ZoomOptions(
domain: "zoom.us",
appKey: "", //API KEY FROM ZOOM - Jwt API Key
appSecret: "", //API SECRET FROM ZOOM - Jwt API Secret
language: "en-US", // Optional - For Web
showMeetingHeader: true, // Optional - For Web
disableInvite: false, // Optional - For Web
disableCallOut: false, // Optional - For Web
disableRecord: false, // Optional - For Web
disableJoinAudio: false, // Optional - For Web
audioPanelAlwaysOpen: false, // Optional - For Web
isSupportAV: true, // Optional - For Web
isSupportChat: true, // Optional - For Web
isSupportQA: true, // Optional - For Web
isSupportCC: true, // Optional - For Web
isSupportPolling: true, // Optional - For Web
isSupportBreakout: true, // Optional - For Web
screenShare: true, // Optional - For Web
rwcBackup: '', // Optional - For Web
videoDrag: true, // Optional - For Web
sharingMode: 'both', // Optional - For Web
videoHeader: true, // Optional - For Web
isLockBottom: true, // Optional - For Web
isSupportNonverbal: true, // Optional - For Web
isShowJoiningErrorDialog: true, // Optional - For Web
disablePreview: false, // Optional - For Web
disableCORP: true, // Optional - For Web
inviteUrlFormat: '', // Optional - For Web
disableVOIP: false, // Optional - For Web
disableReport: false, // Optional - For Web
meetingInfo: const [
// Optional - For Web
'topic',
'host',
'mn',
'pwd',
'telPwd',
'invite',
'participant',
'dc',
'enctype',
'report'
]
);
var meetingOptions = new ZoomMeetingOptions(
userId: 'username', //pass username for join meeting only --- Any name eg:- EVILRATT.
meetingId: meetingIdController.text, //Personal meeting id for start meeting required
meetingPassword: meetingPasswordController.text, //Personal meeting passcode for start meeting required
//To get personal meeting id and passcode follow https://zoom.us/meeting#/ and novigate to Personal Room tab
);

var zoom = ZoomViewWeb();
zoom.initZoom(zoomOptions).then((results) {
if(results[0] == 0) {
var zr = window.document.getElementById("zmmtg-root");
querySelector('body')?.append(zr!);
zoom.onMeetingStatus().listen((status) {
print("[Meeting Status Stream] : " + status[0] + " - " + status[1]);
});
final signature = zoom.generateSignature(zoomOptions.appKey.toString(), zoomOptions.appSecret.toString(), meetingIdController.text, 0);
meetingOptions.jwtAPIKey = zoomOptions.appKey.toString();
meetingOptions.jwtSignature = signature;
zoom.joinMeeting(meetingOptions).then((joinMeetingResult) {
print("[Meeting Status Polling] : " + joinMeetingResult[0] + " - " + joinMeetingResult[1]);
});
}
}).catchError((error) {
print("[Error Generated] : " + error);
});
}
copied to clipboard
Start a Meeting - For Web (JWT Required) #

Pass the Jwt API Key as api key for web & Jwt API Secret as appSecret
Role must be passed as 1 inside generateSignature for start a meeting
Pass your Personal meeting ID and Passcode to staty the meeting (Meeeting ID and Passcode must belong to same user account as JWT credentials)

startMeetingWeb(BuildContext context) {
ZoomOptions zoomOptions = new ZoomOptions(
domain: "zoom.us",
appKey: "", //API KEY FROM ZOOM - Jwt API Key
appSecret: "", //API SECRET FROM ZOOM - Jwt API Secret
language: "en-US", // Optional - For Web
showMeetingHeader: true, // Optional - For Web
disableInvite: false, // Optional - For Web
disableCallOut: false, // Optional - For Web
disableRecord: false, // Optional - For Web
disableJoinAudio: false, // Optional - For Web
audioPanelAlwaysOpen: false, // Optional - For Web
isSupportAV: true, // Optional - For Web
isSupportChat: true, // Optional - For Web
isSupportQA: true, // Optional - For Web
isSupportCC: true, // Optional - For Web
isSupportPolling: true, // Optional - For Web
isSupportBreakout: true, // Optional - For Web
screenShare: true, // Optional - For Web
rwcBackup: '', // Optional - For Web
videoDrag: true, // Optional - For Web
sharingMode: 'both', // Optional - For Web
videoHeader: true, // Optional - For Web
isLockBottom: true, // Optional - For Web
isSupportNonverbal: true, // Optional - For Web
isShowJoiningErrorDialog: true, // Optional - For Web
disablePreview: false, // Optional - For Web
disableCORP: true, // Optional - For Web
inviteUrlFormat: '', // Optional - For Web
disableVOIP: false, // Optional - For Web
disableReport: false, // Optional - For Web
meetingInfo: const [
// Optional - For Web
'topic',
'host',
'mn',
'pwd',
'telPwd',
'invite',
'participant',
'dc',
'enctype',
'report'
]
);
var meetingOptions = new ZoomMeetingOptions(
userId: '', //pass host username for zoom
meetingId: meetingIdController.text, //Personal meeting id for start meeting required
meetingPassword: meetingPasswordController.text, //Personal meeting passcode for start meeting required
//To get personal meeting id and passcode follow https://zoom.us/meeting#/ and navigate to Personal Room tab
);

var zoom = ZoomViewWeb();
zoom.initZoom(zoomOptions).then((results) {
if(results[0] == 0) {
var zr = window.document.getElementById("zmmtg-root");
querySelector('body')?.append(zr!);
zoom.onMeetingStatus().listen((status) {
print("[Meeting Status Stream] : " + status[0] + " - " + status[1]);
});
final signature = zoom.generateSignature(zoomOptions.appKey.toString(), zoomOptions.appSecret.toString(), meetingIdController.text, 1);
meetingOptions.jwtAPIKey = zoomOptions.appKey.toString();
meetingOptions.jwtSignature = signature;
zoom.startMeeting(meetingOptions).then((startMeetingResult) {
print("[Meeting Status Polling] : " + startMeetingResult[0] + " - " + startMeetingResult[1]);
});
}
}).catchError((error) {
print("[Error Generated] : " + error);
});
}
copied to clipboard
Start a Meeting - Login user #

Pass the Zoom user email and password to the plugin.

startMeeting(BuildContext context) {
bool _isMeetingEnded(String status) {
var result = false;

if (Platform.isAndroid)
result = status == "MEETING_STATUS_DISCONNECTING" || status == "MEETING_STATUS_FAILED";
else
result = status == "MEETING_STATUS_IDLE";

return result;
}
ZoomOptions zoomOptions = new ZoomOptions(
domain: "zoom.us",
appKey: "", //API KEY FROM ZOOM - Sdk API Key
appSecret: "", //API SECRET FROM ZOOM - Sdk API Secret
);
var meetingOptions = new ZoomMeetingOptions(
userId: '', //pass host email for zoom
userPassword: '', //pass host password for zoom
disableDialIn: "false",
disableDrive: "false",
disableInvite: "false",
disableShare: "false",
disableTitlebar: "false",
viewOptions: "false",
noAudio: "false",
noDisconnectAudio: "false"
);

var zoom = ZoomView();
zoom.initZoom(zoomOptions).then((results) {
if(results[0] == 0) {
zoom.onMeetingStatus().listen((status) {
print("[Meeting Status Stream] : " + status[0] + " - " + status[1]);
if (_isMeetingEnded(status[0])) {
print("[Meeting Status] :- Ended");
timer.cancel();
}
if(status[0] == "MEETING_STATUS_INMEETING"){
zoom.meetinDetails().then((meetingDetailsResult) {
print("[MeetingDetailsResult] :- " + meetingDetailsResult.toString());
});
}
});
zoom.startMeeting(meetingOptions).then((loginResult) {
print("[LoginResult] :- " + loginResult[0] + " - " + loginResult[1]);
if(loginResult[0] == "SDK ERROR"){
//SDK INIT FAILED
print((loginResult[1]).toString());
}else if(loginResult[0] == "LOGIN ERROR"){
//LOGIN FAILED - WITH ERROR CODES
if (loginResult[1] ==
ZoomError.ZOOM_AUTH_ERROR_WRONG_ACCOUNTLOCKED) {
print("Multiple Failed Login Attempts");
}
print((loginResult[1]).toString());
}else{
//LOGIN SUCCESS & MEETING STARTED - WITH SUCCESS CODE 200
print((loginResult[0]).toString());
}
});
}
}).catchError((error) {
print("[Error Generated] : " + error);
});
}
copied to clipboard
Migration Guide #
Start a Meeting - Login user #
var meetingOptions = new ZoomMeetingOptions(
userId: '', //pass host email for zoom
userPassword: '', // replace 'meetingPassword' with userPassword
disableDialIn: "false",
disableDrive: "false",
disableInvite: "false",
disableShare: "false",
disableTitlebar: "false",
viewOptions: "false",
noAudio: "false",
noDisconnectAudio: "false"
);
copied to clipboard
ZoomView(onViewCreated: (controller) {}) --- Replaced with #
var zoom = ZoomView();
// Initializing Zoom SDK
zoom.initZoom(zoomOptions).then((results) {}

copied to clipboard
controller.zoomStatusEvents.listen((status) {}) -- Replaced With #
var zoom = ZoomView();
zoom.initZoom(zoomOptions).then((results) {
if(results[0] == 0){
zoom.onMeetingStatus().listen((status) {
//Some Statement
//Log for meeting status
}
}
}

copied to clipboard
Start meetion function chaged :- #
controller.login(this.widget.loginOptions).then((loginResult) {})

copied to clipboard
var zoom = ZoomView();
zoom.initZoom(zoomOptions).then((results) {
if(results[0] == 0){
zoom.onMeetingStatus().listen((status) {
//Some Statement
//Log for meeting status
}
zoom.startMeeting(meetingOptions).then((loginResult) {
print("[LoginResult] :- " + loginResult[0] + " - " + loginResult[1]);
if(loginResult[0] == "SDK ERROR"){
//SDK INIT FAILED
print((loginResult[1]).toString());
}else if(loginResult[0] == "LOGIN ERROR"){
//LOGIN FAILED - WITH ERROR CODES
print((loginResult[1]).toString());
}else{
//LOGIN SUCCESS & MEETING STARTED - WITH SUCCESS CODE 200
print((loginResult[0]).toString());
}
});
}
}

copied to clipboard

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Customer Reviews

There are no reviews.