am 533149d5: am fe3e71be: Merge "Update ExoPlayer developer guide." into lmp-docs

automerge: a40eb5d

* commit 'a40eb5db455ebb225a7ff0afa244256079d8cf20':
  Update ExoPlayer developer guide.
This commit is contained in:
Oliver Woodman
2015-02-17 22:27:16 +00:00
committed by android-build-merger
2 changed files with 27 additions and 29 deletions

View File

@@ -72,10 +72,8 @@ page.tags="audio","video","adaptive","streaming","DASH","smoothstreaming"
<ul> <ul>
<li><a class="external-link" href="https://github.com/google/ExoPlayer/tree/master/library"> <li><a class="external-link" href="https://github.com/google/ExoPlayer/tree/master/library">
ExoPlayer Library</a> &mdash; This part of the project contains the core library classes.</li> ExoPlayer Library</a> &mdash; This part of the project contains the core library classes.</li>
<li><a class="external-link" href="https://github.com/google/ExoPlayer/tree/master/demo/src/main/java/com/google/android/exoplayer/demo/simple"> <li><a class="external-link" href="https://github.com/google/ExoPlayer/tree/master/demo">
Simple Demo</a> &mdash; This part of the app demonstrates a basic use of ExoPlayer.</li> Demo App</a> &mdash; This part of the project demonstrates usage of ExoPlayer,
<li><a class="external-link" href="https://github.com/google/ExoPlayer/tree/master/demo/src/main/java/com/google/android/exoplayer/demo/full">
Full Demo</a> &mdash; This part of the app demonstrates more advanced features,
including the ability to select between multiple audio tracks, a background audio mode, including the ability to select between multiple audio tracks, a background audio mode,
event logging and DRM protected playback. </li> event logging and DRM protected playback. </li>
</ul> </ul>
@@ -137,9 +135,10 @@ player.setPlayWhenReady(true);
player.release(); // Dont forget to release when done! player.release(); // Dont forget to release when done!
</pre> </pre>
<p>For a complete example, see the {@code SimplePlayerActivity} in the ExoPlayer demo app, which <p>For a complete example, see {@code PlayerActivity} and {@code DemoPlayer} in the ExoPlayer demo
correctly manages an ExoPlayer instance with respect to both the {@link android.app.Activity} and app. Between them these classes correctly manage an ExoPlayer instance with respect to both the
{@link android.view.Surface} lifecycles.</p> {@link android.app.Activity} and {@link android.view.Surface} lifecycles.
</p>
<h2 id="samplesource">SampleSource</h2> <h2 id="samplesource">SampleSource</h2>
@@ -187,7 +186,7 @@ MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(
</pre> </pre>
<p>The ExoPlayer demo app provides a complete implementation of this code in <p>The ExoPlayer demo app provides a complete implementation of this code in
{@code DefaultRendererBuilder}. The {@code SimplePlaybackActivity} class uses it to play one {@code DefaultRendererBuilder}. The {@code PlayerActivity} class uses it to play one
of the videos available in the demo app. Note that in the example, video and audio 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. The {@code FrameworkSampleSource} are muxed, meaning they are streamed together from a single URI. The {@code FrameworkSampleSource}
instance provides video samples to the {@code videoRenderer} object and audio samples to the instance provides video samples to the {@code videoRenderer} object and audio samples to the
@@ -211,9 +210,9 @@ MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(
which loads chunks of media data from which individual samples can be extracted. Each {@code which loads chunks of media data from which individual samples can be extracted. Each {@code
ChunkSampleSource} requires a {@code ChunkSource} object to be injected through its constructor, ChunkSampleSource} requires a {@code ChunkSource} object to be injected through its constructor,
which is responsible for providing media chunks from which to load and read samples. The {@code which is responsible for providing media chunks from which to load and read samples. The {@code
DashMp4ChunkSource} and {@code SmoothStreamingChunkSource} classes provide DASH and SmoothStreaming DashChunkSource} class provides DASH playback using the FMP4 and WebM container formats. The
playback using the FMP4 container format. The {@code DashWebMChunkSource} class uses the WebM {@code SmoothStreamingChunkSource} class provides SmoothStreaming playback using the FMP4
container format to provide DASH playback.</p> container format.</p>
<p>All of the standard {@code ChunkSource} implementations require a {@code FormatEvaluator} and <p>All of the standard {@code ChunkSource} implementations require a {@code FormatEvaluator} and
a {@code DataSource} to be injected through their constructors. The {@code FormatEvaluator} a {@code DataSource} to be injected through their constructors. The {@code FormatEvaluator}
@@ -242,7 +241,7 @@ BandwidthMeter bandwidthMeter = new BandwidthMeter();
// Build the video renderer. // Build the video renderer.
DataSource videoDataSource = new HttpDataSource(userAgent, DataSource videoDataSource = new HttpDataSource(userAgent,
HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter); HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter);
ChunkSource videoChunkSource = new DashMp4ChunkSource(videoDataSource, ChunkSource videoChunkSource = new DashChunkSource(videoDataSource,
new AdaptiveEvaluator(bandwidthMeter), videoRepresentations); new AdaptiveEvaluator(bandwidthMeter), videoRepresentations);
ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource,
loadControl, VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); loadControl, VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true);
@@ -253,7 +252,7 @@ MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(
// Build the audio renderer. // Build the audio renderer.
DataSource audioDataSource = new HttpDataSource(userAgent, DataSource audioDataSource = new HttpDataSource(userAgent,
HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter); HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter);
ChunkSource audioChunkSource = new DashMp4ChunkSource(audioDataSource, ChunkSource audioChunkSource = new DashChunkSource(audioDataSource,
new FormatEvaluator.FixedEvaluator(), audioRepresentation); new FormatEvaluator.FixedEvaluator(), audioRepresentation);
SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource,
loadControl, AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); loadControl, AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true);
@@ -273,9 +272,8 @@ MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(
</p> </p>
<p>The ExoPlayer demo app provides complete implementation of this code in <p>The ExoPlayer demo app provides complete implementation of this code in
{@code DashVodRendererBuilder}. The {@code SimplePlaybackActivity} class uses this builder to {@code DashRendererBuilder}. The {@code PlayerActivity} class uses this builder to
construct renderers for playing DASH sample videos in the demo app. It asynchronously fetches a construct renderers for playing DASH sample videos in the demo app. For an
specified MPD file in order to construct the required {@code Representation} objects. For an
equivalent SmoothStreaming example, see the {@code SmoothStreamingRendererBuilder} class in the equivalent SmoothStreaming example, see the {@code SmoothStreamingRendererBuilder} class in the
demo app.</p> demo app.</p>
@@ -313,7 +311,7 @@ if (format.width * format.height &lt;= maxDecodableFrameSize) {
} }
</pre> </pre>
<p>This approach is used to filter {@code Representations} in the {@code DashVodRendererBuilder} <p>This approach is used to filter {@code Representations} in the {@code DashRendererBuilder}
class of the ExoPlayer demo app, and similarly to filter track indices in {@code class of the ExoPlayer demo app, and similarly to filter track indices in {@code
SmoothStreamingRendererBuilder}.</p> SmoothStreamingRendererBuilder}.</p>
@@ -372,24 +370,26 @@ boolean isAdaptive = MediaCodecUtil.getDecoderInfo(MimeTypes.VIDEO_H264).adaptiv
<p>In addition to high level listeners, many of the individual components provided by the <p>In addition to high level listeners, many of the individual components provided by the
ExoPlayer library allow their own event listeners. For example, {@code ExoPlayer library allow their own event listeners. For example, {@code
MediaCodecVideoTrackRenderer} has constructors that take a {@code MediaCodecVideoTrackRenderer} has constructors that take a {@code
MediaCodecVideoTrackRenderer.EventListener}. In the ExoPlayer demo app, {@code SimplePlayerActivity} MediaCodecVideoTrackRenderer.EventListener}. In the ExoPlayer demo app, {@code DemoPlayer}
acts as a listener so that it can adjust the dimensions of the target surface to have the correct acts as the listener to multiple individual components, forwarding events to {@code PlayerActivity}.
height and width ratio for the video being played:</p> This approach allows {@code PlayerActivity} to adjust the dimensions of the target surface
to have the correct height and width ratio for the video being played:</p>
<pre> <pre>
&#64;Override &#64;Override
public void onVideoSizeChanged(int width, int height) { public void onVideoSizeChanged(int width, int height, float pixelWidthAspectRatio) {
surfaceView.setVideoWidthHeightRatio(height == 0 ? 1 : (float) width / height); surfaceView.setVideoWidthHeightRatio(
height == 0 ? 1 : (width * pixelWidthAspectRatio) / height);
} }
</pre> </pre>
<p>The {@code RendererBuilder} classes in the ExoPlayer demo app inject the activity as the <p>The {@code RendererBuilder} classes in the ExoPlayer demo app inject the {@code DemoPlayer} as
listener, for example in the {@code DashVodRendererBuilder} class:</p> the listener to each component, for example in the {@code DashRendererBuilder} class:</p>
<pre> <pre>
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer( MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(
videoSampleSource, null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, sampleSource, null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
0, <strong>mainHandler, playerActivity</strong>, 50); null, <strong>player.getMainHandler(), player</strong>, 50);
</pre> </pre>
<p>Note that you must pass a {@link android.os.Handler} object to the renderer, which determines <p>Note that you must pass a {@link android.os.Handler} object to the renderer, which determines
@@ -441,9 +441,7 @@ player.blockingSendMessage(videoRenderer,
<p>You must use a blocking message because the contract of {@link <p>You must use a blocking message because the contract of {@link
android.view.SurfaceHolder.Callback#surfaceDestroyed surfaceDestroyed()} requires that the android.view.SurfaceHolder.Callback#surfaceDestroyed surfaceDestroyed()} requires that the
app does not attempt to access the surface after the method returns. The {@code app does not attempt to access the surface after the method returns.</p>
SimplePlayerActivity} class in the demo app demonstrates how the surface should be set and
cleared.</p>
<h2 id="customizing">Customizing ExoPlayer</h2> <h2 id="customizing">Customizing ExoPlayer</h2>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB