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

# IRTCChannel

> API reference for IRTCChannel, the Windows SRTC per-channel object: the create → configure → join() sequence, settings and event handler, user and channel info queries, local and remote track objects, publishing, and subscribing. Read when working with a channel after createChannel.

## IRTCChannel

`IRTCChannel` represents **one channel** and is created by [IRTCEngine::createChannel](/en/rtc/windows/api-reference/IRTCEngine#create-a-channel-object).

`createChannel` only parses the token and creates the object; it **doesn't join the channel**. This gives you a chance to set up the
configuration and event handler before `join()`—`onJoinChannel` is called back before `join()` returns, so if you set the handler too late, you miss it.

```cpp theme={null}
SRTC::IRTCChannel* ch = nullptr;
if (engine->createChannel(token, &ch) != SRTC::StatusCode::OK) {
    return;   // On failure, ch is always nullptr
}

// 1) Configuration (for items that only matter before join, see IRTCChannelSetting)
SRTC::IRTCChannelSetting* set = nullptr;
ch->getSetting(&set);
set->set_stream_model(1);

// 2) Event handler; must be set before join()
ch->setEventHandler(this);

// 3) Join the channel
if (ch->join() != SRTC::StatusCode::OK) {
    engine->leaveChannel(ch->getChannelId());   // A failed channel object must also be reclaimed
    ch = nullptr;
    return;
}
```

Always leave through [IRTCEngine::leaveChannel](/en/rtc/windows/api-reference/IRTCEngine#leave-a-channel); `IRTCChannel` itself **has no** `leave()`.
After the call, the object has been destroyed, and you must set the pointer to null yourself.

## Basic functions

### Get the channel ID

```cpp theme={null}
virtual const char* getChannelId() = 0;
```

Returns the value of the `channel` field in the token. The pointer is owned by the SDK and stays valid until you leave the channel; you don't need to free it.

### Get the settings object

```cpp theme={null}
virtual StatusCode getSetting(IRTCChannelSetting** set) = 0;
```

**Parameters**

| set | The channel settings class; for details, see [IRTCChannelSetting](/en/rtc/windows/api-reference/IRTCChannelSetting) |
| - | - |

### Set the event handler

```cpp theme={null}
virtual StatusCode setEventHandler(IRTCChannelEvent* e) = 0;
```

**Parameters**

| e | An implementation of the pure virtual channel event callback class; for the callbacks, see [IRTCChannelEvent](/en/rtc/windows/api-reference/IRTCChannelEvent) |
| - | - |

Note: you must set it before `join()`; otherwise you don't receive `onJoinChannel`.

### Join the channel

```cpp theme={null}
virtual StatusCode join() = 0;
```

Note: this is synchronous; `onJoinChannel` has already been called back before it returns. Calling it again returns `Conflict`. On failure, the channel object still exists,
and you need to reclaim it with [IRTCEngine::leaveChannel](/en/rtc/windows/api-reference/IRTCEngine#leave-a-channel).

## User info functions

### Get your own user info

```cpp theme={null}
virtual StatusCode getMe(char** s, int* c) = 0;
```

**Parameters**

| s | User info JSON |
| - | - |
| c | Length of the user info JSON |

### Get channel info

```cpp theme={null}
virtual StatusCode getChannel(char** s, int* c) = 0;
```

**Parameters**

| s | Channel info JSON |
| - | - |
| c | Length of the channel info JSON |

### Get info for all users in the channel

```cpp theme={null}
virtual StatusCode getMembers(char** s, int* c) = 0;
```

**Parameters**

| s | JSON array of all users' info |
| - | - |
| c | Length of the JSON array of all users' info |

### Get info for a specific user

```cpp theme={null}
virtual StatusCode getMember(const char* uid, char** s, int* c) = 0;
virtual StatusCode getMemberByLinkId(const char* linkId, char** s, int* c) = 0;
virtual StatusCode getMemberByLinkId(int linkId, char** s, int* c) = 0;
		
```

**Parameters**

| uid/linkid | User ID, media streaming linkid |
| - | - |
| s | User info JSON |
| c | Length of the user info JSON |

### Error codes for channel-level methods

| Calling a media method before `join()` | `NotInitialized` |
| - | - |

## Media streaming functions

### Get a video track object

```cpp theme={null}
virtual StatusCode getCameraTrack(const char* track_key,IRTCLocalCameraTrack ** track) = 0;
```

**Parameters**

| track\_key | Key of the local video track object, maintained by you. Distinguishes different track objects; it's also the default publishing desc |
| - | - |
| track | [Video track object](/en/rtc/windows/api-reference/IRTCLocalCameraTrack) |

### Get a screen sharing track object

```cpp theme={null}
virtual StatusCode getScreenTrack(const char* track_key,IRTCLocalScreenTrack ** track) = 0;
```

**Parameters**

| track\_key | Key of the local video track object, maintained by you. Distinguishes different track objects; it's also the default publishing desc |
| - | - |
| track | [Screen track object](/en/rtc/windows/api-reference/IRTCLocalScreenTrack) |

### Get an audio track object

```cpp theme={null}
virtual StatusCode getAudioTrack(const char* track_key,IRTCLocalMicTrack** track) = 0;
```

**Parameters**

| track\_key | Key of the local audio track object, maintained by you. Distinguishes different track objects; it's also the default publishing desc |
| - | - |
| track | [Microphone track object](/en/rtc/windows/api-reference/IRTCLocalMicTrack) |

### Get a user's audio track object

```cpp theme={null}
virtual StatusCode getRemoteAudioTrack(const char* uid, const char* trackid, IRTCRemoteAudioTrack** track) = 0;
```

**Parameters**

| uid | User ID (empty for all users) |
| - | - |
| trackid | ID of the user's audio track (empty for all tracks) |
| track | [Local audio mixing track object](/en/rtc/windows/api-reference/IRTCRemoteAudioTrack) |

### Get a user's video track object

```cpp theme={null}
virtual StatusCode getRemoteVideoTrack(const char* uid, const char* trackid, IRTCRemoteVideoTrack** track) = 0;
```

**Parameters**

| uid | User ID |
| - | - |
| trackid | ID of the user's video track |
| track | [User video track object](/en/rtc/windows/api-reference/IRTCRemoteVideoTrack) |

### Get the composite stream video track object

```cpp theme={null}
virtual StatusCode getMCUVideoTrack(IRTCRemoteVideoTrack** track) = 0;
```

**Parameters**

| track | [Composite stream video track object](/en/rtc/windows/api-reference/IRTCRemoteVideoTrack) |
| - | - |

### Subscribe to a track

```cpp theme={null}
virtual StatusCode subscribe(IRTCTrack* tk ) = 0;
```

**Parameters**

| tk | The track, [IRTCRemoteVideoTrack](/en/rtc/windows/api-reference/IRTCRemoteVideoTrack), [IRTCRemoteAudioTrack](/en/rtc/windows/api-reference/IRTCRemoteAudioTrack) |
| - | - |

### Unsubscribe from a track

```cpp theme={null}
virtual StatusCode unsubscribe(IRTCTrack* tk ) = 0;
```

**Parameters**

| tk | The track, [IRTCRemoteVideoTrack](/en/rtc/windows/api-reference/IRTCRemoteVideoTrack), [IRTCRemoteAudioTrack](/en/rtc/windows/api-reference/IRTCRemoteAudioTrack) |
| - | - |

### Publish a video track

```cpp theme={null}
virtual StatusCode publish(IRTCTrack* tk, RTCVideoPublishOptions* opt) = 0;
```

**Parameters**

| tk | The track, [IRTCLocalCameraTrack](/en/rtc/windows/api-reference/IRTCLocalCameraTrack), [IRTCLocalScreenTrack](/en/rtc/windows/api-reference/IRTCLocalScreenTrack) |
| - | - |
| opt | Publishing parameters for the track; `nullptr` uses the default publishing parameters, [RTCVideoPublishOptions](/en/rtc/windows/types#video-track-publishing-options-rtcvideopublishoptions) |

### Publish an audio track

```cpp theme={null}
virtual StatusCode publish(IRTCTrack* tk, RTCAudioPublishOptions* opt) = 0;
```

**Parameters**

| tk | The track, [IRTCLocalMicTrack](/en/rtc/windows/api-reference/IRTCLocalMicTrack) |
| - | - |
| opt | Publishing parameters for the track; `nullptr` uses the default publishing parameters, [RTCAudioPublishOptions](/en/rtc/windows/types#audio-track-publishing-options-rtcaudiopublishoptions) |

Note: the two `publish` overloads no longer have a default argument (the old `publish(tk)` was itself an ambiguous call and didn't compile), so you must pass `opt` explicitly.
