Commit 58953d37 by olly Committed by Oliver Woodman

Simplify DemoPlayer + misc surrounding components.

1. Properly split out listening responsibilities so that
   DemoPlayer only listens to its own components.
2. Revert StreamingDrmSessionManager UnsupportedDrmScheme
   exceptions back to how they worked in V1, and inject
   a DrmSessionManager rather than a MediaDrmCallback into
   DemoPlayer.

This much better prepares DemoPlayer for promotion into
the core ExoPlayer library, since it removes assumptions
such as what SampleSource and DrmSessionManager impls
might be used with it.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=122980952
parent ddde6edb
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer.demo;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.DefaultTrackSelector.TrackInfo;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer;
......@@ -23,7 +24,10 @@ import com.google.android.exoplayer.TrackGroup;
import com.google.android.exoplayer.TrackGroupArray;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackSelection;
import com.google.android.exoplayer.chunk.ChunkTrackStreamEventListener;
import com.google.android.exoplayer.demo.player.DemoPlayer;
import com.google.android.exoplayer.drm.StreamingDrmSessionManager;
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
import android.os.SystemClock;
import android.util.Log;
......@@ -36,7 +40,8 @@ import java.util.Locale;
* Logs player events using {@link Log}.
*/
public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener,
DemoPlayer.InternalErrorListener {
ChunkTrackStreamEventListener, ExtractorSampleSource.EventListener,
StreamingDrmSessionManager.EventListener {
private static final String TAG = "EventLogger";
private static final NumberFormat TIME_FORMAT;
......@@ -140,26 +145,30 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener
}
@Override
public void onAudioFormatEnabled(Format format, int trigger, long mediaTimeMs) {
Log.d(TAG, "audioFormat [" + getSessionTimeString() + ", " + format.id + ", " + trigger + "]");
public void onDroppedFrames(int count, long elapsed) {
Log.d(TAG, "droppedFrames [" + getSessionTimeString() + ", " + count + "]");
}
@Override
public void onVideoFormatEnabled(Format format, int trigger, long mediaTimeMs) {
Log.d(TAG, "videoFormat [" + getSessionTimeString() + ", " + format.id + ", " + trigger + "]");
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
printInternalError("audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", "
+ elapsedSinceLastFeedMs + "]", null);
}
// StreamingDrmSessionManager.EventListener
@Override
public void onBandwidthSample(int elapsedMs, long bytes, long bitrateEstimate) {
Log.d(TAG, "bandwidth [" + getSessionTimeString() + ", " + bytes + ", "
+ getTimeString(elapsedMs) + ", " + bitrateEstimate + "]");
public void onDrmSessionManagerError(Exception e) {
printInternalError("drmSessionManagerError", e);
}
@Override
public void onDroppedFrames(int count, long elapsed) {
Log.d(TAG, "droppedFrames [" + getSessionTimeString() + ", " + count + "]");
public void onDrmKeysLoaded() {
Log.d(TAG, "drmKeysLoaded [" + getSessionTimeString() + "]");
}
// SampleSource listeners
@Override
public void onLoadStarted(int sourceId, long length, int type, int trigger, Format format,
long mediaStartTimeMs, long mediaEndTimeMs) {
......@@ -167,29 +176,36 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener
}
@Override
public void onLoadCompleted(int sourceId, long bytesLoaded, int type, int trigger, Format format,
long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs) {
// Do nothing.
public void onLoadError(int sourceId, IOException e) {
printInternalError("loadError", e);
}
// DemoPlayer.InternalErrorListener
@Override
public void onLoadCanceled(int sourceId, long bytesLoaded) {
// Do nothing.
}
@Override
public void onLoadError(int sourceId, IOException e) {
printInternalError("loadError", e);
public void onLoadCompleted(int sourceId, long bytesLoaded, int type, int trigger, Format format,
long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs) {
// Do nothing.
}
@Override
public void onDrmSessionManagerError(Exception e) {
printInternalError("drmSessionManagerError", e);
public void onUpstreamDiscarded(int sourceId, long mediaStartTimeMs, long mediaEndTimeMs) {
// Do nothing.
}
@Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
printInternalError("audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", "
+ elapsedSinceLastFeedMs + "]", null);
public void onDownstreamFormatChanged(int sourceId, Format format, int trigger,
long mediaTimeMs) {
if (sourceId == C.TRACK_TYPE_VIDEO) {
Log.d(TAG, "videoFormatChanged [" + getSessionTimeString() + ", " + format.id + "]");
}
}
// Internal methods
private void printInternalError(String type, Exception e) {
Log.e(TAG, "internalError [" + getSessionTimeString() + ", " + type + "]", e);
}
......
......@@ -27,7 +27,8 @@ 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.DrmSessionManager;
import com.google.android.exoplayer.drm.StreamingDrmSessionManager;
import com.google.android.exoplayer.drm.UnsupportedDrmException;
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
import com.google.android.exoplayer.hls.HlsSampleSource;
......@@ -55,6 +56,7 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
......@@ -76,6 +78,7 @@ import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.util.List;
import java.util.UUID;
/**
* An activity that plays media using {@link DemoPlayer}.
......@@ -84,9 +87,10 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
DemoPlayer.Listener, DemoPlayer.CaptionListener, DemoPlayer.Id3MetadataListener {
// For use within demo app code.
public static final String CONTENT_ID_EXTRA = "content_id";
public static final String CONTENT_TYPE_EXTRA = "content_type";
public static final String PROVIDER_EXTRA = "provider";
public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
public static final String DRM_CONTENT_ID_EXTRA = "drm_content_id";
public static final String DRM_PROVIDER_EXTRA = "drm_provider";
public static final String USE_EXTENSION_DECODERS = "use_extension_decoders";
// For use when launching the demo app using adb.
......@@ -101,8 +105,10 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
defaultCookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
}
private Handler mainHandler;
private EventLogger eventLogger;
private MediaController mediaController;
private View rootView;
private LinearLayout debugRootView;
private View shutterView;
private AspectRatioFrameLayout videoFrame;
......@@ -127,10 +133,11 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
super.onCreate(savedInstanceState);
String userAgent = Util.getUserAgent(this, "ExoPlayerDemo");
dataSourceFactory = new DefaultDataSourceFactory(this, userAgent);
mainHandler = new Handler();
setContentView(R.layout.player_activity);
View root = findViewById(R.id.root);
root.setOnTouchListener(new OnTouchListener() {
rootView = findViewById(R.id.root);
rootView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
......@@ -141,7 +148,7 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
return true;
}
});
root.setOnKeyListener(new OnKeyListener() {
rootView.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
return keyCode != KeyEvent.KEYCODE_BACK && keyCode != KeyEvent.KEYCODE_ESCAPE
......@@ -161,7 +168,6 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
subtitleLayout = (SubtitleLayout) findViewById(R.id.subtitles);
mediaController = new KeyCompatibleMediaController(this);
mediaController.setAnchorView(root);
retryButton = (Button) findViewById(R.id.retry_button);
retryButton.setOnClickListener(this);
......@@ -273,27 +279,36 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
int type = intent.getIntExtra(CONTENT_TYPE_EXTRA,
inferContentType(uri, intent.getStringExtra(CONTENT_EXT_EXTRA)));
if (player == null) {
String id = intent.getStringExtra(CONTENT_ID_EXTRA);
String provider = intent.getStringExtra(PROVIDER_EXTRA);
UUID drmSchemeUuid = (UUID) intent.getSerializableExtra(DRM_SCHEME_UUID_EXTRA);
DrmSessionManager drmSessionManager = null;
if (drmSchemeUuid != null) {
String drmContentId = intent.getStringExtra(DRM_CONTENT_ID_EXTRA);
String drmProvider = intent.getStringExtra(DRM_PROVIDER_EXTRA);
try {
drmSessionManager = buildDrmSessionManager(drmSchemeUuid, drmContentId, drmProvider);
} catch (UnsupportedDrmException e) {
onUnsupportedDrmError(e);
return;
}
}
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);
player.seekTo(playerPosition);
trackSelectionHelper = new TrackSelectionHelper(player.getTrackSelector());
playerNeedsSource = true;
mediaController.setMediaPlayer(player.getPlayerControl());
mediaController.setEnabled(true);
eventLogger = new EventLogger();
eventLogger.startSession();
player = new DemoPlayer(this, drmSessionManager, useExtensionDecoders);
player.addListener(this);
player.addListener(eventLogger);
player.setInfoListener(eventLogger);
player.setInternalErrorListener(eventLogger);
player.setCaptionListener(this);
player.setMetadataListener(this);
player.seekTo(playerPosition);
player.setSurface(surfaceView.getHolder().getSurface());
player.setPlayWhenReady(true);
trackSelectionHelper = new TrackSelectionHelper(player.getTrackSelector());
mediaController.setMediaPlayer(player.getPlayerControl());
mediaController.setAnchorView(rootView);
debugViewHelper = new DebugTextViewHelper(player, debugTextView);
debugViewHelper.start();
playerNeedsSource = true;
}
if (playerNeedsSource) {
if (maybeRequestPermission(uri)) {
......@@ -306,36 +321,45 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
}
}
private MediaDrmCallback buildDrmCallback(int type, String id, String provider) {
private DrmSessionManager buildDrmSessionManager(UUID uuid, String id, String provider)
throws UnsupportedDrmException {
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;
if (C.PLAYREADY_UUID.equals(uuid)) {
return StreamingDrmSessionManager.newPlayReadyInstance(
new SmoothStreamingTestMediaDrmCallback(), null, mainHandler, eventLogger);
} else if (C.WIDEVINE_UUID.equals(uuid)) {
return StreamingDrmSessionManager.newWidevineInstance(
new WidevineTestMediaDrmCallback(id, provider), null, mainHandler, eventLogger);
} else {
throw new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME);
}
}
private void onUnsupportedDrmError(UnsupportedDrmException e) {
String errorString = getString(Util.SDK_INT < 18 ? R.string.error_drm_not_supported
: e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown);
Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_LONG).show();
}
private SampleSource buildSource(int type, Uri uri) {
switch (type) {
case Util.TYPE_SS:
return new SmoothStreamingSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(),
player.getMainHandler(), player);
mainHandler, eventLogger);
case Util.TYPE_DASH:
return new DashSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(),
player.getMainHandler(), player);
return new DashSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), mainHandler,
eventLogger);
case Util.TYPE_HLS:
return new HlsSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(),
player.getMainHandler(), player);
return new HlsSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), mainHandler,
eventLogger);
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());
mainHandler, eventLogger, 0, ExtractorSampleSource.newDefaultExtractors());
default:
throw new IllegalStateException("Unsupported type: " + type);
}
......@@ -411,12 +435,6 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
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) {
......
......@@ -94,9 +94,10 @@ public class SampleChooserActivity extends Activity {
private void onSampleSelected(Sample sample) {
Intent intent = new Intent(this, PlayerActivity.class)
.setData(Uri.parse(sample.uri))
.putExtra(PlayerActivity.CONTENT_ID_EXTRA, sample.contentId)
.putExtra(PlayerActivity.CONTENT_TYPE_EXTRA, sample.type)
.putExtra(PlayerActivity.PROVIDER_EXTRA, sample.provider)
.putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, sample.drmSchemeUuid)
.putExtra(PlayerActivity.DRM_CONTENT_ID_EXTRA, sample.drmContentId)
.putExtra(PlayerActivity.DRM_PROVIDER_EXTRA, sample.drmProvider)
.putExtra(PlayerActivity.USE_EXTENSION_DECODERS, sample.useExtensionDecoders);
startActivity(intent);
}
......
......@@ -15,7 +15,6 @@
*/
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;
......@@ -48,11 +47,6 @@ public final class SmoothStreamingTestMediaDrmCallback implements MediaDrmCallba
}
@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());
return Util.executePost(url, null, null);
......
......@@ -15,7 +15,6 @@
*/
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;
......@@ -44,11 +43,6 @@ public final class WidevineTestMediaDrmCallback implements MediaDrmCallback {
}
@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());
return Util.executePost(url, null, null);
......
......@@ -281,7 +281,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
return false;
}
if (result == TrackStream.FORMAT_READ) {
format = formatHolder.format;
onInputFormatChanged(formatHolder.format);
return true;
}
if (inputBuffer.isEndOfStream()) {
......@@ -366,12 +366,17 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
private boolean readFormat() {
int result = readSource(formatHolder, null);
if (result == TrackStream.FORMAT_READ) {
format = formatHolder.format;
onInputFormatChanged(formatHolder.format);
return true;
}
return false;
}
private void onInputFormatChanged(Format newFormat) {
format = newFormat;
eventDispatcher.inputFormatChanged(format);
}
@Override
public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
if (messageType == C.MSG_SET_SURFACE) {
......
......@@ -45,6 +45,13 @@ public interface AudioTrackRendererEventListener {
long initializationDurationMs);
/**
* Invoked when the format of the media being consumed by the renderer changes.
*
* @param format The new format.
*/
void onAudioInputFormatChanged(Format format);
/**
* Invoked when an {@link AudioTrack} underrun occurs.
*
* @param bufferSize The size of the {@link AudioTrack}'s buffer, in bytes.
......@@ -92,6 +99,17 @@ public interface AudioTrackRendererEventListener {
}
}
public void inputFormatChanged(final Format format) {
if (listener != null) {
handler.post(new Runnable() {
@Override
public void run() {
listener.onAudioInputFormatChanged(format);
}
});
}
}
public void audioTrackUnderrun(final int bufferSize, final long bufferSizeMs,
final long elapsedSinceLastFeedMs) {
if (listener != null) {
......
......@@ -233,12 +233,13 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
}
@Override
protected void onInputFormatChanged(FormatHolder holder) throws ExoPlaybackException {
super.onInputFormatChanged(holder);
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
super.onInputFormatChanged(newFormat);
eventDispatcher.inputFormatChanged(newFormat);
// If the input format is anything other than PCM then we assume that the audio decoder will
// output 16-bit PCM.
pcmEncoding = MimeTypes.AUDIO_RAW.equals(holder.format.sampleMimeType)
? holder.format.pcmEncoding : C.ENCODING_PCM_16BIT;
pcmEncoding = MimeTypes.AUDIO_RAW.equals(newFormat.sampleMimeType) ? newFormat.pcmEncoding
: C.ENCODING_PCM_16BIT;
}
@Override
......
......@@ -430,7 +430,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
private void readFormat() throws ExoPlaybackException {
int result = readSource(formatHolder, null);
if (result == TrackStream.FORMAT_READ) {
onInputFormatChanged(formatHolder);
onInputFormatChanged(formatHolder.format);
}
}
......@@ -526,7 +526,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
buffer.clear();
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
}
onInputFormatChanged(formatHolder);
onInputFormatChanged(formatHolder.format);
return true;
}
......@@ -641,12 +641,12 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
/**
* Invoked when a new format is read from the upstream {@link SampleSource}.
*
* @param formatHolder Holds the new format.
* @param newFormat The new format.
* @throws ExoPlaybackException If an error occurs reinitializing the {@link MediaCodec}.
*/
protected void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackException {
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
Format oldFormat = format;
format = formatHolder.format;
format = newFormat;
if (codec != null && canReconfigureCodec(codec, codecIsAdaptive, oldFormat, format)) {
codecReconfigured = true;
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
......
......@@ -329,12 +329,13 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
}
@Override
protected void onInputFormatChanged(FormatHolder holder) throws ExoPlaybackException {
super.onInputFormatChanged(holder);
pendingPixelWidthHeightRatio = holder.format.pixelWidthHeightRatio == Format.NO_VALUE ? 1
: holder.format.pixelWidthHeightRatio;
pendingRotationDegrees = holder.format.rotationDegrees == Format.NO_VALUE ? 0
: holder.format.rotationDegrees;
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
super.onInputFormatChanged(newFormat);
eventDispatcher.inputFormatChanged(newFormat);
pendingPixelWidthHeightRatio = newFormat.pixelWidthHeightRatio == Format.NO_VALUE ? 1
: newFormat.pixelWidthHeightRatio;
pendingRotationDegrees = newFormat.rotationDegrees == Format.NO_VALUE ? 0
: newFormat.rotationDegrees;
}
/**
......
......@@ -46,6 +46,13 @@ public interface VideoTrackRendererEventListener {
long initializationDurationMs);
/**
* Invoked when the format of the media being consumed by the renderer changes.
*
* @param format The new format.
*/
void onVideoInputFormatChanged(Format format);
/**
* Invoked to report the number of frames dropped by the renderer. Dropped frames are reported
* whenever the renderer is stopped having dropped frames, and optionally, whenever the count
* reaches a specified threshold whilst the renderer is started.
......@@ -122,6 +129,17 @@ public interface VideoTrackRendererEventListener {
}
}
public void inputFormatChanged(final Format format) {
if (listener != null) {
handler.post(new Runnable() {
@Override
public void run() {
listener.onVideoInputFormatChanged(format);
}
});
}
}
public void droppedFrameCount(final int droppedFrameCount, final long elapsedMs) {
if (listener != null) {
handler.post(new Runnable() {
......
......@@ -27,13 +27,6 @@ import java.util.UUID;
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.
*
* @param uuid The UUID of the content protection scheme.
......
......@@ -35,6 +35,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import java.util.HashMap;
import java.util.UUID;
......@@ -98,37 +99,77 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
private byte[] sessionId;
/**
* Instantiates a new instance using the Widevine 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(MediaDrmCallback callback,
public static StreamingDrmSessionManager newWidevineInstance(MediaDrmCallback callback,
HashMap<String, String> optionalKeyRequestParameters, Handler eventHandler,
EventListener eventListener) {
EventListener eventListener) throws UnsupportedDrmException {
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.optionalKeyRequestParameters = optionalKeyRequestParameters;
this.eventHandler = eventHandler;
this.eventListener = eventListener;
uuid = callback.getUuid();
MediaDrm mediaDrm = null;
try {
mediaDrm = new MediaDrm(uuid);
mediaDrm.setOnEventListener(new MediaDrmEventListener());
state = STATE_CLOSED;
} catch (UnsupportedSchemeException e) {
lastException = new UnsupportedDrmException(
UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME, e);
state = STATE_ERROR;
throw new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME, e);
} catch (Exception e) {
lastException = new UnsupportedDrmException(
UnsupportedDrmException.REASON_INSTANTIATION_ERROR, e);
state = STATE_ERROR;
} finally {
this.mediaDrm = mediaDrm;
throw new UnsupportedDrmException(UnsupportedDrmException.REASON_INSTANTIATION_ERROR, e);
}
mediaDrm.setOnEventListener(new MediaDrmEventListener());
state = STATE_CLOSED;
}
@Override
......
......@@ -232,7 +232,7 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements
return false;
}
if (result == TrackStream.FORMAT_READ) {
inputFormat = formatHolder.format;
onInputFormatChanged(formatHolder.format);
return true;
}
if (inputBuffer.isEndOfStream()) {
......@@ -340,12 +340,17 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements
private boolean readFormat() {
int result = readSource(formatHolder, null);
if (result == TrackStream.FORMAT_READ) {
inputFormat = formatHolder.format;
onInputFormatChanged(formatHolder.format);
return true;
}
return false;
}
private void onInputFormatChanged(Format newFormat) {
inputFormat = newFormat;
eventDispatcher.inputFormatChanged(newFormat);
}
@Override
public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
if (messageType == MSG_SET_VOLUME) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment