上一篇文章 Unity语音通话示例源码跑通 我们分享了Unity语音通话的一个简单示例。今天我们来看下如何集成ZEGO即构的语音SDK,这是实现语音通话功能的前提条件。
Unity语音通话sdk集成步骤
准备环境
在开始集成 ZEGO Express SDK 前,请确保开发环境满足以下要求:
- Unity 2018.4.21f1 或以上版本(建议通过 Unity Hub 下载最新的 LTS 版本)。安装 Unity 时,请根据需要运行的平台,勾选对应的 “Plaforms” 模块一起下载。
- 根据需要运行的平台,确保对应的开发环境和设备。
- Android:Android 4.4 或以上版本且支持音视频的 Android 设备或模拟器(推荐使用真机),如果为真机,请开启“允许调试”选项。
- iOS:Xcode 13.0 或以上版本,iOS 9.0 或以上版本且支持音视频的 iOS 设备或模拟器(推荐使用真机)。
- macOS:macOS 10.11 或以上版本且支持音视频的 macOS 设备。
- Windows:Windows 7 或以上版本且支持音视频的 Windows 设备;并安装 Visual Studio 2015 或以上版本。
- Linux: 任意具有 GLIBC 2.16 或以上版本的 Linux 发行版系统(目前仅支持 x86_64 架构),libasound(ALSA),libv4l2(v4l utils),CMake 3.7 或以上版本。
- 确保运行设备已经连接到 Internet。
集成 SDK
新建项目(可选)
单击 “新建” 按钮,选择 “3D” 模版,填写 “项目名称”,选择 “位置” 存放项目,单击 “创建” 按钮创建项目。
导入 SDK
目前,Unity 支持 Android、iOS、macOS、Windows、Linux 平台。
- 请参考 下载SDK包,下载最新版本的 SDK,下载完成后进行解压。
- 手动将 “Plugins”, “Scripts” 两个目录到拷贝到开发者项目的 “Assets” 目录下,即可集成 SDK。
- 对于不同的运行平台,需要做一些额外处理。
- Windows Unity 项目中不能存在同名的 .dll 文件,否则在 Build 时会出现 “Multiple plugins with the same name ‘zegoexpressengine'” 错误。开发者需根据实际业务情况删除 Plugins/Windows 文件夹下的 x64 文件夹或 x86 文件夹,不准备运行到 Windows 平台则可以直接删除 Plugins/Windows 文件夹。
- macOS 在 Unity 2019.3 之前版本不支持将 macOS dylib 作为 Plugins,需要手动将 “libZegoExpressEngine.dylib” 重命名为 “ZegoExpressEngine.bundle” 才能正确导入 SDK,且 macOS 版本不能低于 10.5。
- iOS 导出 Xcode 工程后,直接运行可能会报如下错误: iOS 平台的 XCFramework 中有三个文件夹:
- “ios-arm64_armv7” 是真机架构,用于真机运行调试以及上架发布。当需要在真机上运行时请保留此文件夹并删除其他两个。
- “ios-arm64_×86_64-simulator” 是模拟器架构,用于模拟器运行调试。如果需要运行 iOS 模拟器请保留此文件夹并删除其他两个。(即当工程配置 iOS Target SDK 指定为 Simulator SDK 时)
- “ios-arm64_×86_64-maccatalyst” 是 iOS MacCatalyst 架构,目前 Unity 暂不支持此架构,请直接删除。参考 https://forum.unity.com/threads/mac-catalyst.1183951/
- Android 构建 Android App 时也可能会提示存在多个 Windows dll 文件的问题。请按照上述 Windows 的处理方式操作。
设置权限
根据实际应用平台,设置 SDK 所需的摄像头和麦克风权限。
Android 平台
在 UNITY_2018_3_OR_NEWER 或以上版本中,Unity 不会主动获取摄像头和麦克风权限,需要开发者调用获取权限。
#if(UNITY_2018_3_OR_NEWER)
using UnityEngine.Android;
#endif
void Start()
{
#if (UNITY_2018_3_OR_NEWER)
permissionList.Add(Permission.Microphone);
permissionList.Add(Permission.Camera);
#endif
}
void Update()
{
#if (UNITY_2018_3_OR_NEWER)
// 获取设备权限
CheckPermission();
#endif
}
private void CheckPermission()
{
#if (UNITY_2018_3_OR_NEWER)
foreach (string permission in permissionList)
{
if (Permission.HasUserAuthorizedPermission(permission))
{
}
else
{
Permission.RequestUserPermission(permission);
}
}
#endif
}
iOS 平台
需要运行到 iOS 设备的项目,导出 Xcode 工程后,选择 Info.plist 文件,添加摄像头和麦克风权限。
界面自适应
由于 Android 设备和 iOS 设备的屏幕方向存在 Portrait、PortraitUpsideDown、LandscapeLeft、LandscapeRight 四种方向,为保证推流预览和拉流的显示界面始终在正确的方向,推荐在 Update 方法中添加以下代码。
private DeviceOrientation preOrientation=DeviceOrientation.Unknown;
void Update()
{
#if UNITY_ANDROID|| UNITY_IPHONE
if (engine != null)
{
if (preOrientation != Input.deviceOrientation)
{
if (Input.deviceOrientation == DeviceOrientation.Portrait)
{
engine.SetAppOrientation(ZegoOrientation.ZegoOrientation_0);
}
else if (Input.deviceOrientation == DeviceOrientation.PortraitUpsideDown)
{
engine.SetAppOrientation(ZegoOrientation.ZegoOrientation_180);
}
else if (Input.deviceOrientation == DeviceOrientation.LandscapeLeft)
{
engine.SetAppOrientation(ZegoOrientation.ZegoOrientation_90);
}
else if (Input.deviceOrientation == DeviceOrientation.LandscapeRight)
{
engine.SetAppOrientation(ZegoOrientation.ZegoOrientation_270);
}
preOrientation = Input.deviceOrientation;
}
}
#endif
}
开发者也可根据实际业务情况,参考上述代码,通过调用 SetAppOrientation
接口传入对应角度,保证推流预览和拉流的显示界面始终在正确的方向。
常见问题
- 为什么在多次启用、停止编辑器调试过程中,Unity 会出现卡死的情况?
在编辑器运行程序调试时,请务必添加以下代码,避免 Unity 出现卡死的问题。
void OnApplicationQuit() {
//It must be added for unity editor debugging, otherwise it will cause unity to be stuck
ZegoExpressEngine.DestroyEngine();
}
- 导出 iOS Xcode 工程后还需要集成 ZegoExpressEngine.framework 吗?
需要集成,以 Unity 2019.4 导出的 Xcode 工程为例,需要在 “TARGETS > Build Phases > Embed Frameworks” 菜单集成 ZegoExpressEngine.framework。
否则运行到设备上时,可能会报出如下的错误:
no suitable image found. Did find:
/private/var/containers/Bundle/Application/3CC0EE65-89C9-45F5-8E22-A4AC194DF260/hello.app/Frameworks/UnityFramework.framework/Frameworks/ZegoExpressEngine.framework/ZegoExpressEngine: code signature in (/private/var/containers/Bundle/Application/3CC0EE65-89C9-45F5-8E22-A4AC194DF260/hello.app/Frameworks/UnityFramework.framework/Frameworks/ZegoExpressEngine.framework/ZegoExpressEngine) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
开发者也可参考以下的 ZEGO_BuildPostProcess.cs 文件,根据实际情况调整代码后,将文件放置在 Unity 的 Assets 目录下的 Editor 目录下,Unity 导出 Xcode 项目的过程中将自动完成 ZegoExpressEngine.framework 的集成,无须手动添加即可实现自动配置集成 ZegoExpressEngine.framework。
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Collections;
#if UNITY_IOS
using UnityEditor.iOS.Xcode.Extensions;
using UnityEditor.iOS.Xcode;
#endif
using System.IO;
public class ZEGO_BuildPostProcess
{
[PostProcessBuild]
public static void OnPostprocessBuild(BuildTarget buildTarget, string path) {
if (buildTarget == BuildTarget.iOS) {
LinkLibraries (path);
}
}
public static void LinkLibraries (string path) {
#if UNITY_IOS
// linked library
string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";
PBXProject proj = new PBXProject();
proj.ReadFromFile(projPath);
string target;
string unityTargetGuid;
var unityMainTargetGuidMethod = proj.GetType().GetMethod("GetUnityMainTargetGuid");
if (unityMainTargetGuidMethod != null)
{
target = (string)unityMainTargetGuidMethod.Invoke(proj, null);
}
else
{
target = proj.TargetGuidByName("Unity-iPhone");
}
var unityFrameworkTargetGuidMethod = proj.GetType().GetMethod("GetUnityFramworkTargetGuid");
if(unityFrameworkTargetGuidMethod != null)
{
unityTargetGuid = (string)unityFrameworkTargetGuidMethod.Invoke(proj, null);
}
else
{
unityTargetGuid = proj.TargetGuidByName("UnityFramework");
}
// Disable bitcode
proj.SetBuildProperty(unityTargetGuid, "ENABLE_BITCODE", "false");
proj.SetBuildProperty(target, "ENABLE_BITCODE", "false");
// Add default framework to main proj
string defaultLocationInProj = path + "/Frameworks/Plugins/iOS/ZegoExpressEngine.xcframework/ios-arm64_armv7";//实际ZegoExrpessFramework路径
string coreFrameworkName = "ZegoExpressEngine.framework";
string framework = Path.Combine(defaultLocationInProj, coreFrameworkName);
string fileGuid = proj.AddFile(framework, "/" + coreFrameworkName, PBXSourceTree.Source);
PBXProjectExtensions.AddFileToEmbedFrameworks(proj, target, fileGuid);
// Write proj
File.WriteAllText(projPath, proj.WriteToString());
// Add permission
string pListPath = path + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(pListPath));
PlistElementDict rootDic = plist.root;
var cameraPermission = "NSCameraUsageDescription";
var micPermission = "NSMicrophoneUsageDescription";
rootDic.SetString(cameraPermission, "Video need to use camera");
rootDic.SetString(micPermission, "Voice call need to user mic");
File.WriteAllText(pListPath, plist.WriteToString());
#endif
}
}
- 为什么集成 SDK 后在 Unity Editor 调试过程中创建 SDK 经常失败?
如果仅在 Unity Editor 中出现创建 SDK 失败,请检查 Unity Editor 是否有如下的配置:
如果按图中勾选了对应设置,Unity Editor 在停止调试后一段时间会缓存静态变量,导致 SDK 内部静态变量没有重置而出现异常,表现为首次 CreateEngine 成功,Unity Player 停止运行后再启动 CreateEngine 失败,详情请参考 域重新加载。
以上就是ZEGO即构 Unity语音通话sdk的集成步骤,集成如果有问题可以向我们咨询或者留言探讨。
本文为原创稿件,版权归作者所有,如需转载,请注明出处:https://www.nxrte.com/jishu/yinshipin/6942.html