UE5开发HoloLens遇到的坑和应对方法

您所在的位置:网站首页 hololens使用方法 UE5开发HoloLens遇到的坑和应对方法

UE5开发HoloLens遇到的坑和应对方法

2023-03-23 02:09| 来源: 网络整理| 查看: 265

第三方库# 源码编译#

对于第三方库最好是使用源码和UE工程代码一起编译,出问题的几率最小,但是需要把编译脚本自己改成UnrealBuildTools的C#,需要视工程大小来确定

vcpkg安装#

HoloLens的运行环境是arm64-uwp,如果不想对于每个第三方库去编译,可以直接安装vcpkg包管理工具,安装一个库的时候分别安装x64-windows和arm64-uwp。如果需要编译为静态库可以到使用社区的编译方案x64-windows-static-md和arm64-uwp-static-md

具体使用MD还是MT可以保持和UE5的UnrealBuildTools一致的编译参数,可以查看源码[ROOT]\Epic_Games\UE_5.0\Engine\Source\Programs\UnrealBuildTool\Platform\。vcpkg中已经有的配置如果不满足要求可以在triplets中自己创建编译配置

静态库#

对于一些普通的第三方库(没有涉及到Windows API)可以直接编译为arm64架构库,作为静态库链接

对于使用了系统API的库,由于Win32应用和UWP应用的权限设置和接口不一样,为了兼容Windows调试和HoloLens实机使用,尽可能的都使用WinRT接口

动态库#

动态库除了需要注意编译问题,加载也需要注意。打包程序的时候可以把动态库和可执行程序放在同一目录,也可以使用延迟加载的方式把动态库打包到plugin里面加载,编译脚本写法不一样,同时延迟加载方案需动态库要在插件的模块初始化时候加载

以下是延迟加载FFmpeg的例子

if (Target.Platform == UnrealTargetPlatform.Win64) { isLibrarySupported = true; prefixDir = "x64"; string[] libs = { "avcodec.lib", "avdevice.lib", "avfilter.lib", "avformat.lib", "avutil.lib", "postproc.lib", "swresample.lib", "swscale.lib" }; foreach (string lib in libs) { PublicAdditionalLibraries.Add(Path.Combine(ModuleDirectory, prefixDir, "lib", lib)); } string[] dlls = { "avcodec-59.dll", "avdevice-59.dll", "avfilter-8.dll", "avformat-59.dll", "avutil-57.dll", "swresample-4.dll", "swscale-6.dll", "postproc-56.dll" }; foreach (string dll in dlls) { PublicDelayLoadDLLs.Add(dll); RuntimeDependencies.Add("$(PluginDir)/Binaries/ThirdParty/FFmpegMediaLibrary/Win64/" + dll); } } else if (Target.Platform == UnrealTargetPlatform.HoloLens) { isLibrarySupported = true; prefixDir = "arm64"; string[] libs = { "avcodec.lib", "avdevice.lib", "avfilter.lib", "avformat.lib", "avutil.lib", "postproc.lib", "swresample.lib", "swscale.lib" }; foreach (string lib in libs) { PublicAdditionalLibraries.Add(Path.Combine(ModuleDirectory, prefixDir, "lib", lib)); } string[] dlls = { "avcodec-59.dll", "avdevice-59.dll", "avfilter-8.dll", "avformat-59.dll", "avutil-57.dll", "swresample-4.dll", "swscale-6.dll", "postproc-56.dll" }; foreach (string dll in dlls) { PublicDelayLoadDLLs.Add(dll); RuntimeDependencies.Add("$(PluginDir)/Binaries/ThirdParty/FFmpegMediaLibrary/HoloLens/" + dll); } } virtual void StartupModule() override { FString BaseDir = IPluginManager::Get().FindPlugin("FFmpegMedia")->GetBaseDir(); #if PLATFORM_WINDOWS || PLATFORM_HOLOLENS #if PLATFORM_WINDOWS //开始d动态加载ffmpeg dll文件 FString avcodeLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/Win64/avcodec-59.dll")); FString avdeviceLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/Win64/avdevice-59.dll")); FString avfilterLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/Win64/avfilter-8.dll")); FString avformatLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/Win64/avformat-59.dll")); FString avutilLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/Win64/avutil-57.dll")); FString postprocLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/Win64/postproc-56.dll")); FString swresampleLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/Win64/swresample-4.dll")); FString swscaleLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/Win64/swscale-6.dll")); #else FString avcodeLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/HoloLens/avcodec-59.dll")); FString avdeviceLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/HoloLens/avdevice-59.dll")); FString avfilterLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/HoloLens/avfilter-8.dll")); FString avformatLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/HoloLens/avformat-59.dll")); FString avutilLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/HoloLens/avutil-57.dll")); FString postprocLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/HoloLens/postproc-56.dll")); FString swresampleLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/HoloLens/swresample-4.dll")); FString swscaleLibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/FFmpegMediaLibrary/HoloLens/swscale-6.dll")); #endif AVUtilLibrary = !avutilLibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*avutilLibraryPath) : nullptr; SWResampleLibrary = !swresampleLibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*swresampleLibraryPath) : nullptr; PostProcLibrary = !postprocLibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*postprocLibraryPath) : nullptr; SWScaleLibrary = !swscaleLibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*swscaleLibraryPath) : nullptr; AVCodecLibrary = !avcodeLibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*avcodeLibraryPath) : nullptr; AVFormatLibrary = !avformatLibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*avformatLibraryPath) : nullptr; AVFilterLibrary = !avfilterLibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*avfilterLibraryPath) : nullptr; AVDeviceLibrary = !avdeviceLibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*avdeviceLibraryPath) : nullptr; if (!(AVUtilLibrary && SWResampleLibrary && PostProcLibrary && SWScaleLibrary && AVCodecLibrary && AVFormatLibrary && AVFilterLibrary && AVDeviceLibrary)) { FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("LoadLibraryError", "Failed to load ffmpeg library")); } #endif //av_register_all(); //ffmpeg注册组件,ffmpeg5中已经不存在 avformat_network_init(); //初始化ffmpeg网络库 UE_LOG(LogFFmpegMedia, Display, TEXT("FFmpeg AVCodec version: %d.%d.%d"), LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO); UE_LOG(LogFFmpegMedia, Display, TEXT("FFmpeg license: %s"), UTF8_TO_TCHAR(avformat_license())); av_log_set_level(AV_LOG_INFO); av_log_set_flags(AV_LOG_SKIP_REPEATED); av_log_set_callback(&log_callback); Initialized = true; } TTS接口#

不要使用UE5中的TextToSpeech插件,测试不能使用,可以直接调用WinRT

FTTSSpeaker::FTTSSpeaker() { auto voices = Synthesizer.AllVoices(); // std::wstringstream ws; // auto v = Synthesizer.DefaultVoice(); // 设置声音源 for (const auto &v : voices) { if (v.DisplayName() == L"Microsoft Yaoyao") { UE_LOG(LogTemp, Log, TEXT("Set voice")); Synthesizer.Voice(v); } // ws.clear(); // ws


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3