Make DrmSessionManager take a Format instead of DrmInitData
Skipping acquirePlaceholderSession which will be removed in a following change. PiperOrigin-RevId: 326402746
This commit is contained in:
parent
6f7524521b
commit
fcb263a407
@ -191,8 +191,8 @@ public class DownloadTracker {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrepared(@NonNull DownloadHelper helper) {
|
public void onPrepared(@NonNull DownloadHelper helper) {
|
||||||
@Nullable DrmInitData drmInitData = findDrmInitData(helper);
|
@Nullable Format format = getFirstFormatWithDrmInitData(helper);
|
||||||
if (drmInitData != null) {
|
if (format != null) {
|
||||||
if (Util.SDK_INT < 18) {
|
if (Util.SDK_INT < 18) {
|
||||||
Toast.makeText(context, R.string.error_drm_unsupported_before_api_18, Toast.LENGTH_LONG)
|
Toast.makeText(context, R.string.error_drm_unsupported_before_api_18, Toast.LENGTH_LONG)
|
||||||
.show();
|
.show();
|
||||||
@ -200,7 +200,7 @@ public class DownloadTracker {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO(internal b/163107948): Support cases where DrmInitData are not in the manifest.
|
// TODO(internal b/163107948): Support cases where DrmInitData are not in the manifest.
|
||||||
if (!hasSchemaData(drmInitData)) {
|
if (!hasSchemaData(format.drmInitData)) {
|
||||||
Toast.makeText(context, R.string.download_start_error_offline_license, Toast.LENGTH_LONG)
|
Toast.makeText(context, R.string.download_start_error_offline_license, Toast.LENGTH_LONG)
|
||||||
.show();
|
.show();
|
||||||
Log.e(
|
Log.e(
|
||||||
@ -212,7 +212,7 @@ public class DownloadTracker {
|
|||||||
try {
|
try {
|
||||||
// TODO(internal b/163107948): Download the license on another thread to keep the UI
|
// TODO(internal b/163107948): Download the license on another thread to keep the UI
|
||||||
// thread unblocked.
|
// thread unblocked.
|
||||||
fetchOfflineLicense(drmInitData);
|
fetchOfflineLicense(format);
|
||||||
} catch (DrmSession.DrmSessionException e) {
|
} catch (DrmSession.DrmSessionException e) {
|
||||||
Toast.makeText(context, R.string.download_start_error_offline_license, Toast.LENGTH_LONG)
|
Toast.makeText(context, R.string.download_start_error_offline_license, Toast.LENGTH_LONG)
|
||||||
.show();
|
.show();
|
||||||
@ -308,14 +308,13 @@ public class DownloadTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(18)
|
@RequiresApi(18)
|
||||||
private void fetchOfflineLicense(DrmInitData drmInitData)
|
private void fetchOfflineLicense(Format format) throws DrmSession.DrmSessionException {
|
||||||
throws DrmSession.DrmSessionException {
|
|
||||||
OfflineLicenseHelper offlineLicenseHelper =
|
OfflineLicenseHelper offlineLicenseHelper =
|
||||||
OfflineLicenseHelper.newWidevineInstance(
|
OfflineLicenseHelper.newWidevineInstance(
|
||||||
mediaItem.playbackProperties.drmConfiguration.licenseUri.toString(),
|
mediaItem.playbackProperties.drmConfiguration.licenseUri.toString(),
|
||||||
httpDataSourceFactory,
|
httpDataSourceFactory,
|
||||||
new DrmSessionEventListener.EventDispatcher());
|
new DrmSessionEventListener.EventDispatcher());
|
||||||
keySetId = offlineLicenseHelper.downloadLicense(drmInitData);
|
keySetId = offlineLicenseHelper.downloadLicense(format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,11 +332,11 @@ public class DownloadTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the first non-null {@link DrmInitData} found in the content's tracks, or null if no
|
* Returns the first {@link Format} with a non-null {@link Format#drmInitData} found in the
|
||||||
* {@link DrmInitData} are found.
|
* content's tracks, or null if none is found.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private DrmInitData findDrmInitData(DownloadHelper helper) {
|
private Format getFirstFormatWithDrmInitData(DownloadHelper helper) {
|
||||||
for (int periodIndex = 0; periodIndex < helper.getPeriodCount(); periodIndex++) {
|
for (int periodIndex = 0; periodIndex < helper.getPeriodCount(); periodIndex++) {
|
||||||
MappedTrackInfo mappedTrackInfo = helper.getMappedTrackInfo(periodIndex);
|
MappedTrackInfo mappedTrackInfo = helper.getMappedTrackInfo(periodIndex);
|
||||||
for (int rendererIndex = 0;
|
for (int rendererIndex = 0;
|
||||||
@ -349,7 +348,7 @@ public class DownloadTracker {
|
|||||||
for (int formatIndex = 0; formatIndex < trackGroup.length; formatIndex++) {
|
for (int formatIndex = 0; formatIndex < trackGroup.length; formatIndex++) {
|
||||||
Format format = trackGroup.getFormat(formatIndex);
|
Format format = trackGroup.getFormat(formatIndex);
|
||||||
if (format.drmInitData != null) {
|
if (format.drmInitData != null) {
|
||||||
return format.drmInitData;
|
return format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import androidx.annotation.IntDef;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||||
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
|
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
|
||||||
import com.google.android.exoplayer2.drm.ExoMediaDrm.OnEventListener;
|
import com.google.android.exoplayer2.drm.ExoMediaDrm.OnEventListener;
|
||||||
@ -32,6 +33,7 @@ import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
|
|||||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
@ -223,8 +225,8 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals that the {@link DrmInitData} passed to {@link #acquireSession} does not contain does
|
* Signals that the {@link Format#drmInitData} passed to {@link #acquireSession} does not contain
|
||||||
* not contain scheme data for the required UUID.
|
* scheme data for the required UUID.
|
||||||
*/
|
*/
|
||||||
public static final class MissingSchemeDataException extends Exception {
|
public static final class MissingSchemeDataException extends Exception {
|
||||||
|
|
||||||
@ -406,8 +408,8 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the mode, which determines the role of sessions acquired from the instance. This must be
|
* Sets the mode, which determines the role of sessions acquired from the instance. This must be
|
||||||
* called before {@link #acquireSession(Looper, DrmSessionEventListener.EventDispatcher,
|
* called before {@link #acquireSession(Looper, DrmSessionEventListener.EventDispatcher, Format)}
|
||||||
* DrmInitData)} or {@link #acquirePlaceholderSession} is called.
|
* or {@link #acquirePlaceholderSession} is called.
|
||||||
*
|
*
|
||||||
* <p>By default, the mode is {@link #MODE_PLAYBACK} and a streaming license is requested when
|
* <p>By default, the mode is {@link #MODE_PLAYBACK} and a streaming license is requested when
|
||||||
* required.
|
* required.
|
||||||
@ -498,13 +500,13 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
|||||||
public DrmSession acquireSession(
|
public DrmSession acquireSession(
|
||||||
Looper playbackLooper,
|
Looper playbackLooper,
|
||||||
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
||||||
DrmInitData drmInitData) {
|
Format format) {
|
||||||
initPlaybackLooper(playbackLooper);
|
initPlaybackLooper(playbackLooper);
|
||||||
maybeCreateMediaDrmHandler(playbackLooper);
|
maybeCreateMediaDrmHandler(playbackLooper);
|
||||||
|
|
||||||
@Nullable List<SchemeData> schemeDatas = null;
|
@Nullable List<SchemeData> schemeDatas = null;
|
||||||
if (offlineLicenseKeySetId == null) {
|
if (offlineLicenseKeySetId == null) {
|
||||||
schemeDatas = getSchemeDatas(drmInitData, uuid, false);
|
schemeDatas = getSchemeDatas(Assertions.checkNotNull(format.drmInitData), uuid, false);
|
||||||
if (schemeDatas.isEmpty()) {
|
if (schemeDatas.isEmpty()) {
|
||||||
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
|
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
|
||||||
if (eventDispatcher != null) {
|
if (eventDispatcher != null) {
|
||||||
@ -546,16 +548,18 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Class<? extends ExoMediaCrypto> getExoMediaCryptoType(
|
public Class<? extends ExoMediaCrypto> getExoMediaCryptoType(Format format) {
|
||||||
@Nullable DrmInitData drmInitData, int trackType) {
|
|
||||||
Class<? extends ExoMediaCrypto> exoMediaCryptoType =
|
Class<? extends ExoMediaCrypto> exoMediaCryptoType =
|
||||||
Assertions.checkNotNull(exoMediaDrm).getExoMediaCryptoType();
|
Assertions.checkNotNull(exoMediaDrm).getExoMediaCryptoType();
|
||||||
if (drmInitData == null) {
|
if (format.drmInitData == null) {
|
||||||
|
int trackType = MimeTypes.getTrackType(format.sampleMimeType);
|
||||||
return Util.linearSearch(useDrmSessionsForClearContentTrackTypes, trackType) != C.INDEX_UNSET
|
return Util.linearSearch(useDrmSessionsForClearContentTrackTypes, trackType) != C.INDEX_UNSET
|
||||||
? exoMediaCryptoType
|
? exoMediaCryptoType
|
||||||
: null;
|
: null;
|
||||||
} else {
|
} else {
|
||||||
return canAcquireSession(drmInitData) ? exoMediaCryptoType : UnsupportedMediaCrypto.class;
|
return canAcquireSession(format.drmInitData)
|
||||||
|
? exoMediaCryptoType
|
||||||
|
: UnsupportedMediaCrypto.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ package com.google.android.exoplayer2.drm;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
import com.google.android.exoplayer2.Format;
|
||||||
|
|
||||||
/** Manages a DRM session. */
|
/** Manages a DRM session. */
|
||||||
public interface DrmSessionManager {
|
public interface DrmSessionManager {
|
||||||
@ -36,7 +36,7 @@ public interface DrmSessionManager {
|
|||||||
public DrmSession acquireSession(
|
public DrmSession acquireSession(
|
||||||
Looper playbackLooper,
|
Looper playbackLooper,
|
||||||
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
||||||
DrmInitData drmInitData) {
|
Format format) {
|
||||||
return new ErrorStateDrmSession(
|
return new ErrorStateDrmSession(
|
||||||
new DrmSession.DrmSessionException(
|
new DrmSession.DrmSessionException(
|
||||||
new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME)));
|
new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME)));
|
||||||
@ -44,9 +44,8 @@ public interface DrmSessionManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Class<UnsupportedMediaCrypto> getExoMediaCryptoType(
|
public Class<UnsupportedMediaCrypto> getExoMediaCryptoType(Format format) {
|
||||||
@Nullable DrmInitData drmInitData, int trackType) {
|
return format.drmInitData != null ? UnsupportedMediaCrypto.class : null;
|
||||||
return drmInitData != null ? UnsupportedMediaCrypto.class : null;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,41 +85,37 @@ public interface DrmSessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link DrmSession} for the specified {@link DrmInitData}, with an incremented
|
* Returns a {@link DrmSession} for the specified {@link Format}, with an incremented reference
|
||||||
* reference count. When the caller no longer needs to use the instance, it must call {@link
|
* count. When the caller no longer needs to use the instance, it must call {@link
|
||||||
* DrmSession#release(DrmSessionEventListener.EventDispatcher)} to decrement the reference count.
|
* DrmSession#release(DrmSessionEventListener.EventDispatcher)} to decrement the reference count.
|
||||||
*
|
*
|
||||||
* @param playbackLooper The looper associated with the media playback thread.
|
* @param playbackLooper The looper associated with the media playback thread.
|
||||||
* @param eventDispatcher The {@link DrmSessionEventListener.EventDispatcher} used to distribute
|
* @param eventDispatcher The {@link DrmSessionEventListener.EventDispatcher} used to distribute
|
||||||
* events, and passed on to {@link
|
* events, and passed on to {@link
|
||||||
* DrmSession#acquire(DrmSessionEventListener.EventDispatcher)}.
|
* DrmSession#acquire(DrmSessionEventListener.EventDispatcher)}.
|
||||||
* @param drmInitData DRM initialization data. All contained {@link SchemeData}s must contain
|
* @param format The {@link Format} for which to acquire a {@link DrmSession}. Must contain a
|
||||||
* non-null {@link SchemeData#data}.
|
* non-null {@link Format#drmInitData}.
|
||||||
* @return The DRM session.
|
* @return The DRM session.
|
||||||
*/
|
*/
|
||||||
DrmSession acquireSession(
|
DrmSession acquireSession(
|
||||||
Looper playbackLooper,
|
Looper playbackLooper,
|
||||||
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher,
|
||||||
DrmInitData drmInitData);
|
Format format);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link ExoMediaCrypto} type associated to sessions acquired using the given
|
* Returns the {@link ExoMediaCrypto} type associated to sessions acquired for the given {@link
|
||||||
* parameters. Returns the {@link UnsupportedMediaCrypto} type if this DRM session manager does
|
* Format}. Returns the {@link UnsupportedMediaCrypto} type if this DRM session manager does not
|
||||||
* not support the given {@link DrmInitData}. If {@code drmInitData} is null, returns an {@link
|
* support "any of the DRM schemes defined in the given {@link Format}. If the {@link Format}
|
||||||
* ExoMediaCrypto} type if this DRM session manager would associate a {@link
|
* describes unencrypted content, returns an {@link ExoMediaCrypto} type if this DRM session
|
||||||
* #acquirePlaceholderSession placeholder session} to the given {@code trackType}, or null
|
* manager would associate a {@link #acquirePlaceholderSession placeholder session} to the given
|
||||||
* otherwise.
|
* {@link Format}, or null otherwise.
|
||||||
*
|
*
|
||||||
* @param drmInitData The {@link DrmInitData} to acquire sessions with. May be null for
|
* @param format The {@link Format} for which to return the {@link ExoMediaCrypto} type.
|
||||||
* unencrypted content (See {@link #acquirePlaceholderSession placeholder sessions}).
|
|
||||||
* @param trackType The type of the track to which {@code drmInitData} belongs. Must be one of the
|
|
||||||
* {@link C}{@code .TRACK_TYPE_*} constants.
|
|
||||||
* @return The {@link ExoMediaCrypto} type associated to sessions acquired using the given
|
* @return The {@link ExoMediaCrypto} type associated to sessions acquired using the given
|
||||||
* parameters, or the {@link UnsupportedMediaCrypto} type if the provided {@code drmInitData}
|
* parameters, or the {@link UnsupportedMediaCrypto} type if the provided {@code drmInitData}
|
||||||
* is not supported, or {@code null} if {@code drmInitData} is null and no DRM session will be
|
* is not supported, or {@code null} if {@code drmInitData} is null and no DRM session will be
|
||||||
* associated to the given {@code trackType}.
|
* associated to the given {@code trackType}.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
Class<? extends ExoMediaCrypto> getExoMediaCryptoType(
|
Class<? extends ExoMediaCrypto> getExoMediaCryptoType(Format format);
|
||||||
@Nullable DrmInitData drmInitData, int trackType);
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import android.os.HandlerThread;
|
|||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode;
|
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode;
|
||||||
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
|
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
|
||||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||||
@ -34,7 +35,8 @@ import java.util.UUID;
|
|||||||
@RequiresApi(18)
|
@RequiresApi(18)
|
||||||
public final class OfflineLicenseHelper {
|
public final class OfflineLicenseHelper {
|
||||||
|
|
||||||
private static final DrmInitData EMPTY_DRM_INIT_DATA = new DrmInitData();
|
private static final Format FORMAT_WITH_EMPTY_DRM_INIT_DATA =
|
||||||
|
new Format.Builder().setDrmInitData(new DrmInitData()).build();
|
||||||
|
|
||||||
private final ConditionVariable conditionVariable;
|
private final ConditionVariable conditionVariable;
|
||||||
private final DefaultDrmSessionManager drmSessionManager;
|
private final DefaultDrmSessionManager drmSessionManager;
|
||||||
@ -182,13 +184,13 @@ public final class OfflineLicenseHelper {
|
|||||||
/**
|
/**
|
||||||
* Downloads an offline license.
|
* Downloads an offline license.
|
||||||
*
|
*
|
||||||
* @param drmInitData The {@link DrmInitData} for the content whose license is to be downloaded.
|
* @param format The {@link Format} of the content whose license is to be downloaded.
|
||||||
* @return The key set id for the downloaded license.
|
* @return The key set id for the downloaded license.
|
||||||
* @throws DrmSessionException Thrown when a DRM session error occurs.
|
* @throws DrmSessionException Thrown when a DRM session error occurs.
|
||||||
*/
|
*/
|
||||||
public synchronized byte[] downloadLicense(DrmInitData drmInitData) throws DrmSessionException {
|
public synchronized byte[] downloadLicense(Format format) throws DrmSessionException {
|
||||||
Assertions.checkArgument(drmInitData != null);
|
Assertions.checkArgument(format.drmInitData != null);
|
||||||
return blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, null, drmInitData);
|
return blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, null, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,7 +204,9 @@ public final class OfflineLicenseHelper {
|
|||||||
throws DrmSessionException {
|
throws DrmSessionException {
|
||||||
Assertions.checkNotNull(offlineLicenseKeySetId);
|
Assertions.checkNotNull(offlineLicenseKeySetId);
|
||||||
return blockingKeyRequest(
|
return blockingKeyRequest(
|
||||||
DefaultDrmSessionManager.MODE_DOWNLOAD, offlineLicenseKeySetId, EMPTY_DRM_INIT_DATA);
|
DefaultDrmSessionManager.MODE_DOWNLOAD,
|
||||||
|
offlineLicenseKeySetId,
|
||||||
|
FORMAT_WITH_EMPTY_DRM_INIT_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,7 +219,9 @@ public final class OfflineLicenseHelper {
|
|||||||
throws DrmSessionException {
|
throws DrmSessionException {
|
||||||
Assertions.checkNotNull(offlineLicenseKeySetId);
|
Assertions.checkNotNull(offlineLicenseKeySetId);
|
||||||
blockingKeyRequest(
|
blockingKeyRequest(
|
||||||
DefaultDrmSessionManager.MODE_RELEASE, offlineLicenseKeySetId, EMPTY_DRM_INIT_DATA);
|
DefaultDrmSessionManager.MODE_RELEASE,
|
||||||
|
offlineLicenseKeySetId,
|
||||||
|
FORMAT_WITH_EMPTY_DRM_INIT_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -231,7 +237,9 @@ public final class OfflineLicenseHelper {
|
|||||||
drmSessionManager.prepare();
|
drmSessionManager.prepare();
|
||||||
DrmSession drmSession =
|
DrmSession drmSession =
|
||||||
openBlockingKeyRequest(
|
openBlockingKeyRequest(
|
||||||
DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, EMPTY_DRM_INIT_DATA);
|
DefaultDrmSessionManager.MODE_QUERY,
|
||||||
|
offlineLicenseKeySetId,
|
||||||
|
FORMAT_WITH_EMPTY_DRM_INIT_DATA);
|
||||||
DrmSessionException error = drmSession.getError();
|
DrmSessionException error = drmSession.getError();
|
||||||
Pair<Long, Long> licenseDurationRemainingSec =
|
Pair<Long, Long> licenseDurationRemainingSec =
|
||||||
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
|
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
|
||||||
@ -254,11 +262,10 @@ public final class OfflineLicenseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private byte[] blockingKeyRequest(
|
private byte[] blockingKeyRequest(
|
||||||
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData)
|
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, Format format)
|
||||||
throws DrmSessionException {
|
throws DrmSessionException {
|
||||||
drmSessionManager.prepare();
|
drmSessionManager.prepare();
|
||||||
DrmSession drmSession =
|
DrmSession drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId, format);
|
||||||
openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId, drmInitData);
|
|
||||||
DrmSessionException error = drmSession.getError();
|
DrmSessionException error = drmSession.getError();
|
||||||
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
|
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
|
||||||
drmSession.release(eventDispatcher);
|
drmSession.release(eventDispatcher);
|
||||||
@ -270,11 +277,11 @@ public final class OfflineLicenseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private DrmSession openBlockingKeyRequest(
|
private DrmSession openBlockingKeyRequest(
|
||||||
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData) {
|
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, Format format) {
|
||||||
drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId);
|
drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId);
|
||||||
conditionVariable.close();
|
conditionVariable.close();
|
||||||
DrmSession drmSession =
|
DrmSession drmSession =
|
||||||
drmSessionManager.acquireSession(handlerThread.getLooper(), eventDispatcher, drmInitData);
|
drmSessionManager.acquireSession(handlerThread.getLooper(), eventDispatcher, format);
|
||||||
// Block current thread until key loading is finished
|
// Block current thread until key loading is finished
|
||||||
conditionVariable.block();
|
conditionVariable.block();
|
||||||
return drmSession;
|
return drmSession;
|
||||||
|
@ -782,8 +782,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
}
|
}
|
||||||
trackFormat =
|
trackFormat =
|
||||||
trackFormat.copyWithExoMediaCryptoType(
|
trackFormat.copyWithExoMediaCryptoType(
|
||||||
drmSessionManager.getExoMediaCryptoType(
|
drmSessionManager.getExoMediaCryptoType(trackFormat));
|
||||||
trackFormat.drmInitData, MimeTypes.getTrackType(trackFormat.sampleMimeType)));
|
|
||||||
trackArray[i] = new TrackGroup(trackFormat);
|
trackArray[i] = new TrackGroup(trackFormat);
|
||||||
}
|
}
|
||||||
trackState = new TrackState(new TrackGroupArray(trackArray), trackIsAudioVideoFlags);
|
trackState = new TrackState(new TrackGroupArray(trackArray), trackIsAudioVideoFlags);
|
||||||
|
@ -832,9 +832,7 @@ public class SampleQueue implements TrackOutput {
|
|||||||
@Nullable DrmInitData newDrmInitData = newFormat.drmInitData;
|
@Nullable DrmInitData newDrmInitData = newFormat.drmInitData;
|
||||||
|
|
||||||
outputFormatHolder.format =
|
outputFormatHolder.format =
|
||||||
newFormat.copyWithExoMediaCryptoType(
|
newFormat.copyWithExoMediaCryptoType(drmSessionManager.getExoMediaCryptoType(newFormat));
|
||||||
drmSessionManager.getExoMediaCryptoType(
|
|
||||||
newFormat.drmInitData, MimeTypes.getTrackType(newFormat.sampleMimeType)));
|
|
||||||
outputFormatHolder.drmSession = currentDrmSession;
|
outputFormatHolder.drmSession = currentDrmSession;
|
||||||
if (!isFirstFormat && Util.areEqual(oldDrmInitData, newDrmInitData)) {
|
if (!isFirstFormat && Util.areEqual(oldDrmInitData, newDrmInitData)) {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
@ -845,7 +843,7 @@ public class SampleQueue implements TrackOutput {
|
|||||||
@Nullable DrmSession previousSession = currentDrmSession;
|
@Nullable DrmSession previousSession = currentDrmSession;
|
||||||
currentDrmSession =
|
currentDrmSession =
|
||||||
newDrmInitData != null
|
newDrmInitData != null
|
||||||
? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newDrmInitData)
|
? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newFormat)
|
||||||
: drmSessionManager.acquirePlaceholderSession(
|
: drmSessionManager.acquirePlaceholderSession(
|
||||||
playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType));
|
playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType));
|
||||||
outputFormatHolder.drmSession = currentDrmSession;
|
outputFormatHolder.drmSession = currentDrmSession;
|
||||||
|
@ -21,6 +21,7 @@ import static java.util.concurrent.TimeUnit.SECONDS;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.testutil.FakeExoMediaDrm;
|
import com.google.android.exoplayer2.testutil.FakeExoMediaDrm;
|
||||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
@ -46,7 +47,8 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
new DrmInitData.SchemeData(
|
new DrmInitData.SchemeData(
|
||||||
DRM_SCHEME_UUID, MimeTypes.VIDEO_MP4, /* data= */ TestUtil.createByteArray(1, 2, 3)));
|
DRM_SCHEME_UUID, MimeTypes.VIDEO_MP4, /* data= */ TestUtil.createByteArray(1, 2, 3)));
|
||||||
private static final DrmInitData DRM_INIT_DATA = new DrmInitData(DRM_SCHEME_DATAS);
|
private static final Format FORMAT_WITH_DRM_INIT_DATA =
|
||||||
|
new Format.Builder().setDrmInitData(new DrmInitData(DRM_SCHEME_DATAS)).build();
|
||||||
|
|
||||||
@Test(timeout = 10_000)
|
@Test(timeout = 10_000)
|
||||||
public void acquireSession_triggersKeyLoadAndSessionIsOpened() throws Exception {
|
public void acquireSession_triggersKeyLoadAndSessionIsOpened() throws Exception {
|
||||||
@ -62,7 +64,7 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
drmSessionManager.acquireSession(
|
drmSessionManager.acquireSession(
|
||||||
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
||||||
/* eventDispatcher= */ null,
|
/* eventDispatcher= */ null,
|
||||||
DRM_INIT_DATA);
|
FORMAT_WITH_DRM_INIT_DATA);
|
||||||
waitForOpenedWithKeys(drmSession);
|
waitForOpenedWithKeys(drmSession);
|
||||||
|
|
||||||
assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
|
assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||||
@ -85,7 +87,7 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
drmSessionManager.acquireSession(
|
drmSessionManager.acquireSession(
|
||||||
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
||||||
/* eventDispatcher= */ null,
|
/* eventDispatcher= */ null,
|
||||||
DRM_INIT_DATA);
|
FORMAT_WITH_DRM_INIT_DATA);
|
||||||
waitForOpenedWithKeys(drmSession);
|
waitForOpenedWithKeys(drmSession);
|
||||||
|
|
||||||
assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
|
assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
|
||||||
@ -110,7 +112,7 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
drmSessionManager.acquireSession(
|
drmSessionManager.acquireSession(
|
||||||
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
||||||
/* eventDispatcher= */ null,
|
/* eventDispatcher= */ null,
|
||||||
DRM_INIT_DATA);
|
FORMAT_WITH_DRM_INIT_DATA);
|
||||||
waitForOpenedWithKeys(drmSession);
|
waitForOpenedWithKeys(drmSession);
|
||||||
drmSession.release(/* eventDispatcher= */ null);
|
drmSession.release(/* eventDispatcher= */ null);
|
||||||
|
|
||||||
@ -132,7 +134,7 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
drmSessionManager.acquireSession(
|
drmSessionManager.acquireSession(
|
||||||
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
||||||
/* eventDispatcher= */ null,
|
/* eventDispatcher= */ null,
|
||||||
DRM_INIT_DATA);
|
FORMAT_WITH_DRM_INIT_DATA);
|
||||||
waitForOpenedWithKeys(drmSession);
|
waitForOpenedWithKeys(drmSession);
|
||||||
drmSession.release(/* eventDispatcher= */ null);
|
drmSession.release(/* eventDispatcher= */ null);
|
||||||
|
|
||||||
@ -147,7 +149,8 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
ImmutableList.of(DRM_SCHEME_DATAS.get(0).copyWithData(TestUtil.createByteArray(4, 5, 6)));
|
ImmutableList.of(DRM_SCHEME_DATAS.get(0).copyWithData(TestUtil.createByteArray(4, 5, 6)));
|
||||||
FakeExoMediaDrm.LicenseServer licenseServer =
|
FakeExoMediaDrm.LicenseServer licenseServer =
|
||||||
FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS, secondSchemeDatas);
|
FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS, secondSchemeDatas);
|
||||||
DrmInitData secondInitData = new DrmInitData(secondSchemeDatas);
|
Format secondFormatWithDrmInitData =
|
||||||
|
new Format.Builder().setDrmInitData(new DrmInitData(secondSchemeDatas)).build();
|
||||||
DrmSessionManager drmSessionManager =
|
DrmSessionManager drmSessionManager =
|
||||||
new DefaultDrmSessionManager.Builder()
|
new DefaultDrmSessionManager.Builder()
|
||||||
.setUuidAndExoMediaDrmProvider(
|
.setUuidAndExoMediaDrmProvider(
|
||||||
@ -161,7 +164,7 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
drmSessionManager.acquireSession(
|
drmSessionManager.acquireSession(
|
||||||
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
||||||
/* eventDispatcher= */ null,
|
/* eventDispatcher= */ null,
|
||||||
DRM_INIT_DATA);
|
FORMAT_WITH_DRM_INIT_DATA);
|
||||||
waitForOpenedWithKeys(firstDrmSession);
|
waitForOpenedWithKeys(firstDrmSession);
|
||||||
firstDrmSession.release(/* eventDispatcher= */ null);
|
firstDrmSession.release(/* eventDispatcher= */ null);
|
||||||
|
|
||||||
@ -172,7 +175,7 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
drmSessionManager.acquireSession(
|
drmSessionManager.acquireSession(
|
||||||
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
||||||
/* eventDispatcher= */ null,
|
/* eventDispatcher= */ null,
|
||||||
secondInitData);
|
secondFormatWithDrmInitData);
|
||||||
// The drmSessionManager had to release firstDrmSession in order to acquire secondDrmSession.
|
// The drmSessionManager had to release firstDrmSession in order to acquire secondDrmSession.
|
||||||
assertThat(firstDrmSession.getState()).isEqualTo(DrmSession.STATE_RELEASED);
|
assertThat(firstDrmSession.getState()).isEqualTo(DrmSession.STATE_RELEASED);
|
||||||
|
|
||||||
@ -195,7 +198,7 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
drmSessionManager.acquireSession(
|
drmSessionManager.acquireSession(
|
||||||
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
||||||
/* eventDispatcher= */ null,
|
/* eventDispatcher= */ null,
|
||||||
DRM_INIT_DATA);
|
FORMAT_WITH_DRM_INIT_DATA);
|
||||||
waitForOpenedWithKeys(firstDrmSession);
|
waitForOpenedWithKeys(firstDrmSession);
|
||||||
firstDrmSession.release(/* eventDispatcher= */ null);
|
firstDrmSession.release(/* eventDispatcher= */ null);
|
||||||
|
|
||||||
@ -207,7 +210,7 @@ public class DefaultDrmSessionManagerTest {
|
|||||||
drmSessionManager.acquireSession(
|
drmSessionManager.acquireSession(
|
||||||
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
/* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()),
|
||||||
/* eventDispatcher= */ null,
|
/* eventDispatcher= */ null,
|
||||||
DRM_INIT_DATA);
|
FORMAT_WITH_DRM_INIT_DATA);
|
||||||
assertThat(secondDrmSession).isSameInstanceAs(firstDrmSession);
|
assertThat(secondDrmSession).isSameInstanceAs(firstDrmSession);
|
||||||
|
|
||||||
// Let the timeout definitely expire, and check the session didn't get released.
|
// Let the timeout definitely expire, and check the session didn't get released.
|
||||||
|
@ -24,6 +24,7 @@ import static org.mockito.Mockito.when;
|
|||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@ -70,7 +71,8 @@ public class OfflineLicenseHelperTest {
|
|||||||
byte[] keySetId = {2, 5, 8};
|
byte[] keySetId = {2, 5, 8};
|
||||||
setStubKeySetId(keySetId);
|
setStubKeySetId(keySetId);
|
||||||
|
|
||||||
byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData());
|
byte[] offlineLicenseKeySetId =
|
||||||
|
offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData());
|
||||||
|
|
||||||
assertOfflineLicenseKeySetIdEqual(keySetId, offlineLicenseKeySetId);
|
assertOfflineLicenseKeySetIdEqual(keySetId, offlineLicenseKeySetId);
|
||||||
|
|
||||||
@ -85,9 +87,9 @@ public class OfflineLicenseHelperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void downloadLicenseFailsIfNullInitData() throws Exception {
|
public void downloadLicenseFailsIfNullDrmInitData() throws Exception {
|
||||||
try {
|
try {
|
||||||
offlineLicenseHelper.downloadLicense(null);
|
offlineLicenseHelper.downloadLicense(new Format.Builder().build());
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// Expected.
|
// Expected.
|
||||||
@ -99,7 +101,7 @@ public class OfflineLicenseHelperTest {
|
|||||||
setStubLicenseAndPlaybackDurationValues(1000, 200);
|
setStubLicenseAndPlaybackDurationValues(1000, 200);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
offlineLicenseHelper.downloadLicense(newDrmInitData());
|
offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData());
|
||||||
fail();
|
fail();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Expected.
|
// Expected.
|
||||||
@ -110,7 +112,8 @@ public class OfflineLicenseHelperTest {
|
|||||||
public void downloadLicenseDoesNotFailIfDurationNotAvailable() throws Exception {
|
public void downloadLicenseDoesNotFailIfDurationNotAvailable() throws Exception {
|
||||||
setDefaultStubKeySetId();
|
setDefaultStubKeySetId();
|
||||||
|
|
||||||
byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData());
|
byte[] offlineLicenseKeySetId =
|
||||||
|
offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData());
|
||||||
|
|
||||||
assertThat(offlineLicenseKeySetId).isNotNull();
|
assertThat(offlineLicenseKeySetId).isNotNull();
|
||||||
}
|
}
|
||||||
@ -122,7 +125,8 @@ public class OfflineLicenseHelperTest {
|
|||||||
setStubLicenseAndPlaybackDurationValues(licenseDuration, playbackDuration);
|
setStubLicenseAndPlaybackDurationValues(licenseDuration, playbackDuration);
|
||||||
setDefaultStubKeySetId();
|
setDefaultStubKeySetId();
|
||||||
|
|
||||||
byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData());
|
byte[] offlineLicenseKeySetId =
|
||||||
|
offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData());
|
||||||
|
|
||||||
Pair<Long, Long> licenseDurationRemainingSec =
|
Pair<Long, Long> licenseDurationRemainingSec =
|
||||||
offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId);
|
offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId);
|
||||||
@ -138,7 +142,8 @@ public class OfflineLicenseHelperTest {
|
|||||||
setStubLicenseAndPlaybackDurationValues(licenseDuration, playbackDuration);
|
setStubLicenseAndPlaybackDurationValues(licenseDuration, playbackDuration);
|
||||||
setDefaultStubKeySetId();
|
setDefaultStubKeySetId();
|
||||||
|
|
||||||
byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData());
|
byte[] offlineLicenseKeySetId =
|
||||||
|
offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData());
|
||||||
|
|
||||||
Pair<Long, Long> licenseDurationRemainingSec =
|
Pair<Long, Long> licenseDurationRemainingSec =
|
||||||
offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId);
|
offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId);
|
||||||
@ -173,8 +178,11 @@ public class OfflineLicenseHelperTest {
|
|||||||
when(mediaDrm.queryKeyStatus(any(byte[].class))).thenReturn(keyStatus);
|
when(mediaDrm.queryKeyStatus(any(byte[].class))).thenReturn(keyStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DrmInitData newDrmInitData() {
|
private static Format newFormatWithDrmInitData() {
|
||||||
return new DrmInitData(
|
return new Format.Builder()
|
||||||
new SchemeData(C.WIDEVINE_UUID, "mimeType", new byte[] {1, 4, 7, 0, 3, 6}));
|
.setDrmInitData(
|
||||||
|
new DrmInitData(
|
||||||
|
new SchemeData(C.WIDEVINE_UUID, "mimeType", new byte[] {1, 4, 7, 0, 3, 6})))
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -665,9 +665,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
for (int j = 0; j < formats.length; j++) {
|
for (int j = 0; j < formats.length; j++) {
|
||||||
Format format = representations.get(j).format;
|
Format format = representations.get(j).format;
|
||||||
formats[j] =
|
formats[j] =
|
||||||
format.copyWithExoMediaCryptoType(
|
format.copyWithExoMediaCryptoType(drmSessionManager.getExoMediaCryptoType(format));
|
||||||
drmSessionManager.getExoMediaCryptoType(
|
|
||||||
format.drmInitData, MimeTypes.getTrackType(format.sampleMimeType)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AdaptationSet firstAdaptationSet = adaptationSets.get(adaptationSetIndices[0]);
|
AdaptationSet firstAdaptationSet = adaptationSets.get(adaptationSetIndices[0]);
|
||||||
|
@ -19,7 +19,6 @@ import android.net.Uri;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
|
||||||
import com.google.android.exoplayer2.extractor.ChunkIndex;
|
import com.google.android.exoplayer2.extractor.ChunkIndex;
|
||||||
import com.google.android.exoplayer2.extractor.Extractor;
|
import com.google.android.exoplayer2.extractor.Extractor;
|
||||||
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
|
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
|
||||||
@ -75,15 +74,15 @@ public final class DashUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads {@link DrmInitData} for a given period in a DASH manifest.
|
* Loads a {@link Format} for acquiring keys for a given period in a DASH manifest.
|
||||||
*
|
*
|
||||||
* @param dataSource The {@link HttpDataSource} from which data should be loaded.
|
* @param dataSource The {@link HttpDataSource} from which data should be loaded.
|
||||||
* @param period The {@link Period}.
|
* @param period The {@link Period}.
|
||||||
* @return The loaded {@link DrmInitData}, or null if none is defined.
|
* @return The loaded {@link Format}, or null if none is defined.
|
||||||
* @throws IOException Thrown when there is an error while loading.
|
* @throws IOException Thrown when there is an error while loading.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static DrmInitData loadDrmInitData(DataSource dataSource, Period period)
|
public static Format loadFormatWithDrmInitData(DataSource dataSource, Period period)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
int primaryTrackType = C.TRACK_TYPE_VIDEO;
|
int primaryTrackType = C.TRACK_TYPE_VIDEO;
|
||||||
Representation representation = getFirstRepresentation(period, primaryTrackType);
|
Representation representation = getFirstRepresentation(period, primaryTrackType);
|
||||||
@ -97,8 +96,8 @@ public final class DashUtil {
|
|||||||
Format manifestFormat = representation.format;
|
Format manifestFormat = representation.format;
|
||||||
Format sampleFormat = DashUtil.loadSampleFormat(dataSource, primaryTrackType, representation);
|
Format sampleFormat = DashUtil.loadSampleFormat(dataSource, primaryTrackType, representation);
|
||||||
return sampleFormat == null
|
return sampleFormat == null
|
||||||
? manifestFormat.drmInitData
|
? manifestFormat
|
||||||
: sampleFormat.withManifestFormatInfo(manifestFormat).drmInitData;
|
: sampleFormat.withManifestFormatInfo(manifestFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,29 +40,29 @@ public final class DashUtilTest {
|
|||||||
@Test
|
@Test
|
||||||
public void loadDrmInitDataFromManifest() throws Exception {
|
public void loadDrmInitDataFromManifest() throws Exception {
|
||||||
Period period = newPeriod(newAdaptationSet(newRepresentation(newDrmInitData())));
|
Period period = newPeriod(newAdaptationSet(newRepresentation(newDrmInitData())));
|
||||||
DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period);
|
Format format = DashUtil.loadFormatWithDrmInitData(DummyDataSource.INSTANCE, period);
|
||||||
assertThat(drmInitData).isEqualTo(newDrmInitData());
|
assertThat(format.drmInitData).isEqualTo(newDrmInitData());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void loadDrmInitDataMissing() throws Exception {
|
public void loadDrmInitDataMissing() throws Exception {
|
||||||
Period period = newPeriod(newAdaptationSet(newRepresentation(null /* no init data */)));
|
Period period = newPeriod(newAdaptationSet(newRepresentation(null /* no init data */)));
|
||||||
DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period);
|
Format format = DashUtil.loadFormatWithDrmInitData(DummyDataSource.INSTANCE, period);
|
||||||
assertThat(drmInitData).isNull();
|
assertThat(format.drmInitData).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void loadDrmInitDataNoRepresentations() throws Exception {
|
public void loadDrmInitDataNoRepresentations() throws Exception {
|
||||||
Period period = newPeriod(newAdaptationSet(/* no representation */ ));
|
Period period = newPeriod(newAdaptationSet(/* no representation */ ));
|
||||||
DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period);
|
Format format = DashUtil.loadFormatWithDrmInitData(DummyDataSource.INSTANCE, period);
|
||||||
assertThat(drmInitData).isNull();
|
assertThat(format).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void loadDrmInitDataNoAdaptationSets() throws Exception {
|
public void loadDrmInitDataNoAdaptationSets() throws Exception {
|
||||||
Period period = newPeriod(/* no adaptation set */ );
|
Period period = newPeriod(/* no adaptation set */ );
|
||||||
DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period);
|
Format format = DashUtil.loadFormatWithDrmInitData(DummyDataSource.INSTANCE, period);
|
||||||
assertThat(drmInitData).isNull();
|
assertThat(format).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Period newPeriod(AdaptationSet... adaptationSets) {
|
private static Period newPeriod(AdaptationSet... adaptationSets) {
|
||||||
|
@ -1319,9 +1319,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
for (int j = 0; j < trackGroup.length; j++) {
|
for (int j = 0; j < trackGroup.length; j++) {
|
||||||
Format format = trackGroup.getFormat(j);
|
Format format = trackGroup.getFormat(j);
|
||||||
exposedFormats[j] =
|
exposedFormats[j] =
|
||||||
format.copyWithExoMediaCryptoType(
|
format.copyWithExoMediaCryptoType(drmSessionManager.getExoMediaCryptoType(format));
|
||||||
drmSessionManager.getExoMediaCryptoType(
|
|
||||||
format.drmInitData, MimeTypes.getTrackType(format.sampleMimeType)));
|
|
||||||
}
|
}
|
||||||
trackGroups[i] = new TrackGroup(exposedFormats);
|
trackGroups[i] = new TrackGroup(exposedFormats);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ import com.google.android.exoplayer2.upstream.Allocator;
|
|||||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -267,9 +266,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
Format manifestFormat = manifestFormats[j];
|
Format manifestFormat = manifestFormats[j];
|
||||||
exposedFormats[j] =
|
exposedFormats[j] =
|
||||||
manifestFormat.copyWithExoMediaCryptoType(
|
manifestFormat.copyWithExoMediaCryptoType(
|
||||||
drmSessionManager.getExoMediaCryptoType(
|
drmSessionManager.getExoMediaCryptoType(manifestFormat));
|
||||||
manifestFormat.drmInitData,
|
|
||||||
MimeTypes.getTrackType(manifestFormat.sampleMimeType)));
|
|
||||||
}
|
}
|
||||||
trackGroups[i] = new TrackGroup(exposedFormats);
|
trackGroups[i] = new TrackGroup(exposedFormats);
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ import android.net.Uri;
|
|||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import androidx.test.rule.ActivityTestRule;
|
import androidx.test.rule.ActivityTestRule;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
|
||||||
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
|
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
||||||
import com.google.android.exoplayer2.drm.OfflineLicenseHelper;
|
import com.google.android.exoplayer2.drm.OfflineLicenseHelper;
|
||||||
@ -213,8 +213,8 @@ public final class DashWidevineOfflineTest {
|
|||||||
DataSource dataSource = httpDataSourceFactory.createDataSource();
|
DataSource dataSource = httpDataSourceFactory.createDataSource();
|
||||||
DashManifest dashManifest = DashUtil.loadManifest(dataSource,
|
DashManifest dashManifest = DashUtil.loadManifest(dataSource,
|
||||||
Uri.parse(DashTestData.WIDEVINE_H264_MANIFEST));
|
Uri.parse(DashTestData.WIDEVINE_H264_MANIFEST));
|
||||||
DrmInitData drmInitData = DashUtil.loadDrmInitData(dataSource, dashManifest.getPeriod(0));
|
Format format = DashUtil.loadFormatWithDrmInitData(dataSource, dashManifest.getPeriod(0));
|
||||||
offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(drmInitData);
|
offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(format);
|
||||||
assertThat(offlineLicenseKeySetId).isNotNull();
|
assertThat(offlineLicenseKeySetId).isNotNull();
|
||||||
assertThat(offlineLicenseKeySetId.length).isGreaterThan(0);
|
assertThat(offlineLicenseKeySetId.length).isGreaterThan(0);
|
||||||
testRunner.setOfflineLicenseKeySetId(offlineLicenseKeySetId);
|
testRunner.setOfflineLicenseKeySetId(offlineLicenseKeySetId);
|
||||||
|
@ -275,7 +275,7 @@ public class FakeSampleStream implements SampleStream {
|
|||||||
Looper playbackLooper = Assertions.checkNotNull(Looper.myLooper());
|
Looper playbackLooper = Assertions.checkNotNull(Looper.myLooper());
|
||||||
currentDrmSession =
|
currentDrmSession =
|
||||||
newDrmInitData != null
|
newDrmInitData != null
|
||||||
? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newDrmInitData)
|
? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newFormat)
|
||||||
: drmSessionManager.acquirePlaceholderSession(
|
: drmSessionManager.acquirePlaceholderSession(
|
||||||
playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType));
|
playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType));
|
||||||
outputFormatHolder.drmSession = currentDrmSession;
|
outputFormatHolder.drmSession = currentDrmSession;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user