【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

相关推荐
每周报刊20 小时前
竞速座舱级视界:爱攻 AGP497UCZD 超宽 QDOLED 显示器解析
数据结构·游戏·计算机外设
zhchyun20081 天前
# 【Unity UI 进阶】仿 Element UI 打造企业级 Unity UI 组件库(06)
ui·unity·游戏引擎
SmalBox1 天前
【动态着色】Unity 实现全息投影着色器
unity3d·游戏开发·图形学
X12499281811 天前
无畏契约更新后卡顿掉帧怎么办?黑屏闪退、游戏打不开解决方法
游戏
wind100321 天前
VC++ 运行库 vcredist 安装失败|CLR 80131522 报错完整修复
开发语言·c++·游戏
Behaviour1 天前
Unity游戏HybridCLR 热更新接入实战
游戏·unity·游戏引擎
2601_966563521 天前
安卓单机游戏合集免费下载 内置修改版无限金币 2.3T 5000+游戏 无限金币、钻石、解锁全角色等修改
游戏
●VON1 天前
谁小时候不想要一个游戏修改器?我把电脑 Skill 做成了 Android 小助手
android·游戏·电脑
本原财经2 天前
卖游戏、筹H股,昆仑万维临IPO磨AI含金量
人工智能·游戏
LONGZETECH2 天前
新能源汽车动力电池实训教学痛点与虚拟仿真技术解决方案
c语言·3d·unity·架构·汽车·汽车教学软件