开发者中心

CLIm SDK Cocos2d-X简化版集成说明书

1.概述

1.1 范围

语音IM聊天在cocos2d-x引擎集成方法,及提供C++集成接口参考。

1.2 发布

1.3 综述

2.定义

2.1 术语

术语 定义
appId 应用编号(申请获取)

3.运行环境

PC版: win32/win64
Android: android4.0以上
IOS:ios7.0以上
cocos2d-x引擎版本: 2.x及3.x
cocos2d-x引擎语言: CPP

4.集成步骤(必读)

4.1 申请appId

提供APP或游戏名称、包名和公司名称等信息。在sdk对接交流群@相关对接人既可。
 
所有平台接入前提:
1要拷贝classes里面的CLImSDK到接入工程的classes文件夹下;
image.png
2要拷贝IM_SDK文件夹和classes同一个目录下。
如下图所示:

4.2 WIN32环境配置

第一步,将SDK目录下的所有的的*.lib及*.dll文件拷贝到你的project.win32下的Debug.win32和 Release.win32。
第二步:右键工程->属性->链接器->输入。在左上角切换配置为所有配置。并在附加依赖项里添加刚才拷贝过来的lib文件名。配置完后,确认即可。


 
第三步便捷的做法还可以,直接在您的代码里加入
#ifdef WIN32
#pragma comment(lib,“CLImpacket.lib”)    
#pragma comment(lib,“LoginSDK.lib”)
#endif

4.3 Android环境配置

第一步:下面的要求修改proj.android目录下的jni目录里的Android.mk文件
a、将下面代码添加到include $(CLEAR_VARS)的下一行
$(call import-add-path,$(LOCAL_PATH)/…/…/…)
b、将下面代码添加到LOCAL_MODULE := cocos2dcpp_shared的下一行
LOCAL_SHARED_LIBRARIES += libCLImSdk
LOCAL_SHARED_LIBRARIES += libVolley
c、在LOCAL_C_INCLUDES := $(LOCAL_PATH)/…/…/…/Classes \的下一行
      加入$(LOCAL_PATH)/…/…/…/Classes/CLImSDK <br />           $(LOCAL_PATH)/…/…/…/IM_SDK/include
如下图所示:
      image.png
d、在文件的最后一行加入
$(call import-module,IM_SDK)
如下所示:
image.png
第二步:在java代码里,在AppActivity (继承Cocos2dxActivity的那个类)里加入如下代码:
static
{
   System.loadLibrary(“CLImSdk”);
}
第四步:添加SDK依赖jar包
1、将SDK目录下的jar包拷贝至proj.android目录下的libs里(如果没有这个目录,请新建一个)。
image.png
第五步:修改AndroidManifest.xml文件
1、加入如下权限(注:文件中manifest标签之后以内,application以外,和application同一层)

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
<uses-permission android:name="android.permission.RECORD_AUDIO" /> 

注意上面申请录音权限的方式在Android6.0系统一下都可以成功,但在Android6.0系统以上,可能会弹出要使用录音权限的提示,但是并没有真正获得录音权限,所以Android6.0以上申请录音权限必须要在代码中动态申请,不然有的厂商机型获取不到录音权限,导致录音失败。
2、在 Application的oncreate()中在初始化前加
com.chuanglan.im.sdk.lib.ImLoginInit.initApplicationOnCreate(this.getApplication(), “300000”);    300000  填写你们自已的appid。在此设置的appid与代码 init里的appid要一致。
第六步:打release包可能会出现jar方法找不到。请在proguard-rules.pro文件中加入混淆代码,混淆码在压缩包混淆文件中。

4.4 iOS环境配置

注:iOS 6.0 以上,iPhone 4以上机型

4.4.1 包含文件

image.png

4.4.2 包含链接

image.png
注意iOS下还需要设置-force_load  libCLVoiceToolsManager.a 如图:
image.png
注意该地方不设置,运行时会奔溃

4.4.3 iOS 录音权限

注意后面必须写获取录音权限的描述,不写描述上架会被拒。
image.png

5.接口设计

5.1 接口调用及事件定义

5.1.1 获取SDK接口实例

C++用户参考如下代码:
//通过此接口实例化,您就可以凭借些实例调用SDK的方法
CLImTool*  pCLImTool = CLImTool::getInstance();
//例如,调用初使化SDK的api
pCLImTool->initSDK(300000, “writablePath”, false,false);

5.1.2 事件监听

API的所有异步接口执行结果的回调,都是通过ImListern中的各事件子类通知到调用层。如果某个类需要监听异步回调,只需要从ImListern中选择相应事件子类(本文档也提供了事件的详细说明)继承,重写需要监听的回调即可。下面以监听登录事件为例:
class  yourClass : public  ImListern::ImLoginListern
{
      void onLoginListern(CPLoginResponce* r ){
             if (r->result != 0){
                    //do your want to do
             }
      }
};
//创建该类的一个实例并添加该实例到API,以监听异步回调
yourClass *plistener = new yourClass();
pCLImTool->addLoginListern(plistener);
注意:如果被添加到API中的监听对象即将要被释放,一定要在释放前调用以下接口将其从API中及时移除,否则会造成API访问野指针而出现不可预知的错误(这里还可以在yourClass的onLoginListern里调用 ):
pCLImTool-> delLoginListener(plistener);

5.1.3 事件定时派发(用户必读)

由于采用了异步派发事件,事件的回调线程和UI线程不在同一个线程。所以需要UI线程定时从回调线程获取数据。本SDK已经为用户完成此步骤,但需要用户自己编写定时器定时调用 CLImTool::getInstance()->dispatchMsg(dt);
下面以cocos2d-x 3.x为例,
1、实现一个定时派发的CCNode
//============= SDK事件Dispatch类====================
1.  class DispatchMsgNode : public cocos2d::Node  
2.  {  
3.  public:  
4.      bool init()  
5.      {  
6.          isschedule = false;  
7.          return  Node::init();  
8.      }  
9.      CREATE_FUNC(DispatchMsgNode);  
10.    void startDispatch()  
11.    {  
12.        if (isschedule) return;  
13.        isschedule = true;  
14.        Director::getInstance()->getScheduler()->scheduleUpdate(this, 0, false);  
15.    }  
16.    void stopDispatch()  
17.    {  
18.        if (!isschedule) return;  
19.        isschedule = false;  
20.        Director::getInstance()->getScheduler()->unscheduleUpdate(this);  
21.    }  
22.    void update(float dt)  
23.    {  
24.        CLImTool::getInstance()->dispatchMsg(dt);  
25.    }  
26. private:  
27.    bool isschedule;  
28.  
29. };  
//==============================================
2、在AppDelegate类中申明一个 DispatchMsgNode* m_dispathMsgNode; 并分别修改AppDelegate的构造及析构函数
1.  AppDelegate::AppDelegate()  
2.  {  
3.      m_dispathMsgNode = NULL;  
4.  }  
5.    
6.  AppDelegate::~AppDelegate()  
7.  {  
8.      if (m_dispathMsgNode != NULL)  
9.      {  
10.        m_dispathMsgNode->stopDispatch();  
11.        m_dispathMsgNode->release();  
12.        m_dispathMsgNode = NULL;  
13.    }  
14. }  
3、在 AppDelegate::applicationDidFinishLaunching()中加入如下代码

m_dispathMsgNode = DispatchMsgNode::create();  
m_dispathMsgNode->retain();  
m_dispathMsgNode->startDispatch();  

5.1.4 Cocos2d-X 2.X版本用户需要注意事项

l   使用pthread做线程锁
屏蔽CImSyncQueue.h代码中加入#define IS_USE_PTHREAD
在VS工程include配置属性里添加(其它平台似乎默认已经加入了)
$(ProjectDir)…\cocos2dx\platform\third_party\win32\pthread

5.2 初使化SDK(测试环境弃用,直接初始化正式环境)

注:游戏初始化时调用此接口 保证后续能够安全使用语音功能;
void CLImTool::initSDK(unsigned long appId, std::string tempPath, bool isDebug, bool isOversea);

协议字段 类型 是否必填 说明
appId unsigned long 应用编号(申请获取)
tempPath std::string 一个可写的路径, SDK生成的中间文件保存的地方
isDebug bool 是否是测试环境,默认值为 false
isOversea bool 是否海外环境,默认值为 false

(测试环境弃用,海外环境使用前请提前告知或更换海外版本)
该接口尽量提前调用(如在游戏加载资源阶段)。

5.3 登录模块

5.3.1 CP帐号登录请求

void CLImTool::cpLogin(std::string nickname = “1” , std::string uid = “1” );

协议字段 类型 是否必填 说明
nickname std::string 用户名称(由CP自己提供)
uid std::string 用户ID,(由CP自己提供,请确保唯一性)

该接口为必须调用接口,但是可以不用关心该接口的返回,该接口返回失败也不会影响
功能的正常使用。Nickname字段可以用uid代替,这样可以避免sdk对一些特殊字符兼容问题

5.3.2 CP帐号登录请求事件

class ImListern::ImLoginListern
{
public: virtual void onLoginListern(CPLoginResponce*)= 0;
};
回调回来的参数:

协议字段 类型 是否必填 说明
result uint32 登录结果 不为0即为失败
msg std::string 错误描述
userid uint32 ID
nickName std::string 用户昵称
iconUrl std::string 用户头像地址
thirdUserId uint32 CP提供的用户id
thirdUserName std::string CP提供的用户名

注意:该回调返回无需关注

5.3.3 注销登录(无需关注)

void  CLImTool::cpLogout();
注意:该接口无需调用

5.4 附加工具模块

5.4.1 开始录音请求

void CLImTool**::**startRecord(std::string savePath, uint8 speech,std::string ext);

协议字段 类型 是否必填 说明
savePath std::string 带绝对路径的文件名(例:xx/test.amr,xx/test.mp3)
注:参数speech = 0-2路径必须是带amr后缀的音频文件路径而非目录路径
注:参数speech = 10-12路径必须是带mp3后缀的音频文件路径而非目录路径。
如果不想设置录音路径,该字段就传“”空字符串,sdk会自动生成,录音结束回调会回调录音文件路径。
speech uint8 0.普通录音; 1边录边上传然后识别;2.边录边上传  (0-2返回录音文件和录音URL为amr音频格式)。10.普通录音; 11边录边上传然后识别;12.边录边上传 (10 -12返回录音文件和录音URL为mp3音频格式)
ext std::string 希望传递给结束录音事件回调的值(有点像cocos2dx中的setUserData)

注意该接口:
speech=0为普通录音,当调用停止录音接口时,会收到停止录音回调,返回amr格式录音文件。
speech=1为边录边上传加识别,当调用停止录音接口时,会收到停止录音回调和上传录音返回回调以及语音识别的回调。(如果没有用到语音识别功能不建议传此参数,影响效率)。停止录音回调接口返回amr 录音文件,上传录音回调接口返回amr文件url,识别回调接口返回录音转文字结果。
speech=2为边录边上传,当调用停止录音接口时,会收到停止录音回调和上传录音返回回调。停止录音回调接口返回amr 录音文件,上传录音回调接口返回amr文件url。
 
speech=10为普通录音,当调用停止录音接口时,会收到停止录音回调,返回mp3格式录音文件。
speech=11为边录边上传加识别,当调用停止录音接口时,会收到停止录音回调和上传录音返回回调以及语音识别的回调。(如果没有用到语音识别功能不建议传此参数,影响效率)。停止录音回调接口返回mp3录音文件,上传录音回调接口返回mp3文件url,识别回调接口返回录音转文字结果。
speech=12为边录边上传,当调用停止录音接口时,会收到停止录音回调和上传录音返回回调。停止录音回调接口返回mp3录音文件,上传录音回调接口返回mp3文件url。
警示:如果是2019年3月之前的老用户,请不要使用【10,11,12】三个参数,因为该参数返回的是mp3格式,不能与之前的接入的老版本互通兼容。

5.4.2 停止录音请求

void CLImTool::stopRecord();

5.4.3 录音完毕事件

class ImListern::ImStopRecordListern
{
      public:
             virtual void onStopRecordListern(RecordStopNotify*) = 0;
};
回调回来的参数:

协议字段 类型 是否必填 说明
time uint32 录音时长(以毫秒计)
strfilepath std::string 录音保存文件路径名
ext std::string 录音请求时传递过来的

5.4.4 播放录音请求

void CLImTool::playRecord(std::string Url, std::string path, std::string ext=“”);

协议字段 类型 是否必填 说明
Url std::string Url/path至少一个不为空 网络url
path std::string Url/path至少一个不为空 带绝对路径的文件名(例:xx/test.amr)
ext std::string 希望传递给结束播放事件回调的值(有点像cocos2dx中的setUserData)

void CLImTool::playFromUrl(std::string url, std::string ext = “”);
注意:此接口有二个事件,分别是ImDownloadVoiceListern和ImFinishPlayListern。其中ImDownloadVoiceListern是用于做UI上语音文件下载展示用的,比如下载菊花。

协议字段 类型 是否必填 说明
url std::string 存放语音文件的(http)URL地址
ext std::string 希望传递给结束播放事件回调的值(有点像cocos2dx中的setUserData)

5.4.5 停止播放录音请求

void CLImTool::stopPlay();

5.4.6 播放录音完成事件

class ImListern::ImFinishPlayListern
{
             public:
                    virtual void onFinishPlayListern(StartPlayVoiceRespond*) = 0;
};
回调回来的参数:

协议字段 类型 是否必填 说明
result uint32 播放完成为0,失败为1
describe std::string 错误描述
ext std::string 调用播放请求时,传递进来的值

5.4.7 语音文件下载完毕事件

class ImDownloadVoiceListern
{
             public:
                    virtual void onDownloadVoiceListern(DownloadVoiceRespond*) = 0;
};
回调回来的参数:

协议字段 类型 是否必填 说明
percent uint8 下载完成为100
ext std::string 调用播放请求时,传递进来的值

5.4.8 设置语音识别语言类型请求(非必需)

void CLImTool::setSpeechType(GtImspeech_language inType, GtImspeech_outlanguage outType)

协议字段 类型 是否必填 说明
inType GtImspeech_language 识别语音类型(默认普通话)
outType GtImspeech_outlanguage 输出语音的文本类型

5.4.9 语音识别完成事件

class ImListern::ImFinishSpeechListern
{
public:
      virtual void onFinishSpeechListern(SpeechStopRespond*) = 0;
};
回调回来的参数:

协议字段 类型 是否必填 说明
err_id uint32 识别结果,不为0即为失败
err_msg std::string 错误描述
result std::string 识别后的文本(注意目前SDK提供给win32的是GBK编码,其它平台都是UTF8编码)
ext std::string 请求识别传入的ext
url std::string 如果识别时加了上传,则这个值就有了

5.4.10 上传文件请求

void CLImTool::upLoadFile(std::string path, std::string fileid = “”);

协议字段 类型 是否必填 说明
path std::string 带绝对路径的文件名(例:xx/test.amr)
fileid std::string 希望传递给上传结束事件回调的值(有点像cocos2dx中的setTag)

5.4.11 上传文件完成事件

class ImListern::ImUpLoadFileListern
{
      public:
             virtual void onUpLoadFileListern(UpLoadFileRespond*) = 0;
};
回调回来的参数:

协议字段 类型 是否必填 说明
result uint32 上传结果,不为0即为失败
msg std::string 错误描述
fileid std::string 请求上传接口传的值
fileurl std::string 返回URL地址
percent uint32 完成百分比

5.4.12 下载文件请求

void CLImTool::downLoadFile(std::string url, std::string savePath, std::string fileid = “”);

协议字段 类型 是否必填 说明
url std::string 所下载的文件所在的URL地址
savePath std::string 保存路径,带绝对路径的文件名(例:xx/test.amr)
fileid std::string 希望传递给下载结束事件回调的值(有点像cocos2dx中的setTag)

5.4.13 下载文件完成事件

class ImListern::ImDownLoadFileListern
{
      public:
             virtual void onDownLoadFileListern(DownLoadFileRespond*) = 0;
};
 
回调回来的参数:

协议字段 类型 是否必填 说明
result uint32 上传结果,不为0即为失败
msg std::string 错误描述
fileid std::string 请求下载接口传的值
filename std::string 文件保存的路径
percent uint32 完成百分比

6.常见问题集锦

6.1 Android版本undefine reference to 的错误。

解决方案:返回至本文档的Android环境配置栏目下,严格按照此说明来配置您的工程。

6.2 Android设备上无法录音,win32上正常

解决方案:没有在android工程下加入完整权限,请参考本文档的Android环境配置栏目配置此权限。

6.3 配置正常却无法录音或播放等操作

解决方案:确认是否已经调用登录并且登录回调结果为成功。如果没有调用登录接口在调用其他接口时会返回错误码1105.

6.4 playFromUrl失败:“play audio file tool small size =0”或返回1924错误码

解决方案:检查录音调用传的参数,第一个参数(savePath)需要是带绝对路径的文件名(例:xx/test.amr)
注:路径必须是带amr后缀的音频文件路径而非目录路径

6.5 调用cpLogin提示“第三方系统没有打通账号”

解决方案:咨询商务是否已经注册appid

6.6 XCODE(iOS)链接报错:

解决方案:添加ImageIO.framework还有CoreMedia.framework

6.7 如没有回调:

//请在定时器运行下面这个方法   具体代码可以看AppDelegate.cpp里面的代码
void dispatchMsg(float t);

6.8 注意事项

初始化、登录接口只需要调用一次就好。在使用功能前必须先调用初始化和登录否则调用失败。

6.9 注意事项

之前老版更新、Android下老板的接入的时间有在AndroidManifest.xml加入了一些Service。这些Service现在都不需要了,需要将它全部删除,不然可能因为找不到Service导致一些异常现象。