use of com.google.android.exoplayer2.drm.DrmSessionManager in project ExoPlayer by google.
the class ExoPlayerTest method shortAdFollowedByUnpreparedAd_playbackDoesNotGetStuck.
@Test
public void shortAdFollowedByUnpreparedAd_playbackDoesNotGetStuck() throws Exception {
AdPlaybackState adPlaybackState = FakeTimeline.createAdPlaybackState(/* adsPerAdGroup= */
2, /* adGroupTimesUs...= */
0);
long shortAdDurationMs = 1_000;
adPlaybackState = adPlaybackState.withAdDurationsUs(new long[][] { { shortAdDurationMs, shortAdDurationMs } });
Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
0, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
Util.msToUs(10000), adPlaybackState));
// Simulate the second ad not being prepared.
FakeMediaSource mediaSource = new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
@Override
protected MediaPeriod createMediaPeriod(MediaPeriodId id, TrackGroupArray trackGroupArray, Allocator allocator, MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher, DrmSessionManager drmSessionManager, DrmSessionEventListener.EventDispatcher drmEventDispatcher, @Nullable TransferListener transferListener) {
return new FakeMediaPeriod(trackGroupArray, allocator, FakeMediaPeriod.TrackDataFactory.singleSampleWithTimeUs(0), mediaSourceEventDispatcher, drmSessionManager, drmEventDispatcher, /* deferOnPrepared= */
id.adIndexInAdGroup == 1);
}
};
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.setMediaSource(mediaSource);
player.prepare();
player.play();
// The player is not stuck in the buffering state.
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY);
}
use of com.google.android.exoplayer2.drm.DrmSessionManager in project ExoPlayer by google.
the class DefaultAnalyticsCollectorTest method drmEvents_periodWithDifferentDrmData_keysLoadedAgain.
@Test
public void drmEvents_periodWithDifferentDrmData_keysLoadedAgain() throws Exception {
MediaSource mediaSource = new ConcatenatingMediaSource(new FakeMediaSource(SINGLE_PERIOD_TIMELINE, drmSessionManager, VIDEO_FORMAT_DRM_1), new FakeMediaSource(SINGLE_PERIOD_TIMELINE, drmSessionManager, VIDEO_FORMAT_DRM_1.buildUpon().setDrmInitData(DRM_DATA_2).build()));
TestAnalyticsListener listener = runAnalyticsTest(mediaSource);
populateEventIds(listener.lastReportedTimeline);
assertThat(listener.getEvents(EVENT_DRM_SESSION_MANAGER_ERROR)).isEmpty();
assertThat(listener.getEvents(EVENT_DRM_SESSION_ACQUIRED)).containsExactly(period0, period1).inOrder();
// The pre-fetched key load for period1 might complete before the blocking key load for period0,
// so we can't assert the order:
assertThat(listener.getEvents(EVENT_DRM_KEYS_LOADED)).containsExactly(period0, period1);
// The period1 release event is lost because it's posted to "ExoPlayerTest thread" after that
// thread has been quit during clean-up.
assertThat(listener.getEvents(EVENT_DRM_SESSION_RELEASED)).containsExactly(period0);
}
use of com.google.android.exoplayer2.drm.DrmSessionManager in project ExoPlayer by google.
the class DefaultAnalyticsCollectorTest method drmEvents_periodsWithSameDrmData_keysReusedButLoadEventReportedTwice.
@Test
public void drmEvents_periodsWithSameDrmData_keysReusedButLoadEventReportedTwice() throws Exception {
BlockingDrmCallback mediaDrmCallback = BlockingDrmCallback.returnsEmpty();
DrmSessionManager blockingDrmSessionManager = new DefaultDrmSessionManager.Builder().setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm.Builder().setEnforceValidKeyResponses(false).build()).setMultiSession(true).build(mediaDrmCallback);
MediaSource mediaSource = new ConcatenatingMediaSource(new FakeMediaSource(SINGLE_PERIOD_TIMELINE, blockingDrmSessionManager, VIDEO_FORMAT_DRM_1), new FakeMediaSource(SINGLE_PERIOD_TIMELINE, blockingDrmSessionManager, VIDEO_FORMAT_DRM_1));
TestAnalyticsListener listener = runAnalyticsTest(mediaSource, // already preacquired by the time the key load completes).
new ActionSchedule.Builder(TAG).waitForIsLoading(false).waitForIsLoading(true).waitForIsLoading(false).executeRunnable(mediaDrmCallback.keyCondition::open).build());
populateEventIds(listener.lastReportedTimeline);
assertThat(listener.getEvents(EVENT_DRM_SESSION_MANAGER_ERROR)).isEmpty();
assertThat(listener.getEvents(EVENT_DRM_SESSION_ACQUIRED)).containsExactly(period0, period1).inOrder();
// This includes both period0 and period1 because period1's DrmSession was preacquired before
// the key load completed. There's only one key load (a second would block forever). We can't
// assume the order these events will arrive in because it depends on the iteration order of a
// HashSet of EventDispatchers inside DefaultDrmSession.
assertThat(listener.getEvents(EVENT_DRM_KEYS_LOADED)).containsExactly(period0, period1);
// The period1 release event is lost because it's posted to "ExoPlayerTest thread" after that
// thread has been quit during clean-up.
assertThat(listener.getEvents(EVENT_DRM_SESSION_RELEASED)).containsExactly(period0);
}
use of com.google.android.exoplayer2.drm.DrmSessionManager in project ExoPlayer by google.
the class DefaultDrmSessionManager method acquireSession.
// DrmSessionManager implementation.
@Override
public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData) {
Assertions.checkState(this.playbackLooper == null || this.playbackLooper == playbackLooper);
if (++openCount != 1) {
return this;
}
if (this.playbackLooper == null) {
this.playbackLooper = playbackLooper;
mediaDrmHandler = new MediaDrmHandler(playbackLooper);
postResponseHandler = new PostResponseHandler(playbackLooper);
}
requestHandlerThread = new HandlerThread("DrmRequestHandler");
requestHandlerThread.start();
postRequestHandler = new PostRequestHandler(requestHandlerThread.getLooper());
if (offlineLicenseKeySetId == null) {
SchemeData schemeData = drmInitData.get(uuid);
if (schemeData == null) {
onError(new IllegalStateException("Media does not support uuid: " + uuid));
return this;
}
schemeInitData = schemeData.data;
schemeMimeType = schemeData.mimeType;
if (Util.SDK_INT < 21) {
// Prior to L the Widevine CDM required data to be extracted from the PSSH atom.
byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(schemeInitData, C.WIDEVINE_UUID);
if (psshData == null) {
// Extraction failed. schemeData isn't a Widevine PSSH atom, so leave it unchanged.
} else {
schemeInitData = psshData;
}
}
if (Util.SDK_INT < 26 && C.CLEARKEY_UUID.equals(uuid) && (MimeTypes.VIDEO_MP4.equals(schemeMimeType) || MimeTypes.AUDIO_MP4.equals(schemeMimeType))) {
// Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
schemeMimeType = CENC_SCHEME_MIME_TYPE;
}
}
state = STATE_OPENING;
openInternal(true);
return this;
}
use of com.google.android.exoplayer2.drm.DrmSessionManager in project ExoPlayer by google.
the class SimpleExoPlayer method buildVideoRenderers.
/**
* Builds video renderers for use by the player.
*
* @param context The {@link Context} associated with the player.
* @param mainHandler A handler associated with the main thread's looper.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the player will
* not be used for DRM protected playbacks.
* @param extensionRendererMode The extension renderer mode.
* @param eventListener An event listener.
* @param allowedVideoJoiningTimeMs The maximum duration in milliseconds for which video renderers
* can attempt to seamlessly join an ongoing playback.
* @param out An array to which the built renderers should be appended.
*/
protected void buildVideoRenderers(Context context, Handler mainHandler, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, @ExtensionRendererMode int extensionRendererMode, VideoRendererEventListener eventListener, long allowedVideoJoiningTimeMs, ArrayList<Renderer> out) {
out.add(new MediaCodecVideoRenderer(context, MediaCodecSelector.DEFAULT, allowedVideoJoiningTimeMs, drmSessionManager, false, mainHandler, eventListener, MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY));
if (extensionRendererMode == EXTENSION_RENDERER_MODE_OFF) {
return;
}
int extensionRendererIndex = out.size();
if (extensionRendererMode == EXTENSION_RENDERER_MODE_PREFER) {
extensionRendererIndex--;
}
try {
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer");
Constructor<?> constructor = clazz.getConstructor(boolean.class, long.class, Handler.class, VideoRendererEventListener.class, int.class);
Renderer renderer = (Renderer) constructor.newInstance(true, allowedVideoJoiningTimeMs, mainHandler, componentListener, MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);
out.add(extensionRendererIndex++, renderer);
Log.i(TAG, "Loaded LibvpxVideoRenderer.");
} catch (ClassNotFoundException e) {
// Expected if the app was built without the extension.
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Aggregations