Skip to content

Commit

Permalink
Merge branch 'master' of github.com:react-native-video/react-native-v…
Browse files Browse the repository at this point in the history
…ideo into feat/addAnalyticsPlugManagement

# Conflicts:
#	android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
#	examples/basic/ios/Podfile.lock
  • Loading branch information
freeboub committed Jun 18, 2024
2 parents b8a230e + 098a754 commit e67808f
Show file tree
Hide file tree
Showing 20 changed files with 362 additions and 111 deletions.
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@


# [6.2.0](https://github.com/TheWidlarzGroup/react-native-video/compare/v6.1.2...v6.2.0) (2024-06-07)


### Bug Fixes

* **android:** allow notification tap to foreground app ([#3831](https://github.com/TheWidlarzGroup/react-native-video/issues/3831)) ([5c29b48](https://github.com/TheWidlarzGroup/react-native-video/commit/5c29b48747b4a30eb9911daa579baaa93402ba67))
* **android:** android cache header ([#3832](https://github.com/TheWidlarzGroup/react-native-video/issues/3832)) ([c2a1424](https://github.com/TheWidlarzGroup/react-native-video/commit/c2a14240ada24cd7c816bcb1ac942986eb855792))
* **android:** fix null pointer exception at playback start with item metadata ([#3879](https://github.com/TheWidlarzGroup/react-native-video/issues/3879)) ([c2cd752](https://github.com/TheWidlarzGroup/react-native-video/commit/c2cd7529fd9c9a3c8b1ae7b87d0b80e822ca400d))
* **android:** optimize lag on old android ([#3860](https://github.com/TheWidlarzGroup/react-native-video/issues/3860)) ([c2ce66e](https://github.com/TheWidlarzGroup/react-native-video/commit/c2ce66ed26efb975335ee7b229744a9957b0621e))
* **android:** refactor source, fix random DRM issue and crop start on local asset ([#3835](https://github.com/TheWidlarzGroup/react-native-video/issues/3835)) ([bdf3e55](https://github.com/TheWidlarzGroup/react-native-video/commit/bdf3e556d802caa426d098d3f5fffe00dfb96660))
* **android:** video resolution orientation android ([#3862](https://github.com/TheWidlarzGroup/react-native-video/issues/3862)) ([b698b18](https://github.com/TheWidlarzGroup/react-native-video/commit/b698b1837b71f2c93d488c521eb363e236e41aa5))
* ensure progress is sent before `onEnd` callback ([#3872](https://github.com/TheWidlarzGroup/react-native-video/issues/3872)) ([7133c96](https://github.com/TheWidlarzGroup/react-native-video/commit/7133c96cac905f06f7a9bccd21eeb2f7a8a27c06))
* ensure view drop stop playback startup ([#3875](https://github.com/TheWidlarzGroup/react-native-video/issues/3875)) ([ff1e24a](https://github.com/TheWidlarzGroup/react-native-video/commit/ff1e24aaad179656af71443b3db3b9817a98eb92))
* **ios:** don't crash app if view wasn't found ([#3841](https://github.com/TheWidlarzGroup/react-native-video/issues/3841)) ([cd28d37](https://github.com/TheWidlarzGroup/react-native-video/commit/cd28d370d27571b6f42b68e506b0bd1eaa9c770c))
* **ios:** fix notification controls enabled by default ([#3861](https://github.com/TheWidlarzGroup/react-native-video/issues/3861)) ([5c6dfb2](https://github.com/TheWidlarzGroup/react-native-video/commit/5c6dfb26c56c2b9165b25a01b9224c489e2fd2a5))
* **ios:** fix playback status with lifecycle ([#3819](https://github.com/TheWidlarzGroup/react-native-video/issues/3819)) ([1b51c15](https://github.com/TheWidlarzGroup/react-native-video/commit/1b51c1534881216f9975834657e8add1e7fe9621))
* **ios:** Implicit use of 'self' in closure - use 'self.' to make capture semantics explicit ([#3764](https://github.com/TheWidlarzGroup/react-native-video/issues/3764)) ([#3881](https://github.com/TheWidlarzGroup/react-native-video/issues/3881)) ([ac0a9c3](https://github.com/TheWidlarzGroup/react-native-video/commit/ac0a9c3e3a4fec474a963207a343765d1776406d)), closes [#3875](https://github.com/TheWidlarzGroup/react-native-video/issues/3875)


### Features

* add getCurrentPosition to component's ref ([#3824](https://github.com/TheWidlarzGroup/react-native-video/issues/3824)) ([c7f4d7b](https://github.com/TheWidlarzGroup/react-native-video/commit/c7f4d7b83bd09178f945d21e1f252a57ee1c8ab1))
* **android:** allow chunckless preparation ([#3882](https://github.com/TheWidlarzGroup/react-native-video/issues/3882)) ([d4a8c24](https://github.com/TheWidlarzGroup/react-native-video/commit/d4a8c24f65eda5f3ce17263b234e47b667947e08))
* **android:** Change subtitleLayout from child to sibling of layout ([#3830](https://github.com/TheWidlarzGroup/react-native-video/issues/3830)) ([c2cc917](https://github.com/TheWidlarzGroup/react-native-video/commit/c2cc91736852ea8b128e63bee71979d64b805c91))
* **android:** handle increment forward and rewind buttons ([#3818](https://github.com/TheWidlarzGroup/react-native-video/issues/3818)) ([5059e7a](https://github.com/TheWidlarzGroup/react-native-video/commit/5059e7a7f122447a1762249429d5fe289cbb0a4d))

## [6.1.2](https://github.com/TheWidlarzGroup/react-native-video/compare/v6.1.1...v6.1.2) (2024-05-23)


Expand Down
66 changes: 66 additions & 0 deletions android/src/main/java/com/brentvatne/common/api/DRMProps.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.brentvatne.common.api

import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetArray
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetString
import com.facebook.react.bridge.ReadableMap
import java.util.UUID

/**
* Class representing DRM props for host.
* Only generic code here, no reference to the player.
*/
class DRMProps {
/**
* string version of configured UUID for drm prop
*/
var drmType: String? = null

/**
* Configured UUID for drm prop
*/
var drmUUID: UUID? = null

/**
* DRM license server to be used
*/
var drmLicenseServer: String? = null

/**
* DRM Http Header to access to license server
*/
var drmLicenseHeader: Array<String> = emptyArray<String>()
companion object {
private const val PROP_DRM_TYPE = "type"
private const val PROP_DRM_LICENSE_SERVER = "licenseServer"
private const val PROP_DRM_HEADERS = "headers"
private const val PROP_DRM_HEADERS_KEY = "key"
private const val PROP_DRM_HEADERS_VALUE = "value"

/** parse the source ReadableMap received from app */
@JvmStatic
fun parse(src: ReadableMap?): DRMProps? {
var drm: DRMProps? = null
if (src != null && src.hasKey(PROP_DRM_TYPE)) {
drm = DRMProps()
drm.drmType = safeGetString(src, PROP_DRM_TYPE)
drm.drmLicenseServer = safeGetString(src, PROP_DRM_LICENSE_SERVER)
val drmHeadersArray = safeGetArray(src, PROP_DRM_HEADERS)
if (drm.drmType != null && drm.drmLicenseServer != null) {
if (drmHeadersArray != null) {
val drmKeyRequestPropertiesList = ArrayList<String?>()
for (i in 0 until drmHeadersArray.size()) {
val current = drmHeadersArray.getMap(i)
drmKeyRequestPropertiesList.add(safeGetString(current, PROP_DRM_HEADERS_KEY))
drmKeyRequestPropertiesList.add(safeGetString(current, PROP_DRM_HEADERS_VALUE))
}
val array = emptyArray<String>()
drm.drmLicenseHeader = drmKeyRequestPropertiesList.toArray(array)
}
} else {
return null
}
}
return drm
}
}
}
11 changes: 11 additions & 0 deletions android/src/main/java/com/brentvatne/common/api/Source.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import android.text.TextUtils
import com.brentvatne.common.toolbox.DebugLog
import com.brentvatne.common.toolbox.DebugLog.e
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetArray
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetBool
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetInt
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetMap
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetString
import com.facebook.react.bridge.ReadableMap
import java.util.Locale
import java.util.Objects

/**
* Class representing Source props for host.
Expand Down Expand Up @@ -44,6 +46,13 @@ class Source {
/** http header list */
val headers: MutableMap<String, String> = HashMap()

/** enable chunckless preparation for HLS
* see:
*/
var textTracksAllowChuncklessPreparation: Boolean = false

override fun hashCode(): Int = Objects.hash(uriString, uri, startPositionMs, cropStartMs, cropEndMs, extension, metadata, headers)

/** return true if this and src are equals */
override fun equals(other: Any?): Boolean {
if (other == null || other !is Source) return false
Expand Down Expand Up @@ -114,6 +123,7 @@ class Source {
private const val PROP_SRC_TYPE = "type"
private const val PROP_SRC_METADATA = "metadata"
private const val PROP_SRC_HEADERS = "requestHeaders"
private const val PROP_SRC_TEXT_TRACKS_ALLOW_CHUNCKLESS_PREPARATION = "textTracksAllowChunklessPreparation"

@SuppressLint("DiscouragedApi")
private fun getUriFromAssetId(context: Context, uriString: String): Uri? {
Expand Down Expand Up @@ -170,6 +180,7 @@ class Source {
source.cropStartMs = safeGetInt(src, PROP_SRC_CROP_START, -1)
source.cropEndMs = safeGetInt(src, PROP_SRC_CROP_END, -1)
source.extension = safeGetString(src, PROP_SRC_TYPE, null)
source.textTracksAllowChuncklessPreparation = safeGetBool(src, PROP_SRC_TEXT_TRACKS_ALLOW_CHUNCKLESS_PREPARATION, true)

val propSrcHeadersArray = safeGetArray(src, PROP_SRC_HEADERS)
if (propSrcHeadersArray != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
import com.brentvatne.common.api.BufferConfig;
import com.brentvatne.common.api.BufferingStrategy;
import com.brentvatne.common.api.ControlsConfig;
import com.brentvatne.common.api.DRMProps;
import com.brentvatne.common.api.ResizeMode;
import com.brentvatne.common.api.SideLoadedTextTrack;
import com.brentvatne.common.api.SideLoadedTextTrackList;
Expand Down Expand Up @@ -239,9 +240,7 @@ public class ReactExoplayerView extends FrameLayout implements
private float mProgressUpdateInterval = 250.0f;
private boolean playInBackground = false;
private boolean mReportBandwidth = false;
private UUID drmUUID = null;
private String drmLicenseUrl = null;
private String[] drmLicenseHeader = null;
private DRMProps drmProps;
private boolean controls;
private Uri adTagUrl;

Expand Down Expand Up @@ -472,7 +471,7 @@ public void handleOnBackPressed() {
//Handling the fullScreenButton click event
final ImageButton fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen);
fullScreenButton.setOnClickListener(v -> setFullscreen(!isFullscreen));
updateFullScreenButtonVisbility();
updateFullScreenButtonVisibility();
refreshProgressBarVisibility();

// Invoking onPlaybackStateChanged and onPlayWhenReadyChanged events for Player
Expand Down Expand Up @@ -779,10 +778,11 @@ private void initializePlayerCore(ReactExoplayerView self) {

private DrmSessionManager initializePlayerDrm(ReactExoplayerView self) {
DrmSessionManager drmSessionManager = null;
if (self.drmUUID != null) {
if (self.drmProps != null) {
try {
drmSessionManager = self.buildDrmSessionManager(self.drmUUID, self.drmLicenseUrl,
self.drmLicenseHeader);
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
Expand All @@ -799,7 +799,7 @@ private void initializePlayerSource() {
return;
}
DrmSessionManager drmSessionManager = initializePlayerDrm(this);
if (drmSessionManager == null && drmUUID != null) {
if (drmSessionManager == null && drmProps != null && drmProps.getDrmUUID() != null) {
// Failed to intialize DRM session manager - cannot continue
DebugLog.e(TAG, "Failed to initialize DRM Session Manager Framework!");
eventEmitter.error("Failed to initialize DRM Session Manager Framework!", new Exception("DRM Session Manager Framework failure!"), "3003");
Expand Down Expand Up @@ -996,6 +996,8 @@ private MediaSource buildMediaSource(Uri uri, String overrideExtension, DrmSessi
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder()
.setUri(uri);

// refresh custom Metadata
customMetadata = ConfigurationUtils.buildCustomMetadata(source.getMetadata());
if (customMetadata != null) {
mediaItemBuilder.setMediaMetadata(customMetadata);
}
Expand Down Expand Up @@ -1049,7 +1051,7 @@ private MediaSource buildMediaSource(Uri uri, String overrideExtension, DrmSessi

mediaSourceFactory = new HlsMediaSource.Factory(
mediaDataSourceFactory
);
).setAllowChunklessPreparation(source.getTextTracksAllowChuncklessPreparation());
break;
case CONTENT_TYPE_OTHER:
if ("asset".equals(uri.getScheme())) {
Expand Down Expand Up @@ -1767,19 +1769,6 @@ public void setSrc(Source source) {
DataSourceUtil.getDefaultDataSourceFactory(this.themedReactContext, bandwidthMeter,
source.getHeaders());

// refresh custom Metadata
MediaMetadata newCustomMetadata = ConfigurationUtils.buildCustomMetadata(source.getMetadata());

// Apply custom metadata is possible
if (player != null && !Util.areEqual(newCustomMetadata, customMetadata)) {
customMetadata = newCustomMetadata;
MediaItem currentMediaItem = player.getCurrentMediaItem();
if (currentMediaItem != null) {
MediaItem newMediaItem = currentMediaItem.buildUpon().setMediaMetadata(customMetadata).build();
// This will cause video blink/reload but won't louse progress
player.setMediaItem(newMediaItem, false);
}
}
if (!isSourceEqual) {
reloadSource();
}
Expand Down Expand Up @@ -2188,18 +2177,14 @@ public boolean getPreventsDisplaySleepDuringVideoPlayback() {
return preventsDisplaySleepDuringVideoPlayback;
}

private void updateFullScreenButtonVisbility() {
private void updateFullScreenButtonVisibility() {
if (playerControlView != null) {
final ImageButton fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen);
if (controls) {
//Handling the fullScreenButton click event
if (isFullscreen && fullScreenPlayerView != null && !fullScreenPlayerView.isShowing()) {
fullScreenButton.setVisibility(GONE);
} else {
fullScreenButton.setVisibility(VISIBLE);
}
} else {
//Handling the fullScreenButton click event
if (isFullscreen && fullScreenPlayerView != null && !fullScreenPlayerView.isShowing()) {
fullScreenButton.setVisibility(GONE);
} else {
fullScreenButton.setVisibility(VISIBLE);
}
}
}
Expand All @@ -2223,7 +2208,7 @@ public void setFullscreen(boolean fullscreen) {
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(window, window.getDecorView());
if (isFullscreen) {
eventEmitter.fullscreenWillPresent();
if (controls && fullScreenPlayerView != null) {
if (fullScreenPlayerView != null) {
fullScreenPlayerView.show();
}
UiThreadUtil.runOnUiThread(() -> {
Expand All @@ -2234,9 +2219,10 @@ public void setFullscreen(boolean fullscreen) {
});
} else {
eventEmitter.fullscreenWillDismiss();
if (controls && fullScreenPlayerView != null) {
if (fullScreenPlayerView != null) {
fullScreenPlayerView.dismiss();
reLayoutControls();
setControls(controls);
}
UiThreadUtil.runOnUiThread(() -> {
WindowCompat.setDecorFitsSystemWindows(window, true);
Expand All @@ -2245,11 +2231,11 @@ public void setFullscreen(boolean fullscreen) {
});
}
// need to be done at the end to avoid hiding fullscreen control button when fullScreenPlayerView is shown
updateFullScreenButtonVisbility();
updateFullScreenButtonVisibility();
}

public void setUseTextureView(boolean useTextureView) {
boolean finallyUseTextureView = useTextureView && this.drmUUID == null;
boolean finallyUseTextureView = useTextureView && drmProps == null;
exoPlayerView.setUseTextureView(finallyUseTextureView);
}

Expand All @@ -2276,16 +2262,11 @@ public void setBufferConfig(BufferConfig config) {
initializePlayer();
}

public void setDrmType(UUID drmType) {
this.drmUUID = drmType;
}

public void setDrmLicenseUrl(String licenseUrl){
this.drmLicenseUrl = licenseUrl;
}

public void setDrmLicenseHeader(String[] header){
this.drmLicenseHeader = header;
public void setDrm(DRMProps drmProps) {
this.drmProps = drmProps;
if (drmProps != null && drmProps.getDrmType() != null) {
this.drmProps.setDrmUUID(Util.getDrmUuid(drmProps.getDrmType()));
}
}

@Override
Expand Down Expand Up @@ -2328,7 +2309,7 @@ public void setControls(boolean controls) {
this.controls = controls;
if (controls) {
addPlayerControl();
updateFullScreenButtonVisbility();
updateFullScreenButtonVisibility();
} else {
int indexOfPC = indexOfChild(playerControlView);
if (indexOfPC != -1) {
Expand Down
Loading

0 comments on commit e67808f

Please sign in to comment.