彻底解决unity universal media player PC平台打包报错问题


前言

UMP是个播放视频流的老插件了。由于其早已停止维护,在Unity较新版本中出现了致命Bug,导致其无法在PC包中正确获取Dll库(其他平台未测),经过我两天的断点调试和魔改,目前PC版本已正确运行。
本文主要能解决以下几个问题,如果你遇到的是其他问题也不妨看看,可能也会有所启发。
1、打PC包后运行时报错,找不到dll
2、打PC包后运行时报错,加载dll失败
3、在本机运行时完全没有报错,但只要放到其他机器上就报错
4、第一次打包时没有报错,但第二次及之后打包就报错
这些Bug的根源都指向同一个问题,应用本文的修复步骤后,理论上能一并解决。


一、解决找不到Dll

1.问题溯源

首先发现的问题就是,原本应该在打包时被放入Plugins根目录的三个dll——libvlc.dll、libvlccore.dll以及UniversalMediaPlayer.dll,被错误拷贝到Plugins/x86_64文件夹下了。

于是我尝试把三个dll移动出来,再次运行程序,报错就消失了。

然而至此,我只能通过每次手动移动dll的方式解决问题,这肯定是不妥的,得找出问题的根源。

经过一番比较后,我发现这三个文件的导入配置使用了Unity内置的插件导出逻辑,而plugins文件夹的则使用了插件自定义的PostBuild脚本,猜测Unity的插件导出逻辑会自动为dll增加父文件夹。

另外有人反馈用2019版本的Unity就没有这个bug,让我高度怀疑是2020版本增加的新特性引入了Bug,后来一查才知道,2020版本确实引入了新的Plugin文件规则

2.解决方案

首先就是将这三个dll的导入设置中的Standalond取消勾选,既然Unity自动导出的这么不靠谱,那么我们干脆不用它了!我们自己写代码把它们导出到正确位置就是了!
在这里插入图片描述
随后我们找到 UMPPostBuilds 脚本,这个就是插件在打包时拷贝 plugins文件夹 的脚本了,只需要在这里改一把,把那三个dll也一起拷贝到Plugins文件夹就行了。
我们先在脚本任意位置插入下面这段新的代码。这是因为以前的 CopyPlugins 方法比较局限,居然不能复制完整的文件结构,于是我只好用递归的方式重新写了一个,现在不管是根目录还是嵌套更多层文件夹都能通通复制出去了:

private static void CopyFullPlugins(string sourcePath, string targetPath)
    {
        string fileName = string.Empty;

        // CopyFiles
        var rootFiles = Directory.GetFiles(sourcePath);
        if (!Directory.Exists(targetPath))
            Directory.CreateDirectory(targetPath);
        foreach (var s in rootFiles)
        {
            if (Path.GetExtension(s).Equals(".meta"))
                continue;

            fileName = Path.GetFileName(s);
            CopyPluginFile(s,Path.Combine(targetPath, fileName));
        }

        string[] directories = Directory.GetDirectories(sourcePath);

        foreach (var d in directories)
        {
            CopyFullPlugins(d, Path.Combine(targetPath, Path.GetFileName(d)));
        }
    }

随后我们找到 BuildWindowsPlayer64 这个方法,里面有个CopyPlugins的方法,直接替换成我们的方法,顺便路径也要改一改,建议直接复制下面这行,替换掉原来的:

CopyFullPlugins(settings.AssetPath + "/Plugins/Win/x86_64/", dataPath + "/Plugins/");

最后就是开心的打包,运行程序,插件已正常运行起来了!
然而!事情到此还并没有完全结束。
此时你可以试着将包体放到一个中文目录下,再尝试运行。
哦吼,一个新的报错弹了出来,插件又JJ了!老外的插件不支持中文目录太常见了,不过这个也可以魔改。

二、解决加载Dll失败

原因其实就是加载Dll的方法不支持中文目录,其实已经有其他大佬写过了,我就不重复造车轮了,写得很细致,可以直接前往查看
解决完这一步之后,理论上所有的Bug及隐患就都排除了,看到这里可以点击关闭了,但如果对Bug3、4的成因很好奇,可以接着往下看。

三、第3、4种Bug的成因

这两条可以归结为一条,虽然根本原因是因为第一个Bug,但如此诡异的表现要归功于这个插件查找dll路径时坑爹的容错设计!

首先,UMPSettings 里有个开关_useExternalLibraries ,你可以通过它配置使用内置Dll还是外部Dll,如果打开它,你可以继续配置 _librariesPath 指定外部Dll路径,这个路径默认指向工程文件中的Dll的绝对路径。此时,如果你按这个配置打包,在自己的电脑上跑是不会报错的,但一旦复制到其他电脑上,马上就跑不起来了!因为别人电脑上可没有你的工程。

但是,我们默认不会打开这个开关啊,怎么还是会出现同样的问题呢——这时候它的容错设计就出场了。一般来说,如果我们设置了使用内置Dll,当打包后内置Dll的路径已经不对的情况下,程序应该立刻抛出错误了对吧,但实际上它又偷偷做了一件事,就是返回了默认的 _librariesPath。由于这个默认值指向了你的工程文件Dll,于是,你在自己电脑上无论怎么测试都没有报错,而把包体发给客户之后就翻了车,这插件的作者真TM是个人才!

而另一个问题,只有第一次打包正常,后面就报错,是它打包时有个自动搜索外部Dll的代码,这段代码只有在第一次打包时运转正常,后面的打包可能因为Unity会在C盘生成临时目录的缘故,最后检索到的都是C盘的一个不存在的路径。于是最后内置Dll没有找到,外部Dll路径也是错的,第一次打包之后的所有包都会报错。

但好在解决了Bug1之后,这两个问题也迎刃而解了,因此不再赘述。


总结

其实这个bug本来是个很好解决的问题,但因为它自以为是的容错设计,给我们查找问题带来了非常多的阻碍,因此在设计程序时,尽早地暴露问题,而不是尽力掩盖问题,是避免出现重大Bug的好习惯之一。

  • 14
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Unity3D是一款广泛用于游戏和应用程序开发的跨平台开发引擎。Universal Media Player(UMP)是Unity3D的一个插件,专门用于播放多媒体文件。在使用Unity3D和UMP完成媒体播放任务时,经常会遇到需要重新连接的情况。 在Unity3D中,要实现UMP的重新连接,可以按照以下步骤进行操作: 1. 在Unity3D项目中,确保已经正确导入UMP插件,并添加UMP的相关脚本。 2. 首先,需要确定何时需要重新连接UMP。例如,在连接UMP时可能会出现网络中断、文件丢失等情况。在这些情况下,通过监测UMP的状态来确定是否需要重新连接。 3. 当需要重新连接时,首先需要断开当前的UMP连接。可以通过调用UMP的断开连接函数或者重置UMP实例来完成。 4. 接下来,重新配置UMP的连接参数。例如,如果使用网络连接,则需要重新设置IP地址、端口号等参数。如果播放的是本地文件,需要重新设置文件路径。 5. 确定好重新连接的参数后,再次调用UMP的连接函数来重新连接。如果连接成功,UMP将开始播放媒体。 6. 在重新连接期间,可以在Unity3D中显示提示信息,告知用户正在重新连接中,以增强用户体验。 总之,Unity3D使用UMP进行重连的过程实际上就是先断开当前连接,然后重新配置连接参数并建立新的连接。理解UMP的连接函数和相关参数设置,能够帮助开发者更好地掌握UMP的重新连接机制,从而保证媒体播放的连贯性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值