Best practices: Azure Communication Services calling SDKs

This article provides information about best practices related to the Azure Communication Services calling SDKs.

Azure Communication Services web JavaScript SDK best practices

This section provides information about best practices associated with the Azure Communication Services JavaScript voice and video calling SDK.

JavaScript voice and video calling SDK

Plug-in microphone or enable microphone from device manager when Azure Communication Services call in progress

When there's no microphone available at the beginning of a call, and then a microphone becomes available, the "noMicrophoneDevicesEnumerated" call diagnostic event is raised. When it happens, your application should invoke askDevicePermission to obtain user consent to enumerate devices. Then user will then be able to mute/unmute the microphone.

Dispose video stream renderer view

Communication Services applications should dispose VideoStreamRendererView, or its parent VideoStreamRenderer instance, when it's no longer needed.

Hang up the call on onbeforeunload event

Your application should invoke call.hangup when the onbeforeunload event is emitted.

Handling multiple calls on multiple Tabs on mobile

Your application shouldn't connect to calls from multiple browser tabs simultaneously as this can cause undefined behavior due to resource allocation for microphone and camera on the device. Developers are encouraged to always hang up calls when completed in the background before starting a new one.

Handle OS muting call when phone call comes in.

While on an Azure Communication Services call (for both iOS and Android) if a phone call comes in or Voice assistant is activated, the OS will automatically mute the user's microphone and camera. On Android, the call automatically unmutes and video restarts after the phone call ends. On iOS, it requires user action to "unmute" and "start video" again. You can listen for the notification that the microphone was muted unexpectedly with the quality event of microphoneMuteUnexpectedly. Do note in order to be able to rejoin a call properly you need to use SDK 1.2.3-beta.1 or higher.

const latestMediaDiagnostic = call.api(SDK.Features.Diagnostics).media.getLatest();
const isIosSafari = (getOS() === OSName.ios) && (getPlatformName() === BrowserName.safari);
if (isIosSafari && latestMediaDiagnostic.microphoneMuteUnexpectedly && latestMediaDiagnostic.microphoneMuteUnexpectedly.value) {
  // received a QualityEvent on iOS that the microphone was unexpectedly muted - notify user to unmute their microphone and to start their video stream
}

Your application should invoke call.startVideo(localVideoStream); to start a video stream and should use this.currentCall.unmute(); to unmute the audio.

Device management

You can use the Azure Communication Services SDK to manage your devices and media operations.

  • Your application shouldn't use native browser APIs like getUserMedia or getDisplayMedia to acquire streams outside of the SDK. If you do, you have to manually dispose your media streams before using DeviceManager or other device management APIs via the Communication Services SDK.

Request device permissions

You can request device permissions using the SDK:

  • Your application should use DeviceManager.askDevicePermission to request access to audio and/or video devices.
  • If the user denies access, DeviceManager.askDevicePermission will return 'false' for a given device type (audio or video) on subsequent calls, even after the page is refreshed. In this scenario, your application must detect that the user previously denied access and instruct the user to manually reset or explicitly grant access to a given device type.

Camera being used by another process

  • On Windows Chrome and Windows Microsoft Edge, if you start/join/accept a call with video on and the camera device is being used by another process other than the browser that the web SDK is running on, then the call is started with audio only and no video. A cameraStartFailed UFD is raised because the camera failed to start since it was being used by another process. Same applies to turning video on mid-call. You can turn off the camera in the other process so that that process releases the camera device, and then start video again from the call and video will now turn on for the call and remote participants start seeing your video.
  • This isn't an issue in macOS Chrome nor macOS Safari because the OS will let processes/threads share the camera device.
  • On mobile devices, if a ProcessA requests the camera device and it's being used by ProcessB, then ProcessA overtakes the camera device and ProcessB stop using the camera device
  • On iOS safari, you can't have the camera on for multiple call clients within the same tab nor across tabs. When any call client uses the camera, it overtakes the camera from any previous call client that was using it. Previous call client gets a cameraStoppedUnexpectedly UFD.

Screen sharing

Closing out of application doesn't stop it from being shared

For example, lets say that from Chromium, you screen share the Microsoft Teams application. You then select on the "X" button on the Teams application to close it. The Teams application won't be closed and it will still be running in the background. You'll even still see the icon in the bottom right of your desktop bar. Since the Teams application is still running, that means that it's still being screen shared and the remote participant in the call can still see your Teams application being screen shared. In order to stop the application from being screen shared, you have to right click its icon on the desktop bar and then click on quit. Or you have to click on "Stop sharing" button on the browser. Or call the SDK's Call.stopScreenSharing() API.

Safari can only do full screen sharing

Safari only allows to screen share the entire screen. Unlike Chromium, which lets you screen share full screen, specific desktop app, or specific browser tab.

Screen sharing permissions on macOS

In order to do screen sharing in macOS Safari or macOS Chrome, screen recording permissions must be granted to the browsers in the OS menu: "Systems Preferences" -> "Security & Privacy" -> "Screen Recording."

Azure Communication Services native SDK best practices

This section provides information about best practices associated with the Azure Communication Services voice and video calling native SDK.

Supported platforms

Here are the minimum OS platform requirements to ensure optimal functionality of the Calling Native SDKs.

  • Support for iOS 10.0+ at build time, and iOS 12.0+ at run time.
  • Xcode 12.0+.
  • Support for iPadOS 13.0+.

App request device permissions

To use the Calling Native SDKs for making or receiving calls, it's necessary to authorize each platform to access device resources. As a developer, you should prompt the user for access and ensure that it's enabled. The consumer authorizes these access rights, so verify that they have been granted permission previously.

  • NSMicrophoneUsageDescription for microphone access.
  • NSCameraUsageDescription for camera access.

Configure the logs

Implementing logging as per the logs file retrieval tutorial is more critical than ever. Detailed logs help in diagnosing issues specific to device models or OS versions that meet the minimum SDK criteria. We encourage to the developers that start configuring the Logs API without the logs the Microsoft Support team won't be able to help debug and troubleshoot the calls.

Track Call ID

CallID is the unique ID for a call. It identifies correlated events from all of the participants and endpoints that connect during a single call, in Most cases you use it to review the logs and Microsoft Support team ask for it to help troubleshoot the calls. You should track the CallID in your telemetry that you configure in your app, you can follow the guidelines in the troubleshooting guide to understand how to retrieve it for each platform.

Subscribe to UFD (User Facing Diagnostics) and media quality statistics

  • User Facing Diagnostics (UFD) that can be used to examine various properties of a call to determine what the issue might be during the call that affects your customers.
  • Media quality statistics examine the low-level audio, video, and screen-sharing quality metrics for incoming and outgoing call metrics. We recommend that you collect the data and send it to your pipeline ingestion after your call ends.

Error Handling

If there are any errors during the call or implementation, the methods return error objects containing error codes. It's crucial to use these error objects for proper error handling and to display alerts. The call states also return error codes to help identify the reason behind call failure. You can refer to the troubleshooting guide, to resolve any issues.

Managing Video Streams

Make sure to dispose of the VideoStreamRendererView when the video is no longer displayed on the UI. Use VideoStreamType to determine the type of the stream.

General memory management

Preallocate Resources. Initialize your calling client and any necessary resources during your app's startup phase rather than on demand. This approach reduces latency when starting a call.

Dispose Properly. Ensure that all call objects are correctly disposed of after use to free up system resources and avoid memory leaks. Make sure to unsubscribe from events preventing memory leaks.

Camera or microphone being used by another process

It's important to note that on mobile devices if multiple processes try to access the camera or microphone at the same time, the first process to request access will take control of the device. As a result, the second process will immediately lose access to it.

Next steps

For more information, see the following articles: