Playing videos and music is a popular activity on Android devices. The Android framework provides MediaPlayer as a quick solution for playing media with minimal code, and the MediaCodec andMediaExtractor classes are provided for building custom media players. The open source project, ExoPlayer, is a solution between these two options, providing a pre-built player that you can extend.

在安卓设备上,我们经常会需要播放视频和音频。Android framework 提供MediaPlayer 以便程序员能快速实现影音播放。同时,Android framework提供了MediaCodec 和MediaExtractor类,我们可以通过这两个类来实现自定义的媒体播放器。ExoPlayer就是一个介于现有Mediaplayer和自定义媒体播放器之间的预建播放器,同时我们通过还可以获得比原有Mediaplayer更多的扩展能力。

ExoPlayer supports features not currently provided by MediaPlayer, including Dynamic adaptive streaming over HTTP (DASH), SmoothStreaming, and persistent caching. ExoPlayer can be extended to handle additional media formats, and because you include it as part of your app code, you can update it along with your app.


This guide describes how to use ExoPlayer for playing Android supported media formats, as well as DASH and SmoothStreaming playback. This guide also discusses ExoPlayer events, messages, DRM support and guidelines for customizing the player.


Note: ExoPlayer is an open source project that is not part of the Android framework and is distributed separately from the Android SDK. The project contains a library and a demo app that shows both simple and more advanced use of ExoPlayer:

注意:ExoPlayer 是一个开源项目,它不属于Android framework ,并且是独立于Android SDK独立分发的。该项目包含一个library和一个demo,其中展示了ExoPlayer的简单应用及其高级定制。

  • ExoPlayer Library — This part of the project contains the core library classes.
  • Simple Demo — This part of the app demonstrates a basic use of ExoPlayer.
  • Full Demo — This part of the app demonstrates more advanced features, including the ability to select between multiple audio tracks, a background audio mode, event logging and DRM protected playback.



ExoPlayer is a media player built on top of the MediaExtractor and MediaCodec APIs released in Android 4.1 (API level 16). At the core of this library is the ExoPlayer class. This class maintains the player’s global state, but makes few assumptions about the nature of the media being played, such as how the media data is obtained, how it is buffered or its format. You inject this functionality through ExoPlayer’s prepare() method in the form of TrackRenderer objects.

ExoPlayer是建立在MediaExtractor and MediaCodec这两组api之上的播放器。

这两组api是在api 16 即Android 4.1发布的,所以ExoPlayer的支持的最小api是api 16,但是由于ExoPlayer的build.gradle的minSdkVersion为9,所以在api《16时,也可以使用ExoPlayer的部分功能ExoPlayer库的核心类是ExoPlayer类。该类维护了播放器的全局状态,同时也。比如如何获取媒体数据,如何缓冲以及是怎样的编码格式。

ExoPlayer provides default TrackRenderer implementations for audio and video, which make use of theMediaCodec and AudioTrack classes in the Android framework. Both renderers require a SampleSourceobject, from which they obtain individual media samples for playback. Figure 1 shows the high level object model for an ExoPlayer implementation configured to play audio and video using these components.

ExoPlayer基于MediaCodec and AudioTrack提供了默认的音视频的TrackRenderer实现。所有的renderers都需要SampleSource对象,ExoPlayer从SampleSource获得media samples 用于播放。图1展示了ExoPlayer是如何配置组合这些组件用于播放音视频的。


Figure 1. High level object model for an ExoPlayer configured to play audio and video using TrackRenderer objects


TrackRenderer processes a component of media for playback, such as video, audio or text. The ExoPlayer class invokes methods on its TrackRenderer instances from a single playback thread, and by doing so causes each media component to be rendered as the global playback position is advanced. The ExoPlayer library provides MediaCodecVideoTrackRenderer as the default implementations rendering video andMediaCodecAudioTrackRenderer for audio. Both implementations make use of MediaCodec to decode individual media samples. They can handle all audio and video formats supported by a given Android device (see Supported Media Formats for details). The ExoPlayer library also provides an implementation for rendering text called TextTrackRenderer.

 TrackRenderer可以处理媒体文件中的音频、视频以及文本。ExoPlayer会在一个单独的播放控制线程里调用TrackRenderer实例中的方法。这一方式使得每部分媒体组件都在播放时呈现出来ExoPlayer库默认提供了MediaCodecVideoTrackRenderer和MediaCodecAudioTrackRenderer 类来分别实现视频和音频的呈现。MediaCodecVideoTrackRenderer和MediaCodecAudioTrackRenderer 类都使用了MediaCodec 来对media samples解码。他们能够处理所有在 Supported Media Formats 列出的媒体格式。ExoPlayer还提供了TextTrackRenderer 来实现对文本的呈现。

The code example below outlines the main steps required to instantiate an ExoPlayer to play video and audio using the standard TrackRenderer implementations.


// 1. Instantiate the player.

// 2. Construct renderers.
MediaCodecVideoTrackRenderer videoRenderer =
MediaCodecAudioTrackRenderer audioRenderer =...
// 3. Inject the renderers through prepare.
.prepare(videoRenderer, audioRenderer);
// 4. Pass the surface to the video renderer.
// 5. Start playback.
.release();// Don’t forget to release when done!

For a complete example, see the SimplePlayerActivity in the ExoPlayer demo app, which correctly manages an ExoPlayer instance with respect to both the Activity and Surface lifecycles.

 如果需要看完整的实例,可以查看demo中的SimplePlayerActivity 类。实例代码中正确的展示了如何在 ActivitySurface 的生命周期中正确管理ExoPlayer实例



A standard TrackRenderer implementation requires a SampleSource to be provided in its constructor. ASampleSource object provides format information and media samples to be rendered. The ExoPlayer library provides FrameworkSampleSource and ChunkSampleSource. The FrameworkSampleSource class usesMediaExtractor to request, buffer and extract the media samples. The ChunkSampleSource class provides adaptive playback using DASH or SmoothStreaming, and implements networking, buffering and media extraction within the ExoPlayer library.

标准的TrackRenderer 实现需要在其构造函数中传入 SampleSource对象。

Providing media using MediaExtractor

使用 MediaExtractor 提供媒体

In order to render media formats supported by the Android framework, the FrameworkSampleSource class usesMediaExtractor for networking, buffering and sample extraction functionality. By doing so, it supports any media container format supported by the version of Android where it is running. For more information about media formats supported by Android, see Supported Media Formats.

The diagram in Figure 2 shows the object model for an ExoPlayer implementation usingFrameworkSampleSource.

为了呈现Android framework,支持的媒体格式。FrameworkSampleSource 类使用MediaExtractor组件来访问网络、缓冲以及采样提取等功能。如此一来,就能支持每一版本android所能支持的媒体格式了。关于格式支持的信息详见: Supported Media Formats.

图2展示了ExoPlayer 如何访问FrameworkSampleSource的对象模型


Figure 2. Object model for an implementation of ExoPlayer that renders media formats supported by Android usingFrameworkSampleSource

The following code example outlines how the video and audio renderers are constructed to load the video from a specified URI.


FrameworkSampleSource sampleSource =newFrameworkSampleSource(
, uri,null,2);
MediaCodecVideoTrackRenderer videoRenderer =newMediaCodecVideoTrackRenderer(
, playerActivity,50);
MediaCodecAudioTrackRenderer audioRenderer =newMediaCodecAudioTrackRenderer(

The ExoPlayer demo app provides a complete implementation of this code in DefaultRendererBuilder. TheSimplePlaybackActivity class uses it to play one of the videos available in the demo app. Note that in the example, video and audio are muxed, meaning they are streamed together from a single URI. TheFrameworkSampleSource instance provides video samples to the videoRenderer object and audio samples to the audioRenderer object as they are extracted from the media container format. It is also possible to play demuxed media, where video and audio are streamed separately from different URIs. This functionality can be achieved by having two FrameworkSampleSource instances instead of one.

ExoPlayer demo项目里面的DefaultRendererBuilder类中完整的包含了上面的代码。SimplePlaybackActivity 类使用其播放了一段视频。注意,在示例代码中,音频和视频是混合在一起的,这意味着视频流和音频流都来自于同一个uri。当采样数据从媒体容器中从提取出来时,FrameworkSampleSource 实例把视频采样输出到 videoRenderer 对象中,同时把音频采样输出到 audioRenderer 对象中。当然我们也可以播放音频和视频流分开的媒体,不过这需要我们建立两个FrameworkSampleSource 实例。

Providing media for adaptive playback


ExoPlayer supports adaptive streaming, which allows the quality of the media data to be adjusted during playback based on the network conditions. DASH and SmoothStreaming are examples of adaptive streaming technologies. Both these approaches load media in small chunks (typically 2 to 10 seconds in duration). Whenever a chunk of media is requested, the client selects from a number of possible formats. For example, a client may select a high quality format if network conditions are good, or a low quality format if network conditions are bad. In both techniques, video and audio are streamed separately.


ExoPlayer supports adaptive playback through use of the ChunkSampleSource class, which loads chunks of media data from which individual samples can be extracted. Each ChunkSampleSource requires aChunkSource object to be injected through its constructor, which is responsible for providing media chunks from which to load and read samples. The DashMp4ChunkSource and SmoothStreamingChunkSource classes provide DASH and SmoothStreaming playback using the FMP4 container format. The DashWebMChunkSourceclass uses the WebM container format to provide DASH playback.

ExoPlayer通过ChunkSampleSource 类来实现适应性播放功能。每个ChunkSampleSource 对象都需要在构造时注入一个ChunkSource 对象。我们通过ChunkSource 对象来加载采样数据,并输出成ChunkSampleSource 类需要的小块媒体数据。DashMp4ChunkSource 类和SmoothStreamingChunkSource 类分别提供了DASH和SmoothStreaming协议下的解决方案,不过这两个类支持的都是FMP4格式。DashWebMChunkSource类 则实现了DASH协议下使用WebM格式解析的解决方案。

All of the standard ChunkSource implementations require a FormatEvaluator and a DataSource to be injected through their constructors. The FormatEvaluator objects select from the available formats before each chunk is loaded. The DataSource objects are responsible for actually loading the data. Finally, theChunkSampleSources require a LoadControl object that controls the chunk buffering policy.

所有的标准ChunkSource 实现都需要在构造器中注入一个FormatEvaluator 对象 和一个 DataSource 对象。

The object model of an ExoPlayer configured for a DASH adaptive playback is shown in the diagram below. This example uses an HttpDataSource object to stream the media over the network. The video quality is varied at runtime using the adaptive implementation of FormatEvaluator, while audio is played at a fixed quality level。FormatEvaluator 对象会在每个数据块被加载之前选择可用的格式。  DataSource 对象负责实际加载数据。

最后,ChunkSampleSources 需要一个LoadControl 对象来控制数据块的缓冲策略。

The object model of an ExoPlayer configured for a DASH adaptive playback is shown in the diagram below. This example uses an HttpDataSource object to stream the media over the network. The video quality is varied at runtime using the adaptive implementation of FormatEvaluator, while audio is played at a fixed quality level.

下图展示了如何实现DASH 自适应播放。此例中通过HttpDataSource 对象从网络获取数据流。使用FormatEvaluator 时,音频流的质量是固定的,而视频流的质量则是在运行时不断变化的。


Figure 3. Object model for a DASH adaptive playback using ExoPlayer

The following code example outlines how the video and audio renderers are constructed.


Handler mainHandler = playerActivity.getMainHandler();
LoadControl loadControl =newDefaultLoadControl(
BandwidthMeter bandwidthMeter =newBandwidthMeter();

// Build the video renderer.
DataSource videoDataSource =newHttpDataSource(userAgent,
HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter);
ChunkSource videoChunkSource =newDashMp4ChunkSource(videoDataSource,
newAdaptiveEvaluator(bandwidthMeter), videoRepresentations);
ChunkSampleSource videoSampleSource =newChunkSampleSource(videoChunkSource,
MediaCodecVideoTrackRenderer videoRenderer =newMediaCodecVideoTrackRenderer(
0, mainHandler, playerActivity,50);

// Build the audio renderer.
DataSource audioDataSource =newHttpDataSource(userAgent,
HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter);
ChunkSource audioChunkSource =newDashMp4ChunkSource(audioDataSource,
newFormatEvaluator.FixedEvaluator(), audioRepresentation);
SampleSource audioSampleSource =newChunkSampleSource(audioChunkSource,
MediaCodecAudioTrackRenderer audioRenderer =newMediaCodecAudioTrackRenderer(

In this code, videoRepresentations and audioRepresentation are Representation objects, each of which describes one of the available media streams. In the DASH model, these streams are parsed from a media presentation description (MPD) file. The ExoPlayer library provides aMediaPresentationDescriptionParser class to obtain Representation objects from MPD files.

在这段代码中,videoRepresentations 和 audioRepresentation 是Representation 对象。它们各自表示了一种可用的媒体流。在DASH模型中,这些数据流从MPD文件中转换而来,这一转换过程通过MediaPresentationDescriptionParser 实现。

Note: Building Representation objects from MPD files is not required. You can build Representation objects from other data sources if necessary.


The ExoPlayer demo app provides complete implementation of this code in DashVodRendererBuilder. TheSimplePlaybackActivity class uses this builder to construct renderers for playing DASH sample videos in the demo app. It asynchronously fetches a specified MPD file in order to construct the requiredRepresentation objects. For an equivalent SmoothStreaming example, see theSmoothStreamingRendererBuilder class in the demo app.

ExoPlayer demo项目在 DashVodRendererBuilder 类中完全实现了这段代码。SimplePlaybackActivity使用DashVodRendererBuilder 构造了renders用以播放DASH样例视频。在demo中,异步获取了指定的MPD文件,来构建Representation 对象。同样地,demo中使用SmoothStreamingRendererBuilder 来实现相同的功能。

Format selection for adaptive playback


For DASH and SmoothStreaming playback, consider both static format selection at the start of playback and dynamic format selection during playback. Static format selection should be used to filter out formats that should not be used throughout the playback, for example formats with resolutions higher than the maximum supported by the playback device. Dynamic selection varies the selected format during playback, typically to adapt video quality in response to changes in network conditions.


Static format selection

When preparing a player, you should consider filtering out some of the available formats if they are not useable for playback. Static format selection allows you to filter out formats that cannot be used on a particular device or are not compatible with your player. For audio playback, this often means picking a single format to play and discarding the others.



For video playback, filtering formats can be more complicated. Apps should first eliminate any streams that whose resolution is too high to be played by the device. For H.264, which is normally used for DASH and SmoothStreaming playback, ExoPlayer’s MediaCodecUtil class provides a maxH264DecodableFrameSize()method that can be used to determine what resolution streams the device is able to handle, as shown in the following code example:

对视频播放来说,过滤格式会稍微复杂一些。首先应用要评估视频的分辨率是不是高过设备所能处理的分辨率。H.264这一格式通常在DASH和SmoothStreaming中采用,ExoPlayer的MediaCodecUtil 类专门提供了一个maxH264DecodableFrameSize()方法。该方法用于判断设备能处理哪一分辨率的视频。示例如下:

int maxDecodableFrameSize =MediaCodecUtil.maxH264DecodableFrameSize();
Format format = representation.format;
if(format.width * format.height <= maxDecodableFrameSize){
// The device can play this stream.
// The device isn't capable of playing this stream.

This approach is used to filter Representations in the DashVodRendererBuilder class of the ExoPlayer demo app, and similarly to filter track indices in SmoothStreamingRendererBuilder.

上面的代码展示了如何过滤Representations。这段代码在demo项目中的DashVodRendererBuilder 类可以看到。

SmoothStreamingRendererBuilder 也可以看到用类似的方法过滤track。

In addition to eliminating unsupported formats, it should be noted that the ability to seamlessly switch between H.264 streams of different resolution is an optional decoder feature available in Android 4.3 (API level 16) and higher, and so is not supported by all devices. The availability of an adaptive H.264 decoder can be queried using MediaCodecUtil, as shown in the following code example:

H.264和其他格式之间的无缝切换需要在Android 4.3 (API level 16) 及以上版本才支持。

如下示例,我们可以通过MediaCodecUtil 类来判断适配性。

boolean isAdaptive =MediaCodecUtil.getDecoderInfo(MimeTypes.VIDEO_H264).adaptive;

The MediaCodecVideoTrackRenderer class is still able to handle resolution changes on devices that do not have adaptive decoders, however the switch is not seamless. Typically, the switch creates a small discontinuity in visual output lasting around 50-100ms. For devices that do not provide an adaptive decoder, app developers may choose to adapt between formats at a single fixed resolution so as to avoid discontinuities. The ExoPlayer demo app implementation does not pick a fixed resolution.


MediaCodecVideoTrackRenderer 类仍然可以在没有自适应解码器的设备上处理分辨率的变化,但是切换过程并不是无缝的。这个切换会引发50-100ms的卡顿。如果要在没有自适应解码器的设备上避免卡顿,开发者可以选择使用固定的的分辨率。不过ExoPlayer里面并没有这一示例。

Dynamic format selection

During playback, you can use a FormatEvaluator to dynamically select from the available video formats. The ExoPlayer library provides a FormatEvaluator.Adaptive implementation for dynamically selecting between video formats based on the current network conditions.


This class provides a simple, general purpose reference implementation, however you are encouraged to write your own FormatEvaluator implementation to best suit your particular needs.


Player Events 


During playback, your app can listen for events generated by the ExoPlayer that indicate the overall state of the player. These events are useful as triggers for updating the app user interface such as playback controls. Many ExoPlayer components also report their own component specific low level events, which can be useful for performance monitoring.


High level events


ExoPlayer allows instances of ExoPlayer.Listener to be added and removed using its addListener() andremoveListener() methods. Registered listeners are notified of changes in playback state, as well as when errors occur that cause playback to fail. For more information about the valid playback states and the possible transitions between them, see the ExoPlayer source code.

ExoPlayer中可以通过addListener() 和removeListener() 方法,添加和删除ExoPlayer.Listener 实例。被注册的监听者会接收到播放时的状态变化以及异常。如果想进一步了解播放状态的细节,还有状态之间的转换等内容,请参看ExoPlayer的源代码。

Developers who implement custom playback controls should register a listener and use it to update their controls as the player’s state changes. An app should also show an appropriate error to the user if playback fails.


Low level events



In addition to high level listeners, many of the individual components provided by the ExoPlayer library allow their own event listeners. For example, MediaCodecVideoTrackRenderer has constructors that take aMediaCodecVideoTrackRenderer.EventListener. In the ExoPlayer demo app, SimplePlayerActivityacts as a listener so that it can adjust the dimensions of the target surface to have the correct height and width ratio for the video being played:

作为高级事件的补充,ExoPlayer的各个独立组件也会有他们自己的事件监听机制。比如MediaCodecVideoTrackRenderer 类就有一个接受MediaCodecVideoTrackRenderer.EventListener的构造函数。


publicvoid onVideoSizeChanged(int width,int height){
.setVideoWidthHeightRatio(height ==0?1:(float) width / height);

The RendererBuilder classes in the ExoPlayer demo app inject the activity as the listener, for example in theDashVodRendererBuilder class:

在demo应用中,RendererBuilder 类注入了activity作为监听者。代码如下:

MediaCodecVideoTrackRenderer videoRenderer =newMediaCodecVideoTrackRenderer(
0,mainHandler, playerActivity,50);

Note that you must pass a Handler object to the renderer, which determines the thread on which the listener’s methods are invoked. In most cases, you should use a Handler associated with the app’s main thread, as is the case in this example.

需要注意的是,你需要传递一个Handler 对象给renderer。这决定了监听者的方法在那个线程上调用。大部分情况下你可以直接像本例一样,传入主线程的handler。

Listening to individual components can be useful for adjusting UI based on player events, as in the example above. Listening to component events can also be helpful for logging performance metrics. For example,MediaCodecVideoTrackRenderer notifies its listener of dropped video frames. A developer may wish to log such metrics to track playback performance in their app.

如上述实例所示,监听独立组件的事件使得根据事件调整ui会更方便。监听组件的事件有助于记录性能指标。例如,MediaCodecVideoTrackRenderer 可以发送丢弃的视频帧数给监听者。开发者可以通过记录这些指标来追踪app的性能。

Many components also notify their listeners when errors occur. Such errors may or may not cause playback to fail. If an error does not cause playback to fail, it may still result in degraded performance, and so you may wish to log all errors in order to track playback performance. Note that an ExoPlayer instance always notifies its high level listeners of errors that cause playback to fail, in addition to the listener of the individual component from which the error originated. Hence, you should display error messages to users only from high level listeners. Within individual component listeners, you should use error notifications only for informational purposes.




Sending messages to components


Some ExoPlayer components allow changes in configuration during playback. By convention, you make these changes by passing asynchronous messages through the ExoPlayer to the component. This approach ensures both thread safety and that the configuration change is executed in order with any other operations being performed on the player.


The most common use of messaging is passing a target surface to MediaCodecVideoTrackRenderer:



Note that if the surface needs to be cleared because SurfaceHolder.Callback.surfaceDestroyed() has been invoked, then you must send this message using the blocking variant of sendMessage():

注意,如果SurfaceHolder.Callback.surfaceDestroyed() 被调用即surface被销毁时,我们需要发送一个阻塞消息给EXOPlayer:



You must use a blocking message because the contract of surfaceDestroyed() requires that the app does not attempt to access the surface after the method returns. The SimplePlayerActivity class in the demo app demonstrates how the surface should be set and cleared.

这么做的原因是因为,surface被销毁时,需要确保MediaCodecVideoTrackRenderer 不会再将数据写入已经释放的surface。


Customizing ExoPlayer

One of the main benefits of ExoPlayer over MediaPlayer is the ability to customize and extend the player to better suit the developer’s use case. The ExoPlayer library is designed specifically with this in mind, defining a number of abstract base classes and interfaces that make it possible for app developers to easily replace the default implementations provided by the library. Here are some use cases for building custom components:


  • TrackRenderer - You may want to implement a custom TrackRenderer to handle media types other than audio and video. The TextTrackRenderer class within the ExoPlayer library is an example of how to implement a custom renderer. You could use the approach it demonstrates to render custom overlays or annotations. Implementing this kind of functionality as a TrackRenderer makes it easy to keep the overlays or annotations in sync with the other media being played.
  • TrackRenderer - 我们可能会想要定制TrackRenderer 来处理视频和音频之外的其他媒体。TextTrackRenderer 就是一个自定义TrackRenderer -的实例。
  • SampleSource - If you need to support a container format not already handled by MediaExtractor or ExoPlayer, consider implementing a custom SampleSource class.
  • SampleSource - 如果你想要支持一个在MediaExtractor 或者 ExoPlayer的默认支持范围之外的容器格式。可以考虑实现自定义的SampleSource类。
  • FormatEvaluator - The ExoPlayer library provides FormatEvaluator.Adaptive as a simple reference implementation that switches between different quality video formats based on the available bandwidth. App developers are encouraged to develop their own adaptive FormatEvaluator implementations, which can be designed to suit their use specific needs.
  • FormatEvaluator - ExoPlayer library provides FormatEvaluator.Adaptive as
  • DataSource - ExoPlayer’s upstream package already contains a number of DataSource implementations for different use cases, such as writing and reading to and from a persistent media cache. You may want to implement you own DataSource class to load data in another way, such as a custom protocol or HTTP stack for data input.
  • DataSource - ExoPlayer的上级包名下已经包含了一系列DataSource 实现,比如从媒体缓存池读写数据等。
  • 你可以实现你自己的DataSource 类,以别的方式加载数据,比如自定义的协议或者HTTP stack 。

Custom component guidelines自定义组件的一些守则

If a custom component needs to report events back to the app, we recommend that you do so using the same model as existing ExoPlayer components, where an event listener is passed together with a Handler to the constructor of the component.

如果你得自定义组件需要有事件交互,我们推荐你使用和已有的ExoPlayer组件相同的编程模型。把 Handler 和事件监听者通过构造器传入组件中去。

We recommended that custom components use the same model as existing ExoPlayer components to allow reconfiguration by the app during playback, as described in Sending messages to components. To do this, you should implement a ExoPlayerComponent and receive configuration changes in its handleMessage()method. Your app should pass configuration changes by calling ExoPlayer’s sendMessage() andblockingSendMessage() methods.

对于组件的设置更改,我们也推荐你同已有的模型保持一致。不过这样的话,你需要实现ExoPlayerComponent ,在handleMessage()方法中接受配置的变更。按照这种模式实现的自定义组件,就可以和默认组件一样,通过调用sendMessage() 和blockingSendMessage() 方法来变更配置了。

Digital Rights Management


On Android 4.3 (API level 18) and higher, ExoPlayer supports Digital Rights Managment (DRM) protected playback. In order to play DRM protected content with ExoPlayer, your app must inject a DrmSessionManagerinto the MediaCodecVideoTrackRenderer and MediaCodecAudioTrackRenderer constructors. ADrmSessionManager object is responsible for providing the MediaCrypto object required for decryption, as well as ensuring that the required decryption keys are available to the underlying DRM module being used.

在安卓4.3及以上系统中,ExoPlayer可以支持DRM技术。但是为了播放drm内容,你需要将一个DrmSessionManager 注入到MediaCodecVideoTrackRenderer 和 MediaCodecAudioTrackRenderer 构造器中。DrmSessionManager 对象提供了一个用于解密的MediaCrypto 对象,当然也要确保解密的keys是有效的。

The ExoPlayer library provides a default implementation of DrmSessionManager, calledStreamingDrmSessionManager, which uses MediaDrm. The session manager supports any DRM scheme for which a modular DRM component exists on the device. All Android devices are required to support Widevine modular DRM (with L3 security, although many devices also support L1). Some devices may support additional schemes such as PlayReady.

ExoPlayer库提供了一个默认的DrmSessionManager 实现,叫做StreamingDrmSessionManager。StreamingDrmSessionManager 有用到MediaDrm. StreamingDrmSessionManager 支持任意一种设备支持的DRM架构。基本上,所有的安卓设备都支持Widevine modular DRM。也有一些设备能支持其他架构。

The StreamingDrmSessionManager class requires a MediaDrmCallback to be injected into its constructor, which is responsible for actually making provisioning and key requests. You should implement this interface to make network requests to your license server and obtain the required keys. TheWidevineTestMediaDrmCallback class in the ExoPlayer demo app sends requests to a Widevine test server.

使用StreamingDrmSessionManager 类时,需要注入一个MediaDrmCallback 到构造器中。MediaDrmCallback 用于获取秘钥。你需要实现这个接口,并通过网络连接你的授权服务器来获取密钥。demo项目中的WidevineTestMediaDrmCallback 类就实现了通过网络连接 Widevine测试服务器以获取密钥。

posted @ 2014-08-04 16:15  lsjwzh  阅读(23801)  评论(0编辑  收藏  举报