消息收发
发送消息
SDK(PC) 支持文本、图片、音频、视频、地理位置、通知消息、提醒消息、文件消息、机器人消息和自定义消息等多种种类型消息。
API介绍
C++
static void SendMsg (const std::string &json_msg, const std::string &json_extension="", FileUpPrgCallback *pcb=nullptr)
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
static void SendMessage (NIMIMMessage message, ReportUploadProgressDelegate action=null)
Namespace:NIM
Class:TalkAPI
C
NIM_SDK_DLL_API void nim_talk_send_msg (const char *json_msg, const char *json_extension, nim_nos_upload_prg_cb_func prg_cb, const void *prg_user_data)
File:nim_talk.h
同时我们也提供了停止发送消息接口,该接口目前主要用于在文件消息上传过程中终止消息发送。
C++
static bool StopSendMsg (const std::string &client_msg_id, const NIMMessageType &type, const std::string &json_extension="")
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
static void StopSendMessage (NIMIMMessage message, ReportUploadProgressDelegate action=null)
Namespace:NIM
Class:TalkAPI
C
NIM_SDK_DLL_API void nim_talk_stop_send_msg (const char *json_msg, const char *json_extension)
File:nim_talk.h
发送消息是否成功(是否成功与对方是否已读是不同的概念)通过登录前注册的全局回调获取。
C++
static void RegSendMsgCb (const SendMsgAckCallback &cb, const std::string &json_extension="")
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
示例:
void OnSendMsgCallback(const nim::SendMessageArc& arc) { ··· } void foo() { nim::Talk::RegSendMsgCb(&OnSendMsgCallback); }
Define: SendMessageArc
C#
static EventHandler< MessageArcEventArgs > OnSendMessageCompleted [get, set]
Namespace:NIM
Class:TalkAPI
示例:
void SendMessageResultHandler(object sender, MessageArcEventArgs args) { if(args.ArcInfo.Response == ResponseCode.kNIMResSuccess) { ··· } if (args.ArcInfo.Response == ResponseCode.kNIMResSuccess) return; Action action = () => { MessageBox.Show(args.Dump(), "发送失败"); }; this.Invoke(action); } private void foo() { NIM.TalkAPI.OnSendMessageCompleted += SendMessageResultHandler; }
Define: MessageArcEventArgs
C
NIM_SDK_DLL_API void nim_talk_reg_ack_cb (const char *json_extension, nim_talk_ack_cb_func cb, const void *user_data)
File:nim_talk.h
示例:
void CallbackSendMsgResult(const char* result, const void *user_data) { //解析result {"msg_id" : "" , "talk_id" : "" , "rescode" : ""} } typedef void(*nim_talk_reg_arc_cb)(const char *json_extension, nim_talk_arc_cb_func cb, const void *user_data); void foo() { nim_talk_reg_arc_cb func = (nim_talk_reg_arc_cb) GetProcAddress(hInst, "nim_talk_reg_arc_cb"); func(nullptr, &CallbackSendMsgResult, nullptr); }
参数说明
- 发送消息接口参数说明
参数 | 类型 | 说明 |
---|---|---|
json_msg(C/C++) | string | 消息体Json字符串,C接口需要自行组装Json数据结构并序列化为无格式的Json字符串, C++接口可以通过Talk::CreateXXXMessage方法生成(具体见本章辅助API介绍) |
message(C#) | object | 消息对象,见NIMIMMessage |
prg_cb/pcb/action | function | 上传进度的回调函数, 如果发送的消息里包含了文件资源, 则通过此回调函数通知上传进度 |
json_extension(C) | string | json扩展参数(备用,目前不需要) |
user_data(C) | void* | APP的自定义用户数据,SDK只负责传回给回调函数cb, 不做任何处理 |
- 停止发送消息接口参数说明
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
client_msg_id(C++) | string | 是 | 停止发送的消息对象的client_msg_id |
message(C#) | object | 是 | 停止发送的消息对象,见NIMIMMessage |
json_msg(C) | string | 是 | 停止发送的消息对象Json string |
json_extension(C) | string | 否 | json扩展参数(备用,目前不需要) |
文字消息
构造API介绍
C++
/** @fn static std::string CreateTextMessage(const std::string& receiver_id, const NIMSessionType session_type, const std::string& client_msg_id, const std::string& content, const MessageSetting& msg_setting, int64_t timetag = 0) * 生成文字消息内容,生成的字符串在调用SendMsg时直接传入 * @param[in] receiver_id 聊天对象的 ID,如果是单聊,为用户帐号,如果是群聊,为群组 ID * @param[in] session_type NIMSessionType,聊天类型,单聊或群组 * @param[in] client_msg_id 客户端消息id,建议uuid * @param[in] content 文本内容 * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return std::string 文字消息Json字符串 */ static std::string CreateTextMessage (const std::string &receiver_id, const NIMSessionType session_type, const std::string &client_msg_id, const std::string &content, const MessageSetting &msg_setting, int64_t timetag=0)
Define: NIMSessionType ; MessageSetting
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
无,操作对象。
C
无,根据定义组装Json数据。
图片消息
构造API介绍
C++
/** @fn static std::string CreateImageMessage(const std::string& receiver_id, const NIMSessionType session_type, const std::string& client_msg_id, const IMImage& image, const std::string& file_path, const MessageSetting& msg_setting, int64_t timetag = 0) * 生成图片消息内容,生成的字符串在调用SendMsg时直接传入 * @param[in] receiver_id 聊天对象的 ID,如果是单聊,为用户帐号,如果是群聊,为群组 ID * @param[in] session_type NIMSessionType,聊天类型,单聊或群组 * @param[in] client_msg_id 客户端消息id,建议uuid * @param[in] image IMImage,图片文件信息 * @param[in] file_path 文件本地绝对路径 * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return std::string 图片消息Json字符串 */ static std::string CreateImageMessage (const std::string &receiver_id, const NIMSessionType session_type, const std::string &client_msg_id, const IMImage &image, const std::string &file_path, const MessageSetting &msg_setting, int64_t timetag=0)
Define: NIMSessionType ; MessageSetting ; IMImage
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
无,操作对象。
C
无,根据定义组装Json数据。
示例
C++
//代码摘抄自DEMO源码 void SessionBox::SendImage( const std::wstring &src ) { nim::IMMessage msg; PackageMsg(msg); msg.type_ = nim::kNIMMessageTypeImage; std::wstring filename = nbase::UTF8ToUTF16(msg.client_msg_id_); std::wstring dest = GetUserImagePath() + filename; GenerateUploadImage(src, dest); msg.local_res_path_ = nbase::UTF16ToUTF8(dest); nim::IMImage img; img.md5_ = GetFileMD5(dest); img.size_ = (long)nbase::GetFileSize(dest); Gdiplus::Image image(dest.c_str()); if (image.GetLastStatus() != Gdiplus::Ok) { assert(0); } else { img.width_ = image.GetWidth(); img.height_ = image.GetHeight(); } msg.attach_ = img.ToJsonString(); std::string json_msg = nim::Talk::CreateImageMessage(msg.receiver_accid_, msg.session_type_, msg.client_msg_id_, img, msg.local_res_path_, msg.timetag_); nim::Talk::SendMsg(json_msg); }
C#
void SendImage(string path) { string fileName = System.IO.Path.GetFileNameWithoutExtension(path); string extension = System.IO.Path.GetExtension(path); NIM.NIMImageMessage imageMsg = new NIMImageMessage(); imageMsg.LocalFilePath = path; imageMsg.ImageAttachment = new NIMImageAttachment(); imageMsg.ImageAttachment.DisplayName = fileName; imageMsg.ImageAttachment.FileExtension = extension; imageMsg.ReceiverID = _peerId; imageMsg.SessionType = _sessionType; using (var i = Image.FromFile(path)) { imageMsg.ImageAttachment.Height = i.Height; imageMsg.ImageAttachment.Width = i.Width; } TalkAPI.SendMessage(imageMsg); }
C
typedef void(*nim_talk_send_msg)(const char* json_msg, const char *json_extension, nim_nos_upload_prg_cb_func prg_cb, const void *prg_user_data); void foo() { Json::Value json; json[kNIMMsgKeyToType] = ; //int 会话类型(NIMSessionType 个人0 群组1) json[kNIMMsgKeyToAccount] = ; //string 消息接收者id json[kNIMMsgKeyTime] = ; //int64 消息发送时间(毫秒),可选 json[kNIMMsgKeyType] = ; //NIMMessageType 消息类型 json[kNIMMsgKeyBody] = ; //string 消息内容 json[kNIMMsgKeyAttach] = ; //string 附加内容 json[kNIMMsgKeyClientMsgid] = ; //string 消息id,一般使用guid json[kNIMMsgKeyResendFlag] = ; //int 重发标记(0不是重发, 1是重发) json[kNIMMsgKeyLocalLogStatus] = ; //NIMMsgLogStatus 消息状态 json[kNIMMsgKeyType] = kNIMMessageTypeImage; //图片详细信息 Json::Value attach; attach[kNIMImgMsgKeyMd5] = ; //string 文件md5,选填 attach[kNIMImgMsgKeySize] = ; //long 文件大小,选填 attach[kNIMImgMsgKeyWidth] = ; //int 图片宽度,必填 attach[kNIMImgMsgKeyHeight] = ; //int 图片高度,必填 json[kNIMMsgKeyAttach] = attach.toStyledString(); json[kNIMMsgKeyLocalFilePath] = ; //string 图片本地路径 json[kNIMMsgKeyLocalLogStatus] = kNIMMsgLogStatusSending; nim_talk_send_msg func = (nim_talk_send_msg) GetProcAddress(hInst, "nim_talk_send_msg"); func(json.toStyledString().c_str(), "", NULL, ""); }
文件消息
构造API介绍
C++
/** @fn static std::string CreateFileMessage(const std::string& receiver_id, const NIMSessionType session_type, const std::string& client_msg_id, const IMFile& file, const std::string& file_path, const MessageSetting& msg_setting, int64_t timetag = 0) * 生成文件消息内容,生成的字符串在调用SendMsg时直接传入 * @param[in] receiver_id 聊天对象的 ID,如果是单聊,为用户帐号,如果是群聊,为群组 ID * @param[in] session_type NIMSessionType,聊天类型,单聊或群组 * @param[in] client_msg_id 客户端消息id,建议uuid * @param[in] file IMFile,文件信息 * @param[in] file_path 文件本地绝对路径 * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return std::string 文件消息Json字符串 */ static std::string CreateFileMessage (const std::string &receiver_id, const NIMSessionType session_type, const std::string &client_msg_id, const IMFile &file, const std::string &file_path, const MessageSetting &msg_setting, int64_t timetag=0)
Define: NIMSessionType ; MessageSetting; IMFile
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
无,操作对象。
C
无,根据定义组装Json数据。
语音消息
构造API介绍
C++
/** @fn static std::string CreateAudioMessage(const std::string& receiver_id, const NIMSessionType session_type, const std::string& client_msg_id, const IMAudio& audio, const std::string& file_path, const MessageSetting& msg_setting, int64_t timetag = 0) * 生成语音消息内容,生成的字符串在调用SendMsg时直接传入 * @param[in] receiver_id 聊天对象的 ID,如果是单聊,为用户帐号,如果是群聊,为群组 ID * @param[in] session_type NIMSessionType,聊天类型,单聊或群组 * @param[in] client_msg_id 客户端消息id,建议uuid * @param[in] audio IMAudio,语音文件信息 * @param[in] file_path 文件本地绝对路径 * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return std::string 语音消息Json字符串 */ static std::string CreateAudioMessage (const std::string &receiver_id, const NIMSessionType session_type, const std::string &client_msg_id, const IMAudio &audio, const std::string &file_path, const MessageSetting &msg_setting, int64_t timetag=0)
Define: NIMSessionType ; MessageSetting; IMAudio
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
无,操作对象。
C
无,根据定义组装Json数据。
短视频消息
构造API介绍
C++
/** @fn static std::string CreateVideoMessage(const std::string& receiver_id, const NIMSessionType session_type, const std::string& client_msg_id, const IMVideo& video, const std::string& file_path, const MessageSetting& msg_setting, int64_t timetag = 0) * 生成视频消息内容,生成的字符串在调用SendMsg时直接传入 * @param[in] receiver_id 聊天对象的 ID,如果是单聊,为用户帐号,如果是群聊,为群组 ID * @param[in] session_type NIMSessionType,聊天类型,单聊或群组 * @param[in] client_msg_id 客户端消息id,建议uuid * @param[in] video IMVideo,视频文件信息 * @param[in] file_path 文件本地绝对路径 * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return std::string 视频消息Json字符串 */ static std::string CreateVideoMessage (const std::string &receiver_id, const NIMSessionType session_type, const std::string &client_msg_id, const IMVideo &video, const std::string &file_path, const MessageSetting &msg_setting, int64_t timetag=0)
Define: NIMSessionType ; MessageSetting; IMVideo
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
无,操作对象。
C
无,根据定义组装Json数据。
位置消息
构造API介绍
C++
/** @fn static std::string CreateLocationMessage(const std::string& receiver_id, const NIMSessionType session_type, const std::string& client_msg_id, const IMLocation& location, const MessageSetting& msg_setting, int64_t timetag = 0) * 生成位置消息内容,生成的字符串在调用SendMsg时直接传入 * @param[in] receiver_id 聊天对象的 ID,如果是单聊,为用户帐号,如果是群聊,为群组 ID * @param[in] session_type NIMSessionType,聊天类型,单聊或群组 * @param[in] client_msg_id 客户端消息id,建议uuid * @param[in] location IMLocation,位置信息 * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return std::string 位置消息Json字符串 */ static std::string CreateLocationMessage (const std::string &receiver_id, const NIMSessionType session_type, const std::string &client_msg_id, const IMLocation &location, const MessageSetting &msg_setting, int64_t timetag=0)
Define: NIMSessionType ; MessageSetting; IMLocation
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
无,操作对象。
C
无,根据定义组装Json数据。
提醒消息
构造API介绍
C++
/** @fn static std::string CreateTipMessage(const std::string& receiver_id, const NIMSessionType session_type, const std::string& client_msg_id, const std::string& tip_content, const MessageSetting& msg_setting, int64_t timetag = 0) * 生成Tip消息内容,生成的字符串在调用SendMsg时直接传入 * @param[in] receiver_id 聊天对象的 ID,如果是单聊,为用户帐号,如果是群聊,为群组 ID * @param[in] session_type NIMSessionType,聊天类型,单聊或群组 * @param[in] client_msg_id 客户端消息id,建议uuid * @param[in] tip_content Tip文本内容 * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return std::string 位置消息Json字符串 */ static std::string CreateTipMessage (const std::string &receiver_id, const NIMSessionType session_type, const std::string &client_msg_id, const std::string &tip_content, const MessageSetting &msg_setting, int64_t timetag=0)
Define: NIMSessionType ; MessageSetting
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
无,操作对象。
C
无,根据定义组装Json数据。
机器人消息
构造API介绍
C++
/** @fn static std::string CreateBotRobotMessage(const std::string& receiver_id, const NIMSessionType session_type, const std::string& client_msg_id, const std::string& content, const IMBotRobot& bot_msg, const MessageSetting& msg_setting, int64_t timetag = 0) * 生成Tip消息内容,生成的字符串在调用SendMsg时直接传入 * @param[in] receiver_id 聊天对象的 ID,如果是单聊,为用户帐号,如果是群聊,为群组 ID * @param[in] session_type NIMSessionType,聊天类型,单聊或群组 * @param[in] client_msg_id 客户端消息id,建议uuid * @param[in] content 内容 * @param[in] bot_msg 机器人消息信息 * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return std::string 位置消息Json字符串 */ static std::string CreateBotRobotMessage (const std::string &receiver_id, const NIMSessionType session_type, const std::string &client_msg_id, const std::string &content, const IMBotRobot &bot_msg, const MessageSetting &msg_setting, int64_t timetag=0)
Define: NIMSessionType ; MessageSetting; IMBotRobot
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
无,操作对象。
C
无,根据定义组装Json数据。
自定义消息
除了内建消息类型外,SDK 也支持收发自定义消息类型。和透传消息一样,SDK 也不会解析自定义消息的具体内容,解释工作由开发者完成。
消息属性设置
发送消息还提供了以下消息属性设置:
消息支持扩展字段,扩展字段分为服务器扩展字段kNIMMsgKeyServerExt和本地扩展字段kNIMMsgKeyLocalExt,最大长度1024字节。对于服务器扩展字段,该字段会发送到其他端,而本地扩展字段仅在本地有效。对于这两种扩展字段, SDK 都会存储在数据库中。示例如下:
json[kNIMMsgKeyServerExt] = ""; // json string json[kNIMMsgKeyLocalExt] = ""; // json string
推送文案字段(kNIMMsgKeyPushContent,最大长度200字节)和自定义推送属性(kNIMMsgKeyPushPayload,最大长度2048字节),请注意最大长度的限制。设置了推送文案后,接收方收到消息时,在通知栏提醒中会显示该文案,如果不设置则采用 SDK 默认的文案。
json[kNIMMsgKeyPushContent] = ""; json[kNIMMsgKeyPushPayload] = ""; // json string
是否需要推送字段(kNIMMsgKeyPushEnable),0:不需要,1:需要。
- 推送是否要做消息计数字段(kNIMMsgKeyNeedBadge),0:不需要,1:需要。
- 推送是否需要推送昵称(kNIMMsgKeyNeedPushNick),0:不需要,1:需要。
- 消息是否存储云端(kNIMMsgKeyHistorySave),如果设置为0,则通过拉取服务器消息历史的接口无法获取该条消息。0:不需要,1:需要。
- 消息是否支持漫游(kNIMMsgKeyMsgRoaming),如果需要,即使某一个客户端收取过这条消息,其他客户端再次登录也会漫游到这条消息。0:不需要,1:需要。
- 消息是否支持多端同步(kNIMMsgKeyMsgSync),如果需要,则会在发送一条消息后,将这条消息同步到同时登录的其他客户端。0:不需要,1:需要。
- 消息是否抄送第三方(kNIMMsgKeyMsgRoutable),0:不支持,1:支持,默认按照app的抄送开关
- 消息是否支持离线(kNIMMsgKeySetMsgOffline),0:不需要, 1:需要,默认1
- 消息重发标记(kNIMMsgKeyResendFlag),第一次发送0,重发1,用于消息去重
针对群组消息,提供强推属性设置(可以用于实现@功能等)和群消息已读回执属性:
- 是否强推字段(kNIMMsgKeyIsForcePush),0:不需要,1:需要。
- 强推列表字段(kNIMMsgKeyForcePushList),推送指定账号id string array json, 如果强推全员不填。
- 强推文本字段(kNIMMsgKeyForcePushContent),群组消息强推文本。
- 单条群消息是否需要已读业务(kNIMMsgKeyTeamMsgAck),0:不需要,1:需要
配合群消息已读回执业务,当接收到群消息后,可以根据以下字段来实现已读回执业务:
- 是否已经发送群消息已读回执(kNIMMsgKeyLocalKeyTeamMsgAckSent), bool, 如果true,不需要再次发送已读回执
- 群消息未读数(kNIMMsgKeyLocalKeyTeamMsgUnreadCount), int, 单条群消息还有几人未读
反垃圾字段:
- 开发者指定的该条消息反垃圾规则的ID(kMsgTagAntiSpamBusinessId) 规则ID,保持与服务端一致
- 是否需要过易盾反垃圾(kNIMMsgKeyAntiSpamEnable),0:不需要,1:需要。
- 需要过易盾反垃圾的自定义内容(kNIMMsgKeyAntiSpamContent),长度限制5000字符,格式为json string,{"type" : 1:文本,2:图片,3视频, "data" : "文本内容or图片地址or视频地址"}
- 单条消息是否使用易盾反垃圾(kNIMMsgKeyAntiSpamUsingYiDun), 0:(在开通易盾的情况下)不过易盾反垃圾而是通用反垃圾 其他都是按照原来的规则.
- 消息是否命中客户端反垃圾(kNIMMsgKeyClientAntiSpam),命中:1 未命中:0 或者不填写
多端推送开关
C++
void OnMultiportPushConfigChange(int rescode, bool switch_on)
{
if (rescode == nim::kNIMResSuccess)
{
···
}
}
void OnInit()
{
//登录前注册的全局回调获取当前多端推送开关状态
nim::Client::RegSyncMultiportPushConfigCb(&OnMultiportPushConfigChange);
}
void SetMultiportConfig(bool switch_on)
{
//当PC/Web端在线时,可以配置消息是否推送给移动端
nim::Client::SetMultiportPushConfigAsync(switch_on, &OnMultiportPushConfigChange);
}
void GetMultiportConfig()
{
//主动获取当前多端推送开关状态
nim::Client::GetMultiportPushConfigAsync(&OnMultiportPushConfigChange);
}
C#
public delegate void ConfigMultiportPushDelegate(ResponseCode response,ConfigMultiportPushParam param)
{
if (response == ResponseCode.kNIMResSuccess)
{
···
}
}
/// <summary>
/// 开启多端推送
/// </summary>
/// <param name="cb">操作结果委托</param>
public static void EnableMultiportPush(ConfigMultiportPushDelegate cb)
{
ConfigMultiportPushParam param = new ConfigMultiportPushParam();
param.Enabled = true;
var ptr = DelegateConverter.ConvertToIntPtr(cb);
ClientNativeMethods.nim_client_set_multiport_push_config(param.Serialize(), null, ConfigMultiportPushCb, ptr);
}
/// <summary>
/// 禁止多端推送
/// </summary>
/// <param name="cb">操作结果委托</param>
public static void DisableMultiportPush(ConfigMultiportPushDelegate cb)
{
ConfigMultiportPushParam param = new ConfigMultiportPushParam();
param.Enabled = false;
var ptr = DelegateConverter.ConvertToIntPtr(cb);
ClientNativeMethods.nim_client_set_multiport_push_config(param.Serialize(), null, ConfigMultiportPushCb, ptr);
}
/// <summary>
/// 获取多端推送控制开关
/// </summary>
/// <param name="cb"></param>
public static void IsMultiportPushEnabled(ConfigMultiportPushDelegate cb)
{
var ptr = DelegateConverter.ConvertToIntPtr(cb);
ClientNativeMethods.nim_client_get_multiport_push_config(null, ConfigMultiportPushCb, ptr);
}
/// <summary>
/// 注册多端推送设置同步回调
/// </summary>
/// <param name="cb"></param>
public static void RegMulitiportPushEnableChangedCb(ConfigMultiportPushDelegate cb)
{
var ptr = DelegateConverter.ConvertToIntPtr(cb);
ClientNativeMethods.nim_client_reg_sync_multiport_push_config_cb(null, OnMultiportPushEnableChanged, ptr);
}
C
static void CallbackMultiportPushConfig(int rescode, const char *content, const char *json_extension, const void *user_data)
{
Json::Value values;
Json::Reader reader;
if (rescode == nim::kNIMResSuccess && reader.parse(content, values) && values.isObject())
{
bool open = values[kNIMMultiportPushConfigContentKeyOpen].asInt() == 1;
···
}
}
typedef void(*nim_client_reg_sync_multiport_push_config_cb)(const char *json_extension, nim_client_multiport_push_config_cb_func cb, const void *user_data);
typedef void(*nim_client_set_multiport_push_config)(const char *switch_content, const char *json_extension, nim_client_multiport_push_config_cb_func cb, const void *user_data);
typedef void(*nim_client_get_multiport_push_config)(const char *json_extension, nim_client_multiport_push_config_cb_func cb, const void *user_data);
void OnInit()
{
//登录前注册的全局回调获取当前多端推送开关状态
nim_client_reg_sync_multiport_push_config_cb func = (nim_client_reg_sync_multiport_push_config_cb) GetProcAddress(hInst, "nim_client_reg_sync_multiport_push_config_cb");
func("", &CallbackMultiportPushConfig, nullptr);
}
void SetMultiportConfig(bool switch_on)
{
//当PC/Web端在线时,可以配置消息是否推送给移动端
nim_client_set_multiport_push_config func = (nim_client_set_multiport_push_config) GetProcAddress(hInst, "nim_client_set_multiport_push_config");
func(switch_on, "", &CallbackMultiportPushConfig, nullptr);
}
void GetMultiportConfig()
{
//主动获取当前多端推送开关状态
nim_client_get_multiport_push_config func = (nim_client_get_multiport_push_config) GetProcAddress(hInst, "nim_client_get_multiport_push_config");
func("", &CallbackMultiportPushConfig, nullptr);
}
消息接收
开发者在登陆SDK之前需要提前注册消息接收的全局广播通知。
API介绍
C++
在线消息广播通知:
static void RegReceiveCb (const ReceiveMsgCallback &cb, const std::string &json_extension="")
离线、同步消息广播通知:
static void RegReceiveMessagesCb (const ReceiveMsgsCallback &cb, const std::string &json_extension="")
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
在线消息广播通知:
static EventHandler< NIMReceiveMessageEventArgs> OnReceiveMessageHandler [get, set]
离线、同步消息广播通知:
static void RegReceiveBatchMessagesCb (ReceiveBatchMesaagesDelegate cb)
Namespace:NIM
Class:TalkAPI
C
在线消息广播通知:
NIM_SDK_DLL_API void nim_talk_reg_receive_cb (const char *json_extension, nim_talk_receive_cb_func cb, const void *user_data)
离线、同步消息广播通知:
NIM_SDK_DLL_API void nim_talk_reg_receiv_msgs_cb (const char *json_extension, nim_talk_receive_cb_func cb, const void *user_data)
File:nim_talk.h
示例
C++
void OnReceiveMsgCallback(const nim::IMMessage& message) { std::string id = GetSessionId(message); if (message.feature_ == nim::kNIMMessageFeatureDefault) { ··· } else if (message.feature_ == nim::kNIMMessageFeatureSyncMsg || message.feature_ == nim::kNIMMessageFeatureRoamMsg) { ··· } else if (message.feature_ == nim::kNIMMessageFeatureCustomizedMsg) { ··· } } void foo() { nim::Talk::RegReceiveCb(&OnReceiveMsgCallback); }
C#
void OnReceiveMessage(object sender, NIM.NIMReceiveMessageEventArgs args) { if (args.Message.MessageContent.SessionType == NIM.Session.NIMSessionType.kNIMSessionTypeP2P && args.Message.MessageContent.SenderID != _peerId) return; if (args.Message.MessageContent.SessionType == NIM.Session.NIMSessionType.kNIMSessionTypeTeam && args.Message.MessageContent.ReceiverID != _peerId) return; //处理自定义消息 if (args.Message != null && args.Message.MessageContent.MessageType == NIMMessageType.kNIMMessageTypeCustom) { ··· } if (args.Message != null && args.Message.MessageContent.MessageType == NIM.NIMMessageType.kNIMMessageTypeText) { ··· } } private void foo() { NIM.TalkAPI.OnReceiveMessageHandler += OnReceiveMessage; }
C
void CallbackReceiveMsg(const char* msg, const char *json_exten, const void *user_data) { Json::Value value; Json::Reader reader; if (reader.parse(msg, value)) { int rescode = value[nim::kNIMMsgKeyLocalRescode].asInt(); int feature = value[nim::kNIMMsgKeyLocalMsgFeature].asInt(); switch (feature) { case kNIMMessageFeatureDefault: ... case kNIMMessageFeatureSyncMsg: ... ... } } } typedef void(*nim_talk_reg_receive_cb)(const char *json_extension, nim_talk_receive_cb_func cb, const void* user_data); void foo() { nim_talk_reg_receive_cb func = (nim_talk_reg_receive_cb) GetProcAddress(hInst, "nim_talk_reg_receive_cb"); func(nullptr, &CallbackReceiveMsg, nullptr); }
转发消息
用户通过构造API获取新的消息对象,然后调用发送消息接口。
构造API介绍
C++
/** @fn static std::string CreateRetweetMessage(const std::string& src_msg_json , const std::string& client_msg_id , const NIMSessionType retweet_to_session_type , const std::string& retweet_to_session_id , const MessageSetting& msg_setting , int64_t timetag = 0) * 由其他消息生成转发消息 * @param[in] src_msg_json 原消息json * @param[in] client_msg_id 新的客户端消息id,建议uuid * @param[in] retweet_to_session_type 转发目标会话类型 NIMSessionType * @param[in] retweet_to_session_id 转发目标ID * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return std::string 位置消息Json字符串 */ static std::string CreateRetweetMessage (const std::string &src_msg_json, const std::string &client_msg_id, const NIMSessionType retweet_to_session_type, const std::string &retweet_to_session_id, const MessageSetting &msg_setting, int64_t timetag=0)
Define: NIMSessionType ; MessageSetting
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
/** @fn * 由其他消息生成转发消息 * @param[in] srcMsg 原始消息对象 * @param[in] msgSetting 新的消息属性 * @param[in] msgId 新的客户端消息id,建议uuid * @param[in] sessionId 转发目标 * @param[in] sessionType 转发目标会话类型 * @param[in] timetag 消息时间 * @return 新的消息对象 */ static NIMIMMessage CreateRetweetMessage (NIMIMMessage srcMsg, NIMMessageSetting msgSetting, string msgId, string sessionId, Session.NIMSessionType sessionType, long timetag)
Define: NIMIMMessage ; NIMMessageSetting ; NIMSessionType
Namespace:NIM
Class:TalkAPI
C
/** @fn char *nim_talk_create_retweet_msg(const char* src_msg_json, const char* client_msg_id, enum NIMSessionType retweet_to_session_type, const char* retweet_to_session_id, const char* msg_setting, int64_t timetag) * 由其他消息生成转发消息 * @param[in] src_msg_json 原消息json * @param[in] client_msg_id 新的客户端消息id,建议uuid * @param[in] retweet_to_session_type 转发目标会话类型 NIMSessionType * @param[in] retweet_to_session_id 转发目标ID * @param[in] msg_setting 消息属性设置 * @param[in] timetag 消息时间 * @return char * 位置消息Json字符串,需要上层调用nim_global.h提供的内存释放接口释放。 */ NIM_SDK_DLL_API char *nim_talk_create_retweet_msg(const char* src_msg_json, const char* client_msg_id, enum NIMSessionType retweet_to_session_type, const char* retweet_to_session_id, const char* msg_setting, int64_t timetag);
Define: NIMSessionType
File:nim_talk.h
示例
C++
void foo(nim::IMMessage msg) { std::string send_msg = nim::Talk::CreateRetweetMessage(msg.ToJsonString(false), QString::GetGUID(), nim::kNIMSessionTypeP2P, session_id, msg.msg_setting_, 1000 * nbase::Time::Now().ToTimeT()); nim::Talk::SendMsg(send_msg); }
C#
void foo(NIMImageMessage msg) { NIM.NIMMessageSetting setting = new NIMMessageSetting(); NIMImageMessage send_msg = TalkAPI.CreateRetweetMessage(msg, setting, NimUtility.Utilities.GenerateGuid(), session_id, NIM.Session.NIMSessionType.kNIMSessionTypeP2P, 0); TalkAPI.SendMessage(send_msg); }
C
typedef char*(*nim_talk_create_retweet_msg)(const char* src_msg_json, const char* client_msg_id, const NIMSessionType retweet_to_session_type, const char* retweet_to_session_id, const char* msg_setting, __int64 timetag); typedef void (*nim_global_free_buf)(void *data); void foo(const char *src_msg_json, const char *msg_id, NIMSessionType session_type, const char *session_id, const char* msg_sessiong_json, __int64 timetag) { nim_talk_create_retweet_msg func = (nim_talk_create_retweet_msg) GetProcAddress(hInst, "nim_talk_create_retweet_msg"); nim_global_free_buf free_func = (nim_global_free_buf) GetProcAddress(hInst, "nim_global_free_buf"); const char *msg = func(src_msg_json, msg_id, session_type, session_id, msg_sessiong_json, timetag); free_func((void *)msg); }
消息撤回
用户通过发送消息发的消息或者群主、管理员可以通过该接口执行撤回操作(不支持聊天室消息),撤回操作一般有时限限制(该限制为全局的APP设置),超过限制返回508。 开发者通过注册撤回消息通知回调,接收其他端的撤回消息的通知,收到通知后SDK会标记主动在消息历史中标记该条消息为删除状态,同时开发者根据自身需求,删除界面上显示的消息,甚至插入一条提示,IM Demo有开发示例。
API介绍
C++
主动撤回消息接口:
static void RecallMsg (const IMMessage &msg, const std::string ¬ify, const RecallMsgsCallback &cb, const std::string &json_extension="")
注册撤回消息通知:
static void RegRecallMsgsCallback (const RecallMsgsCallback &cb, const std::string &json_extension="")
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
主动撤回消息接口:
static void RecallMessage (string msgId, string notify, RecallMessageDelegate cb)
注册撤回消息通知:
static void RegRecallMessageCallback (RecallMessageDelegate cb)
Namespace:NIM
Class:TalkAPI
C
主动撤回消息接口:
NIM_SDK_DLL_API void nim_talk_recall_msg (const char *json_msg, const char *notify, const char *json_extension, nim_talk_recall_msg_func cb, const void *user_data)
注册撤回消息通知:
NIM_SDK_DLL_API void nim_talk_reg_recall_msg_cb (const char *json_extension, nim_talk_recall_msg_func cb, const void *user_data)
File:nim_talk.h
参数说明
- 主动撤回消息接口
参数 | 类型 | 说明 |
---|---|---|
msg(C++) | struct | 撤回消息的对象,见IMMessage |
msgId(C#) | string | 撤回消息的客户端消息ID |
json_msg(C) | string | 撤回消息的Json string |
notify | string | 自定义通知 |
cb | function | 回调函数 |
json_extension | string | json扩展参数(备用,目前不需要) |
user_data | void* | APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
C++
void OnReceiveRecallMsgCallback(nim::NIMResCode code, const std::list<nim::RecallMsgNotify>& message) { for (auto notify : message) { if (code == nim::kNIMResSuccess) { ··· } } } void OnInit() { nim::Talk::RegRecallMsgsCallback(&OnReceiveRecallMsgCallback); } void foo(const nim::IMMessage& msg) { nim::Talk::RecallMsg(msg, "test notify when recall", &OnReceiveRecallMsgCallback); }
C#
private void OnRecallMessage(ResponseCode result, RecallNotification[] notify) { ··· } void OnInit() { NIM.TalkAPI.RegRecallMessageCallback(OnRecallMessage); } private void OnRecallMessageCompleted(ResponseCode result, RecallNotification[] notify) { ··· } void foo(string msg_id) { NIM.TalkAPI.RecallMessage(msg_id, "撤回消息", OnRecallMessageCompleted); }
C
void nim_talk_recall_msg(const char *json_msg, const char *notify, const char *json_extension, nim_talk_recall_msg_func cb, const void *user_data); void nim_talk_reg_recall_msg_cb(const char *json_extension, nim_talk_recall_msg_func cb, const void *user_data); void OnInit() { nim_talk_reg_recall_msg_cb func = (nim_talk_reg_recall_msg_cb) GetProcAddress(hInst, "nim_talk_reg_recall_msg_cb"); func("", &OnReceiveRecallMsgCallback, nullptr); } void foo(const nim::IMMessage& msg) { nim_talk_recall_msg func = (nim_talk_recall_msg) GetProcAddress(hInst, "nim_talk_recall_msg"); func(msg, "test notify when recall", "", &OnReceiveRecallMsgCallback, nullptr); }
已读回执
在会话界面中调用发送已读回执的接口并传入最后一条消息,即表示这之前的消息都已读,对端将收到此回执。在5.0.0版本开始,SDK支持群消息已读业务。
API介绍
C++
P2P消息已读回执
发送已读回执:
static void SendReceiptAsync (const std::string &json_msg, const MessageStatusChangedCallback &cb)
注册消息已读通知:
static void RegMessageStatusChangedCb (const MessageStatusChangedCallback &cb, const std::string &json_extension="")
查询消息是否已读:
static bool QuerySentMessageBeReaded (const IMMessage &msg)
File:nim_cpp_msglog.h
Namespace:NIM
Class:MsgLog
群消息已读回执
发送已读回执:
static void TeamMsgAckRead(const std::string& tid, const std::list
& msgs, const TeamEventCallback& cb, const std::string& json_extension = ""); 群消息已读回执通知:
static void RegTeamEventCb(const TeamEventCallback& cb, const std::string& json_extension = "");
通知ID:
kNIMNotificationIdLocalGetTeamMsgUnreadCount = 2010, /*< 获取群消息未读数 {[{"client_msg_id":"", "count":int, "read_accid":"当前已读成员的accid"},...]}/
kNIMNotificationIdLocalGetTeamMsgUnreadList = 2011, /*< 获取群消息未读列表 {"client_msg_id":"", "read":["id1",...], "unread":["id2",...]}/
获取群消息已读信息(未读已读Accid列表):
static void TeamMsgQueryUnreadList(const std::string& tid, const IMMessage& msg, const TeamEventCallback& cb, const std::string& json_extension = "");
File:nim_cpp_team.h
Namespace:NIM
Class:Team
C#
发送已读回执:
static void SendReceipt (NIMIMMessage msg, MsglogStatusChangedDelegate cb, string jsonExtension=null)
注册消息已读通知:
static void RegMsglogStatusChangedCb (MsglogStatusChangedDelegate cb)
查询消息是否已读:
static bool IsMessageBeReaded (NIMIMMessage msg, string jsonExtension=null)
Namespace:NIM
Class:MessagelogAPI
C
P2P消息已读回执
发送已读回执:
NIM_SDK_DLL_API void nim_msglog_send_receipt_async (const char *json_msg, const char *json_extension, nim_msglog_status_changed_cb_func cb, const void *user_data)
注册消息已读通知:
NIM_SDK_DLL_API void nim_msglog_reg_status_changed_cb (const char *json_extension, nim_msglog_status_changed_cb_func cb, const void *user_data)
查询消息是否已读:
NIM_SDK_DLL_API bool nim_msglog_query_be_readed (const char *json_msg, const char *json_extension)
File:nim_msglog.h
群消息已读回执
发送已读回执:
NIM_SDK_DLL_API void nim_team_msg_ack_read(const char *tid, const char *json_msgs, const char *json_extension, nim_team_opt_cb_func cb, const void *user_data);
群消息已读回执通知:
NIM_SDK_DLL_API void nim_team_reg_team_event_cb(const char *json_extension, nim_team_event_cb_func cb, const void *user_data);
通知ID:
kNIMNotificationIdLocalGetTeamMsgUnreadCount = 2010, /*< 获取群消息未读数 {[{"client_msg_id":"", "count":int, "read_accid":"当前已读成员的accid"},...]}/
kNIMNotificationIdLocalGetTeamMsgUnreadList = 2011, /*< 获取群消息未读列表 {"client_msg_id":"", "read":["id1",...], "unread":["id2",...]}/
获取群消息已读信息(未读已读Accid列表):
NIM_SDK_DLL_API void nim_team_msg_query_unread_list(const char *tid, const char *json_msg, const char *json_extension, nim_team_opt_cb_func cb, const void *user_data);
File:nim_team.h
参数说明
- P2P消息已读回执
参数 | 类型 | 说明 |
---|---|---|
msg(C#) | struct | 已读消息的对象,见NIMIMMessage |
json_msg(C/C++) | string | 标记已读消息的Json string |
cb | function | 回调函数 |
json_extension | string | json扩展参数(备用,目前不需要) |
user_data | void* | APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
- 群消息已读回执
参数 | 类型 | 说明 | |
---|---|---|---|
tid | string | 群id | |
msgs(C++) | std::list | 标记已读消息的对象,见NIMIMMessage | |
msgs(C) | json array string | 标记已读消息的Json string | |
cb | function | 回调函数 | |
json_extension | string | json扩展参数(备用,目前不需要) | |
user_data | void* | APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
C++
P2P消息已读回执
//发送已读回执 void foo(nim::IMMessage msg) { nim::MsgLog::SendReceiptAsync(msg.ToJsonString(false), [](const nim::MessageStatusChangedResult& res) { auto iter = res.results_.begin(); }); } //查询消息是否已读 bool IsMsgReaded(nim::IMMessage &msg) { if (nim::MsgLog::QueryMessageBeReaded(msg)) { return true; } return false; } //通过提前注册的消息状态变更广播通知获取消息被已读的状态 void OnMsgStatusChangedCallback(const nim::MessageStatusChangedResult& res) { for (auto res : res.results_) { if (res.status_ == kNIMMsgLogStatusReceipt) { ... } } } void OnInit() { nim::MsgLog::RegMessageStatusChangedCb(&OnMsgStatusChangedCallback); }
群消息已读回执
//批量标记群消息已读 void SessionBox::InvokeSetRead(const std::list<nim::IMMessage> &msgs) { nim::Team::TeamMsgAckRead(session_id_, msgs, nim::Team::TeamEventCallback()); } //通过提前注册的群时间广播获取群消息已读的状态 void TeamCallback::OnTeamEventCallback(const nim::TeamEvent& result) { if (result.notification_id_ == nim::kNIMNotificationIdLocalGetTeamMsgUnreadCount) { ... } } void Init() { //注册群事件的回调 nim::Team::RegTeamEventCb(nbase::Bind(&nim_comp::TeamCallback::OnTeamEventCallback, std::placeholders::_1)); } //获取群消息已读未读列表 void UnreadForm::DoLoadList() { nim::Team::TeamMsgQueryUnreadList(msg_.receiver_accid_, msg_, nbase::Bind(&UnreadForm::OnTeamEventCallback, std::placeholders::_1)); } void UnreadForm::OnTeamEventCallback(const nim::TeamEvent& result) { UnreadForm * win = (UnreadForm *)nim_comp::WindowsManager::GetInstance()->GetWindow(UnreadForm::kClassName, UnreadForm::kClassName); if (win) win->OnLoadListCallback(result); }
C#
//发送已读回执 //查询消息是否已读 bool IsMsgReaded(NIM.NIMTextMessage msg) { return NIM.Messagelog.MessagelogAPI.IsMessageBeReaded(msg); } //通过提前注册的消息状态变更广播通知获取消息被已读的状态 void OnInit() { NIM.Messagelog.MessagelogAPI.RegMsglogStatusChangedCb((res, result) => { ··· }); }
C
//发送已读回执 typedef bool(*nim_msglog_query_be_readed)(const char *json_msg, const char *json_extension); bool foo(const char *json_msg) { nim_msglog_query_be_readed func = (nim_msglog_query_be_readed) GetProcAddress(hInst, "nim_msglog_query_be_readed"); return func(json_msg, ""); } //通过提前注册的消息状态变更广播通知获取消息被已读的状态 void CallbackMsgStatusChanged(int rescode, const char *result, const char *json_extent, const void *callback) { // 解析result } typedef void(*nim_msglog_reg_status_changed_cb)(const char *json_extension, nim_msglog_status_changed_cb_func cb, const void *user_data); void foo(const char *json_msg) { nim_msglog_reg_status_changed_cb func = (nim_msglog_reg_status_changed_cb) GetProcAddress(hInst, "nim_msglog_reg_status_changed_cb"); func( "", &CallbackMsgStatusChanged, nullptr); }
多媒体消息
语音转文字
SDK 提供语音转文字接口。
void nim_tool_get_audio_text_async(const char *json_audio_info, const char *json_extension, nim_tool_get_audio_text_cb_func cb, const void *user_data);
例:
C++
void foo(nim::IMMessage &msg_data)
{
nim::IMAudio audio;
nim::Talk::ParseAudioMessageAttach(msg_data, audio);
nim::AudioInfo audio_info;
audio_info.samplerate_ = "16000";
audio_info.url_ = audio.url_;
audio_info.duration_ = audio.duration_;
audio_info.mime_type_ = audio.file_extension_;
nim::Tool::GetAudioTextAsync(audio_info, ToWeakCallback([this](int rescode, const std::string& text) {
if (rescode == nim::kNIMResSuccess) {
···
}
else {
···
}
}));
}
C#
private void foo(NIM.NIMIMMessage msg)
{
NIM.NIMAudioInfo info = new NIMAudioInfo();
info.Duration = 1000;
info.SampleRate = "16000";
info.URL = "···";
info.MimeType = "aac";
NIM.ToolsAPI.GetAudioTextAsync(info, "", OnGetText);
}
private void OnGetText(int rescode, string text, string json_extension, IntPtr user_data)
{
}
C
void CallbackGetAudioText(int rescode, const char *text, const char *json_extension, const void *user_data)
{
...
}
typedef void(*nim_tool_get_audio_text_async)(const char *json_audio_info, const char *json_extension, nim_tool_get_audio_text_cb_func cb, const void *user_data);
void foo()
{
Json::Value json_value;
json_value[nim::kNIMTransAudioKeyMime] = ; //mime类型
json_value[nim::kNIMTransAudioKeySample] = ; //采样率
json_value[nim::kNIMTransAudioKeyAudioUrl] = ; //下载地址
json_value[nim::kNIMTransAudioKeyDuration] = ; //时长(毫秒)
nim_tool_get_audio_text_async func = (nim_tool_get_audio_text_async) GetProcAddress(hInst, "nim_tool_get_audio_text_async");
func(json_value.toStyledString().c_str(), nullptr, &CallbackGetAudioText, nullptr);
}
获取图片缩略图
网易云信PC SDK目前默认收到图片消息后会提前下载原图缓存到本地,如果开发者想控制下载图片的质量,可以通过初始化SDK时设置kNIMPreloadImageQuality来控制图片质量,设置kNIMPreloadImageResize来控制图片长宽, IM Demo开发范例中默认下载原图,所以开发者如果想基于IM Demo工程源码开发,需要在图片预览环节或者其他需要显示原图的地方自行下载原图。
以下但不限于以下场景下开发者可以自行下载缩略图:
- 对图片尺寸有特殊要求
- 聊天室接收图片消息
目前SDK提供两种获取缩略图方案:
基于修改图片质量
当用户收到图片消息时,附件kNIMMsgKeyAttach(聊天室消息为kNIMChatRoomMsgKeyAttach)内容解析出来会带有图片下载地址,通过拼接下载接口参数获取指定质量的图片: http(s)://?imageView&quality=N;http(s)://xxx为图片下载地址;N为图片质量,范围为0-100。
基于长宽对图片进行 内缩略 (原图等比例缩略,缩略后的图片“一边等于请求长度,另一边小于等于请求长度”)
当用户收到图片消息时,附件kNIMMsgKeyAttach(聊天室消息为kNIMChatRoomMsgKeyAttach)内容解析出来会带有图片下载地址,通过拼接下载接口参数获取缩略图: http(s)://xxx?imageView&thumbnail=XxY;http(s)://xxx为图片下载地址;X为宽度,Y为高度,中间为小写x,宽度和高度取值范围0-4096。
几种参数变化: 1、XxY:普通缩略(内缩略) 2、Xx0:限定宽度,高度自适应(内缩略) 3、0xY:限定高度,宽度自适应(内缩略)
目前IM Demo工程在消息显示图片的时候对图片进行了压缩处理,开发者可以参考bubble_image.cpp
获取视频封面
网易云信PC SDK目前默认收到视频消息后会提前下载视频封面(视频第1秒的截图)缓存到本地。如开发者有其它应用场景可以参考以下方法进行视频指定帧数下载:
请求链接格式如下:
http(s)://xxx?vframe&offset=1&resize=300x300&type=jpg;
参数说明
名称 | 描述 | 是否必须 |
---|---|---|
vframe | 视频截图的操作标记 | 是 |
offset | 从第几秒开始截,缺省为0 | 否 |
resize | widthxheight,宽和高 | 否 |
crop | crop=x_y_width_height 表示从原坐标(x, y)处截取width*height的子图片 | 否 |
type | 图片格式,默认为jpg | 否 |
开发者可以参考 IM Demo的bubble_video.cpp


此文档对你是否有帮助

