Windows(C++) 快速开始与功能指南
Windows(C++):前置条件、安装、Token、加入频道、发布订阅、事件、错误处理与排障;接口名与签名在构建时取自公开 SDK 接口定义。
Windows 端(C++)是 IRtcEngine + IRtcEngineEventHandler 形状:initialize → joinChannel → 回调驱动。桌面采集支持按窗口 id / 屏幕区域 / 显示器 id 三种方式。
前置条件
- Visual Studio 2022(MSVC v143)、CMake 3.25+、Windows 10 1809+。
- 运行时需要摄像头/麦克风权限(系统「隐私和安全性 → 摄像头 / 麦克风」)。
- 已拿到
appId与 Token 服务(见 控制台开通服务与获取凭证)。
安装
# vcpkg 端口以发布版本为准
vcpkg install nimeet-rtc:x64-windows
# 或直接把 sdk/windows 作为子目录 CMake 工程引入
add_subdirectory(sdk/windows)
target_link_libraries(your_app PRIVATE nimeet::rtc)获取 Token
客户端不能持有 customerSecret。生产形态是宿主程序带一个后端服务签发 Token,C++ 侧只接收字符串; 开发期可以把 Token 放环境变量,不要编译进二进制。
加入频道
#include "nimeet/rtc/IRtcEngine.h"
class Handler : public IRtcEngineEventHandler {
public:
void onJoinChannelSuccess(const char* channel, uid_t uid, int elapsed) override {
// 入会成功
}
void onUserJoined(uid_t uid, int elapsed) override { /* 分配远端画面 */ }
void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason) override { /* 释放画面 */ }
void onTokenPrivilegeWillExpire(const char* token) override { /* 续期后 renewToken */ }
void onError(int err, const char* msg) override { /* 按错误号分流 */ }
};
Handler handler;
IRtcEngine* engine = createAgoraRtcEngine();
RtcEngineContext context;
context.appId = app_id;
context.eventHandler = &handler;
engine->initialize(context);
engine->setChannelProfile(CHANNEL_PROFILE_LIVE_BROADCASTING);
engine->enableVideo();
VideoCanvas canvas;
canvas.view = local_hwnd;
engine->setupLocalVideo(canvas);
engine->startPreview();
engine->joinChannel(token, "weekly-sync", "", 10001);joinChannel 另有带 ChannelMediaOptions& 的重载(可指定角色、订阅范围、发布来源),完整签名见同端 API 参考。
发布与订阅
engine->muteLocalAudioStream(true); // 静音麦克风
engine->muteLocalVideoStream(true); // 关本地画面
engine->enableLocalVideo(false); // 停止采集
engine->updateChannelMediaOptions(options);屏幕共享:
IScreenCaptureSourceList* sources = engine->getScreenCaptureSources({160, 90}, {32, 32}, true);
// 按窗口共享
Rectangle region{0, 0, 0, 0};
ScreenCaptureParameters params;
params.frameRate = 15;
engine->startScreenCaptureByWindowId(window_id, region, params);事件
IRtcEngineEventHandler 有 88 个回调。最常用:onJoinChannelSuccess、onUserJoined、onUserOffline、 onFirstRemoteVideoDecoded、onTokenPrivilegeWillExpire、onError、onConnectionStateChanged。
错误处理
- 同步方法返回
int:0成功,负值为声网错误号。 onError(int err, const char* msg)提供可读消息,日志里两者都要记。- 未实现能力返回
-4(ERR_NOT_SUPPORTED)。
排障
| 现象 | 原因 | 处理 |
|---|---|---|
initialize 返回非 0 | App ID 非法或已初始化 | 只初始化一次;检查 appId |
入会返回 -2 | 频道名/uid 非法 | 频道名 [A-Za-z0-9_-],uid 正数 |
| 本地预览黑屏 | canvas.view 句柄无效 | 等窗口创建完成再 setupLocalVideo |
| 崩溃在回调线程 | 跨线程操作 UI | marshal 回主线程 |
| 采集失败 | 系统摄像头隐私开关关闭 | 系统设置里开启并重启进程 |
下一步
平台信息
| 项 | 值 |
|---|---|
| 平台 | Windows(C++) |
| 语言 | C++ |
| SDK 包 | nimeet_rtc_win |
| 接口版本 | 4.7.0 |
| 兼容参考 | 声网 windows 端 API |
本端公开接口与声网 windows 端 API 对齐;安装与运行要求见上面前置条件。
可用性
该端 SDK:正式可用。本页代码片段使用公开 API;运行时的能力边界以实际发布的 SDK 包为准。
加入频道链路
下列方法名、参数类型与返回值与同端 API 参考一致。一个平台若有多个重载,这里展示最常用的那一个;完整重载见同端 API 参考页。
| 步骤 | 接口 | 方法 | 重载数 |
|---|---|---|---|
| 创建实例 / 初始化 | ILocalSpatialAudioEngine | initialize | 1 |
| 订阅远端媒体 | ILocalSpatialAudioEngine | muteRemoteAudioStream | 1 |
| 续期 Token | IMusicContentCenter | renewToken | 1 |
| 开启视频与本地预览 | IRtcEngine | enableVideo | 1 |
| 加入频道 | IRtcEngine | joinChannel | 2 |
| 离开频道 | IRtcEngine | leaveChannel | 2 |
| 频道场景 | IRtcEngine | setChannelProfile | 1 |
| 切换角色 | IRtcEngine | setClientRole | 2 |
| 绑定本地画面 | IRtcEngine | setupLocalVideo | 1 |
initialize(config: const LocalSpatialAudioConfig&): int
muteRemoteAudioStream(uid: uid_t, mute: bool): int
renewToken(token: const char*): int
enableVideo(): int
joinChannel(token: const char*, channelId: const char*, info: const char*, uid: uid_t): int
leaveChannel(): int
setChannelProfile(profile: CHANNEL_PROFILE_TYPE): int
setClientRole(role: CLIENT_ROLE_TYPE): int
setupLocalVideo(canvas: const VideoCanvas&): int事件与回调
回调注册在 IRtcEngineEventHandler 上;不同端的命名可能不同,完整清单见同端 API 参考页。
| 回调 | 签名 | 用途 |
|---|---|---|
onConnectionStateChanged | onConnectionStateChanged(state: CONNECTION_STATE_TYPE, reason: CONNECTION_CHANGED_REASON_TYPE): void | 入会结果 / 连接状态变化:据此更新 UI 并决定是否重连。 |
onUserJoined | onUserJoined(uid: uid_t, elapsed: int): void | 远端用户加入:分配画面容器。 |
onFirstRemoteVideoDecoded | onFirstRemoteVideoDecoded(uid: uid_t, width: int, height: int, elapsed: int): void | 远端视频状态:首帧解码后即可渲染。 |
onUserOffline | onUserOffline(uid: uid_t, reason: USER_OFFLINE_REASON_TYPE): void | 远端用户离开:释放容器与订阅。 |
onRequestToken | onRequestToken(): void | Token 即将过期:调用服务端续期后 `renewToken`。 |
onError | onError(err: int, msg: const char*): void | 运行时错误:`err` 为声网错误号,按错误码表分流。 |
onNetworkQuality | onNetworkQuality(uid: uid_t, txQuality: int, rxQuality: int): void | 网络质量:上报到水晶球或提示用户。 |
错误码
| 常量 | 值 |
|---|---|
ERR_ABORTED | 20 |
ERR_ADM_GENERAL_ERROR | 1005 |
ERR_ADM_INIT_PLAYOUT | 1008 |
ERR_ADM_INIT_RECORDING | 1011 |
ERR_ADM_START_PLAYOUT | 1009 |
ERR_ADM_START_RECORDING | 1012 |
ERR_ADM_STOP_PLAYOUT | 1010 |
ERR_ADM_STOP_RECORDING | 1013 |
ERR_ALREADY_IN_USE | 19 |
ERR_BIND_SOCKET | 13 |
ERR_BITRATE_LIMIT | 115 |
ERR_BUFFER_TOO_SMALL | 6 |
ERR_CANCELED | 11 |
ERR_CLIENT_IS_BANNED_BY_SERVER | 123 |
ERR_CONNECTION_INTERRUPTED | 111 |
ERR_CONNECTION_LOST | 112 |
ERR_DATASTREAM_DECRYPTION_FAILED | 122 |
ERR_DECRYPTION_FAILED | 120 |
ERR_ENCRYPTED_STREAM_NOT_ALLOWED_PUBLISH | 130 |
ERR_FAILED | 1 |
ERR_INIT_NET_ENGINE | 21 |
ERR_INVALID_ARGUMENT | 2 |
ERR_INVALID_CHANNEL_NAME | 102 |
ERR_INVALID_STATE | 8 |
ERR_INVALID_TOKEN | 110 |
ERR_INVALID_USER_ID | 121 |
ERR_JOIN_CHANNEL_REJECTED | 17 |
ERR_LEAVE_CHANNEL_REJECTED | 18 |
ERR_LOAD_MEDIA_ENGINE | 1001 |
ERR_NET_DOWN | 14 |
ERR_NOT_INITIALIZED | 7 |
ERR_NOT_IN_CHANNEL | 113 |
ERR_NOT_READY | 3 |
ERR_NOT_SUPPORTED | 4 |
ERR_NO_PERMISSION | 9 |
ERR_NO_SERVER_RESOURCES | 103 |
ERR_OK | 0 |
ERR_PCMSEND_BUFFEROVERFLOW | 201 |
ERR_PCMSEND_FORMAT | 200 |
ERR_REFUSED | 5 |
ERR_RESOURCE_LIMITED | 22 |
ERR_SET_CLIENT_ROLE_NOT_AUTHORIZED | 119 |
ERR_SIZE_TOO_LARGE | 114 |
ERR_STREAM_MESSAGE_TIMEOUT | 117 |
ERR_TIMEDOUT | 10 |
ERR_TOKEN_EXPIRED | 109 |
ERR_TOO_MANY_DATA_STREAMS | 116 |
ERR_TOO_OFTEN | 12 |
ERR_VDM_CAMERA_NOT_AUTHORIZED | 1501 |
平台 REST 层用 REST 错误码;SDK 层把连接/鉴权失败映射成声网错误号,映射表见 各端 SDK 错误标识。