Make DRM work in ExoPlayer V2.
Bigger changes will be coming, but this gets DRM back up and working again. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=122719062
This commit is contained in:
parent
80f67d908a
commit
7d4c786e21
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer.demo;
|
package com.google.android.exoplayer.demo;
|
||||||
|
|
||||||
import com.google.android.exoplayer.DefaultTrackSelector.TrackInfo;
|
import com.google.android.exoplayer.DefaultTrackSelector.TrackInfo;
|
||||||
|
import com.google.android.exoplayer.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer.ExoPlayer;
|
import com.google.android.exoplayer.ExoPlayer;
|
||||||
import com.google.android.exoplayer.Format;
|
import com.google.android.exoplayer.Format;
|
||||||
import com.google.android.exoplayer.TrackGroup;
|
import com.google.android.exoplayer.TrackGroup;
|
||||||
@ -65,7 +66,7 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Exception e) {
|
public void onError(ExoPlaybackException e) {
|
||||||
Log.e(TAG, "playerFailed [" + getSessionTimeString() + "]", e);
|
Log.e(TAG, "playerFailed [" + getSessionTimeString() + "]", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import com.google.android.exoplayer.TrackGroupArray;
|
|||||||
import com.google.android.exoplayer.dash.DashSampleSource;
|
import com.google.android.exoplayer.dash.DashSampleSource;
|
||||||
import com.google.android.exoplayer.demo.player.DemoPlayer;
|
import com.google.android.exoplayer.demo.player.DemoPlayer;
|
||||||
import com.google.android.exoplayer.demo.ui.TrackSelectionHelper;
|
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.drm.UnsupportedDrmException;
|
||||||
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
|
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
|
||||||
import com.google.android.exoplayer.hls.HlsSampleSource;
|
import com.google.android.exoplayer.hls.HlsSampleSource;
|
||||||
@ -261,39 +262,21 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
|||||||
return Util.SDK_INT >= 23
|
return Util.SDK_INT >= 23
|
||||||
&& Util.isLocalFileUri(uri)
|
&& Util.isLocalFileUri(uri)
|
||||||
&& checkSelfPermission(permission.READ_EXTERNAL_STORAGE)
|
&& checkSelfPermission(permission.READ_EXTERNAL_STORAGE)
|
||||||
!= PackageManager.PERMISSION_GRANTED;
|
!= PackageManager.PERMISSION_GRANTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal methods
|
// 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() {
|
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) {
|
if (player == null) {
|
||||||
boolean useExtensionDecoders = getIntent().getBooleanExtra(USE_EXTENSION_DECODERS, false);
|
String id = intent.getStringExtra(CONTENT_ID_EXTRA);
|
||||||
player = new DemoPlayer(this, useExtensionDecoders);
|
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.addListener(this);
|
||||||
player.setCaptionListener(this);
|
player.setCaptionListener(this);
|
||||||
player.setMetadataListener(this);
|
player.setMetadataListener(this);
|
||||||
@ -313,22 +296,51 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
|||||||
debugViewHelper.start();
|
debugViewHelper.start();
|
||||||
}
|
}
|
||||||
if (playerNeedsSource) {
|
if (playerNeedsSource) {
|
||||||
Intent intent = getIntent();
|
|
||||||
Uri uri = intent.getData();
|
|
||||||
if (maybeRequestPermission(uri)) {
|
if (maybeRequestPermission(uri)) {
|
||||||
// The player will be reinitialized if permission is granted.
|
// The player will be reinitialized if permission is granted.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String id = intent.getStringExtra(CONTENT_ID_EXTRA);
|
player.setSource(buildSource(type, uri));
|
||||||
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));
|
|
||||||
playerNeedsSource = false;
|
playerNeedsSource = false;
|
||||||
updateButtonVisibilities();
|
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() {
|
private void releasePlayer() {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
shutterView.setVisibility(View.VISIBLE);
|
shutterView.setVisibility(View.VISIBLE);
|
||||||
@ -377,32 +389,34 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Exception e) {
|
public void onError(ExoPlaybackException e) {
|
||||||
String errorString = null;
|
String errorString = null;
|
||||||
if (e instanceof UnsupportedDrmException) {
|
if (e.type == ExoPlaybackException.TYPE_RENDERER) {
|
||||||
// Special case DRM failures.
|
Exception cause = e.getRendererException();
|
||||||
UnsupportedDrmException unsupportedDrmException = (UnsupportedDrmException) e;
|
if (cause instanceof DecoderInitializationException) {
|
||||||
errorString = getString(Util.SDK_INT < 18 ? R.string.error_drm_not_supported
|
// Special case for decoder initialization failures.
|
||||||
: unsupportedDrmException.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
|
DecoderInitializationException decoderInitializationException =
|
||||||
? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown);
|
(DecoderInitializationException) cause;
|
||||||
} else if (e instanceof ExoPlaybackException
|
if (decoderInitializationException.decoderName == null) {
|
||||||
&& e.getCause() instanceof DecoderInitializationException) {
|
if (decoderInitializationException.getCause() instanceof DecoderQueryException) {
|
||||||
// Special case for decoder initialization failures.
|
errorString = getString(R.string.error_querying_decoders);
|
||||||
DecoderInitializationException decoderInitializationException =
|
} else if (decoderInitializationException.secureDecoderRequired) {
|
||||||
(DecoderInitializationException) e.getCause();
|
errorString = getString(R.string.error_no_secure_decoder,
|
||||||
if (decoderInitializationException.decoderName == null) {
|
decoderInitializationException.mimeType);
|
||||||
if (decoderInitializationException.getCause() instanceof DecoderQueryException) {
|
} else {
|
||||||
errorString = getString(R.string.error_querying_decoders);
|
errorString = getString(R.string.error_no_decoder,
|
||||||
} else if (decoderInitializationException.secureDecoderRequired) {
|
decoderInitializationException.mimeType);
|
||||||
errorString = getString(R.string.error_no_secure_decoder,
|
}
|
||||||
decoderInitializationException.mimeType);
|
|
||||||
} else {
|
} else {
|
||||||
errorString = getString(R.string.error_no_decoder,
|
errorString = getString(R.string.error_instantiating_decoder,
|
||||||
decoderInitializationException.mimeType);
|
decoderInitializationException.decoderName);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (cause instanceof UnsupportedDrmException) {
|
||||||
errorString = getString(R.string.error_instantiating_decoder,
|
// Special case DRM failures.
|
||||||
decoderInitializationException.decoderName);
|
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) {
|
if (errorString != null) {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer.demo;
|
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.MediaDrmCallback;
|
||||||
import com.google.android.exoplayer.drm.StreamingDrmSessionManager;
|
import com.google.android.exoplayer.drm.StreamingDrmSessionManager;
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
@ -33,7 +34,7 @@ import java.util.UUID;
|
|||||||
* Demo {@link StreamingDrmSessionManager} for smooth streaming test content.
|
* Demo {@link StreamingDrmSessionManager} for smooth streaming test content.
|
||||||
*/
|
*/
|
||||||
@TargetApi(18)
|
@TargetApi(18)
|
||||||
public class SmoothStreamingTestMediaDrmCallback implements MediaDrmCallback {
|
public final class SmoothStreamingTestMediaDrmCallback implements MediaDrmCallback {
|
||||||
|
|
||||||
private static final String PLAYREADY_TEST_DEFAULT_URI =
|
private static final String PLAYREADY_TEST_DEFAULT_URI =
|
||||||
"http://playready.directtaps.net/pr/svc/rightsmanager.asmx";
|
"http://playready.directtaps.net/pr/svc/rightsmanager.asmx";
|
||||||
@ -46,6 +47,11 @@ public class SmoothStreamingTestMediaDrmCallback implements MediaDrmCallback {
|
|||||||
KEY_REQUEST_PROPERTIES = keyRequestProperties;
|
KEY_REQUEST_PROPERTIES = keyRequestProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUuid() {
|
||||||
|
return C.PLAYREADY_UUID;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] executeProvisionRequest(UUID uuid, ProvisionRequest request) throws IOException {
|
public byte[] executeProvisionRequest(UUID uuid, ProvisionRequest request) throws IOException {
|
||||||
String url = request.getDefaultUrl() + "&signedRequest=" + new String(request.getData());
|
String url = request.getDefaultUrl() + "&signedRequest=" + new String(request.getData());
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer.demo;
|
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.MediaDrmCallback;
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ import java.util.UUID;
|
|||||||
* A {@link MediaDrmCallback} for Widevine test content.
|
* A {@link MediaDrmCallback} for Widevine test content.
|
||||||
*/
|
*/
|
||||||
@TargetApi(18)
|
@TargetApi(18)
|
||||||
public class WidevineTestMediaDrmCallback implements MediaDrmCallback {
|
public final class WidevineTestMediaDrmCallback implements MediaDrmCallback {
|
||||||
|
|
||||||
private static final String WIDEVINE_GTS_DEFAULT_BASE_URI =
|
private static final String WIDEVINE_GTS_DEFAULT_BASE_URI =
|
||||||
"https://proxy.uat.widevine.com/proxy";
|
"https://proxy.uat.widevine.com/proxy";
|
||||||
@ -42,6 +43,11 @@ public class WidevineTestMediaDrmCallback implements MediaDrmCallback {
|
|||||||
defaultUri = WIDEVINE_GTS_DEFAULT_BASE_URI + params;
|
defaultUri = WIDEVINE_GTS_DEFAULT_BASE_URI + params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUuid() {
|
||||||
|
return C.WIDEVINE_UUID;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] executeProvisionRequest(UUID uuid, ProvisionRequest request) throws IOException {
|
public byte[] executeProvisionRequest(UUID uuid, ProvisionRequest request) throws IOException {
|
||||||
String url = request.getDefaultUrl() + "&signedRequest=" + new String(request.getData());
|
String url = request.getDefaultUrl() + "&signedRequest=" + new String(request.getData());
|
||||||
|
@ -33,6 +33,8 @@ import com.google.android.exoplayer.TrackRenderer;
|
|||||||
import com.google.android.exoplayer.VideoTrackRendererEventListener;
|
import com.google.android.exoplayer.VideoTrackRendererEventListener;
|
||||||
import com.google.android.exoplayer.audio.AudioCapabilities;
|
import com.google.android.exoplayer.audio.AudioCapabilities;
|
||||||
import com.google.android.exoplayer.chunk.ChunkTrackStreamEventListener;
|
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.drm.StreamingDrmSessionManager;
|
||||||
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
|
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
|
||||||
import com.google.android.exoplayer.metadata.MetadataTrackRenderer;
|
import com.google.android.exoplayer.metadata.MetadataTrackRenderer;
|
||||||
@ -75,7 +77,7 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
|
|||||||
*/
|
*/
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
void onStateChanged(boolean playWhenReady, int playbackState);
|
void onStateChanged(boolean playWhenReady, int playbackState);
|
||||||
void onError(Exception e);
|
void onError(ExoPlaybackException e);
|
||||||
void onTracksChanged(TrackInfo trackInfo);
|
void onTracksChanged(TrackInfo trackInfo);
|
||||||
void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
|
void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
|
||||||
float pixelWidthHeightRatio);
|
float pixelWidthHeightRatio);
|
||||||
@ -86,8 +88,8 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
|
|||||||
* <p>
|
* <p>
|
||||||
* These errors are not visible to the user, and hence this listener is provided for
|
* 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
|
* 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)}
|
* error if the player fails to recover. If this happens,
|
||||||
* will be invoked.
|
* {@link Listener#onError(ExoPlaybackException)} will be invoked.
|
||||||
*/
|
*/
|
||||||
public interface InternalErrorListener {
|
public interface InternalErrorListener {
|
||||||
void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs);
|
void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs);
|
||||||
@ -153,7 +155,7 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
|
|||||||
private InfoListener infoListener;
|
private InfoListener infoListener;
|
||||||
private CodecCounters videoCodecCounters;
|
private CodecCounters videoCodecCounters;
|
||||||
|
|
||||||
public DemoPlayer(Context context, boolean useExtensionDecoders) {
|
public DemoPlayer(Context context, MediaDrmCallback drmCallback, boolean useExtensionDecoders) {
|
||||||
mainHandler = new Handler();
|
mainHandler = new Handler();
|
||||||
bandwidthMeter = new DefaultBandwidthMeter();
|
bandwidthMeter = new DefaultBandwidthMeter();
|
||||||
listeners = new CopyOnWriteArrayList<>();
|
listeners = new CopyOnWriteArrayList<>();
|
||||||
@ -163,7 +165,7 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
|
|||||||
if (useExtensionDecoders) {
|
if (useExtensionDecoders) {
|
||||||
buildExtensionRenderers(renderersList);
|
buildExtensionRenderers(renderersList);
|
||||||
}
|
}
|
||||||
buildRenderers(context, renderersList);
|
buildRenderers(context, drmCallback, renderersList);
|
||||||
renderers = renderersList.toArray(new TrackRenderer[renderersList.size()]);
|
renderers = renderersList.toArray(new TrackRenderer[renderersList.size()]);
|
||||||
|
|
||||||
// Build the player and associated objects.
|
// Build the player and associated objects.
|
||||||
@ -460,14 +462,18 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildRenderers(Context context, ArrayList<TrackRenderer> renderersList) {
|
private void buildRenderers(Context context, MediaDrmCallback drmCallback,
|
||||||
MediaCodecVideoTrackRenderer videoRenderer =
|
ArrayList<TrackRenderer> renderersList) {
|
||||||
new MediaCodecVideoTrackRenderer(context, MediaCodecSelector.DEFAULT,
|
DrmSessionManager drmSessionManager = drmCallback == null ? null
|
||||||
MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, this, 50);
|
: new StreamingDrmSessionManager(drmCallback, null, mainHandler, this);
|
||||||
|
|
||||||
|
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
|
||||||
|
MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
|
||||||
|
drmSessionManager, false, mainHandler, this, 50);
|
||||||
renderersList.add(videoRenderer);
|
renderersList.add(videoRenderer);
|
||||||
|
|
||||||
TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(MediaCodecSelector.DEFAULT, null,
|
TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(MediaCodecSelector.DEFAULT,
|
||||||
true, mainHandler, this, AudioCapabilities.getCapabilities(context),
|
drmSessionManager, true, mainHandler, this, AudioCapabilities.getCapabilities(context),
|
||||||
AudioManager.STREAM_MUSIC);
|
AudioManager.STREAM_MUSIC);
|
||||||
renderersList.add(audioRenderer);
|
renderersList.add(audioRenderer);
|
||||||
|
|
||||||
|
@ -266,6 +266,8 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
if (drmSessionManager == null) {
|
if (drmSessionManager == null) {
|
||||||
throw ExoPlaybackException.createForRenderer(
|
throw ExoPlaybackException.createForRenderer(
|
||||||
new IllegalStateException("Media requires a DrmSessionManager"), getIndex());
|
new IllegalStateException("Media requires a DrmSessionManager"), getIndex());
|
||||||
|
} else if (drmSessionManager.getState() == DrmSessionManager.STATE_ERROR) {
|
||||||
|
throw ExoPlaybackException.createForRenderer(drmSessionManager.getError(), getIndex());
|
||||||
}
|
}
|
||||||
if (!openedDrmSession) {
|
if (!openedDrmSession) {
|
||||||
drmSessionManager.open(Looper.myLooper(), format.drmInitData);
|
drmSessionManager.open(Looper.myLooper(), format.drmInitData);
|
||||||
|
@ -26,6 +26,13 @@ import java.util.UUID;
|
|||||||
@TargetApi(18)
|
@TargetApi(18)
|
||||||
public interface MediaDrmCallback {
|
public interface MediaDrmCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link UUID} of the DRM scheme that this callback supports.
|
||||||
|
*
|
||||||
|
* @return The DRM scheme {@link UUID}.
|
||||||
|
*/
|
||||||
|
UUID getUuid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a provisioning request.
|
* Executes a provisioning request.
|
||||||
*
|
*
|
||||||
|
@ -35,7 +35,6 @@ import android.os.Handler;
|
|||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -99,77 +98,37 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
|
|||||||
private byte[] sessionId;
|
private byte[] sessionId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new instance using the Widevine scheme.
|
|
||||||
*
|
|
||||||
* @param callback Performs key and provisioning requests.
|
* @param callback Performs key and provisioning requests.
|
||||||
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
|
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
|
||||||
* to {@link MediaDrm#getKeyRequest(byte[], byte[], String, int, HashMap)}. May be null.
|
* to {@link MediaDrm#getKeyRequest(byte[], byte[], String, int, HashMap)}. May be null.
|
||||||
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
|
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
|
||||||
* null if delivery of events is not required.
|
* null if delivery of events is not required.
|
||||||
* @param eventListener A listener of events. 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 newWidevineInstance(MediaDrmCallback callback,
|
public StreamingDrmSessionManager(MediaDrmCallback callback,
|
||||||
HashMap<String, String> optionalKeyRequestParameters, Handler eventHandler,
|
HashMap<String, String> optionalKeyRequestParameters, Handler eventHandler,
|
||||||
EventListener eventListener) throws UnsupportedDrmException {
|
EventListener eventListener) {
|
||||||
return new StreamingDrmSessionManager(C.WIDEVINE_UUID, callback, optionalKeyRequestParameters,
|
|
||||||
eventHandler, eventListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiates a new instance using the PlayReady scheme.
|
|
||||||
* <p>
|
|
||||||
* 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<String, String> optionalKeyRequestParameters;
|
|
||||||
if (!TextUtils.isEmpty(customData)) {
|
|
||||||
optionalKeyRequestParameters = new HashMap<>();
|
|
||||||
optionalKeyRequestParameters.put(PLAYREADY_CUSTOM_DATA_KEY, customData);
|
|
||||||
} else {
|
|
||||||
optionalKeyRequestParameters = null;
|
|
||||||
}
|
|
||||||
return new StreamingDrmSessionManager(C.PLAYREADY_UUID, callback, optionalKeyRequestParameters,
|
|
||||||
eventHandler, eventListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uuid The UUID of the drm scheme.
|
|
||||||
* @param callback Performs key and provisioning requests.
|
|
||||||
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
|
|
||||||
* to {@link MediaDrm#getKeyRequest(byte[], byte[], String, int, HashMap)}. May be null.
|
|
||||||
* @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 StreamingDrmSessionManager(UUID uuid, MediaDrmCallback callback,
|
|
||||||
HashMap<String, String> optionalKeyRequestParameters, Handler eventHandler,
|
|
||||||
EventListener eventListener) throws UnsupportedDrmException {
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.optionalKeyRequestParameters = optionalKeyRequestParameters;
|
this.optionalKeyRequestParameters = optionalKeyRequestParameters;
|
||||||
this.eventHandler = eventHandler;
|
this.eventHandler = eventHandler;
|
||||||
this.eventListener = eventListener;
|
this.eventListener = eventListener;
|
||||||
|
uuid = callback.getUuid();
|
||||||
|
MediaDrm mediaDrm = null;
|
||||||
try {
|
try {
|
||||||
mediaDrm = new MediaDrm(uuid);
|
mediaDrm = new MediaDrm(uuid);
|
||||||
|
mediaDrm.setOnEventListener(new MediaDrmEventListener());
|
||||||
|
state = STATE_CLOSED;
|
||||||
} catch (UnsupportedSchemeException e) {
|
} catch (UnsupportedSchemeException e) {
|
||||||
throw new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME, e);
|
lastException = new UnsupportedDrmException(
|
||||||
|
UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME, e);
|
||||||
|
state = STATE_ERROR;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new UnsupportedDrmException(UnsupportedDrmException.REASON_INSTANTIATION_ERROR, e);
|
lastException = new UnsupportedDrmException(
|
||||||
|
UnsupportedDrmException.REASON_INSTANTIATION_ERROR, e);
|
||||||
|
state = STATE_ERROR;
|
||||||
|
} finally {
|
||||||
|
this.mediaDrm = mediaDrm;
|
||||||
}
|
}
|
||||||
mediaDrm.setOnEventListener(new MediaDrmEventListener());
|
|
||||||
state = STATE_CLOSED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user