多人音视频通话
本章节介绍多人实时音视频通话的相关功能。多人实时音视频通话顾名思义是支持多个人同时进行实时音视频通话,可以选择纯音频模式,或音视频模式。在这里需要明确几个概念:
房间:房间就是用户进行多人实时音视频通话的地方,房间以房间名称为唯一标识,多人房间需要先创建成功后才能加入,当所有用户都离开房间后,可以复用该房间名重新创建。
互动者:互动者是指在多人通话时可以参与互动,可以发言的人,这些用户可以发送上行的音频或视频数据,也可以接收其他互动者下行的音频或视频数据。
观众:观众是指在多人通话时只可以观看的人,没有发言的权限,这些用户只可以接收互动者下行的音频或视频数据,不可以发送上行音频或视频数据。 其中互动者和观众身份可以随时切换。
多人音视频通话流程
预定会议
API介绍
根据房间名,创建一个多人会议房间。创建后的房间需要有人加入后才会实际产生话单。其中webrtc标记支持webrtc互通,无需要不要打开。房间推流的配置信息需要从扩展字段传入。
API原型
C++
static void CreateRoom(const std::string& room_name, const std::string& custom_info, const std::string& json_extension, Opt2Callback cb)
File:nim_cpp_vchat.h
Namespace:NIM
Class:VChat
C#
public static void CreateRoom(string room_name, string custom_info, NIMCreateRoomJsonEx createRoomInfo, NIMVChatOpt2Handler cb)
Namespace:NIM
Class:VChatAPI
C
void nim_vchat_create_room(const char *room_name, const char *custom_info, const char *json_extension, nim_vchat_opt2_cb_func cb, const void *user_data)
File:nim_vchat.h
参数说明
- C++
参数 | 类型 | 说明 |
---|---|---|
room_name | string | 房间名 |
custom_info | string | 自定义信息,所有加入房间的成员都会收到此信息 |
json_extension | string | Json string 扩展,房间配置信息,详见nim_vchat_def.h |
cb | function | 回调函数 |
- C#
参数 | 类型 | 说明 |
---|---|---|
room_name | string | 房间名 |
custom_info | string | 自定义信息,所有加入房间的成员都会收到此信息 |
createRoomInfo | Json | Json string 扩展,房间配置信息 |
cb | function | 回调函数 |
- C
参数 | 类型 | 说明 |
---|---|---|
room_name | string | 房间名 |
custom_info | string | 自定义信息,所有加入房间的成员都会收到此信息 |
json_extension | string | Json string 扩展,房间配置信息,详见nim_vchat_def.h |
cb | function | 回调函数 |
user_data | void* | 无效扩展 |
返回值说明
无返回值。
示例
C++
void CreateRoomCb(int code, __int64 channel_id, const std::string& json_extension) { } void foo() { nim::VChat::CreateRoom("room_name", "custom_info", "", CreateRoomCb); }
C#
void CreateMultiVChatRoomCallback(bool ret, int code,string json_extension,IntPtr user_data) { if (ret) { } else { Action action = () => { MessageBox.Show("创建房间失败-错误码:" + code.ToString()); }; this.BeginInvoke(action); } } void foo() { string custom_info = "custom_info"; string json_extension = ""; room_name = Guid.NewGuid().ToString("N"); VChatAPI.CreateRoom(room_name, custom_info, json_extension, CreateMultiVChatRoomCallback, IntPtr.Zero); }
C
void OnOpt2Callback(int code, __int64 cannel_id, const char *json_extension, const void *user_data) { } typedef void(*nim_vchat_create_room)(const char *room_name, const char *custom_info, const char *json_extension, nim_vchat_opt2_cb_func cb, const void *user_data); void foo() { nim_vchat_create_room func = (nim_vchat_create_room) GetProcAddress(hInst, "nim_vchat_create_room"); func("room_name", "custom_info", "", OnOpt2Callback, nullptr); }
特殊说明
返回错误码中417说明已经存在同名的房间,如果是目标房间议,则可以直接走后面流程加入此房间。如果不是希望创建的目标房间,则需要重新设定房间名后再创建。
加入会议
API介绍
加入一个房间。所有音视频相关通话都是互斥,只允许存在一个,并且加入前必选预先创建房间。
API原型
C++
static bool JoinRoom(NIMVideoChatMode mode, const std::string& room_name, const std::string& json_extension, Opt2Callback cb)
File:nim_cpp_vchat.h
Namespace: nim
Class:VChat
C#
static bool JoinRoom(NIMVideoChatMode mode, string room_name, NIMJoinRoomJsonEx joinRoomInfo, NIMVChatOpt2Handler cb)
Namespace:NIM
Class:VChatAPI
C
bool nim_vchat_join_room(enum NIMVideoChatMode mode, const char *room_name, const char *json_extension, nim_vchat_opt2_cb_func cb, const void *user_data)
File:nim_vchat.h
参数说明
参数 | 类型 | 说明 |
---|---|---|
mode | enum | 音视频通话类型,见nim_vchat_def.h |
room_name | string | 房间名 |
json_extension(C/C++) | string | Json string 扩展,音视频通话的扩展参数设置 |
joinRoomInfo(C#) | object | C接口中json_extension的封装类,见NIMJoinRoomJsonEx |
cb | function | 结果回调 |
user_data(C) | void* | APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理! |
返回值说明
返回一个bool类型值。接口调用成功返回true,否则返回false。失败一般是由于已存在通话,无法重复发起。
示例
C++
void OnOpt2Callback(int code, __int64 cannel_id, const char *json_extension, const void *user_data) { } void foo() { Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatSessionId] = session_id; value[nim::kNIMVChatVideoQuality] = kNIMVChatVideoQualitySuper;//分辨率 std::string json_value = fs.write(value); nim::VChat::JoinRoom(nim::kNIMVideoChatModeAudio, "room_name", json_value, OnOpt2Callback); }
C#
void JoinMultiVChatRoomCallback(int code, Int64 channel_id, string json_extension,IntPtr user_data) { if (code==200) { } else { Action action = () => { MessageBox.Show("加入房间失败-错误码:" + code.ToString()); }; this.BeginInvoke(action); } } void foo() { NIM.NIMJoinRoomJsonEx joinRoomJsonEx = new NIMJoinRoomJsonEx(); joinRoomJsonEx.SessionId = Guid.NewGuid().ToString("N"); joinRoomJsonEx.VideoQuality = NIMVChatVideoQuality.kNIMVChatVideoQualitySuper;//设置分辨率 string room_name = "room1"; Action action = () => { if (VChatAPI.JoinRoom(NIMVideoChatMode.kNIMVideoChatModeVideo, room_name, joinRoomJsonEx, _joinroomcb)) { //调用成功 } else { string info = String.Format("加入房间-{0}-失败", room_name); MessageBox.Show(info); } }; this.Invoke(action); }
C
void OnOpt2Callback(int code, __int64 cannel_id, const char *json_extension, const void *user_data) { } typedef bool(*nim_vchat_join_room)(NIMVideoChatMode mode, const char *room_name, const char *json_extension, nim_vchat_opt2_cb_func cb, const void *user_data); void foo() { nim_vchat_join_room func = (nim_vchat_join_room) GetProcAddress(hInst, "nim_vchat_join_room"); Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatSessionId] = session_id; value[nim::kNIMVChatVideoQuality] = kNIMVChatVideoQualitySuper;//分辨率 std::string json_value = fs.write(value); func(nim::kNIMVideoChatModeAudio, "room_name", json_value, cb); }
离开会议
API介绍
需要在结束时调用,用于底层挂断和清理数据。
API原型
C++
static void End(const std::string& json_extension);
File:nim_cpp_vchat.h
Namespace:NIM
Class:VChat
C#
public static void End(string jsonExtension="")
Namespace:NIM
Class:VChatAPI
C
void nim_vchat_end(const char *json_extension)
File:nim_vchat.h
参数说明
需要带上加入时填写的session_id。
- C++
参数 | 类型 | 说明 |
---|---|---|
json_extension | string | Json string 扩展,kNIMVChatSessionId |
- C#
参数 | 类型 | 说明 |
---|---|---|
jsonExtension | string | Json string 扩展,kNIMVChatSessionId |
- C
参数 | 类型 | 说明 |
---|---|---|
json_extension | string | Json string 扩展,kNIMVChatSessionId |
返回值说明
无返回值。
示例
C++
void foo() { Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatSessionId] = session_id; std::string json_value = fs.write(value); nim::VChat::End(json_value); }
C#
void foo() { string json = "{\"session_id\":\"session_id_temp\"}"; NIM.VChatAPI.End(json); }
C
typedef void(*nim_vchat_end)(const char* json_extension); void foo() { nim_vchat_end func = (nim_vchat_end) GetProcAddress(hInst, "nim_vchat_end"); Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatSessionId] = session_id; std::string json_value = fs.write(value); func(json_value.c_str()); }
用户进出会议通知
API介绍
在连接建立后,如果已有成员在通话中,或新进来的成员都会通过此回调通知。有成员离开也通过此回调,并告诉是正常离开还是超时离开,超时离开代表本地超时未收到对端数据,可能对方网络异常也可能是本地网络异常。
API原型
C#
NIMVChatSessionStatus.onSessionPeopleStatus
public delegate void onSessionPeopleStatusHandler(long channel_id, string uid, int status)
Namespace:NIM
Class:VChatAPI
C++/C
typedef void (*nim_vchat_cb_func)(enum NIMVideoChatSessionType type, int64 channel_id, int code, const char *json_extension, const void *user_data)
NIMVideoChatSessionType::kNIMVideoChatSessionTypePeopleStatus
File:nim_vchat_def.h
参数说明
- C#
参数 | 类型 | 说明 |
---|---|---|
channel_id | long | 频道id |
uid | string | 对方id |
status | int | 成员状态,离开、加入等 |
- C++/C
参数 | 类型 | 说明 |
---|---|---|
type | enum | 回调类型kNIMVideoChatSessionTypePeopleStatus |
channel_id | int64 | 频道id |
code | int | 状态码,对应NIMVideoChatSessionStatus |
json_extension | string | Json string 扩展,返回kNIMVChatUid,如果是离开带kNIMVChatStatus对应NIMVideoChatUserLeftType |
user_data | void* | 注册回调时的APP自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
C#
private static void OnSessionPeopleStatus(long channel_id, string uid, int status) { DemoTrace.WriteLine("SessionPeopleStatus channel_id:" + channel_id.ToString() + " status:" + status.ToString() + " uid:" + uid); if (status == NIMVideoChatSessionStatus.kNIMVideoChatSessionStatusJoined) { MessageBox.Show("用户加入"); } else if (status == NIMVideoChatSessionStatus.kNIMVideoChatSessionStatusLeaved) { MessageBox.Show("用户离开"); } }
C++/C
void VChatCb(nim::NIMVideoChatSessionType type, __int64 channel_id, int code, const char *json, const void*) { switch (type) { case nim::kNIMVideoChatSessionTypePeopleStatus:{ if (code == nim::kNIMVideoChatSessionStatusJoined) { //用户加入 } else if (code == nim::kNIMVideoChatSessionStatusLeaved) { //用户离开 Json::Value valus; Json::Reader reader; if (reader.parse(json, valus)) { std::string uid = valus[nim::kNIMVChatUid].asString(); int32_t leave_type = valus[nim::kNIMVChatStatus].asInt(); QLOG_APP(L"vchat people leave uid: {0}, leave_type {1}") << uid << leave_type; } } }break; //··· } }
会议发生了错误
API介绍
当房间发生异常,统一返回连接错误信息,和开始时连接成功及连接失败是同一个回调函数。
API原型
C#
NIMVChatSessionStatus.onSessionConnectNotify
public delegate void onSessionConnectNotifyHandler(long channel_id, int code, string record_file, string video_record_file)
Namespace:NIM
Class:VChatAPI
C++/C
typedef void (*nim_vchat_cb_func)(enum NIMVideoChatSessionType type, int64 channel_id, int code, const char *json_extension, const void *user_data)
NIMVideoChatSessionType::kNIMVideoChatSessionTypeConnect
File:nim_vchat_def.h
参数说明
- C#
参数 | 类型 | 说明 |
---|---|---|
channel_id | long | 频道id |
code | int | 状态码见NIMVChatConnectErrorCode |
record_file | string | 服务器录制的音频文件名 |
video_record_file | string | 服务器录制的视频文件名 |
- C++/C
参数 | 类型 | 说明 |
---|---|---|
type | enum | 回调类型kNIMVideoChatSessionTypeConnect |
channel_id | int64 | 频道id |
code | int | 错误码NIMVChatConnectErrorCode,200代表连接成功 |
json_extension | string | Json string 扩展,如果成功返回 kNIMVChatVideoRecordFile和kNIMVChatRecordFile |
user_data | void* | 注册回调时的APP自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
- NIMVChatConnectErrorCode
枚举定义 | 值 | 说明 |
---|---|---|
kNIMVChatConnectDisconn | 0 | 断开连接 |
kNIMVChatConnectStartFail | 1 | 启动失败 |
kNIMVChatConnectTimeout | 101 | 超时 |
kNIMVChatConnectMeetingModeError | 102 | 会议模式错误 |
kNIMVChatConnectRtmpModeError | 103 | 非rtmp用户加入rtmp频道 |
kNIMVChatConnectRtmpNodesError | 104 | 超过频道最多rtmp人数限制 |
kNIMVChatConnectRtmpHostError | 105 | 已经存在一个主播 |
kNIMVChatConnectRtmpCreateError | 106 | 需要旁路直播, 但频道创建者非主播 |
kNIMVChatConnectSuccess | 200 | 成功 |
kNIMVChatConnectLayoutError | 208 | 主播自定义布局错误 |
kNIMVChatConnectInvalidParam | 400 | 错误参数 |
kNIMVChatConnectDesKey | 401 | 密码加密错误 |
kNIMVChatConnectInvalidRequst | 417 | 错误请求 |
kNIMVChatConnectServerUnknown | 500 | 服务器内部错误 |
kNRTCChatJoinChannelBusy | 9104 | 通道繁忙 |
kNIMVChatConnectLogout | 1001 | 退出 |
kNIMVChatChannelStartFail | 11000 | 发起失败 |
kNIMVChatChannelDisconnected | 11001 | 断开连接 |
kNIMVChatVersionSelfLow | 11002 | 本人SDK版本太低不兼容 |
kNIMVChatVersionRemoteLow | 11003 | 对方SDK版本太低不兼容 |
kNRTCChatLocalChannelClosed | 11004 | 通道被关闭 |
kNRTCChatLocalChannelKicked | 11005 | 账号被踢 |
示例
C#
private static void OnSessionConnectNotify(long channel_id, int code, string record_file, string video_record_file) { if (code == 200) { //连接成功 } else { //连接失败 NIM.VChatAPI.End(); } }
C++/C
void VChatCb(nim::NIMVideoChatSessionType type, __int64 channel_id, int code, const char *json, const void*) { switch (type) { case nim::kNIMVideoChatSessionTypeConnect:{ if (code == 200) { //连接成功 } else { //连接失败 } }break; //··· } }