> ## 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.

# Key concepts

> The SRTC Swift SDK object model: SRTCEngine vs. Channel, local and remote track types, the default audio mix mode, create/capture/publish steps for video, the three rendering options, DeviceManager, and the ChannelDelegate / TrackDelegate event model. Read before using the Swift API reference.

### Overall model

The Swift SDK's object model can be summarized as:

* `SRTCEngine`: the main SDK entry point, responsible for joining channels and creating local tracks
* `Channel`: an actual channel connection, responsible for publishing, subscribing, the user list, and event dispatch
* `Track`: the abstraction of an audio or video stream
* `ChannelDelegate` / `TrackDelegate`: entry points for event callbacks
* `SRTCVideoView` / `VideoView` / `SRTCVideoRenderer`: the video rendering layer

At its core, an RTC system synchronizes three kinds of state:

* Connection state
* User state
* Media track state

The Swift SDK's API is designed around these three kinds of state, so once you understand this model, most APIs become intuitive.

***

### SRTCEngine and Channel

#### `SRTCEngine`

`SRTCEngine` works more like a "factory + entry point for joining". You typically use it for two things:

* `joinChannel(token:options:)`
* `createLocalMicTrack(...)` / `createLocalCameraTrack(...)` / `createLocalScreenTrack(...)`

#### `Channel`

After you join a channel, `Channel` is what actually holds the channel's state:

* Publish local tracks
* Subscribe to remote tracks
* Get channel info and user info
* Listen for users joining and leaving, track changes, disconnects and reconnects, and custom messages

Think of it as "an RTC session that has completed authentication and network connection".

`joinChannel` can be called multiple times—one engine can join multiple channels at the same time, and each channel's publishing, subscriptions, users, and events
are independent of each other; `srtc.channels` is the list of currently live channels. **Tracks belong to the engine, not to a channel**: the same capture track
can be published to multiple channels, capture happens only once, and cleanup is handled by the last releaser. Publishing **audio** to multiple channels at the same time has one
hard constraint (the set of audio sources must be the same in every channel)—see [Multi-channel](/zh/rtc/swift/advanced/multi-channel) (Chinese).

***

### Track system

#### Local tracks

| Type | How to create | Description |
| - | - | - |
| `LocalMicTrack` | `srtc.createLocalMicTrack(...)` | Microphone capture |
| `LocalCameraTrack` | `srtc.createLocalCameraTrack(...)` | Camera capture |
| `LocalScreenTrack` | `srtc.createLocalScreenTrack(...)` | Screen sharing |
| `LocalAudioTrack` | `srtc.createLocalCustomAudioTrack(...)` | Custom audio injection |
| `LocalVideoTrack` | `srtc.createLocalCustomVideoTrack(...)` | Custom video frame injection |

#### Remote tracks

| Type | How to get | Description |
| - | - | - |
| `RemoteAudioTrack` | `channel.getRemoteTrack(...)` | A single remote audio track |
| `RemoteAudioMixTrack` | A kind of remote audio track | Channel-wide mixed audio track |
| `RemoteVideoTrack` | `channel.getRemoteTrack(...)` | Remote video |

***

### Audio mix mode

A key implementation detail of the current Swift SDK: **local audio is sent in mix mode by default**.

This means:

* The microphone, custom audio, and screen audio first go into the internal `AudioMixer`
* What the PeerConnection actually sends is a single internal `audio_mix` audio track
* Your code can still control creation, muting, and stopping capture of each audio source separately

The reasons for this design:

* It reduces the complexity of publishing multiple audio tracks concurrently
* Custom audio, the microphone, and screen audio share one sending model
* It stays consistent with the existing rtc-js architecture

***

### Video capture and publishing

A video track's lifecycle usually has three steps:

```swift theme={null}
let track = srtc.createLocalCameraTrack(preset: .h720p)
try await track.startCapture()
try await channel.publishLocalTrack(track)
```

Separating the three steps gives you these benefits:

* You can preview locally first, then decide whether to publish
* You can control hardware capture and network sending independently
* When a permission failure or device switch failure occurs, the state is easier to pinpoint

***

### Video rendering

The SDK provides three common rendering entry points:

#### `SRTCVideoView`

A SwiftUI component, best for rendering directly in a view:

```swift theme={null}
SRTCVideoView(track: track)
    .frame(width: 320, height: 180)
```

#### `VideoView`

For UIKit / AppKit; use `bind(track:)` to manage binding.

#### `SRTCVideoRenderer`

A lower-level rendering view, bound by the track itself calling `addRenderer(...)` / `removeRenderer(...)`.

***

### Device management

`DeviceManager.shared` handles device enumeration and device change monitoring:

* Enumerate cameras: `cameras()`
* Enumerate microphones / speakers on macOS: `microphones()`, `speakers()`
* Enumerate audio routes on iOS: `audioRoutes()`
* Monitor device hot-plugging and audio session interruptions: `DeviceManagerDelegate`

If your app needs a device picker, build a UI layer directly on top of `DeviceManager` rather than writing your own platform-specific handling.

***

### Event model

Channel-level events go through `ChannelDelegate`:

* Join succeeded
* Reconnect / disconnect
* User joined, left, or updated
* Remote track added, updated, or removed
* Custom messages

Track-level events go through `TrackDelegate`:

* Track info changes
* Mute / unmute
* Capture ended
* Underlying WebRTC track binding completed

For the full event list, see [Events](/zh/rtc/swift/events) (Chinese).

***

### Further reading

* [Mute vs. unpublish](/zh/rtc/swift/advanced/mute-vs-unpublish) (Chinese)
* [Device management](/zh/rtc/swift/advanced/device-management) (Chinese)
* [Screen sharing](/zh/rtc/swift/advanced/screen-sharing) (Chinese)
* [Multi-channel](/zh/rtc/swift/advanced/multi-channel) (Chinese)
* [Custom tracks](/zh/rtc/swift/advanced/custom-track) (Chinese)
