From 2e623ca0fb074e64a6125994effb8723f5c4ce59 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet <62574056+freeboub@users.noreply.github.com> Date: Mon, 13 May 2024 19:19:20 +0200 Subject: [PATCH 1/7] fix(avoid): avoid early return in setSrc (#3759) * 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 * fix(android): avoid easly return in setSrc --- .../com/brentvatne/exoplayer/ReactExoplayerView.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 9eb60e2275..441f7610a3 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -1646,14 +1646,13 @@ public void setSrc(final Uri uri, final long startPositionMs, final long cropSta if (this.customMetadata != customMetadata && player != null) { MediaItem currentMediaItem = player.getCurrentMediaItem(); - if (currentMediaItem == null) { - return; - } + if (currentMediaItem != null) { - MediaItem newMediaItem = currentMediaItem.buildUpon().setMediaMetadata(customMetadata).build(); + MediaItem newMediaItem = currentMediaItem.buildUpon().setMediaMetadata(customMetadata).build(); - // This will cause video blink/reload but won't louse progress - player.setMediaItem(newMediaItem, false); + // This will cause video blink/reload but won't louse progress + player.setMediaItem(newMediaItem, false); + } } if (uri != null) { From 9716f4cb363b6cc8378c45f28e9136032965bb87 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet <62574056+freeboub@users.noreply.github.com> Date: Mon, 13 May 2024 19:20:36 +0200 Subject: [PATCH 2/7] Fix(android): avoid video resizing flickering (#3751) * 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 --- .../brentvatne/exoplayer/ExoPlayerView.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java index db56f65659..9b7904c5c3 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java @@ -4,16 +4,13 @@ import androidx.core.content.ContextCompat; import androidx.media3.common.AdViewProvider; import androidx.media3.common.C; -import androidx.media3.common.PlaybackException; -import androidx.media3.common.PlaybackParameters; +import androidx.media3.common.Format; import androidx.media3.common.Player; -import androidx.media3.common.Timeline; import androidx.media3.common.Tracks; import androidx.media3.common.VideoSize; import androidx.media3.common.text.Cue; import androidx.media3.common.util.Assertions; import androidx.media3.exoplayer.ExoPlayer; -import androidx.media3.exoplayer.trackselection.TrackSelectionArray; import androidx.media3.ui.SubtitleView; import android.util.AttributeSet; @@ -27,6 +24,7 @@ import com.brentvatne.common.api.ResizeMode; import com.brentvatne.common.api.SubtitleStyle; +import com.google.common.collect.ImmutableList; import java.util.List; @@ -247,19 +245,22 @@ public void setHideShutterView(boolean hideShutterView) { layout(getLeft(), getTop(), getRight(), getBottom()); }; - private void updateForCurrentTrackSelections() { - if (player == null) { + private void updateForCurrentTrackSelections(Tracks tracks) { + if (tracks == null) { return; } - TrackSelectionArray selections = player.getCurrentTrackSelections(); - for (int i = 0; i < selections.length; i++) { - if (player.getRendererType(i) == C.TRACK_TYPE_VIDEO && selections.get(i) != null) { - // Video enabled so artwork must be hidden. If the shutter is closed, it will be opened in - // onRenderedFirstFrame(). + ImmutableList groups = tracks.getGroups(); + for (Tracks.Group group: groups) { + if (group.getType() == C.TRACK_TYPE_VIDEO && group.length > 0) { + // get the first track of the group to identify aspect ratio + Format format = group.getTrackFormat(0); + + // update aspect ratio ! + layout.setAspectRatio(format.height == 0 ? 1 : (format.width * format.pixelWidthHeightRatio) / format.height); return; } } - // Video disabled so the shutter must be closed. + // no video tracks, in that case refresh shutterView visibility shutterView.setVisibility(this.hideShutterView ? View.INVISIBLE : View.VISIBLE); } @@ -293,8 +294,7 @@ public void onRenderedFirstFrame() { @Override public void onTracksChanged(Tracks tracks) { - updateForCurrentTrackSelections(); + updateForCurrentTrackSelections(tracks); } } - } From b3f08f6c990f4670311e6d918aea191e72673057 Mon Sep 17 00:00:00 2001 From: Krzysztof Moch Date: Mon, 13 May 2024 21:32:51 +0200 Subject: [PATCH 3/7] fix(ios): call `onLoadStart` earlier (#3750) --- examples/basic/ios/Podfile.lock | 8 +++---- ios/Video/RCTVideo.swift | 39 ++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/examples/basic/ios/Podfile.lock b/examples/basic/ios/Podfile.lock index 9223d33499..548f7ee67d 100644 --- a/examples/basic/ios/Podfile.lock +++ b/examples/basic/ios/Podfile.lock @@ -935,7 +935,7 @@ PODS: - React-Mapbuffer (0.74.0): - glog - React-debug - - react-native-video (6.0.0-rc.0): + - react-native-video (6.0.0-rc.1): - DoubleConversion - glog - hermes-engine @@ -949,7 +949,7 @@ PODS: - React-featureflags - React-graphics - React-ImageManager - - react-native-video/Video (= 6.0.0-rc.0) + - react-native-video/Video (= 6.0.0-rc.1) - React-NativeModulesApple - React-RCTFabric - React-rendererdebug @@ -957,7 +957,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-video/Video (6.0.0-rc.0): + - react-native-video/Video (6.0.0-rc.1): - DoubleConversion - glog - hermes-engine @@ -1421,7 +1421,7 @@ SPEC CHECKSUMS: React-jsitracing: 72dce571a387f9d085482142837222c31a8d6c3a React-logger: 03f2f7b955cfe24593a2b8c9705c23e142d1ad24 React-Mapbuffer: 1ab3316cb736411bc641311b4b71e75099ae56ad - react-native-video: 3262598f55f8632e5d4dae90ba63d9d6e09bd563 + react-native-video: 6bcf0049420848ecf85a46bc5ab3225022843fe6 React-nativeconfig: fef0a46effa630d72f137636a990d7df2f6a5f7c React-NativeModulesApple: 8257dd73991f2e410b9c9d12801691439a0dc821 React-perflogger: 271f1111779fef70f9502d1d38da5132e5585230 diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index 80e6707f01..6d425906a0 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -81,6 +81,12 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH } } + private var _isBuffering = false { + didSet { + onVideoBuffer?(["isBuffering": _isBuffering, "target": reactTag as Any]) + } + } + /* IMA Ads */ private var _adTagUrl: String? #if USE_GOOGLE_IMA @@ -375,6 +381,17 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH throw NSError(domain: "", code: 0, userInfo: nil) } + // Perform on next run loop, otherwise onVideoLoadStart is nil + onVideoLoadStart?([ + "src": [ + "uri": _source?.uri ?? NSNull(), + "type": _source?.type ?? NSNull(), + "isNetwork": NSNumber(value: _source?.isNetwork ?? false), + ], + "drm": _drm?.json ?? NSNull(), + "target": reactTag, + ]) + if let uri = source.uri, uri.starts(with: "ph://") { let photoAsset = await RCTVideoUtils.preparePHAsset(uri: uri) return await playerItemPrepareText(asset: photoAsset, assetOptions: nil, uri: source.uri ?? "") @@ -467,16 +484,6 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH _imaAdsManager.setUpAdsLoader() } #endif - // Perform on next run loop, otherwise onVideoLoadStart is nil - onVideoLoadStart?([ - "src": [ - "uri": _source?.uri ?? NSNull(), - "type": _source?.type ?? NSNull(), - "isNetwork": NSNumber(value: _source?.isNetwork ?? false), - ], - "drm": _drm?.json ?? NSNull(), - "target": reactTag, - ]) isSetSourceOngoing = false applyNextSource() } @@ -1296,7 +1303,9 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH } func handleReadyForDisplay(changeObject _: Any, change _: NSKeyValueObservedChange) { - onVideoBuffer?(["isBuffering": false, "target": reactTag as Any]) + if _isBuffering { + _isBuffering = false + } onReadyForDisplay?([ "target": reactTag, ]) @@ -1430,12 +1439,16 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH } func handlePlaybackBufferKeyEmpty(playerItem _: AVPlayerItem, change _: NSKeyValueObservedChange) { - onVideoBuffer?(["isBuffering": true, "target": reactTag as Any]) + if !_isBuffering { + _isBuffering = true + } } // Continue playing (or not if paused) after being paused due to hitting an unbuffered zone. func handlePlaybackLikelyToKeepUp(playerItem _: AVPlayerItem, change _: NSKeyValueObservedChange) { - onVideoBuffer?(["isBuffering": false, "target": reactTag as Any]) + if _isBuffering { + _isBuffering = false + } } func handleTimeControlStatusChange(player: AVPlayer, change: NSKeyValueObservedChange) { From aa854fb4ad576c625a61ba5086d7f66be086db3c Mon Sep 17 00:00:00 2001 From: Krzysztof Moch Date: Mon, 13 May 2024 21:41:24 +0200 Subject: [PATCH 4/7] chore: release v6.0.0-rc.2 --- CHANGELOG.md | 20 ++++++++++++++++++++ package.json | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73b52b245a..cd62b9b241 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ +# [6.0.0-rc.2](https://github.com/TheWidlarzGroup/react-native-video/compare/v6.0.0-rc.1...v6.0.0-rc.2) (2024-05-13) + + +### Bug Fixes + +* **avoid:** avoid early return in setSrc ([#3759](https://github.com/TheWidlarzGroup/react-native-video/issues/3759)) ([2e623ca](https://github.com/TheWidlarzGroup/react-native-video/commit/2e623ca0fb074e64a6125994effb8723f5c4ce59)) +* **ios:** call `onLoadStart` earlier ([#3750](https://github.com/TheWidlarzGroup/react-native-video/issues/3750)) ([b3f08f6](https://github.com/TheWidlarzGroup/react-native-video/commit/b3f08f6c990f4670311e6d918aea191e72673057)) +* **js:** fix onPlaybackStateChanged callback ([#3753](https://github.com/TheWidlarzGroup/react-native-video/issues/3753)) ([f87a793](https://github.com/TheWidlarzGroup/react-native-video/commit/f87a7938c6941c69915477fcf5f08c54a2635597)) +* **ts:** add missing type ([#3757](https://github.com/TheWidlarzGroup/react-native-video/issues/3757)) ([2d94844](https://github.com/TheWidlarzGroup/react-native-video/commit/2d9484499cfb58d86b0aa82872d494a03fe67bba)) + + +### Features + +* **android:** make buffering strategy dynamic ([#3756](https://github.com/TheWidlarzGroup/react-native-video/issues/3756)) ([e420418](https://github.com/TheWidlarzGroup/react-native-video/commit/e420418e8f74894c443bd232e99f9b860e1d0b93)) + + +### Reverts + +* Revert "fix(android): video flickering add playback start (#3746)" (#3748) ([d25629b](https://github.com/TheWidlarzGroup/react-native-video/commit/d25629bb62cb9a7772ec2704f678e0fdf4927d12)), closes [#3746](https://github.com/TheWidlarzGroup/react-native-video/issues/3746) [#3748](https://github.com/TheWidlarzGroup/react-native-video/issues/3748) + # [6.0.0-rc.1](https://github.com/TheWidlarzGroup/react-native-video/compare/v6.0.0-rc.0...v6.0.0-rc.1) (2024-05-08) diff --git a/package.json b/package.json index a0bb59ba67..9333e14387 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-video", - "version": "6.0.0-rc.1", + "version": "6.0.0-rc.2", "description": "A