From a2e9e27f4c87112dfd27ced16254a4736180cd4f Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Mon, 16 Feb 2015 17:49:34 +0000 Subject: Update ExoPlayer developer guide. This is a minimal update, just to fix things that are broken or no longer make sense as of the v1.2.0 release. Change-Id: If519709c91c975d96b62e2dd28e18e2105735c2b --- docs/html/guide/topics/media/exoplayer.jd | 56 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'docs/html/guide/topics') diff --git a/docs/html/guide/topics/media/exoplayer.jd b/docs/html/guide/topics/media/exoplayer.jd index 17b4669..1e8601f 100644 --- a/docs/html/guide/topics/media/exoplayer.jd +++ b/docs/html/guide/topics/media/exoplayer.jd @@ -72,10 +72,8 @@ page.tags="audio","video","adaptive","streaming","DASH","smoothstreaming" @@ -137,9 +135,10 @@ player.setPlayWhenReady(true); player.release(); // Don’t forget to release when done! -

For a complete example, see the {@code SimplePlayerActivity} in the ExoPlayer demo app, which - correctly manages an ExoPlayer instance with respect to both the {@link android.app.Activity} and - {@link android.view.Surface} lifecycles.

+

For a complete example, see {@code PlayerActivity} and {@code DemoPlayer} in the ExoPlayer demo + app. Between them these classes correctly manage an ExoPlayer instance with respect to both the + {@link android.app.Activity} and {@link android.view.Surface} lifecycles. +

SampleSource

@@ -187,7 +186,7 @@ MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(

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 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 @@ -211,9 +210,9 @@ MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer( 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, 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 - playback using the FMP4 container format. The {@code DashWebMChunkSource} class uses the WebM - container format to provide DASH playback.

+ DashChunkSource} class provides DASH playback using the FMP4 and WebM container formats. The + {@code SmoothStreamingChunkSource} class provides SmoothStreaming playback using the FMP4 + container format.

All of the standard {@code ChunkSource} implementations require a {@code FormatEvaluator} and a {@code DataSource} to be injected through their constructors. The {@code FormatEvaluator} @@ -242,7 +241,7 @@ BandwidthMeter bandwidthMeter = new BandwidthMeter(); // Build the video renderer. DataSource videoDataSource = new HttpDataSource(userAgent, HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter); -ChunkSource videoChunkSource = new DashMp4ChunkSource(videoDataSource, +ChunkSource videoChunkSource = new DashChunkSource(videoDataSource, new AdaptiveEvaluator(bandwidthMeter), videoRepresentations); ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl, VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); @@ -253,7 +252,7 @@ MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer( // Build the audio renderer. DataSource audioDataSource = new HttpDataSource(userAgent, HttpDataSource.REJECT_PAYWALL_TYPES, bandwidthMeter); -ChunkSource audioChunkSource = new DashMp4ChunkSource(audioDataSource, +ChunkSource audioChunkSource = new DashChunkSource(audioDataSource, new FormatEvaluator.FixedEvaluator(), audioRepresentation); SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl, AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); @@ -273,9 +272,8 @@ MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(

The ExoPlayer demo app provides complete implementation of this code in - {@code DashVodRendererBuilder}. The {@code SimplePlaybackActivity} 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 required {@code Representation} objects. For an + {@code DashRendererBuilder}. The {@code PlayerActivity} class uses this builder to + construct renderers for playing DASH sample videos in the demo app. For an equivalent SmoothStreaming example, see the {@code SmoothStreamingRendererBuilder} class in the demo app.

@@ -313,7 +311,7 @@ if (format.width * format.height <= maxDecodableFrameSize) { } -

This approach is used to filter {@code Representations} in the {@code DashVodRendererBuilder} +

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 SmoothStreamingRendererBuilder}.

@@ -372,24 +370,26 @@ boolean isAdaptive = MediaCodecUtil.getDecoderInfo(MimeTypes.VIDEO_H264).adaptiv

In addition to high level listeners, many of the individual components provided by the ExoPlayer library allow their own event listeners. For example, {@code MediaCodecVideoTrackRenderer} has constructors that take a {@code - MediaCodecVideoTrackRenderer.EventListener}. In the ExoPlayer demo app, {@code SimplePlayerActivity} - acts 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:

+ MediaCodecVideoTrackRenderer.EventListener}. In the ExoPlayer demo app, {@code DemoPlayer} + acts as the listener to multiple individual components, forwarding events to {@code PlayerActivity}. + 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:

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

The {@code RendererBuilder} classes in the ExoPlayer demo app inject the activity as the - listener, for example in the {@code DashVodRendererBuilder} class:

+

The {@code RendererBuilder} classes in the ExoPlayer demo app inject the {@code DemoPlayer} as + the listener to each component, for example in the {@code DashRendererBuilder} class:

 MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(
-        videoSampleSource, null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT,
-        0, mainHandler, playerActivity, 50);
+        sampleSource, null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
+        null, player.getMainHandler(), player, 50);
 

Note that you must pass a {@link android.os.Handler} object to the renderer, which determines @@ -441,9 +441,7 @@ player.blockingSendMessage(videoRenderer,

You must use a blocking message because the contract of {@link android.view.SurfaceHolder.Callback#surfaceDestroyed surfaceDestroyed()} requires that the - app does not attempt to access the surface after the method returns. The {@code - SimplePlayerActivity} class in the demo app demonstrates how the surface should be set and - cleared.

+ app does not attempt to access the surface after the method returns.

Customizing ExoPlayer

-- cgit v1.1