> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stmlink.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> 对外开放的服务端接口有两组前缀，都用同一套鉴权：`/server/v1/...`（SRTC 与 SMeeting 的主接口）和 `/stm/srvapi/v1/...`（SMeeting 的用户体系，服务端极简对接会用到）。鉴权是 app_id + nonce + timestamp + signature 四个请求头，用 app_key 做 HMAC-SHA256 签名，只能从业务方自己的后端调用。除这两组前缀外的接口均为内部接口，不要建议客户调用。 Public server APIs use two path prefixes with the same authentication: `/server/v1/...` (the main APIs of both SRTC and SMeeting) and `/stm/srvapi/v1/...` (the SMeeting user system, used by server-side low-code integration). Authenticate with four request headers, app_id + nonce + timestamp + signature, where signature is HMAC-SHA256 keyed with app_key; call these APIs only from the customer's own backend. Any other path is internal: never suggest calling it.
> app_key 是服务端密钥，绝不能出现在客户端代码、前端配置或移动 App 里。客户端加入频道用的 token 必须由业务方后端签发后下发（SRTC 走 `/server/v1/channel/grant`，SMeeting 走 `/stm/srvapi/v1/member/grant`）。 app_key is a server-side secret and must never appear in client code, frontend config, or a mobile app. The token a client uses to join must be issued by the customer's backend and passed down to the client (SRTC: `/server/v1/channel/grant`; SMeeting: `/stm/srvapi/v1/member/grant`).
> SRTC 与 SMeeting 是上下两层不同的产品，术语不通用：SRTC 是音视频底座，说「频道 channel」「加入 / 退出」；SMeeting 建在 SRTC 之上，说「房间 room」「会议 meeting」「进入 / 退出」。回答时按用户所在的层用对应术语，不要把「房间」「会议」安到 SRTC 的接口上，也不要用「频道」「加入 / 离开」描述 SMeeting 的概念（接口标识符原样保留）。 SRTC and SMeeting are two separate layers with different terminology. SRTC is the audio/video foundation: it has channels, and users join and leave a channel. SMeeting is built on top of SRTC: it has rooms and meetings, and members enter and exit a meeting. Answer in the terms of the layer the user is working with: never apply "room" or "meeting" to SRTC APIs, and never describe SMeeting concepts in prose with "channel", "join", or "leave" (API identifiers such as `force_join` keep their literal names).
> 同一能力在各端 SDK 里的包名、类名、方法名并不相同。写示例代码时请使用文档中该端自己的 API，不要把一个端的写法套到另一个端上。苹果平台每个产品都有两套 SDK（Swift 原生与 Objective-C），两套 API 不能混用。 Package, class, and method names differ between platform SDKs for the same capability. In sample code, use the API documented for that platform; never carry one platform's code over to another. On Apple platforms each product ships two SDKs (native Swift and Objective-C) whose APIs must not be mixed.

# Virtual background

> Virtual background in the SMeeting iOS (Objective-C) SDK: person segmentation for background blur or replacement, no license key needed. Covers why it's a device-level setting, why camera switches and reconnects need no re-apply, and two frame-rate parameters for low-end devices.

Virtual background performs person segmentation in the camera capture pipeline and replaces everything outside the person with blur or a specified image. It's an in-house component, and installing it doesn't require a license key.

<Note>
  The APIs are on the global singleton `MeetingKit`, not on `MeetingKitRoom`—virtual background applies to the single shared camera capture pipeline in the process, so it's **a device-level setting that applies to all rooms at once**. When you're in multiple rooms at the same time, there's no way to "turn on virtual background for just one room."

  Switching cameras during the meeting (`switchCamera`) and reconnecting after a disconnect both rebuild the capture pipeline, and the SDK automatically replays the whole current configuration, so **you don't need to re-apply anything at these points**.
</Note>

<Warning>
  Starting with `2.1.0`, the minimum system requirement is **iOS 16.0**. Virtual background depends on `onnxruntime`; with CocoaPods, it's pulled in transitively by the `RTCEngineKit` podspec, so you don't need to declare it in your `Podfile`. For details, see [Quickstart](/en/meeting/ios/quickstart).
</Warning>

### Step 1: **Install the virtual background component**

We recommend installing it before you need virtual background, for example when entering the meeting page. Pass `nil` for `modelPath` to use the SDK's built-in person segmentation model.

```objectivec theme={null}
/// Install the virtual background component
/// @param modelPath Path to the person segmentation model file; pass nil to use the built-in model
SEAError error = [[MeetingKit sharedInstance] installVirtualBackground:nil];
```

Return values:

| **Return value** | **Description** |
| - | - |
| SEAErrorOK | Installed successfully |
| SEAErrorConflict | The component is already installed; this call is discarded |
| SEAErrorNotFound | The model file doesn't exist; check `modelPath` |
| SEAErrorSystemError | Failed to create the inference session; this is a runtime environment problem |

### Step 2: **Set the background effect**

Background blur and background replacement are **mutually exclusive; the later call wins**. Both APIs are remembered even if called before installation and take effect automatically once installation completes, so you don't need to care about their order relative to `installVirtualBackground:`.

```objectivec theme={null}
/// Set background blur
/// @param level Blur level, range 1–10, default 5 (out-of-range values are clamped to the boundary)
[[MeetingKit sharedInstance] setVirtualBackgroundBlur:5];

/// Set background replacement
/// @param image Background image, cropped to cover without stretching; pass nil to cancel replacement and go back to blur
[[MeetingKit sharedInstance] setVirtualBackgroundImage:[UIImage imageNamed:@"background"]];
```

### Step 3: **Turn virtual background on or off**

After installation, it's **off** by default and must be turned on explicitly. When off, frames pass straight through with zero overhead, and no inference runs.

```objectivec theme={null}
/// Virtual background switch
/// @param enabled YES: on, NO: off
[[MeetingKit sharedInstance] enabledVirtualBackground:YES];

/// Get whether virtual background is on
BOOL enabled = [[MeetingKit sharedInstance] isVirtualBackgroundEnabled];
```

Calling the switch before the component is installed returns `SEAErrorConflict`. Turning it off clears the inter-frame state, so the next time it's turned on it converges again from the first frame and doesn't flash a stale mask.

### Step 4: **Keep the frame rate up on low-end devices (optional)**

By default, person segmentation runs on every frame. On low-end devices, you can increase the inference interval, trading mask reuse for frame rate; then turn on mask sync as needed to eliminate trailing artifacts.

```objectivec theme={null}
/// Set the segmentation inference interval
/// @param interval Run segmentation every N frames (compositing still runs every frame); default 1
[[MeetingKit sharedInstance] setVirtualBackgroundInferenceInterval:2];

/// Set mask sync
/// @param enabled YES: on, NO: off; default NO
[[MeetingKit sharedInstance] setVirtualBackgroundMaskSync:YES];
```

| **Parameter** | **Default** | **Description** |
| - | :-: | - |
| inferenceInterval | `1` | Run segmentation every N frames; values below 1 are treated as 1. Increasing it lowers inference overhead, at the cost of the mask following more slowly during fast motion |
| maskSync | `NO` | When on, non-inference frames aren't recomposited, so the video and the mask always come from the same moment, eliminating misaligned trails when waving; the cost is that the video update rate drops to the mask rate |

<Note>
  When `inferenceInterval` is `1`, turning `setVirtualBackgroundMaskSync:` on or off makes no difference at all—it only takes effect after you increase the inference interval.
</Note>

### Step 5: **Uninstall the virtual background component**

Uninstall it when no longer needed to release the inference session and related buffers.

```objectivec theme={null}
/// Uninstall the virtual background component
[[MeetingKit sharedInstance] uninstallVirtualBackground];
```

### Consistency between local preview and the published stream

When virtual background is on, the local preview shows the processed video, which is the same data other members see; when it's off, the local preview goes back to the raw camera video. For full signatures and parameters, see [MeetingKit](/en/meeting/ios/api-reference/MeetingKit#virtual-background-apis).
