Skip to content

Commit

Permalink
feat(android): add multiDrm flag support
Browse files Browse the repository at this point in the history
  • Loading branch information
freeboub committed Jun 27, 2024
1 parent f9fa8fd commit 62e9e9d
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 13 deletions.
9 changes: 9 additions & 0 deletions android/src/main/java/com/brentvatne/common/api/DRMProps.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.brentvatne.common.api

import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetArray
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetBool
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetString
import com.facebook.react.bridge.ReadableMap
import java.util.UUID
Expand Down Expand Up @@ -30,11 +31,17 @@ class DRMProps {
*/
var drmLicenseHeader: Array<String> = emptyArray<String>()

/**
*
*/
var multiDrm: Boolean = false

/** return true if this and src are equals */
override fun equals(other: Any?): Boolean {
if (other == null || other !is DRMProps) return false
return drmType == other.drmType &&
drmLicenseServer == other.drmLicenseServer &&
multiDrm == other.multiDrm &&
drmLicenseHeader.contentDeepEquals(other.drmLicenseHeader) // drmLicenseHeader is never null
}

Expand All @@ -44,6 +51,7 @@ class DRMProps {
private const val PROP_DRM_HEADERS = "headers"
private const val PROP_DRM_HEADERS_KEY = "key"
private const val PROP_DRM_HEADERS_VALUE = "value"
private const val PROP_DRM_MULTI_DRM = "multiDrm"

/** parse the source ReadableMap received from app */
@JvmStatic
Expand All @@ -53,6 +61,7 @@ class DRMProps {
drm = DRMProps()
drm.drmType = safeGetString(src, PROP_DRM_TYPE)
drm.drmLicenseServer = safeGetString(src, PROP_DRM_LICENSE_SERVER)
drm.multiDrm = safeGetBool(src, PROP_DRM_MULTI_DRM, false)
val drmHeadersArray = safeGetArray(src, PROP_DRM_HEADERS)
if (drm.drmType != null && drm.drmLicenseServer != null) {
if (drmHeadersArray != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -791,9 +791,7 @@ private DrmSessionManager initializePlayerDrm() {
if (uuid != null) {
try {
DebugLog.w(TAG, "drm buildDrmSessionManager");
drmSessionManager = buildDrmSessionManager(uuid,
drmProps.getDrmLicenseServer(),
drmProps.getDrmLicenseHeader());
drmSessionManager = buildDrmSessionManager(uuid, drmProps);
} catch (UnsupportedDrmException e) {
int errorStringId = Util.SDK_INT < 18 ? R.string.error_drm_not_supported
: (e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
Expand Down Expand Up @@ -951,21 +949,21 @@ private void cleanupPlaybackService() {
}
}

private DrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl, String[] keyRequestPropertiesArray) throws UnsupportedDrmException {
return buildDrmSessionManager(uuid, licenseUrl, keyRequestPropertiesArray, 0);
private DrmSessionManager buildDrmSessionManager(UUID uuid, DRMProps drmProps) throws UnsupportedDrmException {
return buildDrmSessionManager(uuid, drmProps, 0);
}

private DrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl, String[] keyRequestPropertiesArray, int retryCount) throws UnsupportedDrmException {
private DrmSessionManager buildDrmSessionManager(UUID uuid, DRMProps drmProps, int retryCount) throws UnsupportedDrmException {
if (Util.SDK_INT < 18) {
return null;
}
try {
HttpMediaDrmCallback drmCallback = new HttpMediaDrmCallback(licenseUrl,
HttpMediaDrmCallback drmCallback = new HttpMediaDrmCallback(drmProps.getDrmLicenseServer(),
buildHttpDataSourceFactory(false));
if (keyRequestPropertiesArray != null) {
for (int i = 0; i < keyRequestPropertiesArray.length - 1; i += 2) {
drmCallback.setKeyRequestProperty(keyRequestPropertiesArray[i], keyRequestPropertiesArray[i + 1]);
}

String[] keyRequestPropertiesArray = drmProps.getDrmLicenseHeader();
for (int i = 0; i < keyRequestPropertiesArray.length - 1; i += 2) {
drmCallback.setKeyRequestProperty(keyRequestPropertiesArray[i], keyRequestPropertiesArray[i + 1]);
}
FrameworkMediaDrm mediaDrm = FrameworkMediaDrm.newInstance(uuid);
if (hasDrmFailed) {
Expand All @@ -975,15 +973,15 @@ private DrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl, S
return new DefaultDrmSessionManager.Builder()
.setUuidAndExoMediaDrmProvider(uuid, (_uuid) -> mediaDrm)
.setKeyRequestParameters(null)
.setMultiSession(false)
.setMultiSession(drmProps.getMultiDrm())
.build(drmCallback);
} catch (UnsupportedDrmException ex) {
// Unsupported DRM exceptions are handled by the calling method
throw ex;
} catch (Exception ex) {
if (retryCount < 3) {
// Attempt retry 3 times in case where the OS Media DRM Framework fails for whatever reason
return buildDrmSessionManager(uuid, licenseUrl, keyRequestPropertiesArray, ++retryCount);
return buildDrmSessionManager(uuid, drmProps, ++retryCount);
}
// Handle the unknow exception and emit to JS
eventEmitter.error(ex.toString(), ex, "3006");
Expand Down
7 changes: 7 additions & 0 deletions docs/pages/component/drm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ Default: false

The URL pointing to the licenseServer that will provide the authorization to play the protected stream.

### `multiDrm`
<PlatformsList types={['Android']} />
Type: boolean\
Default: false

Indicates that drm system shall support key rotation, see: https://developer.android.google.cn/media/media3/exoplayer/drm?hl=en#key-rotation

### `type`

<PlatformsList types={['Android', 'iOS']} />
Expand Down
1 change: 1 addition & 0 deletions src/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
certificateUrl: selectedDrm.certificateUrl,
base64Certificate: selectedDrm.base64Certificate,
useExternalGetLicense: !!selectedDrm.getLicense,
multiDrm: selectedDrm.multiDrm,
};

return {
Expand Down
1 change: 1 addition & 0 deletions src/specs/VideoNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type Drm = Readonly<{
certificateUrl?: string; // ios
base64Certificate?: boolean; // ios default: false
useExternalGetLicense?: boolean; // ios
multiDrm?: boolean; // android
}>;

type TextTracks = ReadonlyArray<
Expand Down
1 change: 1 addition & 0 deletions src/types/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export type Drm = Readonly<{
contentId?: string; // ios
certificateUrl?: string; // ios
base64Certificate?: boolean; // ios default: false
multiDrm: boolean; // android
/* eslint-disable @typescript-eslint/no-unused-vars */
getLicense?: (
spcBase64: string,
Expand Down

0 comments on commit 62e9e9d

Please sign in to comment.