ExoPlayer如何使用MediaExtractor的思路

说明:以下内容均为基于网络公开的ExoPlayer官方源码进行的解读

OldExo源码本体也是来源于Github并非涉及任何公司相关任何代码

本文主要针对于,自己的设备解码能力(比如底层集成ffmpeg 、qti、android 、需要付费的格式等等)大于ExoPlayer自己封装的固有Extractor,基于现在Android架构通俗的来说,就是MediaPlayer可以播,但是ExoPlayer播不了的情况。

底层集成的优势在于,不需要每个app都来集成,那样每个app都非常庞大,工作繁琐也很难以统一,第三方app使用系统播放器也没有相关的能力。

ExoPlayer现在已被集成到Media3.AndroidX,但仍然没有解决此问题。

ExoPlayer如何使用MediaExtractor的思路_第1张图片

 通过寻找多年历史的蛛丝马迹,我们可以看到,是因为每台设备的解码能力不同,而且在我们实际开发中,会发现有些文件duration等一些参数存在问题,需要兼容。ExoPlayer作为一个通用播放器不可能面面俱到,故舍弃了此方案,选用了需要明确指出Extractor的方案。

该方案会导致,明明底层软硬解支持的情况下,却会因为封装视频container组合的不符合Exo

固有的Extractor组合直接抛出失败异常,一般呈现Source Error非常模糊,这一点需要这篇文章的人相信已经有了深刻的理解

ExoPlayer现版本,需要指定Extractor,或者通过ffmpeg拓展格式,但这回导致设备底层原本支持的格式会出现不支持,如果你是做自己的设备,比如手机、平板、车载等,你是明确知道能力的。

核心修改思想如下,咱们长话短说,下面是我简化整理的,ExoPlayer解码过程,和codec解码过程的区别,其核心就是替换的Extractor的read过程,也就是将inputBufff填满的过程。所以如果想打通就必须再次进入Android.MediaExtractor

ExoPlayer如何使用MediaExtractor的思路_第2张图片

所以说我们想要对接底层的解码能力,就必须换掉ExoExtractor,不需要再去遍历sniff,换为通用的MediaExtractor,让其走到底层,自行去寻找分发软硬解能力。

ExoPlayer如何使用MediaExtractor的思路_第3张图片

再根据上述我整理的api调用图,可以看到,Extractor在exo中是通过sniff打分来判断是执行哪个真正的Extractor。经过层层封装最终其实在MediaSource中创建最初的Factory。所以

思路1:就是替换整个MediaSoure,使其直接走codec原始调用。
思路2:是自定义通用Extractor,sniff放到最前面且始终返回true,再对接Extractor.read

目前我们先实现思路1

想要既使用ExoPlayer的Api又对接底层解码能力的记录 ,我们需要改掉read填充buffer的部分

ExoPlayer如何使用MediaExtractor的思路_第4张图片

FrameworkSampleSource sampleSource = new FrameworkSampleSource(
                context, uri, null);

        MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
                sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
                mainHandler, player, 50);
        MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
                MediaCodecSelector.DEFAULT, null, true, mainHandler, player,
                AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
        TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
                mainHandler.getLooper());

FrameworkSampleSource相关代码已经在ExoPlayer,Github上被删除,先贴上谷歌历史代码,基于此思路基本可以打通,就整合代码替换繁琐,后续补充详细整改资源,

https://github.com/RexSuper/ExoPlayeOldDemo

你可能感兴趣的:(ExoPlayer,Android,视频播放器,MediaCodec)