Manage in-meeting audio settings

The code on this page works with either the default UI or the custom UI.

Through the SDK, let individual users manage their own various audio settings and control their in-meeting audio state. Additionally, meeting hosts can manage settings for other users and for the meeting as a whole. Most of the functionality is done through IAudioSettingContext, which can be accessed after the participant joins the meeting.

ISettingService* settingService = nullptr;
  if (CreateSettingService(&settingService) == SDKERR_SUCCESS && settingService) {
      IAudioSettingContext* audioSetting = settingService->GetAudioSettings();
      if (audioSetting) {
          // use audioSetting here
      }
  }

Connect to meeting audio

Before joining a meeting, enable or disable auto connect to the meeting audio with VOIP.

 audioSetting->EnableAutoJoinAudio(true);

You can also be update the current meeting's meeting settings to mute by default upon joining the meeting using IAudioSettingContext EnableAlwaysMuteMicWhenJoinVoip. Unless the meeting explicitly prevents participants from unmuting themselves, any client instances can override this behavior.

audioSetting->EnableAlwaysMuteMicWhenJoinVoip(true);

After joining a meeting, the SDK instance may not automatically connect to the meeting audio. To send or receive audio in the meeting, connect the SDK to the audio channel.

  IMeetingService* meetingService = /* existing service instance */;
  if (meetingService) {
      IMeetingParticipantsController* participants = meetingService->GetMeetingParticipantsController();
      IUserInfo* myself = participants ? participants->GetMySelfUser() : nullptr;
      if (myself && myself->GetAudioJoinType() == AUDIOTYPE_NONE) {
          IMeetingAudioController* audioCtrl = meetingService->GetMeetingAudioController();
          if (audioCtrl) {
              SDKError err = audioCtrl->JoinVoip();
              // optional: handle err
          }
      }
  }

Once connected, the SDK can also disconnect from the audio channel. After disconnecting from audio, the SDK will no longer be able to send or receive audio until it reconnects.

  IMeetingService* meetingService = /* existing service instance */;
  if (meetingService) {
      IMeetingParticipantsController* participants = meetingService->GetMeetingParticipantsController();
      IUserInfo* myself = participants ? participants->GetMySelfUser() : nullptr;
      if (myself && myself->GetAudioJoinType() == AUDIOTYPE_VOIP) {
          IMeetingAudioController* audioCtrl = meetingService->GetMeetingAudioController();
          if (audioCtrl) {
              SDKError err = audioCtrl->LeaveVoip();
              // optional: handle err
          }
      }
  }

Check whether a specific user is connected to the audio channel by checking their audio type against AudioType constants. AudioType_Voip means that they're connected to the meeting audio channel, AudioType_Phone means that they're using audio from their phone, and AudioType_None means that they aren't connected.

  // From participants controller:
  IUserInfo* user = /* ... */;
  if (user) {
      AudioType t1 = user->GetAudioJoinType();
  }
  // From audio status object:
  IUserAudioStatus* userAudioStatus = /* ... */;
  if (userAudioStatus) {
      AudioType t2 = userAudioStatus->GetAudioType();
  }

Depending on your audio connection, you can also hide the audio dialog that appears when joining the meeting when you are not connected to audio using ZoomSDKPremeetingService.

Managing audio speaker

Get the list of available speakers using GetAudioSettings, and check which of the speakers is selected based on IsSelectedDevice state. Then call the SelectSpeaker with the Device_ID and Device_Name parameter.

  ISettingService* settingService = nullptr;
  if (CreateSettingService(&settingService) == SDKERR_SUCCESS && settingService) {
      IAudioSettingContext* audioSetting = settingService->GetAudioSettings();
      if (audioSetting) {
          IList<ISpeakerInfo*>* speakerList = audioSetting->GetSpeakerList();
          if (speakerList) {
              for (int i = 0; i < speakerList->GetCount(); ++i) {
                  ISpeakerInfo* device = speakerList->GetItem(i);
                  if (device && device->IsSelectedDevice()) {
                      printf("Selected speaker: %s - %s\n",
                          device->GetDeviceName(), device->GetDeviceId());
                  }
              }
          }
          audioSetting->SelectSpeaker("Device_ID", "Device_Name");
      }
  }

Managing audio microphone

Get the list of available speakers using GetAudioSettings, and check which of the microphone is selected based on IsSelectedDevice state. Then call the SelectMic with the Device_ID and Device_Name parameter.

    ISettingService* settingService = nullptr;
    if (CreateSettingService(&settingService) == SDKERR_SUCCESS && settingService) {
        IAudioSettingContext* audioSetting = settingService->GetAudioSettings();
        if (audioSetting) {
            IList<IMicInfo*>* micList = audioSetting->GetMicList();
            if (micList) {
                for (int i = 0; i < micList->GetCount(); ++i) {
                    IMicInfo* device = micList->GetItem(i);
                    if (device && device->IsSelectedDevice()) {
                        printf("Selected mic: %s - %s\n",
                            device->GetDeviceName(), device->GetDeviceId());
                    }
                }
            }
            audioSetting->SelectMic("Device_ID", "Device_Name");
        }
    }

Mute or unmute audio

Mute the local user's audio with IMeetingAudioController using MuteAudio and the userid, boolean parameter. Additionally, if the meeting supports participants unmuting their own audio, use UnMuteAudio(myUserID).

  // Mute/unmute self
  if (meetingService) {
      auto* audioCtrl = meetingService->GetMeetingAudioController();
      auto* participants = meetingService->GetMeetingParticipantsController();
      auto* me = participants ? participants->GetMySelfUser() : nullptr;
      if (audioCtrl && me) {
          unsigned int myUserId = me->GetUserID();
          SDKError muteErr = audioCtrl->MuteAudio(myUserId, true);
          if (muteErr == SDKERR_SUCCESS && audioCtrl->CanUnMuteBySelf()) {
              SDKError unmuteErr = audioCtrl->UnMuteAudio(myUserId);
          }
      }
  }

If the current user is the meeting's host, they can mute the other meeting participants' audio. For privacy reasons, the host cannot force another participant to unmute their audio. If the user is currently muted, this code will ask them to unmute their microphone.

  // Host/co-host mute a specific participant
  unsigned int targetUserId = /* selected participant user id */;
  SDKError err = audioCtrl->MuteAudio(targetUserId, true);

The host can also mute all attendees' audio simultaneously.

  // Host/co-host mute all and ask all to unmute
  if (meetingService) {
      auto* audioCtrl = meetingService->GetMeetingAudioController();
      auto* participantsCtrl = meetingService->GetMeetingParticipantsController();
      if (audioCtrl) {
          // userid = 0 => mute all participants
          SDKError muteAllErr = audioCtrl->MuteAudio(0, true);
      }
      if (participantsCtrl) {
          SDKError askAllErr = participantsCtrl->AskAllToUnmute();
      }
  }

Stop incoming audio

The SDK supports stopping your device from receiving audio while staying connected to the audio channel. This lets your microphone continue capturing audio and sending it to other meeting participants, and prevents your device from playing any audio produced by others.

if (meetingService) {
      IMeetingAudioController* audioCtrl = meetingService->GetMeetingAudioController();
      if (audioCtrl) {
          bool stopped = audioCtrl->IsIncomingAudioStopped();
          SDKError err = audioCtrl->StopIncomingAudio(!stopped);
          // optional: handle err
      }
  }