本文主要介绍如何快速运行 GME Unreal Sample Project,并将工程示例代码接入到项目中。
请提前申请开通 GME 实时语音、语音消息服务,获取到 AppId 以及 Key。申请 GME 服务,详情请参见 服务开通,appId 对应控制台的 AppID,authKey 对应控制台的权限密钥。
通过 下载指引 下载 Unreal Sample Project。由于 UE5 和 UE4 的 Demo 配置不同,需要下载相对应引擎版本的 Sample Project。
下载后打开工程目录,路径 Source\UEDemo1 中,找到 UserConfig.cpp,将图中红色框处 appID 及 appKey 修改为所申请的 GME 控制台 服务管理-应用设置 中的 AppID 以及权限密钥。
1)运行程序
单击编辑器运行按钮 ,进入运行程序。
2)初始化
单击 Login,进行初始化,再单击 Voice Chat 进入实时语音房间配置界面。
3)实时语音进房
配置好实时语音房间号后,单击 JoinRoom 进入实时语音房间。
4)实时语音功能
界面上会显示进房的 RoomID 以及本端的 openID。
本端勾选 Mic 及 Speaker 后,另一个终端的机器也重复以上步骤,进入相同的房间,也勾选 Mic 以及 Speaker,便可以实现双方沟通。
如果两个终端都勾选 3D Voice Effect,可通过键盘 【A】【S】【D】【W】改变方位,体验3D语音方位感。
5)语音消息功能
按住 Push to Talk 按钮,对着麦克风进行说话,放开后语音会转成文本显示在界面中。
使用 GME 实时语音主要的流程是 Init > EnterRoom > EnableMic > EnableSpeaker。Sample Project主要的代码在 BaseViewController.cpp 以及 ExperientialDemoViewController.cpp 中。
初始化相关的代码在 BaseViewController.cpp 文件中的 InitGME 函数中。这里面包含了初始化、语音消息的鉴权初始化以及设置回调 TMGDelegate。
int UBaseViewController::InitGME(std::string sdkAppId, std::string sdkAppKey, std::string userId) {
int nAppid = atoi(sdkAppId.c_str());
int ret = ITMGContextGetInstance()->Init(sdkAppId.c_str(), userId.c_str());
ITMGContextGetInstance()->SetTMGDelegate(this);
int RetCode = (int) ITMGContextGetInstance()->CheckMicPermission();
FString msg = FString::Printf(TEXT("check Permission retcode =%d"), RetCode);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, *msg);
char strSig[128] = {0};
unsigned int nLength = 128;
nLength = QAVSDK_AuthBuffer_GenAuthBuffer(nAppid, "0", userId.c_str(), sdkAppKey.c_str(), (unsigned char *)strSig, nLength);
ITMGContextGetInstance()->GetPTT()->ApplyPTTAuthbuffer(strSig, nLength);
m_appId = sdkAppId;
m_appKey = sdkAppKey;
m_userId = userId;
m_isEnableTips = false;
m_tipsMark = 0;
return ret;
}
使用 GME 需要周期性的调用 Poll 函数。在 UEDemoLevelScriptActor.cpp 脚本中的 Tick 中调用。
void AUEDemoLevelScriptActor::Tick(float DeltaSeconds) {
Super::Tick(DeltaSeconds);
m_pTestDemoViewController->UpdateTips();
m_pCurrentViewController->UpdatePosition();
ITMGContextGetInstance()->Poll();
}
进房相关的代码在 BaseViewController.cpp 文件中的 EnterRoom 函数中。
void UBaseViewController::EnterRoom(std::string roomID, ITMG_ROOM_TYPE roomType) {
int nAppid = atoi(m_appId.c_str());
UserConfig::SetRoomID(roomID);
char strSig[128] = {0};
unsigned int nLength = 128;
nLength = QAVSDK_AuthBuffer_GenAuthBuffer(nAppid, roomID.c_str(), m_userId.c_str(), m_appKey.c_str(), (unsigned char *)strSig, nLength);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, TEXT("onEnterRoom"));
ITMGContextGetInstance()->EnterRoom(roomID.c_str(), roomType, strSig, nLength);
}
进房回调在同一脚本中的 OnEvent 函数中。
if (eventType == ITMG_MAIN_EVENT_TYPE_ENTER_ROOM) {
int32 result = JsonObject->GetIntegerField(TEXT("result"));
FString error_info = JsonObject->GetStringField(TEXT("error_info"));
if (result == 0) {
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 20.0f, FColor::Yellow, TEXT("Enter room success."));
}
else {
FString msg = FString::Printf(TEXT("Enter room failed. result=%d, info = %ls"), result, *error_info);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 20.0f, FColor::Yellow, *msg);
}
onEnterRoomCompleted(result, error_info);
进房成功后打开设备,相关代码在 ExperientialDemoViewController.cpp 中。
void UExperientialDemoViewController::onCheckMic(bool isChecked) {
//GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, L"onCheckMic");
ITMGContext *pContext = ITMGContextGetInstance();
if (pContext) {
ITMGAudioCtrl *pTmgCtrl = pContext->GetAudioCtrl();
if (pTmgCtrl) {
pTmgCtrl->EnableMic(isChecked);
}
}
}
void UExperientialDemoViewController::onCheckSpeaker(bool isChecked) {
//GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, L"onCheckSpeaker");
ITMGContext *pContext = ITMGContextGetInstance();
if (pContext) {
ITMGAudioCtrl *pTmgCtrl = pContext->GetAudioCtrl();
if (pTmgCtrl) {
pTmgCtrl->EnableSpeaker(isChecked);
}
}
}
3D 音效的接入可以参考 3D 音效文档。在工程中,首先初始化 3D 音效功能,相关代码在 ExperientialDemoViewController.cpp 中。
void UExperientialDemoViewController::onCheckSpatializer(bool isChecked) {
char buffer[256]={0};
// snprintf(buffer, sizeof(buffer), "%s3d_model", getFilePath().c_str());
snprintf(buffer, sizeof(buffer), "%sgme_2.8_3d_model.dat", getFilePath().c_str());
int ret1 = ITMGContextGetInstance()->GetAudioCtrl()->InitSpatializer(buffer);
int ret2 = ITMGContextGetInstance()->GetAudioCtrl()->EnableSpatializer(isChecked, false);
FString msg = FString::Printf(TEXT("InitSpatializer=%d, EnableSpatializer ret=%d"), ret1, ret2);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, msg);
}
在 UEDemoLevelScriptActor.cpp 脚本 Tick 中调用 UpdatePosition 函数。
void AUEDemoLevelScriptActor::Tick(float DeltaSeconds) {
Super::Tick(DeltaSeconds);
m_pTestDemoViewController->UpdateTips();
m_pCurrentViewController->UpdatePosition();
ITMGContextGetInstance()->Poll();
}
void UBaseViewController::UpdatePosition() {
if (!m_isCreated)
return;
ITMGRoom *pTmgRoom = ITMGContextGetInstance()->GetRoom();
if (!pTmgRoom)
{
return;
}
int nRange = GetRange();
pTmgRoom->UpdateAudioRecvRange(nRange);
FVector cameraLocation = UGameplayStatics::GetPlayerCameraManager(m_pActor->GetWorld(), 0)->GetCameraLocation();
FRotator cameraRotation = UGameplayStatics::GetPlayerCameraManager(m_pActor->GetWorld(), 0)->GetCameraRotation();
FString msg = FString::Printf(TEXT("location(x=%.2f,y=%.2f,z=%.2f), rotation(pitch=%.2f,yaw=%.2f,roll=%.2f)"),
cameraLocation.X, cameraLocation.Y, cameraLocation.Z, cameraRotation.Pitch, cameraRotation.Yaw, cameraRotation.Roll);
int position[] = { (int)cameraLocation.X,(int)cameraLocation.Y, (int)cameraLocation.Z };
FMatrix matrix = ((FRotationMatrix)cameraRotation);
float forward[] = { matrix.GetColumn(0).X,matrix.GetColumn(1).X,matrix.GetColumn(2).X };
float right[] = { matrix.GetColumn(0).Y,matrix.GetColumn(1).Y,matrix.GetColumn(2).Y };
float up[] = { matrix.GetColumn(0).Z,matrix.GetColumn(1).Z,matrix.GetColumn(2).Z };
pTmgRoom->UpdateSelfPosition(position, forward, right, up);
SetPositionInfo(msg);
}
在 ExperientialDemoViewController.cpp 中打开3D 效果。
void UExperientialDemoViewController::onCheckSpatializer(bool isChecked) {
char buffer[256]={0};
// snprintf(buffer, sizeof(buffer), "%s3d_model", getFilePath().c_str());
snprintf(buffer, sizeof(buffer), "%sgme_2.8_3d_model.dat", getFilePath().c_str());
int ret1 = ITMGContextGetInstance()->GetAudioCtrl()->InitSpatializer(buffer);
int ret2 = ITMGContextGetInstance()->GetAudioCtrl()->EnableSpatializer(isChecked, false);
FString msg = FString::Printf(TEXT("InitSpatializer=%d, EnableSpatializer ret=%d"), ret1, ret2);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, msg);
}
本页内容是否解决了您的问题?