下面列出了android.media.UnsupportedSchemeException#android.media.MediaDrm 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void setOnKeyStatusChangeListener(
final OnKeyStatusChangeListener<? super FrameworkMediaCrypto> listener) {
if (Util.SDK_INT < 23) {
throw new UnsupportedOperationException();
}
mediaDrm.setOnKeyStatusChangeListener(
listener == null
? null
: (mediaDrm, sessionId, keyInfo, hasNewUsableKey) -> {
List<KeyStatus> exoKeyInfo = new ArrayList<>();
for (MediaDrm.KeyStatus keyStatus : keyInfo) {
exoKeyInfo.add(new KeyStatus(keyStatus.getStatusCode(), keyStatus.getKeyId()));
}
listener.onKeyStatusChange(
FrameworkMediaDrm.this, sessionId, exoKeyInfo, hasNewUsableKey);
},
null);
}
@Override
public void setOnKeyStatusChangeListener(
final ExoMediaDrm.OnKeyStatusChangeListener<? super FrameworkMediaCrypto> listener) {
if (Util.SDK_INT < 23) {
throw new UnsupportedOperationException();
}
mediaDrm.setOnKeyStatusChangeListener(listener == null ? null
: new MediaDrm.OnKeyStatusChangeListener() {
@Override
public void onKeyStatusChange(@NonNull MediaDrm md, @NonNull byte[] sessionId,
@NonNull List<MediaDrm.KeyStatus> keyInfo, boolean hasNewUsableKey) {
List<KeyStatus> exoKeyInfo = new ArrayList<>();
for (MediaDrm.KeyStatus keyStatus : keyInfo) {
exoKeyInfo.add(new DefaultKeyStatus(keyStatus.getStatusCode(), keyStatus.getKeyId()));
}
listener.onKeyStatusChange(FrameworkMediaDrm.this, sessionId, exoKeyInfo,
hasNewUsableKey);
}
}, null);
}
@Override
public void setOnKeyStatusChangeListener(
final ExoMediaDrm.OnKeyStatusChangeListener<? super FrameworkMediaCrypto> listener) {
if (Util.SDK_INT < 23) {
throw new UnsupportedOperationException();
}
mediaDrm.setOnKeyStatusChangeListener(listener == null ? null
: new MediaDrm.OnKeyStatusChangeListener() {
@Override
public void onKeyStatusChange(@NonNull MediaDrm md, @NonNull byte[] sessionId,
@NonNull List<MediaDrm.KeyStatus> keyInfo, boolean hasNewUsableKey) {
List<KeyStatus> exoKeyInfo = new ArrayList<>();
for (MediaDrm.KeyStatus keyStatus : keyInfo) {
exoKeyInfo.add(new DefaultKeyStatus(keyStatus.getStatusCode(), keyStatus.getKeyId()));
}
listener.onKeyStatusChange(FrameworkMediaDrm.this, sessionId, exoKeyInfo,
hasNewUsableKey);
}
}, null);
}
@TargetApi(18)
@SuppressWarnings("ResourceType")
private static boolean isL1WidevineAvailable(String videoMimeType) {
try {
// Force L3 if secure decoder is not available.
if (MediaCodecUtil.getDecoderInfo(videoMimeType, true) == null) {
return false;
}
MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID);
String securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY);
mediaDrm.release();
return WIDEVINE_SECURITY_LEVEL_1.equals(securityProperty);
} catch (DecoderQueryException | UnsupportedSchemeException e) {
throw new IllegalStateException(e);
}
}
@SuppressWarnings("deprecation")
@Override
public void handleMessage(Message msg) {
if (openCount == 0 || (state != STATE_OPENED && state != STATE_OPENED_WITH_KEYS)) {
return;
}
switch (msg.what) {
case MediaDrm.EVENT_KEY_REQUIRED:
doLicense();
break;
case MediaDrm.EVENT_KEY_EXPIRED:
// When an already expired key is loaded MediaDrm sends this event immediately. Ignore
// this event if the state isn't STATE_OPENED_WITH_KEYS yet which means we're still
// waiting for key response.
if (state == STATE_OPENED_WITH_KEYS) {
state = STATE_OPENED;
onError(new KeysExpiredException());
}
break;
case MediaDrm.EVENT_PROVISION_REQUIRED:
state = STATE_OPENED;
postProvisionRequest();
break;
}
}
@Override
public KeyRequest getKeyRequest(byte[] scope, byte[] init, String mimeType, int keyType,
HashMap<String, String> optionalParameters) throws NotProvisionedException {
final MediaDrm.KeyRequest request = mediaDrm.getKeyRequest(scope, init, mimeType, keyType,
optionalParameters);
return new KeyRequest() {
@Override
public byte[] getData() {
return request.getData();
}
@Override
public String getDefaultUrl() {
return request.getDefaultUrl();
}
};
}
@TargetApi(Build.VERSION_CODES.M)
private void onSessionMessage(final SessionId sessionId, final MediaDrm.KeyRequest request) {
if (!isNativeMediaDrmBridgeValid()) return;
int requestType = MediaDrm.KeyRequest.REQUEST_TYPE_INITIAL;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestType = request.getRequestType();
} else {
// Prior to M, getRequestType() is not supported. Do our best guess here: Assume
// requests with a URL are renewals and all others are initial requests.
requestType = request.getDefaultUrl().isEmpty()
? MediaDrm.KeyRequest.REQUEST_TYPE_INITIAL
: MediaDrm.KeyRequest.REQUEST_TYPE_RENEWAL;
}
nativeOnSessionMessage(
mNativeMediaDrmBridge, sessionId.emeId(), requestType, request.getData());
}
@Override
public void onKeyStatusChange(MediaDrm md, byte[] drmSessionId,
final List<MediaDrm.KeyStatus> keyInformation, final boolean hasNewUsableKey) {
final SessionId sessionId = getSessionIdByDrmId(drmSessionId);
assert sessionId != null;
assert mSessionManager.get(sessionId) != null;
final boolean isKeyRelease =
mSessionManager.get(sessionId).keyType() == MediaDrm.KEY_TYPE_RELEASE;
deferEventHandleIfNeeded(sessionId, new Runnable() {
@Override
public void run() {
Log.d(TAG,
"KeysStatusChange: " + sessionId.toHexString() + ", "
+ hasNewUsableKey);
onSessionKeysChange(sessionId, getKeysInfo(keyInformation).toArray(),
hasNewUsableKey, isKeyRelease);
}
});
}
@Override
public void onExpirationUpdate(
MediaDrm md, byte[] drmSessionId, final long expirationTime) {
final SessionId sessionId = getSessionIdByDrmId(drmSessionId);
assert sessionId != null;
deferEventHandleIfNeeded(sessionId, new Runnable() {
@Override
public void run() {
Log.d(TAG,
"ExpirationUpdate: " + sessionId.toHexString() + ", " + expirationTime);
onSessionExpirationUpdate(sessionId, expirationTime);
}
});
}
@Override
public void onResult(Boolean success) {
if (!success) {
onPromiseRejected(mPromiseId, "failed to update key after response accepted");
return;
}
Log.d(TAG, "Key successfully %s for session %s", mIsKeyRelease ? "released" : "added",
mSessionId.toHexString());
onPromiseResolved(mPromiseId);
if (!mIsKeyRelease && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
onSessionKeysChange(mSessionId,
getDummyKeysInfo(MediaDrm.KeyStatus.STATUS_USABLE).toArray(), true,
mIsKeyRelease);
}
}
@Override
public void handleMessage(Message msg) {
if (openCount == 0 || (state != STATE_OPENED && state != STATE_OPENED_WITH_KEYS)) {
return;
}
switch (msg.what) {
case MediaDrm.EVENT_KEY_REQUIRED:
postKeyRequest();
return;
case MediaDrm.EVENT_KEY_EXPIRED:
state = STATE_OPENED;
postKeyRequest();
return;
case MediaDrm.EVENT_PROVISION_REQUIRED:
state = STATE_OPENED;
postProvisionRequest();
return;
}
}
@Override
public void setOnKeyStatusChangeListener(
final ExoMediaDrm.OnKeyStatusChangeListener<? super FrameworkMediaCrypto> listener) {
if (Util.SDK_INT < 23) {
throw new UnsupportedOperationException();
}
mediaDrm.setOnKeyStatusChangeListener(
listener == null
? null
: (mediaDrm, sessionId, keyInfo, hasNewUsableKey) -> {
List<KeyStatus> exoKeyInfo = new ArrayList<>();
for (MediaDrm.KeyStatus keyStatus : keyInfo) {
exoKeyInfo.add(new KeyStatus(keyStatus.getStatusCode(), keyStatus.getKeyId()));
}
listener.onKeyStatusChange(
FrameworkMediaDrm.this, sessionId, exoKeyInfo, hasNewUsableKey);
},
null);
}
@Override
public void setOnKeyStatusChangeListener(
final ExoMediaDrm.OnKeyStatusChangeListener<? super FrameworkMediaCrypto> listener) {
if (Util.SDK_INT < 23) {
throw new UnsupportedOperationException();
}
mediaDrm.setOnKeyStatusChangeListener(
listener == null
? null
: (mediaDrm, sessionId, keyInfo, hasNewUsableKey) -> {
List<KeyStatus> exoKeyInfo = new ArrayList<>();
for (MediaDrm.KeyStatus keyStatus : keyInfo) {
exoKeyInfo.add(new KeyStatus(keyStatus.getStatusCode(), keyStatus.getKeyId()));
}
listener.onKeyStatusChange(
FrameworkMediaDrm.this, sessionId, exoKeyInfo, hasNewUsableKey);
},
null);
}
private FrameworkMediaDrm(UUID uuid) throws UnsupportedSchemeException {
Assertions.checkNotNull(uuid);
Assertions.checkArgument(!C.COMMON_PSSH_UUID.equals(uuid), "Use C.CLEARKEY_UUID instead");
this.uuid = uuid;
this.mediaDrm = new MediaDrm(adjustUuid(uuid));
// Creators of an instance automatically acquire ownership of the created instance.
referenceCount = 1;
if (C.WIDEVINE_UUID.equals(uuid) && needsForceWidevineL3Workaround()) {
forceWidevineL3(mediaDrm);
}
}
@Override
public KeyRequest getKeyRequest(
byte[] scope,
@Nullable List<SchemeData> schemeDatas,
int keyType,
@Nullable HashMap<String, String> optionalParameters)
throws NotProvisionedException {
SchemeData schemeData = null;
byte[] initData = null;
String mimeType = null;
if (schemeDatas != null) {
schemeData = getSchemeData(uuid, schemeDatas);
initData = adjustRequestInitData(uuid, Assertions.checkNotNull(schemeData.data));
mimeType = adjustRequestMimeType(uuid, schemeData.mimeType);
}
MediaDrm.KeyRequest request =
mediaDrm.getKeyRequest(scope, initData, mimeType, keyType, optionalParameters);
byte[] requestData = adjustRequestData(uuid, request.getData());
String licenseServerUrl = request.getDefaultUrl();
if (MOCK_LA_URL_VALUE.equals(licenseServerUrl)) {
licenseServerUrl = "";
}
if (TextUtils.isEmpty(licenseServerUrl)
&& schemeData != null
&& !TextUtils.isEmpty(schemeData.licenseServerUrl)) {
licenseServerUrl = schemeData.licenseServerUrl;
}
return new KeyRequest(requestData, licenseServerUrl);
}
private FrameworkMediaDrm(UUID uuid) throws UnsupportedSchemeException {
Assertions.checkNotNull(uuid);
Assertions.checkArgument(!C.COMMON_PSSH_UUID.equals(uuid), "Use C.CLEARKEY_UUID instead");
// ClearKey had to be accessed using the Common PSSH UUID prior to API level 27.
uuid = Util.SDK_INT < 27 && C.CLEARKEY_UUID.equals(uuid) ? C.COMMON_PSSH_UUID : uuid;
this.uuid = uuid;
this.mediaDrm = new MediaDrm(uuid);
if (C.WIDEVINE_UUID.equals(uuid) && needsForceL3Workaround()) {
mediaDrm.setPropertyString("securityLevel", "L3");
}
}
@Override
public void setOnEventListener(
final ExoMediaDrm.OnEventListener<? super FrameworkMediaCrypto> listener) {
mediaDrm.setOnEventListener(listener == null ? null : new MediaDrm.OnEventListener() {
@Override
public void onEvent(@NonNull MediaDrm md, @Nullable byte[] sessionId, int event, int extra,
byte[] data) {
listener.onEvent(FrameworkMediaDrm.this, sessionId, event, extra, data);
}
});
}
@Override
public KeyRequest getKeyRequest(byte[] scope, byte[] init, String mimeType, int keyType,
HashMap<String, String> optionalParameters) throws NotProvisionedException {
// Prior to L the Widevine CDM required data to be extracted from the PSSH atom. Some Amazon
// devices also required data to be extracted from the PSSH atom for PlayReady.
if ((Util.SDK_INT < 21 && C.WIDEVINE_UUID.equals(uuid))
|| (C.PLAYREADY_UUID.equals(uuid)
&& "Amazon".equals(Util.MANUFACTURER)
&& ("AFTB".equals(Util.MODEL) // Fire TV Gen 1
|| "AFTS".equals(Util.MODEL) // Fire TV Gen 2
|| "AFTM".equals(Util.MODEL)))) { // Fire TV Stick Gen 1
byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(init, uuid);
if (psshData == null) {
// Extraction failed. schemeData isn't a PSSH atom, so leave it unchanged.
} else {
init = psshData;
}
}
// Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
if (Util.SDK_INT < 26
&& C.CLEARKEY_UUID.equals(uuid)
&& (MimeTypes.VIDEO_MP4.equals(mimeType) || MimeTypes.AUDIO_MP4.equals(mimeType))) {
mimeType = CENC_SCHEME_MIME_TYPE;
}
final MediaDrm.KeyRequest request = mediaDrm.getKeyRequest(scope, init, mimeType, keyType,
optionalParameters);
byte[] requestData = request.getData();
if (C.CLEARKEY_UUID.equals(uuid)) {
requestData = ClearKeyUtil.adjustRequestData(requestData);
}
return new DefaultKeyRequest(requestData, request.getDefaultUrl());
}
private FrameworkMediaDrm(UUID uuid) throws UnsupportedSchemeException {
Assertions.checkNotNull(uuid);
Assertions.checkArgument(!C.COMMON_PSSH_UUID.equals(uuid), "Use C.CLEARKEY_UUID instead");
// ClearKey had to be accessed using the Common PSSH UUID prior to API level 27.
uuid = Util.SDK_INT < 27 && C.CLEARKEY_UUID.equals(uuid) ? C.COMMON_PSSH_UUID : uuid;
this.uuid = uuid;
this.mediaDrm = new MediaDrm(uuid);
if (C.WIDEVINE_UUID.equals(uuid) && needsForceL3Workaround()) {
mediaDrm.setPropertyString("securityLevel", "L3");
}
}
@Override
public void setOnEventListener(
final ExoMediaDrm.OnEventListener<? super FrameworkMediaCrypto> listener) {
mediaDrm.setOnEventListener(listener == null ? null : new MediaDrm.OnEventListener() {
@Override
public void onEvent(@NonNull MediaDrm md, @Nullable byte[] sessionId, int event, int extra,
byte[] data) {
listener.onEvent(FrameworkMediaDrm.this, sessionId, event, extra, data);
}
});
}
@Override
public KeyRequest getKeyRequest(byte[] scope, byte[] init, String mimeType, int keyType,
HashMap<String, String> optionalParameters) throws NotProvisionedException {
// Prior to L the Widevine CDM required data to be extracted from the PSSH atom. Some Amazon
// devices also required data to be extracted from the PSSH atom for PlayReady.
if ((Util.SDK_INT < 21 && C.WIDEVINE_UUID.equals(uuid))
|| (C.PLAYREADY_UUID.equals(uuid)
&& "Amazon".equals(Util.MANUFACTURER)
&& ("AFTB".equals(Util.MODEL) // Fire TV Gen 1
|| "AFTS".equals(Util.MODEL) // Fire TV Gen 2
|| "AFTM".equals(Util.MODEL)))) { // Fire TV Stick Gen 1
byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(init, uuid);
if (psshData == null) {
// Extraction failed. schemeData isn't a PSSH atom, so leave it unchanged.
} else {
init = psshData;
}
}
// Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
if (Util.SDK_INT < 26
&& C.CLEARKEY_UUID.equals(uuid)
&& (MimeTypes.VIDEO_MP4.equals(mimeType) || MimeTypes.AUDIO_MP4.equals(mimeType))) {
mimeType = CENC_SCHEME_MIME_TYPE;
}
final MediaDrm.KeyRequest request = mediaDrm.getKeyRequest(scope, init, mimeType, keyType,
optionalParameters);
byte[] requestData = request.getData();
if (C.CLEARKEY_UUID.equals(uuid)) {
requestData = ClearKeyUtil.adjustRequestData(requestData);
}
return new DefaultKeyRequest(requestData, request.getDefaultUrl());
}
@Override
public void setOnEventListener(
final ExoMediaDrm.OnEventListener<? super FrameworkMediaCrypto> listener) {
mediaDrm.setOnEventListener(listener == null ? null : new MediaDrm.OnEventListener() {
@Override
public void onEvent(MediaDrm md, byte[] sessionId, int event, int extra, byte[] data) {
listener.onEvent(FrameworkMediaDrm.this, sessionId, event, extra, data);
}
});
}
@Override
public ProvisionRequest getProvisionRequest() {
final MediaDrm.ProvisionRequest provisionRequest = mediaDrm.getProvisionRequest();
return new ProvisionRequest() {
@Override
public byte[] getData() {
return provisionRequest.getData();
}
@Override
public String getDefaultUrl() {
return provisionRequest.getDefaultUrl();
}
};
}
/**
* Check whether the crypto scheme is supported for the given container.
* If |containerMimeType| is an empty string, we just return whether
* the crypto scheme is supported.
*
* @return true if the container and the crypto scheme is supported, or
* false otherwise.
*/
@CalledByNative
private static boolean isCryptoSchemeSupported(byte[] schemeUUID, String containerMimeType) {
UUID cryptoScheme = getUUIDFromBytes(schemeUUID);
if (containerMimeType.isEmpty()) {
return MediaDrm.isCryptoSchemeSupported(cryptoScheme);
}
return MediaDrm.isCryptoSchemeSupported(cryptoScheme, containerMimeType);
}
/**
* Get a key request.
*
* @param sessionId ID of session on which we need to get the key request.
* @param data Data needed to get the key request.
* @param mime Mime type to get the key request.
* @param keyType Key type for the requested key.
* @param optionalParameters Optional parameters to pass to the DRM plugin.
*
* @return the key request.
*/
private MediaDrm.KeyRequest getKeyRequest(SessionId sessionId, byte[] data, String mime,
int keyType, HashMap<String, String> optionalParameters)
throws android.media.NotProvisionedException {
assert mMediaDrm != null;
assert mMediaCryptoSession != null;
assert !mProvisioningPending;
if (optionalParameters == null) {
optionalParameters = new HashMap<String, String>();
}
MediaDrm.KeyRequest request = null;
try {
byte[] scopeId =
keyType == MediaDrm.KEY_TYPE_RELEASE ? sessionId.keySetId() : sessionId.drmId();
assert scopeId != null;
request = mMediaDrm.getKeyRequest(scopeId, data, mime, keyType, optionalParameters);
} catch (IllegalStateException e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && e
instanceof android.media.MediaDrm.MediaDrmStateException) {
// See b/21307186 for details.
Log.e(TAG, "MediaDrmStateException fired during getKeyRequest().", e);
}
}
String result = (request != null) ? "successed" : "failed";
Log.d(TAG, "getKeyRequest %s!", result);
return request;
}
private List<KeyStatus> getKeysInfo(List<MediaDrm.KeyStatus> keyInformation) {
List<KeyStatus> keysInfo = new ArrayList<KeyStatus>();
for (MediaDrm.KeyStatus keyStatus : keyInformation) {
keysInfo.add(new KeyStatus(keyStatus.getKeyId(), keyStatus.getStatusCode()));
}
return keysInfo;
}
/**
* @param uuid The UUID of the drm scheme.
* @param playbackLooper The looper associated with the media playback thread. Should usually be
* obtained using {@link com.google.android.exoplayer.ExoPlayer#getPlaybackLooper()}.
* @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 UnsupportedSchemeException If the specified DRM scheme is not supported.
*/
public StreamingDrmSessionManager(UUID uuid, Looper playbackLooper, MediaDrmCallback callback,
HashMap<String, String> optionalKeyRequestParameters, Handler eventHandler,
EventListener eventListener) throws UnsupportedSchemeException {
this.uuid = uuid;
this.callback = callback;
this.optionalKeyRequestParameters = optionalKeyRequestParameters;
this.eventHandler = eventHandler;
this.eventListener = eventListener;
mediaDrm = new MediaDrm(uuid);
mediaDrm.setOnEventListener(new MediaDrmEventListener());
mediaDrmHandler = new MediaDrmHandler(playbackLooper);
postResponseHandler = new PostResponseHandler(playbackLooper);
state = STATE_CLOSED;
}
private void postKeyRequest() {
KeyRequest keyRequest;
try {
keyRequest = mediaDrm.getKeyRequest(sessionId, schemePsshData, mimeType,
MediaDrm.KEY_TYPE_STREAMING, optionalKeyRequestParameters);
postRequestHandler.obtainMessage(MSG_KEYS, keyRequest).sendToTarget();
} catch (NotProvisionedException e) {
onKeysError(e);
}
}
private FrameworkMediaDrm(UUID uuid) throws UnsupportedSchemeException {
Assertions.checkNotNull(uuid);
Assertions.checkArgument(!C.COMMON_PSSH_UUID.equals(uuid), "Use C.CLEARKEY_UUID instead");
this.uuid = uuid;
this.mediaDrm = new MediaDrm(adjustUuid(uuid));
if (C.WIDEVINE_UUID.equals(uuid) && needsForceWidevineL3Workaround()) {
forceWidevineL3(mediaDrm);
}
}
@Override
public KeyRequest getKeyRequest(
byte[] scope,
@Nullable List<DrmInitData.SchemeData> schemeDatas,
int keyType,
@Nullable HashMap<String, String> optionalParameters)
throws NotProvisionedException {
SchemeData schemeData = null;
byte[] initData = null;
String mimeType = null;
if (schemeDatas != null) {
schemeData = getSchemeData(uuid, schemeDatas);
initData = adjustRequestInitData(uuid, Assertions.checkNotNull(schemeData.data));
mimeType = adjustRequestMimeType(uuid, schemeData.mimeType);
}
MediaDrm.KeyRequest request =
mediaDrm.getKeyRequest(scope, initData, mimeType, keyType, optionalParameters);
byte[] requestData = adjustRequestData(uuid, request.getData());
String licenseServerUrl = request.getDefaultUrl();
if (MOCK_LA_URL_VALUE.equals(licenseServerUrl)) {
licenseServerUrl = "";
}
if (TextUtils.isEmpty(licenseServerUrl)
&& schemeData != null
&& !TextUtils.isEmpty(schemeData.licenseServerUrl)) {
licenseServerUrl = schemeData.licenseServerUrl;
}
return new KeyRequest(requestData, licenseServerUrl);
}