refactor: move view type and drm in source (#3867)
* perf: ensure we do not provide callback to native if no callback provided from app * chore: rework bufferConfig to make it more generic and reduce ReactExoplayerView code size * chore: improve issue template * fix(android): avoid video view flickering at playback startup * chore(android): refactor DRM props into a dedicated class * Update android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java * chore: fix linter * fix: ensure drm prop is correctly cleaned * feat(android): move viewType (secure texture) & drm inside the source The origianl behavior has been kept for interoperability, but marked as deprecated in doc * chore: fix linter * chore(ios): move drm prop in source like on android * chore: fix linter * chore: clean log * fix: allow to disable secure View * chore: fix viewType resolution (source value was not handled) * chore: use contentDeepEquals instead of manual checks * chore: fix linter * fix: ensure player doesn't start when view is unmounted * Fix/ensure view drop stop playback startup (#3875) * fix: ensure player doesn't start when view is unmounted * chore: revert change * chore: add warning in case of invalid Surface configuration * chore: code clean * fix: simplify surface management * chore: restore previous code * chore: fix typo * chore: code cleanup * feat(android): add multiDrm flag support * docs: update docs * chore: fix ios build * chore: fix deprecated declaration --------- Co-authored-by: Krzysztof Moch <krzysmoch.programs@gmail.com>
This commit is contained in:
@@ -217,7 +217,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
private boolean hasDrmFailed = false;
|
||||
private boolean isUsingContentResolution = false;
|
||||
private boolean selectTrackWhenReady = false;
|
||||
private Handler mainHandler;
|
||||
private final Handler mainHandler;
|
||||
private Runnable mainRunnable;
|
||||
private boolean useCache = false;
|
||||
private ControlsConfig controlsConfig = new ControlsConfig();
|
||||
@@ -241,7 +241,6 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
private float mProgressUpdateInterval = 250.0f;
|
||||
private boolean playInBackground = false;
|
||||
private boolean mReportBandwidth = false;
|
||||
private DRMProps drmProps;
|
||||
private boolean controls;
|
||||
private Uri adTagUrl;
|
||||
|
||||
@@ -311,7 +310,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
this.eventEmitter = new VideoEventEmitter();
|
||||
this.config = config;
|
||||
this.bandwidthMeter = config.getBandwidthMeter();
|
||||
|
||||
mainHandler = new Handler();
|
||||
createViews();
|
||||
|
||||
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
@@ -334,12 +333,9 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
LayoutParams.MATCH_PARENT);
|
||||
exoPlayerView = new ExoPlayerView(getContext());
|
||||
exoPlayerView.setLayoutParams(layoutParams);
|
||||
|
||||
addView(exoPlayerView, 0, layoutParams);
|
||||
|
||||
exoPlayerView.setFocusable(this.focusable);
|
||||
|
||||
mainHandler = new Handler();
|
||||
}
|
||||
|
||||
// LifecycleEventListener implementation
|
||||
@@ -781,19 +777,22 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
}
|
||||
}
|
||||
|
||||
private DrmSessionManager initializePlayerDrm(ReactExoplayerView self) {
|
||||
private DrmSessionManager initializePlayerDrm() {
|
||||
DrmSessionManager drmSessionManager = null;
|
||||
if (self.drmProps != null) {
|
||||
try {
|
||||
drmSessionManager = self.buildDrmSessionManager(self.drmProps.getDrmUUID(),
|
||||
self.drmProps.getDrmLicenseServer(),
|
||||
self.drmProps.getDrmLicenseHeader());
|
||||
} catch (UnsupportedDrmException e) {
|
||||
int errorStringId = 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);
|
||||
eventEmitter.onVideoError.invoke(getResources().getString(errorStringId), e, "3003");
|
||||
return null;
|
||||
DRMProps drmProps = source.getDrmProps();
|
||||
// need to realign UUID in DRM Props from source
|
||||
if (drmProps != null && drmProps.getDrmType() != null) {
|
||||
UUID uuid = Util.getDrmUuid(drmProps.getDrmType());
|
||||
if (uuid != null) {
|
||||
try {
|
||||
DebugLog.w(TAG, "drm buildDrmSessionManager");
|
||||
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
|
||||
? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown);
|
||||
eventEmitter.onVideoError.invoke(getResources().getString(errorStringId), e, "3003");
|
||||
}
|
||||
}
|
||||
}
|
||||
return drmSessionManager;
|
||||
@@ -803,14 +802,14 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
if (source.getUri() == null) {
|
||||
return;
|
||||
}
|
||||
DrmSessionManager drmSessionManager = initializePlayerDrm(this);
|
||||
if (drmSessionManager == null && drmProps != null && drmProps.getDrmUUID() != null) {
|
||||
// Failed to intialize DRM session manager - cannot continue
|
||||
/// init DRM
|
||||
DrmSessionManager drmSessionManager = initializePlayerDrm();
|
||||
if (drmSessionManager == null && source.getDrmProps() != null && source.getDrmProps().getDrmType() != null) {
|
||||
// Failed to initialize DRM session manager - cannot continue
|
||||
DebugLog.e(TAG, "Failed to initialize DRM Session Manager Framework!");
|
||||
eventEmitter.onVideoError.invoke("Failed to initialize DRM Session Manager Framework!", new Exception("DRM Session Manager Framework failure!"), "3003");
|
||||
return;
|
||||
}
|
||||
|
||||
// init source to manage ads and external text tracks
|
||||
ArrayList<MediaSource> mediaSourceList = buildTextSources();
|
||||
MediaSource videoSource = buildMediaSource(source.getUri(), source.getExtension(), drmSessionManager, source.getCropStartMs(), source.getCropEndMs());
|
||||
MediaSource mediaSourceWithAds = null;
|
||||
@@ -945,21 +944,21 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -969,7 +968,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
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
|
||||
@@ -977,7 +976,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
} 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.onVideoError.invoke(ex.toString(), ex, "3006");
|
||||
@@ -1818,7 +1817,9 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
}
|
||||
|
||||
public void setResizeModeModifier(@ResizeMode.Mode int resizeMode) {
|
||||
exoPlayerView.setResizeMode(resizeMode);
|
||||
if (exoPlayerView != null) {
|
||||
exoPlayerView.setResizeMode(resizeMode);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyModifiers() {
|
||||
@@ -2261,13 +2262,6 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
initializePlayer();
|
||||
}
|
||||
|
||||
public void setDrm(DRMProps drmProps) {
|
||||
this.drmProps = drmProps;
|
||||
if (drmProps != null && drmProps.getDrmType() != null) {
|
||||
this.drmProps.setDrmUUID(Util.getDrmUuid(drmProps.getDrmType()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrmKeysLoaded(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId) {
|
||||
DebugLog.d("DRM Info", "onDrmKeysLoaded");
|
||||
|
||||
Reference in New Issue
Block a user