ExoPlayer简析(一)

ExoPlayer是Google推出的一款非常优秀的视频播放器,具有非常好的灵活性和扩展性。

ExoPlayer主要组件类型

关于ExoPlayer的详细介绍可参考官方介绍.

简析的源码基于r2.8.1版本;

主要组件有:

  1. MediaSource:定义了将要播放的媒体源数据;(播放时创建)
  2. Renderer :渲染媒体数据;(ExoPlayer实例化时创建)
  3. TrackSelector:轨道选择器:从MediaSource中选择合适的轨道数据供Renderer渲染;(ExoPlayer实例化时创建)
  4. LoadControl:控制何时缓冲媒体数据,以及缓冲多少媒体数据。(ExoPlayer实例化时创建)

通过以上不同的组件,将数据的处理,媒体轨道的选择,媒体数据的渲染及加载单独处理;同时,以上提到的组件分别都是接口,在内部提供默认实现,实例化时可由使用者提供自定义实现。通过以上两点实现业务分离,高度可定制化。

ExoPlayer性能

官方文档性能介绍中提到,使用SurfaceView会比TextureView节省30%的电量,因此推荐使用SurfaceView.

Should I use SurfaceView or TextureView?

SurfaceView has a number of benefits over TextureView for video playback:

  • Significantly lower power consumption on many devices.
  • More accurate frame timing, resulting in smoother video playback.
  • Support for secure output when playing DRM protected content.

SurfaceView should therefore be preferred over TextureView where possible. TextureView should be used only if SurfaceView does not meet your needs. One example is where smooth animations or scrolling of the video surface is required prior to Android N (see How do I get smooth animation/scrolling of video?). For this case, it’s preferable to use TextureView only when SDK_INT is less than 24 (Android N) and SurfaceView otherwise.

在播放音频时推荐使用MediaPlayer,因为MediaPlayer支持audio offload,此特性允许音频的处理运行在一个专用的进程中;而ExoPlayer不支持此特性的原因是因为android fragmework没有公开相应的接口(google有望在未来公开此接口);

ExoPlayer库压缩

针对依赖库压缩,通常采用的方式莫过于配置gradle,精简不使用的代码。在官方介绍中有个值得关注的细节:如果播放器仅支持部分特性即可实现功能,则可仅采用支持该特性的代码,不必将全部特性代码都引用。

Specify which Renderer implementations your app needs

If your app uses SimpleExoPlayer, be aware that by default the player’s renderers will be created using DefaultRenderersFactory. DefaultRenderersFactory depends on all of the Renderer implementations provided in the ExoPlayer library, and as a result none of them will be removed by ProGuard. If you know that your app only needs a subset of renderers, you can specify your own RenderersFactory instead. For example, an app that only plays audio can define a factory like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> private class AudioOnlyRenderersFactory implements RenderersFactory {
>
> private final Context context;
>
> public AudioOnlyRenderersFactory(Context context) {
> this.context = context;
> }
>
> @Override
> public Renderer[] createRenderers(
> Handler eventHandler,
> VideoRendererEventListener videoRendererEventListener,
> AudioRendererEventListener audioRendererEventListener,
> TextOutput textRendererOutput,
> MetadataOutput metadataRendererOutput,
> DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
> return new Renderer[] {new MediaCodecAudioRenderer(
> MediaCodecSelector.DEFAULT, eventHandler, audioRendererEventListener)};
> }
>
> }
>

And use it when instantiating SimpleExoPlayer instances, like:

1
2
3
> SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(
> new AudioOnlyRenderersFactory(context), trackSelector);
>

This will allow other Renderer implementations to be removed by ProGuard. In this particular example video, text and metadata renderers are removed.

在精简安装包时,依赖库通常是一个倍感无法下手的问题,以上的处理方式灵活的采用了ProGuard特性,自动去除未引用的代码,是一个可值得借鉴的思路。

0%