您的位置:首页 > 运维架构

ExoPlayer 开发者指导

2016-09-12 13:17 176 查看

ExoPlayer 开发者指导

字数2134
阅读12051 评论36
喜欢32

原文地址

想深入了解ExoPlayer的童鞋可以查看我的另外一篇文章:ExoPlayer源码浅析

Developer guide

在Android设备中,播放视频和音乐是非常普遍的。Android框架提供了一个对于媒体的操作的最省代码的解决方案:MediaPlayer。它提供了低等级的媒体API,例如:MediaCodecAudioTrackMediaDrm,可以用于建立自定义媒体播放的解决方案。

ExpPlayer是一个开源的,App等级的媒体API,它的开源项目包含了library和示例:

ExoPlayer library - 这部分是核心的库
Demo app - 这部分是演示怎么使用ExoPlayer的Demo

Pros and cons

ExoPlayer相较于MediaPlayer有很多很多的优点:

支持动态的自适应流HTTP(DASH) 和 平滑流,任何目前MediaPlayer支持的视频格式(同时它还支持HTTP直播了(HLS),MP4,MP3,WebM,M4A,MPEG-TS 和 AAC).
支持高级的HLS特性,例如正确处理
EXT-X-DISCONTINUITY
标签;
支持自定义和扩治你的使用场景。ExoPlayer专门为此设计;
便于随着App的升级而升级。因为ExoPlayer是一个包含在你的应用中的库,对于你使用哪个版本有完全的控制权,并且你可以简单的跟随应用的升级而升级;
更少的适配性问题。
值得注意的时,ExoPlayer同时有些缺点:

ExoPlayer的音频和视频组件依赖Android的
MediaCodec
接口,该接口发布于Android4.1(API 等级16)。因此它不能工作于之前的Android版本。
ExoPlayer目前还不支持自动检查需要播放的媒体格式。应用需要知道他想要播放的媒体格式去构建一个ExoPlayer去播放媒体。这个问题已经在Issue #438解决。

Library overview

在ExoPlayer的库中最重要的类是
ExoPlayer
,这个类维护着播放器的全局状态,和正在播放的媒体特质,例如怎么获取到的媒体数据,它使怎么缓存或者它的格式。你可以以
TrackRenderer
类的方式通过ExoPlayer的
prepare
方法注入。

ExoPlayer提供默认的音频和视频渲染器,利用了Android框架中的
MediaCodec
AudioTrach
类。这两个都需要一个
SampleSource
对象中注入,用来实现媒体示例的播放。

组件的注入在当前ExoPlayer库中是普遍存在的。图1展示了使用一个ExoPlayer来配置和播放MP4媒体流的高级对象模型。默认的音频和视频渲染器已经被注解到
ExoPlayer
中。一个叫
ExtractorSampleSource
类的实现被注解到渲染器中用于提供简单的媒体播放功能。
DataSource
Extractor
示例被注解到
ExtractorSampleSource
来支持加载媒体流和在被加载的数据中提取样板。在这个示例中
DefaultUriDataSource
Mp4Extractor
被用于播放从URIs中导入的MP4流。



图1.ExoPlayer中播放MP4的对象模型

总的来说,ExoPlayer实例被用来注解支持开发者需求的组件,这个模型使定制播放器变得非常简单,并支持自定义组件。以下部分介绍了在这个模型图种三个最最重要的部分:
TrackRender
,
SampleSource
DataSource


TrackRenderer

一个
TrackRenderer
播放特定类型的媒体,例如视频,音频和文字。ExoPlayer类在它的
TrackRenderer
上执行方法,使用单独的线程,因此,导致每种类型的媒体被渲染全局的播放位置,ExoPlayer库提供
MediaCodecVideoTrackRenderer
作为默认的实现用于渲染视频,
MediaCodecAudioTrackRender
渲染音频。两种实现都是利用Android的 MediaCodec
去解码每个媒体样本。他们可以处理所有Android设备支持的音频和视频格式(详细信息请看支持媒体类型)。ExoPlayer库也提供了一个渲染文本的渲染器
TextTrackRenderer


以下代码示例使用标准的
TrackRenderer
实现视频,音频播放需要的步骤:

//1.初始化播放器
player = ExoPlayer.Factory.newInstance(RENDERER_COUNT);
//2.构建渲染器
MediaCodecVideoTrackRender videoRender = ...
MediaCodecAudioTrackRender audioRender = ...
//3.通过prepare注入渲染器
player.prepare(videoRender,audioRender);
//4.将surface传递到渲染器
player.sendMessage(videoRender,MediaCodecVideoTrackRenderer.MSG_SET_SURFACE,surface);
//5.开始播放
player.setPlayWhenReady(true);
....
player.release(); //当播放完成,别忘了释放!

想看完整的例子,请在ExoPlayer demo app中查看
PlayerActivity和
DemoPlayer
。其中详细的示范如何使用ExoPlayer实例,以及
Activity
Surface`的生命周期。

SampleSource

库中提供标准的
TrackRenderer
实现需要
SampleSource
实例被注入到他们的构造方法中。一个
SampleSource
对象提供了格式信息,和被渲染的媒体样本。ExoPlayer库提供了一些不同类型的
SampleSource
实例:

ExtractorSampleSource
- 用于MP3,M4A,WebM,MPEG-TS和AAC;
ChunkSampleSource
- 用于DASH和平滑流的播放;
HlsSampleSource
- 用于HLS 播放;
后面的部分会详细介绍这些实例的使用。

DataSource

ExoPlayer库提供的标准的
SampleSource
实例是利用了
DataSource
来加载媒体数据的。各种类型的实现都放在
upstream
包种。最最多用到的实现是:

DefaultUriDataSource
- 用于播放本地和网络媒体;
AssetDataSource
- 用于播放应用中
assets
文件夹下的媒体。

Traditional media playbacks

Explayer库提供了
ExtractorSampleSource
用于播放传统格式的媒体,包括MP3,M4A,MP4,WebM,MPEG-TS和AAC,图1中展示了ExoPlayer播放MP4流的对象模型,以下代码展示了如何构造和实例化
TrackRenderer


DataSource dataSource = new DefaultUriDataSource(userAgent, null);
Mp4Extractor extractor = new Mp4Extractor();
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
uri, dataSource, extractor, 2, BUFFER_SIZE);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(
sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);

每种类型的媒体格式都需要一个对应的解析器(
Extractor
)。在ExoPlayer库的
extractor
包种包含了不同类型的解析器,你可以实现你自己的解析器,如果库中不包含你需要的类型的话。

ExoPlayer的示例代码中提供了一个完整的
ExtractorRendererBuilder
的示例。
PlayerActivity
使用它播放一些可用的视频。

Adaptive media playbacks

ExoPlayer 支持自适应流,即在播放的时候,根据网络状况自动调节视频质量。DASH,SmoothStreaming和HLS展示了自适应流技术。以上三种,媒体都是通过小块的方式加载(通常2到10秒的长度)。每当一块媒体被请求,客户端将会选择一种可能的规格。例如:如果网络情况比较好,客户端将选择高质量的规格,如果网络比较差则会低质量的。在两种技术中,视频和音频都需要被分割。

DASH android SmoothStreaming

ExoPlayer库通过
ChunkSampleSource
支持DASH和SmoothStreaming动态播放,即通过读取独立的媒体块。每个
ChunkSampleSOurce
需要一个
ChunkSource
通过构造方法注入进来。
ChunkSource
主要负责加载和读取样本来提供媒体块。
DashChunkSource
类使用FMP4和WebM容器格式来提供DASH播放。
SmoothStreamingChunkSource
类使用FMP4容器格式。

两种类型的
ChunkSource
实例需要一个解析器
FormatEvaluator
和一个数据源
DataSource
通过构造的方式注入。
FormatEvaluator
在每个块被加载之前选择一种可用的格式,
DataSource
提供数据源。最终,
ChunkSampleSource
需要一个
LoadControl
对象去控制缓冲块。

图2演示了DASH动态播放通常的配置。通过
FormatEvaluator
实现视频质量的动态变化,但是音频的质量是固定的。



图2:DASH动态播放对象模型

这部分动态视频流暂时用不着,以后有机会翻译...

Player events

在播放阶段,你的App可以收到所有ExoPlayer产生的时间,这些事件对于提升用户体验有很大的帮助,如对播放的控制。一些ExoPlayer组件还提供了他们自己底层的事件,可以监听性能。

High level events

ExoPlayer允许通过
addListener()
removeListener()
的方式添加
ExoPlayer.Listener
实例,被注册的监听器将会得到播放状态的回调,还要错误导致的播放失败,如果需要知道更多的播放状态和可能的状态直接的相互转换,请查阅ExoPlayer源码。

Low level events

除了高级事件,个别的组件还允许监听他们自己的时间,例如,
MediaCodecVideoTrackRenderer
的构造方法提供了
MediaCodecVideoTrackRenderer.EventListener
。在ExoPlayer的demo中,这给
PlayerAcitivity
调整目标surface的尺寸到合适的高度和宽度的途径。

@Override
public void onVideoSizeChanged(int width, int height, float pixelWidthAspectRatio) {
surfaceView.setVideoWidthHeightRatio(
height == 0 ? 1 : (width * pixelWidthAspectRatio) / height);
}

Customization

懒得翻译了...

转载请注明出处:
http://www.jianshu.com/p/3251a5189f56
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: