基本概念
- ISMeetingEngine:SDK 引擎类,负责登录、会议管理 HTTP 接口、设备枚举、IM、资源盘以及频道生命周期。
- ISMeetingChannel:一个会议对应一个 channel,由
ISMeetingEngine::createChannel()创建,包含会中所有操作和媒体对象。 - 部分接口只允许在进入会议后调用。
ISMeetingEngine / ISMeetingChannel 及回调都是纯虚接口,接口签名变动会改变 vtable;升级 SDK 后必须重新编译业务工程,不能只替换 dll。
初始化 SDK
#include "SMeeting.h"
// 初始化引擎
SMeeting::ISMeetingEngine* engine = nullptr;
SMeeting::StatusCode ret = SMeeting::SMeetingEngine_Init(&engine);
if (ret != SMeeting::StatusCode::OK) {
return ret;
}
// 设置引擎级事件回调(当前类需继承 ISMeetingEngineEvent)
engine->setEventHandler(this);
实现引擎事件回调类
class MyEngineHandler : public SMeeting::ISMeetingEngineEvent {
public:
void onDeviceChange(SMeeting::DeviceType tp, bool isadd, std::string name) override {
// 处理设备变化
}
void onImEnabled(std::string uid, std::string sid) override {
// IM 已启用
}
// ... 实现其他需要的引擎级回调
};
登录与登出
登录
std::string token = "your_token_here";
engine->login(token, [&](SMeeting::StatusCode status, std::string msg) {
if (status == SMeeting::StatusCode::OK) {
// 登录成功
} else {
// 登录失败
}
});
登出
engine->logout([&](SMeeting::StatusCode status, std::string msg) {
if (status == SMeeting::StatusCode::OK) {
// 登出成功
}
});
创建会议
SMeeting::SMeetingCreateMeetingModel model;
model.title = "我的会议";
model.content = "会议说明";
model.meeting_type = 1; // 1: 临时会议,2: 预约会议
model.meeting_mode = 1; // 1: 普通
engine->createRoom(model, [&](SMeeting::StatusCode status, std::string msg) {
if (status == SMeeting::StatusCode::OK) {
// msg 为会议号
std::cout << "会议创建成功,会议号:" << msg << std::endl;
}
});
加入会议
创建频道并配置
std::string roomno = "123456789";
SMeeting::ISMeetingChannel* channel = nullptr;
SMeeting::StatusCode sc = engine->createChannel(roomno, &channel);
if (sc != SMeeting::StatusCode::OK) {
return;
}
// 设置频道级配置
SMeeting::ISMeetingChannelSetting* csetting = nullptr;
channel->getSetting(&csetting);
if (csetting) {
csetting->set_stream_model(1); // 设置流媒体模式
csetting->set_speaker_interval(500); // 音柱回调周期 (ms)
csetting->set_stat_interval(10000); // 网络统计回调周期 (ms)
csetting->set_enable_audio_record(1); // 启用音频录制
csetting->set_room_name("张三"); // 入会昵称
}
设置频道回调并进入
// 设置频道级事件回调(当前类需继承 ISMeetingChannelEvent)
channel->setEventHandler(this);
// 进入会议
std::string pass = ""; // 会议密码,无密码则为空
channel->enter(pass, [&](SMeeting::StatusCode status, std::string msg) {
if (status == SMeeting::StatusCode::OK) {
// 进入房间成功
} else {
// 进入房间失败,仍然需要 leaveChannel 回收对象
}
});
实现频道事件回调类
class MyChannelHandler : public SMeeting::ISMeetingChannelEvent {
public:
void onDisconnected(SMeeting::DisconnectReason reason,
SMeeting::StatusCode code,
std::string message) override {
// 处理断开连接事件
}
void onReconnected() override {
// 重连成功
}
void onUserEnter(std::string userdata) override {
// 处理用户进入事件
}
// ... 实现其他需要的频道级回调
};
退出会议
// 离开后 channel 对象会被销毁,不要再使用原指针
engine->leaveChannel(channel->getChannelId(), [&](SMeeting::StatusCode status, std::string msg) {
// 退出房间结果
});
channel = nullptr;
结束会议(主持人)
// 主持人解散会议
channel->adminDestroyRoom([&](SMeeting::StatusCode status, std::string msg) {
// 结束会议结果
});
取消会议(会议外)
std::string meeting_id = "sw46gz";
engine->cancelRoom(meeting_id, [&](SMeeting::StatusCode status, std::string msg) {
// 取消会议结果
});
获取房间和成员信息
std::string s;
// 获取自身信息
channel->getMe(s);
// 获取房间信息
channel->getRoom(s);
// 获取所有成员信息
channel->getMembers(s);
// 获取指定成员信息
std::string uid = "user_123";
channel->getMember(uid, s);
更新昵称
std::string new_name = "新昵称";
channel->updateName(new_name, [&](SMeeting::StatusCode status, std::string msg) {
// 昵称修改结果
});
获取设备列表
// type: 1=麦克风,2=扬声器,3=摄像头
std::vector<int> types = {1, 2, 3};
int page = 1;
std::string find_key = "";
engine->listAgent(types, page, find_key, [&](SMeeting::StatusCode status, std::string msg) {
if (status == SMeeting::StatusCode::OK) {
// msg 为设备列表 JSON 字符串
}
});
摄像头操作
获取摄像头对象
SMeeting::IMEETLocalCamera* camera = nullptr;
SMeeting::StatusCode sc = channel->getLocalCamera(&camera);
if (sc != SMeeting::StatusCode::OK) {
return;
}
打开摄像头
// 设置渲染窗口(hwnd 为窗口句柄)
camera->addPlayView(hwnd);
// 请求打开摄像头
camera->requestOpenCamera([&](SMeeting::StatusCode status, std::string msg) {
if (status == SMeeting::StatusCode::OK) {
// 摄像头打开成功
}
});
切换摄像头
std::string camera_name = "Integrated Camera";
int width = 640;
int height = 480;
camera->switchCamera(camera_name, width, height);
关闭摄像头
camera->closeCamera([&](SMeeting::StatusCode status, std::string msg) {
// 摄像头关闭结果
});
远端视频播放
获取远端视频对象
std::string uid = "user_123";
std::string track_desc = SMeeting::TRACK_DESC_CAMERA_BIG; // 或 TRACK_DESC_CAMERA_SMALL
SMeeting::IMEETRemoteVideo* remote_video = nullptr;
channel->getRemoteVideo(uid, track_desc, &remote_video);
开始播放
// 设置渲染窗口
remote_video->addPlayView(hwnd);
// 开始加载远端视频流
remote_video->loadRemoteVideo();
停止播放
remote_video->unLoadRemoteVideo();
remote_video->removeAllPlayView();
麦克风操作
获取麦克风对象
SMeeting::IMEETLocalMic* mic = nullptr;
channel->getLocalMic(&mic);
打开麦克风
mic->requestOpenMic([&](SMeeting::StatusCode status, std::string msg) {
if (status == SMeeting::StatusCode::OK) {
// 麦克风打开成功
}
});
切换麦克风
std::string mic_name = "Default Microphone";
mic->switchMic(mic_name);
关闭麦克风
mic->closeMic([&](SMeeting::StatusCode status, std::string msg) {
// 麦克风关闭结果
});
扬声器操作
获取远端音频对象
SMeeting::IMEETRemoteAudio* audio = nullptr;
channel->getRemoteAudio("", &audio);
打开扬声器
audio->openSpeaker();
切换扬声器
std::string speaker_name = "Default Speakers";
audio->switchSpeaker(speaker_name);
关闭扬声器
audio->closeSpeaker();
屏幕共享
获取屏幕共享对象
SMeeting::IMEETLocalScreen* screen = nullptr;
channel->getLocalScreen(&screen);
开始共享
// tp: 1=屏幕共享,2=窗口共享
// data: 屏幕索引或窗口句柄字符串
int tp = 1;
std::string data = "0,0,1920,1080"; // 主屏幕
//std::string data_hwnd = "hwnd:123321";//窗口采集
screen->requestShare(tp, data, [&](SMeeting::StatusCode status, std::string msg) {
if (status == SMeeting::StatusCode::OK) {
// 共享开始成功
}
});
停止共享
screen->stopShare([&](SMeeting::StatusCode status, std::string msg) {
// 共享停止结果
});
聊天消息
发送聊天消息
// tp: 1=文本,2=文件,3=图片,4=声音
int msg_type = 1;
std::string msg = "大家好!";
channel->sendRoomChatMessage(msg_type, msg, [&](SMeeting::StatusCode status, std::string m) {
// 发送结果
});
主持人管理接口
请求用户打开摄像头
std::string uid = "user_123";
channel->adminRequestUserOpenCamera(uid, [&](SMeeting::StatusCode status, std::string msg) {
// 请求结果
});
关闭用户摄像头
channel->adminCloseUserCamera(uid, [&](SMeeting::StatusCode status, std::string msg) {
// 操作结果
});
请求用户打开麦克风
channel->adminRequestUserOpenMic(uid, [&](SMeeting::StatusCode status, std::string msg) {
// 请求结果
});
关闭用户麦克风
channel->adminCloseUserMic(uid, [&](SMeeting::StatusCode status, std::string msg) {
// 操作结果
});
踢出用户
channel->adminKickUserOut(uid, [&](SMeeting::StatusCode status, std::string msg) {
// 踢出结果
});
设置房间麦克风权限
bool self_unmute_mic_disabled = true; // 是否禁止自行解除静音
bool mic_disabled = true; // 是否禁用房间音频
channel->adminUpdateRoomMicState(self_unmute_mic_disabled, mic_disabled,
[&](SMeeting::StatusCode status, std::string msg) {
// 设置结果
});
MCU 合成视频
获取 MCU 视频对象
SMeeting::IMEETRemoteVideo* mcu_video = nullptr;
channel->getMcuVideo(&mcu_video);
播放合成流
mcu_video->addPlayView(hwnd);
mcu_video->loadRemoteVideo();
停止播放
mcu_video->unLoadRemoteVideo();
释放资源
// 先离开所有会议
engine->leaveAllChannel();
// 释放引擎
if (engine) {
engine->del();
engine = nullptr;
}
完整示例
#include "SMeeting.h"
#include <iostream>
class MyEngineHandler : public SMeeting::ISMeetingEngineEvent {
public:
void onDeviceChange(SMeeting::DeviceType tp, bool isadd, std::string name) override {
// 处理设备变化
}
void onImEnabled(std::string uid, std::string sid) override {
// IM 已启用
}
};
class MyChannelHandler : public SMeeting::ISMeetingChannelEvent {
public:
void onDisconnected(SMeeting::DisconnectReason reason,
SMeeting::StatusCode code,
std::string message) override {
std::cout << "Disconnected: " << (int)code << std::endl;
}
void onUserEnter(std::string userdata) override {
std::cout << "User entered: " << userdata << std::endl;
}
// 实现其他需要的回调...
};
int main() {
// 初始化引擎
SMeeting::ISMeetingEngine* engine = nullptr;
SMeeting::StatusCode ret = SMeeting::SMeetingEngine_Init(&engine);
if (ret != SMeeting::StatusCode::OK) {
return -1;
}
MyEngineHandler engine_handler;
engine->setEventHandler(&engine_handler);
// 登录
std::string token = "your_token";
engine->login(token, [&](SMeeting::StatusCode status, std::string msg) {
if (status != SMeeting::StatusCode::OK) {
return;
}
// 创建会议
SMeeting::SMeetingCreateMeetingModel model;
model.title = "测试会议";
engine->createRoom(model, [&](SMeeting::StatusCode status, std::string roomno) {
if (status != SMeeting::StatusCode::OK) {
return;
}
// 创建频道
SMeeting::ISMeetingChannel* channel = nullptr;
engine->createChannel(roomno, &channel);
if (!channel) {
return;
}
MyChannelHandler channel_handler;
channel->setEventHandler(&channel_handler);
// 进入会议
channel->enter("", [&](SMeeting::StatusCode status, std::string msg) {
if (status == SMeeting::StatusCode::OK) {
std::cout << "进入会议成功" << std::endl;
}
});
});
});
// 等待异步操作完成(实际应用中应有事件循环)
std::this_thread::sleep_for(std::chrono::seconds(30));
// 清理
engine->logout();
engine->del();
return 0;
}