All pages
Powered by GitBook
1 of 1

Loading...

Kotlin

Sariska Media provides a robust suite of Kotlin APIs designed to streamline the development of real-time android applications. With Sariska, you can seamlessly integrate a variety of features.

Installation

Step 1 : Install Sariska Media Transport Client

With Pre-built Artifacts

  • For older Android Studio versions:

  1. In your project's root directory, locate the build.gradle file.

  2. Add the following code block within the repositories section:

In recent versions of Android Studio, the allprojects section might be absent in build.gradle

In that case, the repository goes into the settings.gradle file in the root of your project.

  • For newer Android Studio versions:

  1. In your project's root directory, locate the settings.gradle file.

  2. Add the following code block within the repositories section:

With Maven

Add the dependency:

Step 2 : Initialize SDK

After installing the Sariska Media Transport SDK, begin by initializing it.

Step 3 : Establish a WebSocket Connection

Media Services utilizes WebSockets to establish a continuous, two-way communication channel between your application and the server. This persistent connection offers significant advantages over traditional HTTP requests, particularly in terms of responsiveness.

Step 4 : Initiate a Conference

Create a Jitsi-powered conference for real-time audio and video.

Customize conference

To join with audio muted

startAudioMuted: true

Step 5 : Capture Local Stream

A MediaStream consists of various audio or video tracks represented by MediaStreamTrack objects. Each track can have multiple channels, which are the smallest units of the stream (e.g., left and right audio channels in stereo).

Customize tracks

devices:

  • Type: Array of strings

  • Values: "desktop", "video", "audio"

Step 6 : Play Local Stream

Additional view properties

view.setMirror(mirror): Set whether to mirror your video (true/false).

view.setObjectFit("cover"): Set how the video fills the view ("cover" or "contain").

view.setZOrderMediaOverlay(0): Set the layering order (0 or 1).

Audio playback is handled automatically with the video stream.

Step 7 : Handle User Joined Event

This event is triggered when a new user joins the conference. Moderators have exclusive control over meetings and can manage participants. To assign a moderator, set the moderator value to true when generating the token.

Moderator permissions
  • Password Protection:

Ability to add a password to the meeting room, restricting access.

  • Role Assignment:

Joined participant properties

avatar:

  • Type: String

  • Purpose: Used to display their profile picture in the UI.

email:

Step 8 : Publish Streams

Make audio and video streams visible to others in the conference by publishing them using the following code:

Step 9 : Play Remote Peers Streams

Analytics

Sariska-media-transport offers pre-configured events to help you track and analyze user interactions, media usage, and overall performance. This data can be used to enhance your product, improve user experience, and make informed decisions.

Available Events

Here are some of the key events you can track:

  • User Actions:

    • User joined

    • User left

  • Media Usage:

Add Event Listener to Track Events

Features

Sariska offers powerful features to enhance your application's capabilities. Find your desired feature using the search bar or explore below!

Active/Dominant Speaker

Identify the main speaker: Easily detect the active or dominant speaker in a conference. Choose to stream only their video for improved resolution and reduced bandwidth usage. Ideal for one-way streaming scenarios like virtual concerts.

Last N Speakers

Dynamically showcase recent speakers: Focus on the active conversation by displaying video only for the last N participants who spoke. This automatically adjusts based on speech activity, offering a more efficient and relevant view.

Participant Information

Set local participant properties: Define additional information about participants beyond the default settings. This can include screen-sharing status, custom roles, or any other relevant attributes.

Participant Count

Get the total number of participants: Retrieve the complete participant count, including both visible and hidden members.

Some conferences may include hidden participants besides attendees, such as bots assisting with recording, transcription, or pricing.

Participant Lists

Access all participants: Obtain a list of all participants, including their IDs and detailed information.

Pinning Participants

  • Pin a single participant: Give a participant higher video quality (if simulcast is enabled).

  • Pin multiple participants: Give multiple participants higher video quality.

Access Local User Details

Retrieve information about the local user directly from the conference object.

Set Meeting Subject

Set the subject of the meeting.

Manage Tracks

  • Get all remote tracks: Retrieve a list of all remote tracks (audio and video) in the conference.

  • Get all local tracks: Retrieve a list of all local tracks (audio and video)

Kick Participants

  • Listen for participant kick events

  • Kick a participant

Manage Owner Roles

The room creator has a moderator role, while other users have a participatory role.

  • Grant owner rights

  • Listen for role changes

  • Revoke owner rights

Change Display Names

  • Setting a new display name

  • Listen for display name changes

Lock/Unlock Room

  • Lock room: Moderators can restrict access to the room with a password.

  • Unlock room: Removes any existing password restriction.

Subtitles

  • Request subtitles: Enable subtitles for spoken content.

  • Request language translation: Translate subtitles into a specific language.

Language Code
Language Name

  • Receive subtitles: Listen for incoming subtitles.

  • Stop subtitles: Disable subtitles.

Screen Share

Each participant can contribute two types of data to a meeting: audio and video. Screen sharing counts as a video track. If you want to share your screen while also showing your own video (like when presenting), you need to enable "Presenter mode". This mode hides the gallery of other participants' videos and gives you more control over the meeting layout.

  • Start screen share: Share your screen with other participants.

Messages

Sariska offers robust messaging capabilities for both private and group communication scenarios.

  • Send a group message to all participants

  • Send a private message to a specific participant

  • Listen for incoming messages

Transcription

  • Start Transcription: Initiate transcription for the ongoing conference.

  • Stop Transcription: Stop transcription and get a download link for the transcript.

Mute/Unmute Participants

  • Mute Remote Participant

The moderator has the ability to temporarily silence the microphone of any participant who is not physically present in the meeting room.

  • Mute/Unmute Local Participant

Connection Quality

  • Local Connection Statistics Received

  • Remote Connection Statistics Received

Internet Connectivity Status

The SDK features intelligent auto-join/leave functionality based on internet connectivity status. This helps optimize network resources and improve user experience.

Peer-to-Peer Mode

Designed for efficient communication between two participants.

  • Start Peer-to-Peer Mode

Sariska automatically activates Peer-to-Peer mode when your conference has exactly two participants. This mode bypasses the central server and directly connects participants, maximizing bandwidth efficiency and reducing latency. However, even with more than two participants, you can forcefully start Peer-to-Peer mode.

Starting Peer-to-Peer mode eliminates server charges as long as the central turn server remains unused.

  • Stop Peer-to-Peer Mode

If you need to revert to server-mediated communication, you can easily stop Peer-to-Peer mode.

CallStats Integration

Monitor your WebRTC application performance using CallStats (or build your own). See the "RTC Stats" section for details.

Join Muted/Silent

Join conferences with audio and video already muted, or in a silent mode where no audio is transmitted or received. This ensures a seamless experience and respects participant preferences.

  • Join with Muted Audio and Video

  • Join in Silent Mode

Live Stream

Broadcast your conference to multiple platforms simultaneously. Embed live streams directly into your app or website using various formats.

  • Stream to YouTube

  • Stream to Facebook

  • Stream to Twitch

  • Stream to any RTMP Server

Listen for RECORDER_STATE_CHANGED event to track streaming status

Stop Live Stream

Cloud Recording

Store your recordings and transcriptions in various cloud storage services.

Supported storage providers
  1. Object-based storage: Amazon S3, Google Cloud Storage, Azure Blob Storage, other S3-compatible cloud providers.

  2. Dropbox

Set credentials
  1. Object-based storage

    • Access your Sariska dashboard

PSTN

  • Dial-in(PSTN)

Share this phone number and pin with users to enable PSTN conference call participation.

  • Dial-out(PSTN)

This initiates a call to the provided phone number, inviting them to join the conference.

Lobby/Waiting Room

SIP Video Gateway

One-to-One Calling

This allows synchronous phone calls, similar to WhatsApp, even if the receiver's app is closed or in the background.

Initiating Calls:

  • Make a call even if the callee's app is closed or in the background.

  • Play a busy tone if the callee is on another call or disconnects your call.

  • Play ringtone/ringback/DTMF tones.

Step 1 : Caller Initiates Call

  1. HTTP Call to Sariska Server

{API Method}

  1. Push Notification to callee using Firebase or APNS

This notifies the receiver even if their app is closed or in the background.

Step 2 : Callee Responds to Call

  1. Reads Push Notification

Processes the notification even if the app is closed or in the background.

  1. HTTP Call to Update Status

{API Method}

  1. No need to join conference via SDK

Status update through the HTTP call suffices.

Step 3 : Caller Receives Response

Listens for USER_STATUS_CHANGED event

Event status details
  • ringing: receiver's phone is ringing

  • busy: receiver is on another call

  • rejected: receiver declined your call

Step 4 : After Connection Established

The call proceeds like a normal conference call.

To join with video muted

startVideoMuted: true

To join with startSilent no audio receive/send

startSilent: true

To enable rtcstats tracking analytics

rtcstatsServer: ""

CallStats ID

callStatsID: ""

CallStats Secret

callStatsSecret: ""

Last n speakers

channelLastN: 10

Purpose: Specifies which devices to request from the browser's GetUserMedia (GUM) API.

  • Default: If this property is not set, GUM will attempt to access all available devices.

  • resolution:

    • Type: String

    • Values: 180, 240, 360, vga, 480, qhd, 540, hd, 720, fullhd, 1080, 4k, 2160

    • Purpose: Sets the preferred resolution for the local video stream.

    cameraDeviceId

    • Type: String

    • Purpose: Specifies the device ID of the camera to use.

    micDeviceId

    • Type: String

    • Purpose: Specifies the device ID of the microphone to use.

    minFps

    • Type: Integer

    • Purpose: Sets the minimum frame rate for the video stream.

    maxFps

    • Type: Integer

    • Purpose: Sets the maximum frame rate for the video stream.

    desktopSharingFrameRate

    • Type: Object

    • Properties:

      • min: Minimum frame rate for desktop sharing

      • max: Maximum frame rate for desktop sharing

    desktopSharingSourceDevice

    • Type: String

    • Purpose: Specifies the device ID or label of the video input source to use for screen sharing.

    facingMode

    • Type: String

    • Values: "user", "environment"

    • Purpose: Sets the camera's facing mode (front-facing or back-facing).

    view.setZOrderOnTop(0)
    : Set the layering order (0, 1, or 2).
    Ability to grant moderator privileges to other participants.

    • Participant Removal:

    Ability to kick non-moderators or even other moderators from the meeting.

    • Audio Control:

    Ability to mute individual participants or all participants at once.

    • Video Focus:

    Ability to make everyone's video view follow the moderator's video.

    • Joining Settings: Ability to:

      • Set participants to join with audio muted by default.

      • Set participants to join with video disabled by default.

    • Lobby Management:

    Ability to enable or disable the lobby room, requiring approval for participants to join.

    • Join Approval:

    Ability to approve or deny join requests when the lobby is enabled.

    • Moderator Transfer:

    If the current moderator leaves the meeting, a new moderator is automatically selected.

  • Type: String

  • Purpose: May be used for identification or communication purposes.

  • moderator:

    • Type: Boolean

    • Purpose: Used to control moderation-related features in the UI.

    audioMuted:

    • Type: Boolean

    • Purpose: Used to display the audio muted state in the UI.

    videoMuted:

    • Type: Boolean

    • Purpose: Used to display the video muted state in the UI.

    displayName:

    • Type: String

    • Purpose: Used to identify them in the UI.

    role:

    • Type: String

    • Purpose: Used to determine their permissions and UI features.

    status:

    • Type: String

    • Purpose: Used to display ("online", "offline", "away") their availability in the UI.

    hidden:

    • Type: Boolean

    • Purpose: Typically used for bots like transcribers or recorders.

    botType:

    • Type: String

    • Purpose: Used to identify the bot's purpose and capabilities.

    Conference duration

  • Camera duration

  • Audio track duration

  • Video track duration

  • Recording:

    • Recording started

    • Recording stopped

    • Local recording started

    • Local recording stopped

  • Transcription:

    • Transcription started

    • Transcription stopped

  • Performance:

    • Speaker stats

    • Connection stats

    • Performance stats

  • Danish

    de

    German

    el

    Greek

    en

    English

    enGB

    English (United Kingdom)

    eo

    Esperanto

    es

    Spanish

    esUS

    Spanish (Latin America)

    et

    Estonian

    eu

    Basque

    fi

    Finnish

    fr

    French

    frCA

    French (Canadian)

    he

    Hebrew

    hi

    Hindi

    hr

    Croatian

    hu

    Hungarian

    hy

    Armenian

    id

    Indonesian

    it

    Italian

    ja

    Japanese

    kab

    Kabyle

    ko

    Korean

    lt

    Lithuanian

    ml

    Malayalam

    lv

    Latvian

    nl

    Dutch

    oc

    Occitan

    fa

    Persian

    pl

    Polish

    pt

    Portuguese

    ptBR

    Portuguese (Brazil)

    ru

    Russian

    ro

    Romanian

    sc

    Sardinian

    sk

    Slovak

    sl

    Slovenian

    sr

    Serbian

    sq

    Albanian

    sv

    Swedish

    te

    Telugu

    th

    Thai

    tr

    Turkish

    uk

    Ukrainian

    vi

    Vietnamese

    zhCN

    Chinese (China)

    zhTW

    Chinese (Taiwan)

    mr

    Marathi

    Locate the storage credentials section
  • Enter the required credentials for your chosen provider

  • Dropbox

    • Obtain a Dropbox OAuth token

  • connected: receiver accepted your call

  • expired: receiver didn't answer within 40 seconds

  • af

    Afrikaans

    ar

    Arabic

    bg

    Bulgarian

    ca

    Catalan

    cs

    Czech

    da

    allprojects {
        // Add the Sariska repository
        repositories {
            maven {
                url "https://github.com/SariskaIO/sariska-maven-repository/raw/master/releases"
            }
            
            // Add other repositories
            google()
            mavenCentral()
            maven { url 'https://www.jitpack.io' }
        }
    }
    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
            maven {
                url "https://github.com/SariskaIO/sariska-maven-repository/raw/master/releases"
            }
            maven {
                url "https://maven.google.com"
            }
        }
    }
    dependencies {
        implementation 'io.sariska:sariska-media-transport:5.4.9'
    }
    import io.sariska.sdk.SariskaMediaTransport;
    import io.sariska.sdk.Connection;
    import io.sariska.sdk.Conference;
    import io.sariska.sdk.JitsiRemoteTrack;
    import io.sariska.sdk.JitsiLocalTrack;
    import io.sariska.sdk.Participant;
    
    SariskaMediaTransport.initializeSdk();
    // Replace {your-token} with your actual Sariska token
    val token = {your-token}
      
    // Create a connection object
    val connection = SariskaMediaTransport.JitsiConnection(token, "roomName", isNightly)
      
      
    // Add event listeners for connection status
      
    connection.addEventListener("CONNECTION_ESTABLISHED"), { 
    // Handle successful connection establishment
    }
    
    connection.addEventListener("CONNECTION_FAILED"), { error->
      if (error === PASSWORD_REQUIRED) {
        // Token expired, update the connection with a new token
        connection.setToken(token)
      }
    }
    
    connection.addEventListener("CONNECTION_DISCONNECTED"), {
    // Handle connection disconnection  
    }
      
    
    // Connect to the Sariska server
    connection.connect()
    // Create a conference object using the connection and optional configuration
    val conference = connection.initJitsiConference(options);
    
    // Join the conference
    conference.join();
    // Define options for local stream capture
    val options = Bundle()
    
    // Enable audio and video tracks in the stream
    options.putBoolean("audio", true)
    options.putBoolean("video", true)
    
    // Set desired video resolution
    options.putInt("resolution", 240) // Specify desired resolution
    // ... (additional options for desktop sharing, facing mode, devices, etc.)
    
    // Create local audio and video tracks based on the options
    SariskaMediaTransport.createLocalTracks(options) { tracks ->
    localTracks = tracks;
    }
    runOnUiThread(() -> {
        // Loop through each local track
        for (JitsiLocalTrack track : localTracks) {
            if (track.getType().equals("video")) {
                // Get the view for rendering the video track
                val view = track.render();
                
                // Set the view to fill the container
                view.setObjectFit("cover");
                
                // Add the video view to the container layout
                mLocalContainer.addView(view);
            }
        }
    })
    conference.addEventListener("USER_JOINED", (id,  participant)=>{
    });
    // Loop through all local tracks
    for (JitsiLocalTrack track : localTracks) {
        // Add the track to the conference, allowing others to see/hear you
        conference.addTrack(track);
    }
    // Add an event listener to the conference for "TRACK_ADDED" events
    conference.addEventListener("TRACK_ADDED") { p ->
        // Cast the event object to a JitsiRemoteTrack instance
        val track: JitsiRemoteTrack = p as JitsiRemoteTrack
        
        // Run code on the UI thread
        runOnUiThread {
            // Check if the track type is video
            if (track.getType().equals("video")) {
                // Render the video track using Jitsi's WebRTCView component
                val view: WebRTCView = track.render()
                
                // Set the view to cover the entire container
                view.setObjectFit("cover")
                
                // Store the view for potential later reference
                remoteView = view
                
                // Add the view to the container layout, displaying the remote video
                mRemoteContainer!!.addView(view)
            }
        }
    }
    conference.startTracking();
    conference.addEventListener("DOMINANT_SPEAKER_CHANGED") { p ->
        // participantId is a string containing the ID of the dominant speaker
        val participantId = p as String 
    }
    // Listen for last N speakers changed event
    conference.addEventListener("LAST_N_ENDPOINTS_CHANGED") { leavingEndpointIds,  enteringEndpointIds -> 
        // leavingEndpointIds: Array of IDs of users leaving lastN
        // enteringEndpointIds: Array of IDs of users entering lastN
    };
    
    // Set the number of last speakers to show
    conference.setLastN(10)
    // Set local participant property 
    conference.setLocalParticipantProperty(key, value);
    
    // Remove a local participant property
    conference.rempveLocalParticipantProperty(key)
    
    // Get the value of a local participant property 
    conference.getLocalParticipantProperty(key)
    
    // Listen for changes in participant properties
    conference.addEventListener("PARTICIPANT_PROPERTY_CHANGED"){ participant, key, oldValue, newValue ->
    }
    conference.getParticipantCount(); 
    // Pass true to include hidden participants
    // Get all participants
    conference.getParticipants(); // List of all participants
    
    // Get participants excluding hidden users
    conference.getParticipantsWithoutHidden(); // List of all participants
    conference.selectParticipant(participantId) // Select participant with ID
    conference.selectParticipants(participantIds) // Select participant with IDs
    // Check if the local user is hidden
    conference.isHidden()
    
    // Get local user details
    confernece.getUserId()
    conference.getUserRole()
    conference.getUserEmail()
    conference.getUserAvatar()
    conference.getUserName()
    conference.setSubject(subject)
    conference.getRemoteTracks();
    conference.getLocalTracks()
    conference.addEventListener("KICKED"){ id ->
       // Handle participant kicked
    };
    
    conference.addEventListener("PARTICIPANT_KICKED") { actorParticipant, kickedParticipant, reason ->
    }
    confernece.kickParticipant(id)
    conference.grantOwner(id) // Grant owner rights to a participant
    conference.addEventListener("USER_ROLE_CHANGED"){ id, role ->
        
        if (confernece.getUserId() === id ) {
            // My role changed, new role: role;
        } else {
           // Participant role changed: role;
        }
    };
    conference.revokeOwner(id) // Revoke owner rights from a participant
    conference.setDisplayName(name); // Change the local user's display name
    conference.addEventListener("DISPLAY_NAME_CHANGED"){ id, displayName->
        // Access the participant ID
    };
    conference.lock(password); // Lock the room with the specified password
    conference.unlock();
    conference.setLocalParticipantProperty("requestingTranscription", true);
    conference.setLocalParticipantProperty("translation_language", 'hi'); // Example for Hindi
    conference.addEventListener("SUBTITLES_RECEIVED"){ id, name, text->
    // Handle received subtitle data (id, speaker name, text)
    };
    conference.setLocalParticipantProperty("requestingTranscription", false);
    // Create a desktop track
    val options = new Bundle();  
    options.putBoolean("desktop", true);
    
    val videoTrack = localTracks[1]; // Participant's local video track
    
    SariskaMediaTransport.createLocalTracks(options, tracks -> {
        conference.replaceTrack(videoTrack, tracks[0]);
    });
    conference.sendMessage("message");
    conference.sendMessage("message", participantId);
    // Add an event listener to handle incoming messages
    conference.addEventListener("MESSAGE_RECEIVED" ){ message, senderId->
    // Process the received message
    });
    conference.startTranscriber();
    conference.stopTranscriber();
    conference.muteParticipant(participantId, mediaType)
    // participantId: ID of the participant to be muted
    // mediaType: Type of media to mute ('audio' or 'video')
    // Mute a local track (audio or video)
    track.mute()
    
    // Unmute a previously muted local track
    track.unmute()
    conference.addEventListener(event: "LOCAL_STATS_UPDATED"){ stats in
    // Handle local connection statistics
    }
    conference.addEventListener(event: "REMOTE_STATS_UPDATED") { id, stats-> 
    // Handle remote connection statistics
    }
    conference.startP2PSession();
    conference.stopP2PSession();
    val options = new Bundle();
    options.putString("callStatsID", 'callstats-id');
    options.putString("callStatsSecret", 'callstats-secret');
    
    val conference = connection.initJitsiConference(options);
    val options = new Bundle();
    options.putBoolean("startAudioMuted", true);
    options.putBoolean("starVideoMuted", true);
    
    val conference = connection.initJitsiConference(options);
    val options = new Bundle();
    options.putBoolean("startSilent", true);
    
    val confernce = connection.initJitsiConference(options);
    val options = new Bundle();
    options.putString("broadcastId", "youtubeBroadcastID"); // Put any string this will become part of your publish URL
    options.putString("mode", "stream");
    options.putString("streamId", "youtubeStreamKey"); 
    
    // Start live stream
    conference.startRecording(options);
    val options = new Bundle();
    options.putString("mode", "stream");
    options.putString("streamId", "rtmps://live-api-s.facebook.com:443/rtmp/FB-4742724459088842-0-AbwKHwKiTd9lFMPy");
    
    // Start live stream
    conference.startRecording(options);
    val options = new Bundle();     
    options.putString("mode", "stream");        
    options.putString("streamId", "rtmp://live.twitch.tv/app/STREAM_KEY");      
    
    // Start live stream
    conference.startRecording(options);     
    val options = new Bundle();
    options.putString("mode", "stream");
    options.putString("streamId", "rtmps://rtmp-server/rtmp"); // RTMP server URL
    
    // Start live stream
    conference.startRecording(options);
    conference.addEventListener("RECORDER_STATE_CHANGED"){ sessionId, mode, status in
    // Verify mode is "stream"
    // Get the live streaming session ID
    // Check the streaming status: on, off, or pending
    };
    conference.stopRecording(sessionId);
    // Configure for Object-based storage
    val options = new Bundle();
    options.putString("mode", "file");
    options.putString("serviceName", "s3");
    
    
    // Configure for Dropbox
    val options = new Bundle();
    options.putString("mode", "file");
    options.putString("serviceName", "dropbox");
    options.putString("token", "dropbox_oauth_token");
    
    
    // Start recording
    conference.startRecording(options);
    
    
    // Monitor recording state
    conference.addEventListener("RECORDER_STATE_CHANGED"){ sessionId, mode, status ->
       val sessionId = sessionId as String; // Unique identifier for the cloud recording session
       val mode = mode as String; // Recording mode (e.g., "file")
       val status = status as String; // Current recording status ("on", "off", or "pending")
    // Handle recording state changes based on mode, sessionId, and status
    });
    
    // Stop recording
    conference.stopRecording(sessionId)
    // Retrieve the phone pin and number for users to join via PSTN:
    
    val phonePin = conference.getPhonePin() // Get the phone pin for PSTN access
    val phoneNumber = conference.getPhoneNumber() // Get the phone number for PSTN access 
    // Dial a phone number to invite a participant to the conference
    conference.dial(phoneNumber)
    // Join the lobby
    conference.joinLobby(displayName, email); // Request to join the conference lobby
    
    // Event listeners for lobby-related actions:
    conference.addEventListener("LOBBY_USER_JOINED"){ id, name ->
        // Handle events when a user joins the lobby
        val id = id as String;
        val name = name as String
    })
    
    conference.addEventListener(event: "LOBBY_USER_UPDATED"), { id, participant ->
        // Handle events when a user's information in the lobby is updated
        val id = id as String;
        val name = participant as Participant
    }
    
    
    // Additional event listeners for lobby actions:
    conference.addEventListener(event: "LOBBY_USER_LEFT") { id ->
        val id = id as String;
    }
    
    conference.addEventListener(event: "MEMBERS_ONLY_CHANGED") { enabled ->
        val enabled = enabled as Boolean;
    }
    
    
    // Moderator actions for lobby access:
    conference.lobbyDenyAccess(participantId); // Deny access to a participant in the lobby
    conference.lobbyApproveAccess(participantId); // Approve access to a participant in the lobby
    
    
    // Lobby management methods:
    conference.enableLobby() // Enable lobby mode for the conference (moderator only)
    conference.disableLobby(); // Disable lobby mode for the conference (moderator only)
    conference.isMembersOnly(); // Check if the conference is in members-only mode (lobby disabled)
    // Initiate a SIP video call
    conference.startSIPVideoCall("[email protected]", "display name"); // Start a SIP video call with the specified address and display name
    
    // Terminate a SIP video call
    conference.stopSIPVideoCall('[email protected]');
    
    // Event listeners for SIP gateway state changes
    conference.addEventListener("VIDEO_SIP_GW_SESSION_STATE_CHANGED", (state)=>{
        // Handle events when the SIP gateway session state changes (on, off, pending, retrying, failed)
    }
    
    // Event listener for SIP gateway availability changes
    conference.addEventListener("VIDEO_SIP_GW_AVAILABILITY_CHANGED"){ status ->
        // Handle events when the SIP gateway availability changes (busy or available)
    }
    conference.addEventListener(event: "USER_STATUS_CHANGED"){ id, status ->
        val id = id as! String;
        val status = status as!
    // - id: receiver's user id
    // - status: "ringing", "busy", "rejected", "connected", "expired"
    };