Android播放不清晰?看看软硬解

前言

产品同学反馈春季滋养计划第二节播放不清晰,在码率为500kbps(线上课程通用码率)、体积为72MB时机型表现如下。

手机型号 效果 是否可用于课程
iphone 6(常用) 画质清晰
iphone 7 画质清晰
iphone 5 画质清晰
OPPO A83 流动时明显马赛克 存在拖色 ×
OPPO A9 流动时明显马赛克 存在拖色 ×
小米 4LTE 流动时明显马赛克虚边 卡顿严重 ×
HUAWEI MATE30 还存在明显马赛克虚边情况 画质出现条纹 ×
HUAWEI MATE30 5G 流动时还存在少许明显马赛克虚边情况 ×
HUAWEI RHA 画质清晰
HUAWEI MRD 流动时会出现虚边 马赛克 ×
HUAWEI AMZ 流动时会出现虚边 马赛克 ×
HUAWEI P30 PRO 流动时会出现虚边 马赛克 ×
iphone 6S 快速流动会有虚边 没有马赛克 ×
iphone 6 快速流动会有轻微虚边 没有马赛克
iphone 7 快速流动会有轻微虚边 没有马赛克

Android9款机型中只有1款是符合标准的,其中8款都有虚边、马赛克等问题。

视频基本参数

分辨率视频是由连续的图像构成的。每一张图像,我们称为一帧(frame)。图像则是由像素(pixel)构成的。一张图像有多少像素,称为这个图像的分辨率。比如说1920×1080的图像,说明它是由横纵1920×1080个像素点构成。视频的分辨率就是每一帧图像的分辨率。

帧率一个视频,每一秒由多少图像构成,称为这个视频的帧率(frame-rate)。常见的帧率有24000/1001=23.976, 30000/1001=29.970, 60000/1001=59.940, 25.000, 50.000等等。这个数字是一秒钟内闪过的图像的数量。比如23.976,就是1001秒内,有24000张图像。视频的帧率是可以是恒定的(cfr, Const Frame-Rate),也可以是变化的(vfr, Variable Frame-Rate)

码流/码率码流(Data Rate)是指视频文件在单位时间内使用的数据流量,也叫码率或码流率,通俗一点的理解就是取样率,是视频编码中画面质量控制中最重要的部分,一般我们用的单位是kb/s或者Mb/s。一般来说同样分辨率下,视频文件的码流越大,压缩比就越小,画面质量就越高。码流越大,说明单位时间内取样率越大,数据流,精度就越高,处理出来的文件就越接近原始文件,图像质量越好,画质越清晰,要求播放设备的解码能力也越高。

视频画质

对最终用户而言,其只关心视频的文件大小和画面质量。其中画面质量包括:分辨率,清晰度和流畅度。

  • 流畅度:这个因素相对独立,其影响因素就是视频帧率(FPS) 

  • 分辨率:视频画面大小 

  • 清晰度:单位面积的画面所承载的信息。

在对视频进行评价时,就是当FPS和分辨率固定时,考察视频的清晰度。

获取视频参数

ffprobe -show_format /Users/youga/Documents/assets/mp4/act_10a.mp4
   Metadata:
    major_brand     : avc1
    minor_version   : 0
    compatible_brands: isomavc1
    creation_time   : 2020-04-02T08:20:15.000000Z
    Duration: 00:01:10.08, start: 0.000000, bitrate: 503 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1920x1080, 498 kb/s, 50 fps, 50 tbr, 50k tbn, 100k tbc (default)
    Metadata:
      creation_time   : 2020-04-02T08:20:15.000000Z
      handler_name    : GPAC ISO Video Handler

滋养计划第二节第10个动作视频信息:编码格式是H264格式(封装格式为AVC1),每一帧的数据表示为yuv420p,分辨率为1920×1080,码率为498Kbit/s,帧率为50 fps。

固定分辨率1920×1080、帧率50 fps,提高码率对比视频清晰度。在码率为1200kbps、体积为198MB时机型表现如下。

手机型号 效果 是否可用于课程
iphone 6(常用) 画质清晰
iphone 7 画质清晰
iphone 5 画质清晰
OPPO A83 画质清晰
OPPO A9 流动虚边 存在拖色 存在色块
小米 4LTE 存在拖色 存在色块 ×
HUAWEI MATE30 流动虚边 存在拖色 存在色块 ×
HUAWEI MATE30 5G 没有明显虚边马赛克 虚边轻微
HUAWEI RHA 画质清晰
HUAWEI MRD 快速流动会有轻微虚边 没有马赛克
HUAWEI AMZ 快速流动会有轻微虚边 没有马赛克
HUAWEI P30 PRO 快速流动会有轻微虚边 没有马赛克
iphone 6S 画面清晰
iphone 6 画面清晰
iphone 7 画面清晰

Android9款机型中只有7款是符合标准的,其中2款还存在些许问题。播放清晰度有明显的改善,但是视频体积增加了1.75倍。增大码率可以改善播放时的清晰度,但是这对用户的网络和我们的CDN费用是个巨大的挑战。

经过我在HUAWEI P30 PRO、HUAWEI MATE30两款机型测试,发现并不是春季滋养计划第二节有播放不清晰的问题,其他新课或多或少都有一些不清晰的问题,最终和产品同学沟通发现是一致的,播放不清晰的问题并不是个例。

由于线上的课程视频都是基于分辨率1920×1080、帧率50 fps、码率500kbps标准制作的,播放不清晰的问题又不是个例。那么优化这个问题就有两个出发点(1)视频本身(2)视频播放器。第一条上述已经有结论,下面着重看播放器对播放不清晰的影响。

PLMediaPlayer

视频播放器播放视频可以简单的理解为两个过程(1)视频解码(2)数据渲染,这两个过程下又有很多细分维度和因素会影响视频播放的清晰度。

回到播放器本身,观察过程(1)视频解码最主观影响影响的因素, 解码方式

// codec=AVOptions.MEDIA_CODEC_HW_DECODE,硬解
// codec=AVOptions.MEDIA_CODEC_SW_DECODE, 软解
// codec=AVOptions.MEDIA_CODEC_AUTO, 硬解优先,失败后自动切换到软解
// 默认值是:MEDIA_CODEC_SW_DECODE
avOptions.setInteger(AVOptions.KEY_MEDIACODEC,  AVOptions.MEDIA_CODEC_SW_DECODE);

项目中默认使用的解码方式为AVOptions.MEDIA CODEC SW_DECODE(软解),更改解码方式对比视频播放的清晰度。

神奇代码动态修改解码方式提高灵活度

//动态插入提供修改的界面
    private void addPlayerKit() {
            FloatingBoxManager boxManager = FloatingBoxManager.getInstance();
            final Class clazz = boxManager.getClass();
            final Field kits = clazz.getDeclaredField("kits");
            kits.setAccessible(true);
            List kitList = (List) kits.get(boxManager);
            kitList.add(new PlayerKit());
    }
    //保存设置
    mRgCodec.setOnCheckedChangeListener((group, checkedId) -> {
            int value = 0;
            switch (checkedId) {
                case R.id.rb_sw:
                    value = AVOptions.MEDIA_CODEC_SW_DECODE;
                    break;
                case R.id.rb_hw:
                    value = AVOptions.MEDIA_CODEC_HW_DECODE;
                    break;
                case R.id.rb_auto:
                    value = AVOptions.MEDIA_CODEC_AUTO;
                    break;
            }
            PersistencePreferencesUtil.putInt(AVOptions.KEY_MEDIACODEC, value);
        });
     //动态修改
         AVOptions avOptions = new AVOptions();
       avOptions.setInteger(AVOptions.KEY_MEDIACODEC, PersistencePreferencesUtil.getInt(AVOptions.KEY_MEDIACODEC, AVOptions.MEDIA_CODEC_SW_DECODE));

对比结果

HUAWEI P30上软下硬

HUAWEI MATE30上软下硬

Oppo r7上软下硬

OPPO A9 、HUAWEI MATE30 5G 、HUAWEI RHA、MI 4L TE 硬解明显优于软解,MRD-AL00、Honor 8C 硬解、软解差别不大(整体清晰度可以接受)。

Android9款机型中,有7款硬解明显优于软解,硬解后清晰度可以接受,2款机型硬解、软解差别不大清晰度可以接受。

总结

播放清晰度与视频本身和播放器的解码方式有关,改变视频本身参数成本较高,改变播放器的解码方式在Android9款机型中,有7款硬解明显优于软解,硬解后清晰度可以接受,2款机型硬解、软解差别不大清晰度可以接受。

由于国产设备机型差异,暂无法明确哪款手机应该选用哪种解码方式最优。目前项目中默认的解码方式为软解,建议修改默认解码方式为自动(优先硬解,硬解失败后自动切换为软解),同时借助产品优化的形式提供给用户可以切换解码方式的选项,明确告知用户当遇到播放不清晰时,可以选择切换解码方式,同时后台统计设备与解码方式的关联性,制定设备型号对应的最优解码方式,同时动态设置解码方式,提高用户体验。

备选项

Android播放器框架升级备忘 ,结合PLMediaPlayer现状以及遇到的问题,ExoPlayer 在HUAWEI MATE30上表现良好,升级播放器也是一个不错的选择。

拖地先生,从事互联网技术工作,在这里每周两篇文章,聊聊日常的实践和心得。往期推荐:

说说这个公众号

平均响应1000ms到200ms,PHP和Go那家强?

崩溃率从1%到0.02%,iOS稳定性解决之道

七招优化Android包体减少30%

技术产品职业瓶颈?29份腾讯通道材料教你成长

低头赶路,也别忘了抬头看天

加班能解决交付的期望么?

如果对你有帮助,让大家也看看呗~