diff --git a/client/packages/lowcoder-design/src/components/Section.tsx b/client/packages/lowcoder-design/src/components/Section.tsx
index feae5402a..a0c18134f 100644
--- a/client/packages/lowcoder-design/src/components/Section.tsx
+++ b/client/packages/lowcoder-design/src/components/Section.tsx
@@ -142,4 +142,5 @@ export const sectionNames = {
   validation: trans("prop.validation"),
   layout: trans("prop.layout"),
   style: trans("prop.style"),
+  meetings : trans("prop.meetings"),
 };
diff --git a/client/packages/lowcoder-design/src/i18n/design/locales/en.ts b/client/packages/lowcoder-design/src/i18n/design/locales/en.ts
index 0082f6f98..59e045b55 100644
--- a/client/packages/lowcoder-design/src/i18n/design/locales/en.ts
+++ b/client/packages/lowcoder-design/src/i18n/design/locales/en.ts
@@ -23,6 +23,7 @@ export const en = {
     validation: "Validation",
     layout: "Layout",
     style: "Style",
+    meetings : "Meeting Settings",
   },
   passwordInput: {
     label: "Password:",
diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx
index d3ad399a5..b6034a6db 100644
--- a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx
+++ b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx
@@ -179,6 +179,7 @@ let ButtonTmpComp = (function () {
     iconSize: withDefault(StringControl, "20px"),
     type: dropdownControl(typeOptions, ""),
     autoHeight: withDefault(AutoHeightControl, "fixed"),
+    aspectRatio: withDefault(StringControl, "1 / 1"),
     onEvent: ButtonEventHandlerControl,
     disabled: BoolCodeControl,
     loading: BoolCodeControl,
@@ -244,8 +245,16 @@ let ButtonTmpComp = (function () {
                   loading={props.loading}
                   style={
                     props.autoHeight
-                      ? { width: "100%", height: "100%" }
-                      : undefined
+                      ? { 
+                        width: "100%", 
+                        height: "100%",
+                        aspectRatio: props.aspectRatio,
+                        borderRadius: props.style.radius,
+                      }
+                      : {
+                        aspectRatio: props.aspectRatio,
+                        borderRadius: props.style.radius,
+                      }
                   }
                   disabled={
                     props.disabled ||
@@ -304,6 +313,9 @@ let ButtonTmpComp = (function () {
         </Section>
         <Section name={sectionNames.style}>
           {children.style.getPropertyView()}
+          {children.aspectRatio.propertyView({
+            label: "Video Aspect Ratio",
+          })}
         </Section>
       </>
     ))
diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx
index 427feabb3..49a5f2cbb 100644
--- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx
@@ -41,7 +41,10 @@ import { useUserViewMode } from "util/hooks";
 import { isNumeric } from "util/stringUtils";
 import { NameConfig, withExposingConfigs } from "../../generators/withExposing";
 
-import axios from "axios";
+import { v4 as uuidv4 } from 'uuid';
+
+// import axios from "axios";
+
 import AgoraRTC, {
   ICameraVideoTrack,
   IMicrophoneAudioTrack,
@@ -51,7 +54,7 @@ import AgoraRTC, {
   ILocalVideoTrack,
 } from "agora-rtc-sdk-ng";
 
-import { JSONValue } from "@lowcoder-ee/index.sdk";
+import { JSONValue, NumberControl } from "@lowcoder-ee/index.sdk";
 import { getData } from "../listViewComp/listViewUtils";
 import AgoraRTM, { RtmChannel, RtmClient } from "agora-rtm-sdk";
 
@@ -103,7 +106,16 @@ export const client: IAgoraRTCClient = AgoraRTC.createClient({
   mode: "rtc",
   codec: "vp8",
 });
-AgoraRTC.setLogLevel(3);
+
+AgoraRTC.setLogLevel(4);
+
+/* 
+0: DEBUG. Output all API logs.
+1: INFO. Output logs of the INFO, WARNING and ERROR level.
+2: WARNING. Output logs of the WARNING and ERROR level.
+3: ERROR. Output logs of the ERROR level.
+4: NONE. Do not output any log. 
+*/
 
 let audioTrack: IMicrophoneAudioTrack;
 let videoTrack: ICameraVideoTrack;
@@ -111,20 +123,6 @@ let screenShareStream: ILocalVideoTrack;
 let userId: UID | null | undefined;
 let rtmChannelResponse: RtmChannel;
 let rtmClient: RtmClient;
-const agoraTokenUrl = `https://sandbox.wiggolive.com/token/rtc`;
-
-const generateToken = async (
-  appId: any,
-  certificate: any,
-  channelName: any
-) => {
-  let response = await axios.post(agoraTokenUrl, {
-    appId,
-    certificate,
-    channelName,
-  });
-  return response.data;
-};
 
 const turnOnCamera = async (flag?: boolean) => {
   if (videoTrack) {
@@ -147,7 +145,7 @@ const turnOnMicrophone = async (flag?: boolean) => {
 };
 const shareScreen = async (sharing: boolean) => {
   try {
-    if (sharing == false) {
+    if (sharing === false) {
       await client.unpublish(screenShareStream);
       await client.publish(videoTrack);
       videoTrack.play(userId + "");
@@ -179,23 +177,18 @@ const leaveChannel = async () => {
   await rtmChannelResponse.leave();
 };
 
-const hostChanged = (users: any) => {};
-
 const publishVideo = async (
   appId: string,
-  channel: any,
-  height: any,
-  certifiCateKey: string
+  channel: string,
+  rtmToken: string,
+  rtcToken: string
 ) => {
-  let token = null;
-  if (certifiCateKey) {
-    token = await generateToken(appId, certifiCateKey, channel);
-  }
-  await turnOnCamera(true);
-  await client.join(appId, channel, token, userId);
-  await client.publish(videoTrack);
-
-  await rtmInit(appId, userId, channel);
+    // initializing the Agora Meeting Client
+    await turnOnCamera(true);
+    await client.join(appId, channel, rtcToken, userId);
+    await client.publish(videoTrack);
+    // initializing the Agora RTM Client
+    await rtmInit(appId, userId, rtmToken, channel);
 };
 
 const sendMessageRtm = (message: any) => {
@@ -206,10 +199,11 @@ const sendPeerMessageRtm = (message: any, toId: string) => {
   rtmClient.sendMessageToPeer({ text: JSON.stringify(message) }, toId);
 };
 
-const rtmInit = async (appId: any, uid: any, channel: any) => {
+const rtmInit = async (appId: any, uid: any, token: any, channel: any) => {
   rtmClient = AgoraRTM.createInstance(appId);
   let options = {
     uid: String(uid),
+    token: token ? token : null,
   };
   await rtmClient.login(options);
 
@@ -237,8 +231,10 @@ export const meetingControllerChildren = {
   participants: stateComp<JSONValue>([]),
   usersScreenShared: stateComp<JSONValue>([]),
   localUser: jsonObjectExposingStateControl(""),
-  meetingName: stringStateControl("meetingName"),
-  certifiCateKey: stringStateControl(""),
+  localUserID : withDefault(stringStateControl(trans("meeting.localUserID")), uuidv4() + ""),
+  meetingName: withDefault(stringStateControl(trans("meeting.meetingName")), uuidv4() + ""),
+  rtmToken: stringStateControl(trans("meeting.rtmToken")),
+  rtcToken: stringStateControl(trans("meeting.rtcToken")),
   messages: stateComp<JSONValue>([]),
 };
 let MTComp = (function () {
@@ -269,34 +265,29 @@ let MTComp = (function () {
       });
       const [rtmMessages, setRtmMessages] = useState<any>([]);
       const [localUserSpeaking, setLocalUserSpeaking] = useState<any>(false);
-      const [localUserVideo, setLocalUserVideo] =
-        useState<IAgoraRTCRemoteUser>();
+      const [localUserVideo, setLocalUserVideo] = useState<IAgoraRTCRemoteUser>();
       const [userJoined, setUserJoined] = useState<IAgoraRTCRemoteUser>();
       const [userLeft, setUserLeft] = useState<IAgoraRTCRemoteUser>();
 
       useEffect(() => {
         if (userJoined) {
+          let prevUsers: any[] = props.participants as [];
           let userData = {
             user: userJoined.uid,
-            host: false,
             audiostatus: userJoined.hasAudio,
             streamingVideo: true,
           };
           setUserIds((userIds: any) => [...userIds, userData]);
-          if (userIds.length == 0) {
-            userData.host = true;
-          } else {
-            userData.host = false;
-          }
           dispatch(
             changeChildAction(
               "participants",
-              removeDuplicates(getData([...userIds, userData]).data, "user"),
+              removeDuplicates(getData([...prevUsers, userData]).data, "user"),
               false
             )
           );
         }
       }, [userJoined]);
+
       function removeDuplicates(arr: any, prop: any) {
         const uniqueObjects = [];
         const seenValues = new Set();
@@ -320,7 +311,6 @@ let MTComp = (function () {
           let hostExists = newUsers.filter((f: any) => f.host === true);
           if (hostExists.length == 0 && newUsers.length > 0) {
             newUsers[0].host = true;
-            hostChanged(newUsers);
           }
           setUserIds(newUsers);
           dispatch(
@@ -432,8 +422,6 @@ let MTComp = (function () {
           client.on(
             "user-unpublished",
             (user: IAgoraRTCRemoteUser, mediaType: "video" | "audio") => {
-              console.log("user-unpublished");
-
               setLocalUserVideo(user);
             }
           );
@@ -507,15 +495,6 @@ let MTComp = (function () {
     .setPropertyViewFn((children) => (
       <>
         <Section name={sectionNames.basic}>
-          {children.appId.propertyView({ label: trans("meeting.appid") })}
-          {children.certifiCateKey.propertyView({
-            label: trans("meeting.certifiCateKey"),
-          })}
-
-          {children.meetingName.propertyView({
-            label: trans("meeting.meetingName"),
-          })}
-
           {children.placement.propertyView({
             label: trans("drawer.placement"),
             radioButton: true,
@@ -541,6 +520,23 @@ let MTComp = (function () {
             label: trans("prop.showMask"),
           })}
         </Section>
+        <Section name={sectionNames.meetings}>
+          {children.appId.propertyView({ 
+            label: trans("meeting.appid") 
+          })}
+          {children.meetingName.propertyView({
+            label: trans("meeting.meetingName"),
+          })}
+          {children.localUserID.propertyView({
+            label: trans("meeting.localUserID"),
+          })}
+          {children.rtmToken.propertyView({
+            label: trans("meeting.rtmToken"),
+          })}
+          {children.rtcToken.propertyView({
+            label: trans("meeting.rtcToken"),
+          })}
+        </Section>
         <Section name={sectionNames.interaction}>
           {children.onEvent.getPropertyView()}
         </Section>
@@ -636,7 +632,8 @@ MTComp = withMethodExposing(MTComp, [
       params: [],
     },
     execute: async (comp, values) => {
-      userId = Math.floor(100000 + Math.random() * 900000);
+      if (comp.children.meetingActive.getView().value) return;
+      userId = comp.children.localUserID.getView().value === "" ? uuidv4() : comp.children.localUserID.getView().value;
       comp.children.localUser.change({
         user: userId + "",
         audiostatus: false,
@@ -659,11 +656,9 @@ MTComp = withMethodExposing(MTComp, [
       comp.children.videoControl.change(true);
       await publishVideo(
         comp.children.appId.getView(),
-        comp.children.meetingName.getView().value == ""
-          ? "_meetingId"
-          : comp.children.meetingName.getView().value,
-        comp.children,
-        comp.children.certifiCateKey.getView().value
+        comp.children.meetingName.getView().value === "" ? uuidv4() : comp.children.meetingName.getView().value, 
+        comp.children.rtmToken.getView().value,
+        comp.children.rtcToken.getView().value
       );
       comp.children.meetingActive.change(true);
     },
@@ -677,9 +672,9 @@ MTComp = withMethodExposing(MTComp, [
     execute: async (comp, values) => {
       if (!comp.children.meetingActive.getView().value) return;
       let otherData =
-        values != undefined && values[1] !== undefined ? values[1] : "";
+        values !== undefined && values[1] !== undefined ? values[1] : "";
       let toUsers: any =
-        values != undefined && values[0] !== undefined ? values[0] : "";
+        values !== undefined && values[0] !== undefined ? values[0] : "";
 
       let message: any = {
         time: Date.now(),
@@ -711,7 +706,7 @@ MTComp = withMethodExposing(MTComp, [
   {
     method: {
       name: "setUserName",
-      description: trans("meeting.meetingName"),
+      description: trans("meeting.userName"),
       params: [],
     },
     execute: async (comp, values) => {
@@ -720,6 +715,28 @@ MTComp = withMethodExposing(MTComp, [
       comp.children.localUser.change({ ...userLocal, userName: userName });
     },
   },
+  {
+    method: {
+      name: "setRTCToken",
+      description: trans("meeting.rtcToken"),
+      params: [],
+    },
+    execute: async (comp, values) => {
+      let rtcToken: any = values[0];
+      comp.children.rtcToken.change(rtcToken);
+    },
+  },
+  {
+    method: {
+      name: "setRTMToken",
+      description: trans("meeting.rtmToken"),
+      params: [],
+    },
+    execute: async (comp, values) => {
+      let rtmToken: any = values[0];
+      comp.children.rtmToken.change(rtmToken);
+    },
+  },
   {
     method: {
       name: "endMeeting",
@@ -758,7 +775,10 @@ export const VideoMeetingControllerComp = withExposingConfigs(MTComp, [
   new NameConfig("appId", trans("meeting.appid")),
   new NameConfig("localUser", trans("meeting.host")),
   new NameConfig("participants", trans("meeting.participants")),
-  new NameConfig("meetingActive", trans("meeting.meetingName")),
+  new NameConfig("meetingActive", trans("meeting.meetingActive")),
   new NameConfig("meetingName", trans("meeting.meetingName")),
-  new NameConfig("messages", trans("meeting.meetingName")),
+  new NameConfig("localUserID", trans("meeting.localUserID")),
+  new NameConfig("messages", trans("meeting.messages")), 
+  new NameConfig("rtmToken", trans("meeting.rtmToken")),
+  new NameConfig("rtcToken", trans("meeting.rtcToken")),
 ]);
diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx
index 2218ba0c3..5fbc372b7 100644
--- a/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx
@@ -151,10 +151,7 @@ export const meetingStreamChildren = {
   style: ButtonStyleControl,
   viewRef: RefControl<HTMLElement>,
   userId: stringExposingStateControl(""),
-  profileImageUrl: withDefault(
-    StringStateControl,
-    "https://via.placeholder.com/120"
-  ),
+  profileImageUrl: withDefault(StringStateControl, "https://api.dicebear.com/7.x/fun-emoji/svg?seed=Peanut&radius=50&backgroundColor=transparent&randomizeIds=true&eyes=wink,sleepClose"),
   noVideoText: stringExposingStateControl("No Video"),
 };
 
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 7f20f9c9e..40138fb17 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -2,7 +2,8 @@ import table from "./componentDocExtra/table.md?url";
 
 export const en = {
   productName: "Lowcoder",
-  productDesc: "Create software applications for your Company and your Customers with minimal coding experience. Lowcoder is the best Retool, Appsmith or Tooljet Alternative.",
+  productDesc:
+    "Create software applications for your Company and your Customers with minimal coding experience. Lowcoder is the best Retool, Appsmith or Tooljet Alternative.",
   notSupportedBrowser:
     "Your current browser may have compatibility issues. For a better user experience, it is recommended to use the latest version of the Chrome browser.",
   create: "Create",
@@ -1441,6 +1442,7 @@ export const en = {
     height: "Drawer height",
   },
   meeting: {
+    logLevel: "Agora SDK Log Level",
     placement: "Meeting placement",
     meeting: "Meeting Settings",
     cameraView: "Camera View",
@@ -1454,17 +1456,21 @@ export const en = {
     videoOn: "Video On",
     size: "Size",
     top: "Top",
-    host: "Host",
-    participants: "Participants",
-    shareScreen: "Share Screen",
-    appid: "Application Id",
+    host: "Host of the Meetingroom",
+    participants: "Participants of the Meetingroom",
+    shareScreen: "Local Screenshare",
+    appid: "Agora Application Id",
     meetingName: "Meeting Name",
+    localUserID: "Host User Id",
+    userName: "Host User Name",
+    rtmToken : "Agora RTM Token",
+    rtcToken : "Agora RTC Token",
     videoCompText: "No video Text",
     profileImageUrl: "Profile Image Url",
     right: "Right",
     bottom: "Bottom",
-    videoId: "Video Id",
-    audioStatus: "audio status",
+    videoId: "Video Stream Id",
+    audioStatus: "Audio status",
     left: "Left",
     widthTooltip: "Number or percentage, e.g. 520, 60%",
     heightTooltip: "Number, e.g. 378",
@@ -1474,11 +1480,10 @@ export const en = {
     height: "Drawer height",
     actionBtnDesc: "Action Button",
     broadCast: "BroadCast Messages",
-    certifiCateKey: "certifiCate Key",
-    title: "Meeting title",
+    title: "Meeting Title",
     meetingCompName: "Meeting Controller",
     videoCompName: "Video Stream",
-    videoSharingCompName: "Video Sharing",
+    videoSharingCompName: "Screen Sharing",
     meetingControlCompName: "Controls Buttons",
     meetingCompDesc: "Meeting component",
     meetingCompControls: "Meeting control",
@@ -1486,6 +1491,8 @@ export const en = {
     iconSize: "Icon Size",
     userId: "userId",
     roomId: "roomId",
+    meetingActive :  "Ongoing Meeting",
+    messages : "Broadcasted Messages",
   },
   settings: {
     title: "Settings",
@@ -2094,7 +2101,7 @@ export const en = {
     resetSuccessDesc:
       "Password reset succeeded. The new password is: {password}",
     copyPassword: "Copy password",
-    poweredByLowcoder: "Powered by Lowcoder.cloud"
+    poweredByLowcoder: "Powered by Lowcoder.cloud",
   },
   preLoad: {
     jsLibraryHelpText: