【unity】Vulkan模式下部分Android机型使用VideoPlayer组件播放视频异常问题

一、问题背景

考虑到Vulkan高性能的优势,项目组决定打包设置为vulkan优先,opengl es次之的方案;但由于部分低端设备或者部分模拟器对Vulkan的兼容性良莠不齐,导致诸如使用VideoPlayer组件无法正常播放视频等问题频发,而这些问题在opengl es模式下不存在。鉴于Unity官方未在2022系列修复该问题,以及本项目优先使用Vulkan模式的需求,本方案决定在UnityPlayerActivity.java源文件或者自定义的UnityPlayerActivity入手,检测设备是否支持特定特性,进而显示指定以哪种模式启动unity运行时。

二、问题原因

根据问题设备日志可以发现,视频为正常播放的根本原因可能原因在于设备厂商在定制vulkan驱动时,未充分兼容其所需特性,甚至不支持指定特性,并且在回退操作中可能处理不恰当,进而导致视频播放异常。

unity中在移动平台下对mp4视频文件默认处理成H264编码格式(对应MIME为"video/avc"),在运行时优先使用硬件解码,在不支持硬件解码时回退到软件解码,而部分设备在vulkan模式下这个回退操作有问题,因此在启动unity运行时前先检测视频解码器是否支持硬件解码,支持则走vulkan模式,不支持则走opengl es模式;对于部分特殊较老设备即使支持硬件解码也会有问题,直接过滤解码器关键字,强制设为opengl es模式。

三、解决办法

在UnityPlayerActivity.java源文件中新加硬件加速检测方法,并在unity运行时启动前检测,根据检测结果设置unity运行时启动参数,vulkan为"-force-vulkan",opengl es为"-force-opengl";

java 复制代码
  //判断指定MimeType视频在当前平台下是否支持硬件加速,不支持的话,在vulkan模式下大概率无法播放视频,则切换为opengl es模式   
    public boolean isHardwareDecodeSupported(String mimeType) {
        Log.e("User", "---------------------------------mimeType Check-------------------------------");
        MediaCodecList codecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
        ArrayList<String> ignoreList=new ArrayList<>();
        ignoreList.add("mtk");//mtk的soc比较低端,很容易出问题,直接忽略
        boolean _s = false;
        for (MediaCodecInfo codecInfo : codecList.getCodecInfos()) {
            if (codecInfo.isEncoder()) continue; // 仅检查解码器
            for (String type : codecInfo.getSupportedTypes()) {
                if (type.equalsIgnoreCase(mimeType)) {
                    String name = codecInfo.getName().toLowerCase();
                    Log.e("User", "decoder name:" + name);
                    // 检查是否为硬件加速
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                        boolean support = false;
                        try {
                            support = codecInfo.isHardwareAccelerated();
                            if (support) {
                                for (String ignore:ignoreList){
                                    if (name.contains(ignore)) {
                                        Log.e("User", "ignore:" + name);
                                        return false;
                                    }
                                }

                            }
                        } catch (Exception e) {
                            Log.e("User", "isHardwareAccelerated not find");
                        }
                        if (support)
                            Log.e("User", "HardwareAccelerate support:true");
                        else
                            Log.e("User", "HardwareAccelerate support:false");
                        if (!_s && support) {
                            _s = support;
                        }
                    }
                }
            }
        }
        return _s;
    }
java 复制代码
// Setup activity layout
    @Override protected void onCreate(Bundle savedInstanceState)
    {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);

        String cmdLine = updateUnityCommandLineArguments(getIntent().getStringExtra("unity"));
		
        boolean vulkansupport=isHardwareDecodeSupported("video/avc");// H.264 的 MIME 类型为 video/avc
        if(vulkansupport){
            cmdLine+=" -force-vulkan";
            Log.e("User","start in Vulkan mode!"+cmdLine);
        }else{
            cmdLine+=" -force-gles";
            Log.e("User","start in OpenGL ES mode!"+cmdLine);
        }
		
        getIntent().putExtra("unity", cmdLine);

        mUnityPlayer = new UnityPlayer(this, this);
        setContentView(mUnityPlayer);
        mUnityPlayer.requestFocus();
    }

引入依赖的java类

java 复制代码
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import java.util.ArrayList;

四、相关参考

1、https://blog.csdn.net/gaozhaoyuyu/article/details/136299359

2、https://forum.unity.com/threads/videoplayer-dont-play-well-on-android-with-exynos-2100-s21-ultra.1460107/

3、https://forum.unity.com/threads/video-lags-on-android-device-in-unity-version-2022-3-14f1.1529137/#post-9541912

相关推荐
XR-AI-JK2 小时前
Unity VR/MR开发-VR设备与适用场景分析
unity·vr·mr
ChiLi_Lin3 小时前
Unity异常上报飞书工具
unity·游戏引擎·飞书
Magnum Lehar5 小时前
vulkan游戏引擎的makefile启动环境实现
游戏引擎
地狱为王13 小时前
基于VLC的Unity视频播放器(四)
unity·游戏引擎·音视频
14 小时前
Unity与Excel表格交互热更方案
unity·游戏引擎·excel
量子炒饭大师1 天前
项目实战——C语言扫雷游戏
c语言·开发语言·游戏
Thomas游戏开发1 天前
Unity3D 逻辑代码性能优化策略
前端框架·unity3d·游戏开发
装大炮的自行车1 天前
【Unity】R3 CSharp 响应式编程 - 使用篇(集合)(三)
windows·unity·游戏引擎
阿松爱学习1 天前
【Unity开发】控制手机移动端的震动
unity·游戏引擎·unity开发
快乐觉主吖1 天前
Unity安卓平台开发,启动app并传参
android·unity·游戏引擎