diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/EventLogger.java b/demo/src/main/java/com/google/android/exoplayer/demo/EventLogger.java index a19e7b9e2e..a41a76a750 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/EventLogger.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/EventLogger.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer.demo; import com.google.android.exoplayer.DefaultTrackSelector.TrackInfo; +import com.google.android.exoplayer.ExoPlaybackException; import com.google.android.exoplayer.ExoPlayer; import com.google.android.exoplayer.Format; import com.google.android.exoplayer.TrackGroup; @@ -65,7 +66,7 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener } @Override - public void onError(Exception e) { + public void onError(ExoPlaybackException e) { Log.e(TAG, "playerFailed [" + getSessionTimeString() + "]", e); } diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java index 27ec5bb6d1..575b0e7d7e 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java @@ -27,6 +27,7 @@ import com.google.android.exoplayer.TrackGroupArray; import com.google.android.exoplayer.dash.DashSampleSource; import com.google.android.exoplayer.demo.player.DemoPlayer; import com.google.android.exoplayer.demo.ui.TrackSelectionHelper; +import com.google.android.exoplayer.drm.MediaDrmCallback; import com.google.android.exoplayer.drm.UnsupportedDrmException; import com.google.android.exoplayer.extractor.ExtractorSampleSource; import com.google.android.exoplayer.hls.HlsSampleSource; @@ -261,39 +262,21 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, return Util.SDK_INT >= 23 && Util.isLocalFileUri(uri) && checkSelfPermission(permission.READ_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED; + != PackageManager.PERMISSION_GRANTED; } // Internal methods - @SuppressWarnings("unused") - private SampleSource buildSource(Uri uri, String id, String provider, int type) { - switch (type) { - case Util.TYPE_SS: - // TODO: Bring back DRM support. new SmoothStreamingTestMediaDrmCallback() - return new SmoothStreamingSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), - player.getMainHandler(), player); - case Util.TYPE_DASH: - // TODO: Bring back DRM support. new WidevineTestMediaDrmCallback(id, provider) - return new DashSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), - player.getMainHandler(), player); - case Util.TYPE_HLS: - return new HlsSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), - player.getMainHandler(), player); - case Util.TYPE_OTHER: - Allocator allocator = new DefaultAllocator(C.DEFAULT_BUFFER_SEGMENT_SIZE); - DataSource dataSource = dataSourceFactory.createDataSource(player.getBandwidthMeter()); - return new ExtractorSampleSource(uri, dataSource, allocator, C.DEFAULT_MUXED_BUFFER_SIZE, - player.getMainHandler(), player, 0, ExtractorSampleSource.newDefaultExtractors()); - default: - throw new IllegalStateException("Unsupported type: " + type); - } - } - private void initializePlayer() { + Intent intent = getIntent(); + Uri uri = intent.getData(); + int type = intent.getIntExtra(CONTENT_TYPE_EXTRA, + inferContentType(uri, intent.getStringExtra(CONTENT_EXT_EXTRA))); if (player == null) { - boolean useExtensionDecoders = getIntent().getBooleanExtra(USE_EXTENSION_DECODERS, false); - player = new DemoPlayer(this, useExtensionDecoders); + String id = intent.getStringExtra(CONTENT_ID_EXTRA); + String provider = intent.getStringExtra(PROVIDER_EXTRA); + boolean useExtensionDecoders = intent.getBooleanExtra(USE_EXTENSION_DECODERS, false); + player = new DemoPlayer(this, buildDrmCallback(type, id, provider), useExtensionDecoders); player.addListener(this); player.setCaptionListener(this); player.setMetadataListener(this); @@ -313,22 +296,51 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, debugViewHelper.start(); } if (playerNeedsSource) { - Intent intent = getIntent(); - Uri uri = intent.getData(); if (maybeRequestPermission(uri)) { // The player will be reinitialized if permission is granted. return; } - String id = intent.getStringExtra(CONTENT_ID_EXTRA); - String provider = intent.getStringExtra(PROVIDER_EXTRA); - int type = intent.getIntExtra(CONTENT_TYPE_EXTRA, - inferContentType(uri, intent.getStringExtra(CONTENT_EXT_EXTRA))); - player.setSource(buildSource(uri, id, provider, type)); + player.setSource(buildSource(type, uri)); playerNeedsSource = false; updateButtonVisibilities(); } } + private MediaDrmCallback buildDrmCallback(int type, String id, String provider) { + if (Util.SDK_INT < 18) { + return null; + } + switch (type) { + case Util.TYPE_SS: + return new SmoothStreamingTestMediaDrmCallback(); + case Util.TYPE_DASH: + return new WidevineTestMediaDrmCallback(id, provider); + default: + return null; + } + } + + private SampleSource buildSource(int type, Uri uri) { + switch (type) { + case Util.TYPE_SS: + return new SmoothStreamingSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), + player.getMainHandler(), player); + case Util.TYPE_DASH: + return new DashSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), + player.getMainHandler(), player); + case Util.TYPE_HLS: + return new HlsSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), + player.getMainHandler(), player); + case Util.TYPE_OTHER: + Allocator allocator = new DefaultAllocator(C.DEFAULT_BUFFER_SEGMENT_SIZE); + DataSource dataSource = dataSourceFactory.createDataSource(player.getBandwidthMeter()); + return new ExtractorSampleSource(uri, dataSource, allocator, C.DEFAULT_MUXED_BUFFER_SIZE, + player.getMainHandler(), player, 0, ExtractorSampleSource.newDefaultExtractors()); + default: + throw new IllegalStateException("Unsupported type: " + type); + } + } + private void releasePlayer() { if (player != null) { shutterView.setVisibility(View.VISIBLE); @@ -377,32 +389,34 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, } @Override - public void onError(Exception e) { + public void onError(ExoPlaybackException e) { String errorString = null; - if (e instanceof UnsupportedDrmException) { - // Special case DRM failures. - UnsupportedDrmException unsupportedDrmException = (UnsupportedDrmException) e; - errorString = getString(Util.SDK_INT < 18 ? R.string.error_drm_not_supported - : unsupportedDrmException.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME - ? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown); - } else if (e instanceof ExoPlaybackException - && e.getCause() instanceof DecoderInitializationException) { - // Special case for decoder initialization failures. - DecoderInitializationException decoderInitializationException = - (DecoderInitializationException) e.getCause(); - if (decoderInitializationException.decoderName == null) { - if (decoderInitializationException.getCause() instanceof DecoderQueryException) { - errorString = getString(R.string.error_querying_decoders); - } else if (decoderInitializationException.secureDecoderRequired) { - errorString = getString(R.string.error_no_secure_decoder, - decoderInitializationException.mimeType); + if (e.type == ExoPlaybackException.TYPE_RENDERER) { + Exception cause = e.getRendererException(); + if (cause instanceof DecoderInitializationException) { + // Special case for decoder initialization failures. + DecoderInitializationException decoderInitializationException = + (DecoderInitializationException) cause; + if (decoderInitializationException.decoderName == null) { + if (decoderInitializationException.getCause() instanceof DecoderQueryException) { + errorString = getString(R.string.error_querying_decoders); + } else if (decoderInitializationException.secureDecoderRequired) { + errorString = getString(R.string.error_no_secure_decoder, + decoderInitializationException.mimeType); + } else { + errorString = getString(R.string.error_no_decoder, + decoderInitializationException.mimeType); + } } else { - errorString = getString(R.string.error_no_decoder, - decoderInitializationException.mimeType); + errorString = getString(R.string.error_instantiating_decoder, + decoderInitializationException.decoderName); } - } else { - errorString = getString(R.string.error_instantiating_decoder, - decoderInitializationException.decoderName); + } else if (cause instanceof UnsupportedDrmException) { + // Special case DRM failures. + UnsupportedDrmException unsupportedDrmException = (UnsupportedDrmException) cause; + errorString = getString(Util.SDK_INT < 18 ? R.string.error_drm_not_supported + : unsupportedDrmException.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME + ? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown); } } if (errorString != null) { diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/SmoothStreamingTestMediaDrmCallback.java b/demo/src/main/java/com/google/android/exoplayer/demo/SmoothStreamingTestMediaDrmCallback.java index 257b0cac2e..139279e890 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/SmoothStreamingTestMediaDrmCallback.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/SmoothStreamingTestMediaDrmCallback.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer.demo; +import com.google.android.exoplayer.C; import com.google.android.exoplayer.drm.MediaDrmCallback; import com.google.android.exoplayer.drm.StreamingDrmSessionManager; import com.google.android.exoplayer.util.Util; @@ -33,7 +34,7 @@ import java.util.UUID; * Demo {@link StreamingDrmSessionManager} for smooth streaming test content. */ @TargetApi(18) -public class SmoothStreamingTestMediaDrmCallback implements MediaDrmCallback { +public final class SmoothStreamingTestMediaDrmCallback implements MediaDrmCallback { private static final String PLAYREADY_TEST_DEFAULT_URI = "http://playready.directtaps.net/pr/svc/rightsmanager.asmx"; @@ -46,6 +47,11 @@ public class SmoothStreamingTestMediaDrmCallback implements MediaDrmCallback { KEY_REQUEST_PROPERTIES = keyRequestProperties; } + @Override + public UUID getUuid() { + return C.PLAYREADY_UUID; + } + @Override public byte[] executeProvisionRequest(UUID uuid, ProvisionRequest request) throws IOException { String url = request.getDefaultUrl() + "&signedRequest=" + new String(request.getData()); diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/WidevineTestMediaDrmCallback.java b/demo/src/main/java/com/google/android/exoplayer/demo/WidevineTestMediaDrmCallback.java index 4d9fcf22b8..faf2cf8846 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/WidevineTestMediaDrmCallback.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/WidevineTestMediaDrmCallback.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer.demo; +import com.google.android.exoplayer.C; import com.google.android.exoplayer.drm.MediaDrmCallback; import com.google.android.exoplayer.util.Util; @@ -30,7 +31,7 @@ import java.util.UUID; * A {@link MediaDrmCallback} for Widevine test content. */ @TargetApi(18) -public class WidevineTestMediaDrmCallback implements MediaDrmCallback { +public final class WidevineTestMediaDrmCallback implements MediaDrmCallback { private static final String WIDEVINE_GTS_DEFAULT_BASE_URI = "https://proxy.uat.widevine.com/proxy"; @@ -42,6 +43,11 @@ public class WidevineTestMediaDrmCallback implements MediaDrmCallback { defaultUri = WIDEVINE_GTS_DEFAULT_BASE_URI + params; } + @Override + public UUID getUuid() { + return C.WIDEVINE_UUID; + } + @Override public byte[] executeProvisionRequest(UUID uuid, ProvisionRequest request) throws IOException { String url = request.getDefaultUrl() + "&signedRequest=" + new String(request.getData()); diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java index b1fa7d5763..7616e9208e 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java @@ -33,6 +33,8 @@ import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.VideoTrackRendererEventListener; import com.google.android.exoplayer.audio.AudioCapabilities; import com.google.android.exoplayer.chunk.ChunkTrackStreamEventListener; +import com.google.android.exoplayer.drm.DrmSessionManager; +import com.google.android.exoplayer.drm.MediaDrmCallback; import com.google.android.exoplayer.drm.StreamingDrmSessionManager; import com.google.android.exoplayer.extractor.ExtractorSampleSource; import com.google.android.exoplayer.metadata.MetadataTrackRenderer; @@ -75,7 +77,7 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even */ public interface Listener { void onStateChanged(boolean playWhenReady, int playbackState); - void onError(Exception e); + void onError(ExoPlaybackException e); void onTracksChanged(TrackInfo trackInfo); void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio); @@ -86,8 +88,8 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even *
* These errors are not visible to the user, and hence this listener is provided for
* informational purposes only. Note however that an internal error may cause a fatal
- * error if the player fails to recover. If this happens, {@link Listener#onError(Exception)}
- * will be invoked.
+ * error if the player fails to recover. If this happens,
+ * {@link Listener#onError(ExoPlaybackException)} will be invoked.
*/
public interface InternalErrorListener {
void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs);
@@ -153,7 +155,7 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
private InfoListener infoListener;
private CodecCounters videoCodecCounters;
- public DemoPlayer(Context context, boolean useExtensionDecoders) {
+ public DemoPlayer(Context context, MediaDrmCallback drmCallback, boolean useExtensionDecoders) {
mainHandler = new Handler();
bandwidthMeter = new DefaultBandwidthMeter();
listeners = new CopyOnWriteArrayList<>();
@@ -163,7 +165,7 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
if (useExtensionDecoders) {
buildExtensionRenderers(renderersList);
}
- buildRenderers(context, renderersList);
+ buildRenderers(context, drmCallback, renderersList);
renderers = renderersList.toArray(new TrackRenderer[renderersList.size()]);
// Build the player and associated objects.
@@ -460,14 +462,18 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
}
}
- private void buildRenderers(Context context, ArrayList
- * Note that PlayReady is unsupported by most Android devices, with the exception of Android TV
- * devices, which do provide support.
- *
- * @param callback Performs key and provisioning requests.
- * @param customData Optional custom data to include in requests generated by the instance.
- * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
- * null if delivery of events is not required.
- * @param eventListener A listener of events. May be null if delivery of events is not required.
- * @throws UnsupportedDrmException If the specified DRM scheme is not supported.
- */
- public static StreamingDrmSessionManager newPlayReadyInstance(MediaDrmCallback callback,
- String customData, Handler eventHandler, EventListener eventListener)
- throws UnsupportedDrmException {
- HashMap