插入一只广告: 欢迎成都ccc开发者入群 573289987
在接入之前请到http://www.17yaya.com下载云娃呀呀语音COCOS版本。并且联系客服申请appid(没有appid是无法正常使用功能的)。
下面进入正题,要在cocos creator接入呀呀语音SDK实现即时语音通信功能需要掌握以下知识:
1.NDK编译流程;
2.C++相关知识;
3.js手动绑定相关知识;
4.js相关知识。
前置条件:新建项目->已执行default模板构建和编译android项目
进入目录:![]()
然后打开AndroidManifest.xml文件,修改以下处内容:
在权限部分增加以下权限:

完成以后关闭文件,然后打开build-cfg.json文件。
在此文件中增加jar包的复制命令。
然后进入jni目录,打开Android.mk文件,注意我红色圈中部分需要修改。
进入目录![]()
打开编辑AppActivity.java文件

注意红色抹掉的部分是我项目里需要用的不用管,重点在我用红色框中的部分是必须要加的。下面的if…建议加上。
进入目录
添加以下jar包

此jar包在下面的zip中有。

然后进入目录
在此目录中增加IM_SDK目录,此目录在下载的压缩包中。

加入后

进入classes目录,将压缩包中classes目录中YunVaSDK目录复制到此目录

在此目录中打开AppDelegate.h和AppDelegate.cpp文件。
AppDelegate.h文件内容如下:
//
// GCTestAppDelegate.h
// GCTest
//
// Created by Rohan Kuruvilla on 06/08/2012.
// Copyright MyCompanyName 2012. All rights reserved.
//
#ifndef _APP_DELEGATE_H_
#define _APP_DELEGATE_H_
#include "platform/CCApplication.h"
#include "cocos2d.h"
#include "YunVaSDK/YVTool.h"
using namespace YVSDK;
class DispatchMsgNode;
/**
@brief The cocos2d Application.
The reason for implement as private inheritance is to hide some interface call by Director.
*/
class AppDelegate : private cocos2d::Application
{
public:
AppDelegate();
virtual ~AppDelegate();
void initGLContextAttrs() override;
/**
@brief Implement Director and Scene init code here.
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
virtual bool applicationDidFinishLaunching();
/**
@brief The function be called when the application enter background
@param the pointer of the application
*/
virtual void applicationDidEnterBackground();
/**
@brief The function be called when the application enter foreground
@param the pointer of the application
*/
virtual void applicationWillEnterForeground();
private:
DispatchMsgNode* m_dispatchMsgNode;
};
#endif // _APP_DELEGATE_H_
AppDelegate.cpp文件内容如下:
#include "AppDelegate.h"
#include "platform/CCGLView.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#include "platform/ios/CCGLViewImpl-ios.h"
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_IOS
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/CCGLViewImpl-android.h"
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "platform/desktop/CCGLViewImpl-desktop.h"
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
#include "platform/desktop/CCGLViewImpl-desktop.h"
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_MAC
#include "base/CCDirector.h"
#include "base/CCEventDispatcher.h"
#include "js_module_register.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && PACKAGE_AS
#include "SDKManager.h"
#include "jsb_anysdk_protocols_auto.hpp"
#include "manualanysdkbindings.hpp"
using namespace anysdk::framework;
#endif
USING_NS_CC;
class DispatchMsgNode : public cocos2d::Node
{
public:
bool init()
{
isschedule = false;
return Node::init();
}
CREATE_FUNC(DispatchMsgNode);
void startDispatch()
{
if (isschedule) return;
isschedule = true;
Director::getInstance()->getScheduler()->scheduleUpdate(this, 0, false);
}
void stopDispatch()
{
if (!isschedule) return;
isschedule = false;
Director::getInstance()->getScheduler()->unscheduleUpdate(this);
}
void update(float dt)
{
YVTool::getInstance()->dispatchMsg(dt);
}
private:
bool isschedule;
};
AppDelegate::AppDelegate()
{
m_dispatchMsgNode = NULL;
}
AppDelegate::~AppDelegate()
{
ScriptEngineManager::destroyInstance();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && PACKAGE_AS
SDKManager::getInstance()->purge();
#endif
if (m_dispatchMsgNode != NULL)
{
m_dispatchMsgNode->stopDispatch();
m_dispatchMsgNode->release();
m_dispatchMsgNode = NULL;
}
}
void AppDelegate::initGLContextAttrs()
{
GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
GLView::setGLContextAttrs(glContextAttrs);
}
bool AppDelegate::applicationDidFinishLaunching()
{
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS && PACKAGE_AS
SDKManager::getInstance()->loadAllPlugins();
#endif
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
glview = GLViewImpl::create("mahjong");
#else
glview = GLViewImpl::createWithRect("mahjong", Rect(0,0,900,640));
#endif
director->setOpenGLView(glview);
}
// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);
js_module_register();
ScriptingCore* sc = ScriptingCore::getInstance();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && PACKAGE_AS
sc->addRegisterCallback(register_all_anysdk_framework);
sc->addRegisterCallback(register_all_anysdk_manual);
#endif
sc->start();
sc->runScript("script/jsb_boot.js");
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
sc->enableDebugger();
#endif
ScriptEngineManager::getInstance()->setScriptEngine(sc);
ScriptingCore::getInstance()->runScript("main.js");
if (m_dispatchMsgNode == NULL)
{
m_dispatchMsgNode = DispatchMsgNode::create();
m_dispatchMsgNode->retain();
m_dispatchMsgNode->startDispatch();
}
return true;
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
auto director = Director::getInstance();
director->stopAnimation();
director->getEventDispatcher()->dispatchCustomEvent("game_on_hide");
}
// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
auto director = Director::getInstance();
director->startAnimation();
director->getEventDispatcher()->dispatchCustomEvent("game_on_show");
}
完成之后,android接入的部分就完成了。
进入目录![]()
增加目录audio-yvsdk,新建以下两个文件

IMDispatchMsgNode.h
#ifndef IMDispatchMsgNode_h
#define IMDispatchMsgNode_h
#include
#include <stdio.h>
#include “cocos2d.h”
#include “YunVaSDK/YVTool.h”
using namespace YVSDK;
class IMDispatchMsgNode: public cocos2d::Node,
public YVListern::YVUpLoadFileListern,
public YVListern::YVFinishPlayListern,
public YVListern::YVStopRecordListern,
public YVListern::YVLoginListern,
public YVListern::YVDownLoadFileListern,
public YVListern::YVRecordVoiceListern
{
public:
IMDispatchMsgNode();
~IMDispatchMsgNode();
class Delegate{
public:
virtual ~Delegate() {}
virtual void onMessage(IMDispatchMsgNode* node, const std::string& data) = 0;
};
bool init(const Delegate& delegate);
void addListern();
void initSDK(unsigned long appid,unsigned int length);
void cpLogin(std::string nickname,std::string uid);
void destroy();
bool startRecord();
void stopRecord();
bool playRecord();
void playFromUrl(std::string url);
void stopPlay();
void upLoadFile(std::string path);
void onLoginListern(CPLoginResponce* r);
void onStopRecordListern(RecordStopNotify* r);
void onFinishPlayListern(StartPlayVoiceRespond* r);
void onUpLoadFileListern(UpLoadFileRespond* r);
void onDownLoadFileListern(DownLoadFileRespond* r);
void onRecordVoiceListern(RecordVoiceNotify*);
// static IMDispatchMsgNode getInstance();
private:
bool _sdk_inited;
static int time;
unsigned int m_length;
Delegate* _delegate;
// static IMDispatchMsgNode m_instance;
};
#endif /* IMDispatchMsgNode_h */
IMDispatchMsgNode.cpp
#include “IMDispatchMsgNode.h”
#include
#include “base/CCEventDispatcher.h”
#include “base/CCEventListenerCustom.h”
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include <stdlib.h>
#include <string.h>
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#define RECODEPATH ("C:/imsdkk/path/test.amr")
#define DOWNPATH ("C:/imsdkk/path/http.amr")
#else
#define RECODEPATH (FileUtils::getInstance()->getWritablePath() +"test.amr")
#define DOWNPATH (FileUtils::getInstance()->getWritablePath()+"dwtest.amr")
#endif
USING_NS_CC;
// using namespace CocosDenshion;
using namespace std;
using namespace cocos2d;
#define BUFFER_SIZE 8192
#define MAX_FILENAME 512
int IMDispatchMsgNode::time = 0;
IMDispatchMsgNode::IMDispatchMsgNode()
:_delegate(nullptr)
,_sdk_inited(false)
{
}
IMDispatchMsgNode::~IMDispatchMsgNode(){
}
bool IMDispatchMsgNode::init(const Delegate& delegate) {
_delegate = const_cast<Delegate*>(&delegate);
if(!Node::init()){
return false;
}
addListern();
return true;
}
void IMDispatchMsgNode::addListern() {
YVTool::getInstance()->addRecordVoiceListern(this);
YVTool::getInstance()->addDownLoadFileListern(this);
YVTool::getInstance()->addFinishPlayListern(this);
YVTool::getInstance()->addLoginListern(this);
YVTool::getInstance()->addStopRecordListern(this);
YVTool::getInstance()->addUpLoadFileListern(this);
}
void IMDispatchMsgNode::destroy(){
YVTool::getInstance()->delRecordVoiceListern(this);
YVTool::getInstance()->delDownLoadFileListern(this);
YVTool::getInstance()->delFinishPlayListern(this);
YVTool::getInstance()->delLoginListern(this);
YVTool::getInstance()->delStopRecordListern(this);
YVTool::getInstance()->delUpLoadFileListern(this);
YVTool::getInstance()->cpLogout();
YVTool::getInstance()->releaseSDK();
Director::getInstance()->end();
}
void IMDispatchMsgNode::initSDK(unsigned long appid,unsigned int length){
auto director = Director::getInstance();
if(_sdk_inited)return; _sdk_inited=true;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
std::string path = "C:/imsdkk/path/";
#else
std::string path = FileUtils::getInstance()->getWritablePath();
#endif
YVTool::getInstance()->initSDK(appid, path, false, false);
//m_length = length;
}
void IMDispatchMsgNode::cpLogin(std::string nickname,std::string uid){
YVTool::getInstance()->cpLogin(nickname, uid);
}
bool IMDispatchMsgNode::startRecord(){
YVTool::getInstance()->startRecord(RECODEPATH,2);//2:边录音边上传
}
void IMDispatchMsgNode::stopRecord(){
YVTool::getInstance()->stopRecord();
}
bool IMDispatchMsgNode::playRecord(){
YVTool::getInstance()->playRecord("", RECODEPATH, "");
}
void IMDispatchMsgNode::playFromUrl(std::string url){
// #if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
// if (FileUtils::getInstance()->isFileExist(DOWNPATH))
// {
// rmdir(DOWNPATH.c_str());
// }
// #else
// if (isFileExist(DOWNPATH))
// {
// remove(DOWNPATH.c_str());
// }
// #endif
YVTool::getInstance()->playRecord(url,""); //只云播放
}
void IMDispatchMsgNode::stopPlay(){
YVTool::getInstance()->stopPlay();
}
void IMDispatchMsgNode::upLoadFile(std::string path){
YVTool::getInstance()->upLoadFile(RECODEPATH);
}
void IMDispatchMsgNode::onLoginListern(CPLoginResponce* r){
//auto event = new EventCustom("YVSDK_LOGIN_COMPLETED");
if (r->result == 0) {
cocos2d::log("语音模块登录成功");
YVTool::getInstance()->setRecord(10, true);
_delegate->onMessage(this, "{\"name\":\"YVSDK_LOGIN_COMPLETED\",\"result\":0}");
}else{
cocos2d::log("登录失败");
_delegate->onMessage(this, "{\"name\":\"YVSDK_LOGIN_COMPLETED\",\"result\":1}");
}
}
void IMDispatchMsgNode::onStopRecordListern(RecordStopNotify* r){
cocos2d::log("yvsdk onStopRecordListern");
cocos2d::log("time:%d,path:%s",r->time,r->strfilepath.c_str());
char ttStr1[500] = { 0 };
const char* ttFormat = "{\"name\":\"YVSDK_STOP_RECORD\",\"time\":%d,\"path\":\"%s\"}";
IMDispatchMsgNode::time = r->time;
sprintf(ttStr1, ttFormat, r->time, r->strfilepath.c_str());
_delegate->onMessage(this, ttStr1);
}
void IMDispatchMsgNode::onFinishPlayListern(StartPlayVoiceRespond* r){
cocos2d::log("播放完成");
_delegate->onMessage(this, "{\"name\":\"YVSDK_PLAY_COMPLETED\",\"result\":0}");
}
void IMDispatchMsgNode::onUpLoadFileListern(UpLoadFileRespond* r){
char ttStr1[200] = { 0 };
if(r->result == 0){
cocos2d::log("yvsdk upfile successful:%s",r->fileurl.c_str());
const char* ttFormat = "{\"name\":\"YVSDK_UPLOAD_COMPLETED\",\"result\":%d,\"url\":\"%s\"}";
sprintf(ttStr1, ttFormat, r->result, r->fileurl.c_str());
//event->setUserData(ttStr1);
}else{
cocos2d::log("yvsdk upfile fail:%s",r->msg.c_str());
//char ttStr1[200] = { 0 };
const char* ttFormat = "{\"name\":\"YVSDK_UPLOAD_COMPLETED\",\"result\":%d,\"url\":\"%s\"}";
sprintf(ttStr1, ttFormat, r->result, r->msg.c_str());
//event->setUserData(ttStr1);
}
//Director::getInstance()->getEventDispatcher()->dispatchEvent(event);
_delegate->onMessage(this, ttStr1);
}
void IMDispatchMsgNode::onDownLoadFileListern(DownLoadFileRespond* r){
//auto event = new EventCustom("YVSDK_DOWNLOAD");
char ttStr1[200] = { 0 };
const char* ttFormat = "{\"name\":\"YVSDK_DOWNLOAD\",\"result\":%s,\"localpath\":\"%s\",\"percent\":%s}";
if(r->result == 0){
cocos2d::log("yvsdk DownLoadFile success");
}
else{
cocos2d::log("yvsdk DownLoadFile failed");
}
sprintf(ttStr1, ttFormat, r->result, r->filename.c_str(),r->percent);
_delegate->onMessage(this, ttStr1);
}
void IMDispatchMsgNode::onRecordVoiceListern(RecordVoiceNotify* r)
{
cocos2d::log("音量变化回调");
char ttStr1[200] = { 0 };
const char* ttFormat = "{\"name\":\"YVSDK_VOICE_CHANGE\",\"volume\":%d}";
sprintf(ttStr1, ttFormat, r->volume);
_delegate->onMessage(this, ttStr1);
}
完成之后回到cocos目录将刚才的YunVaSDK目录再添加到此处并且打开android.mk文件。

进入目录:
新建audio-yvsdk目录

添加以上两个文件。
jsb_IMDispatchMsgNode.h
jsb_IMDispatchMsgNode.cpp
因本文字数限制和商业版本版权限制,此文件不予公布。
回到目录manual,打开js_module_register.cpp文件
OK,完成,现在JS里就可以调用了。

下面cplogin后面传id,注意登录的id不能重复,前面的账号可以重复。
对了还要把资源包放到以下目录

本文完毕…
欢迎加入群:573289987 交流学习







