From aaa961296b3d735ffaa0be480703a395b8de383d Mon Sep 17 00:00:00 2001 From: Sunbreak Date: Thu, 9 Mar 2023 16:41:11 +0800 Subject: [PATCH 01/12] fix: remove dummy nativeOnly --- Video.js | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Video.js b/Video.js index 808c0a51..dc451d3e 100644 --- a/Video.js +++ b/Video.js @@ -416,13 +416,6 @@ Video.propTypes = { FilterType.SEPIA, ]), filterEnabled: PropTypes.bool, - /* Native only */ - src: PropTypes.object, - seek: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.object, - ]), - fullscreen: PropTypes.bool, onVideoLoadStart: PropTypes.func, onVideoLoad: PropTypes.func, onVideoBuffer: PropTypes.func, @@ -566,10 +559,4 @@ Video.propTypes = { ...ViewPropTypes, }; -const RCTVideo = requireNativeComponent('RCTVideo', Video, { - nativeOnly: { - src: true, - seek: true, - fullscreen: true, - }, -}); +const RCTVideo = requireNativeComponent('RCTVideo'); From 7f3d707628fc4cfa1bb5de8ac616f1d23a4961a7 Mon Sep 17 00:00:00 2001 From: Roland Yeghiazaryan Date: Thu, 15 Jun 2023 10:56:37 +0200 Subject: [PATCH 02/12] Fix ids in exo_player_control_view --- .../res/layout/exo_player_control_view.xml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/android/src/main/res/layout/exo_player_control_view.xml b/android/src/main/res/layout/exo_player_control_view.xml index 19440912..27d3883e 100644 --- a/android/src/main/res/layout/exo_player_control_view.xml +++ b/android/src/main/res/layout/exo_player_control_view.xml @@ -14,27 +14,27 @@ android:paddingTop="4dp" android:orientation="horizontal"> - - - - - - @@ -46,7 +46,7 @@ android:gravity="center_vertical" android:orientation="horizontal"> - - Date: Mon, 3 Jul 2023 22:12:44 +0200 Subject: [PATCH 03/12] feat: RN 0.73 support Adds `namespace` prop which is required by Gradle 8 (dep. of RN 0.73) --- android/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/android/build.gradle b/android/build.gradle index 0c3969c9..de702f92 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -17,6 +17,7 @@ def configStringPath = ( ).md5() android { + namespace 'com.brentvatne.react' compileSdkVersion safeExtGet('compileSdkVersion', 31) buildToolsVersion safeExtGet('buildToolsVersion', '30.0.2') From 12d7dd6d8b578c3049cbd461882406472af34059 Mon Sep 17 00:00:00 2001 From: Cedric Guinoiseau Date: Thu, 6 Jul 2023 09:33:05 +0200 Subject: [PATCH 04/12] fix: issue 2744, call replaceCurrentItem in dispatch thread --- ios/Video/RCTVideo.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index 264b1de3..82a604f2 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -310,7 +310,10 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH } self._player = self._player ?? AVPlayer() - self._player?.replaceCurrentItem(with: playerItem) + // https://github.com/react-native-video/react-native-video/issues/2744#issuecomment-1237459473 + DispatchQueue.global(qos: .default).async { [weak self] in + self?._player?.replaceCurrentItem(with: playerItem) + } self._playerObserver.player = self._player self.applyModifiers() self._player?.actionAtItemEnd = .none From d526479fe0983cbd1aa1a4a6ab1dd1ba82e85bb7 Mon Sep 17 00:00:00 2001 From: Cedric Guinoiseau Date: Thu, 6 Jul 2023 09:37:02 +0200 Subject: [PATCH 05/12] fix: issue 3040, prevent crash --- ios/Video/RCTVideo.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index 82a604f2..fbfd635b 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -665,6 +665,11 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH self.onVideoFullscreenPlayerWillPresent?(["target": reactTag as Any]) if let playerViewController = _playerViewController { + if(_controls) { + // prevents crash https://github.com/react-native-video/react-native-video/issues/3040 + self._playerViewController?.removeFromParent() + } + viewController.present(playerViewController, animated:true, completion:{ self._playerViewController?.showsPlaybackControls = self._controls self._fullscreenPlayerPresented = fullscreen From 50b3650e2fe5a2624559f50bc81f4481be2475ee Mon Sep 17 00:00:00 2001 From: Cedric Guinoiseau Date: Thu, 6 Jul 2023 09:52:33 +0200 Subject: [PATCH 06/12] fix: memory leak due to [weak self] and delegate not being weak --- ios/Video/Features/RCTIMAAdsManager.swift | 17 ++++++++++------- ios/Video/Features/RCTPlayerObserver.swift | 19 +++++++++++++------ ios/Video/RCTVideo.swift | 10 ++++++---- ios/Video/RCTVideoPlayerViewController.swift | 10 ++++------ 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/ios/Video/Features/RCTIMAAdsManager.swift b/ios/Video/Features/RCTIMAAdsManager.swift index 44aff4be..d069af72 100644 --- a/ios/Video/Features/RCTIMAAdsManager.swift +++ b/ios/Video/Features/RCTIMAAdsManager.swift @@ -4,7 +4,7 @@ import GoogleInteractiveMediaAds class RCTIMAAdsManager: NSObject, IMAAdsLoaderDelegate, IMAAdsManagerDelegate { - private var _video:RCTVideo + private weak var _video: RCTVideo? /* Entry point for the SDK. Used to make ad requests. */ private var adsLoader: IMAAdsLoader! @@ -23,6 +23,7 @@ class RCTIMAAdsManager: NSObject, IMAAdsLoaderDelegate, IMAAdsManagerDelegate { } func requestAds() { + guard let _video = _video else {return} // Create ad display container for ad rendering. let adDisplayContainer = IMAAdDisplayContainer(adContainer: _video, viewController: _video.reactViewController()) @@ -54,6 +55,7 @@ class RCTIMAAdsManager: NSObject, IMAAdsLoaderDelegate, IMAAdsManagerDelegate { // MARK: - IMAAdsLoaderDelegate func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) { + guard let _video = _video else {return} // Grab the instance of the IMAAdsManager and set yourself as the delegate. adsManager = adsLoadedData.adsManager adsManager?.delegate = self @@ -71,12 +73,13 @@ class RCTIMAAdsManager: NSObject, IMAAdsLoaderDelegate, IMAAdsManagerDelegate { print("Error loading ads: " + adErrorData.adError.message!) } - _video.setPaused(false) + _video?.setPaused(false) } // MARK: - IMAAdsManagerDelegate func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) { + guard let _video = _video else {return} // Mute ad if the main player is muted if (_video.isMuted()) { adsManager.volume = 0; @@ -102,19 +105,19 @@ class RCTIMAAdsManager: NSObject, IMAAdsLoaderDelegate, IMAAdsManagerDelegate { } // Fall back to playing content - _video.setPaused(false) + _video?.setPaused(false) } func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) { // Pause the content for the SDK to play ads. - _video.setPaused(true) - _video.setAdPlaying(true) + _video?.setPaused(true) + _video?.setAdPlaying(true) } func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) { // Resume the content since the SDK is done playing ads (at least for now). - _video.setAdPlaying(false) - _video.setPaused(false) + _video?.setAdPlaying(false) + _video?.setPaused(false) } // MARK: - Helpers diff --git a/ios/Video/Features/RCTPlayerObserver.swift b/ios/Video/Features/RCTPlayerObserver.swift index 68fc56dd..9e798dc3 100644 --- a/ios/Video/Features/RCTPlayerObserver.swift +++ b/ios/Video/Features/RCTPlayerObserver.swift @@ -25,7 +25,7 @@ protocol RCTPlayerObserverHandler: RCTPlayerObserverHandlerObjc { class RCTPlayerObserver: NSObject { - var _handlers: RCTPlayerObserverHandler! + weak var _handlers: RCTPlayerObserverHandler? var player:AVPlayer? { willSet { @@ -84,11 +84,13 @@ class RCTPlayerObserver: NSObject { private var _playerViewControllerOverlayFrameObserver:NSKeyValueObservation? deinit { - NotificationCenter.default.removeObserver(_handlers) + if let _handlers = _handlers { + NotificationCenter.default.removeObserver(_handlers) + } } func addPlayerObservers() { - guard let player = player else { + guard let player = player, let _handlers = _handlers else { return } @@ -102,7 +104,7 @@ class RCTPlayerObserver: NSObject { } func addPlayerItemObservers() { - guard let playerItem = playerItem else { return } + guard let playerItem = playerItem, let _handlers = _handlers else { return } _playerItemStatusObserver = playerItem.observe(\.status, options: [.new, .old], changeHandler: _handlers.handlePlayerItemStatusChange) _playerPlaybackBufferEmptyObserver = playerItem.observe(\.isPlaybackBufferEmpty, options: [.new, .old], changeHandler: _handlers.handlePlaybackBufferKeyEmpty) @@ -118,7 +120,7 @@ class RCTPlayerObserver: NSObject { } func addPlayerViewControllerObservers() { - guard let playerViewController = playerViewController else { return } + guard let playerViewController = playerViewController, let _handlers = _handlers else { return } _playerViewControllerReadyForDisplayObserver = playerViewController.observe(\.isReadyForDisplay, options: [.new], changeHandler: _handlers.handleReadyForDisplay) @@ -131,6 +133,7 @@ class RCTPlayerObserver: NSObject { } func addPlayerLayerObserver() { + guard let _handlers = _handlers else {return} _playerLayerReadyForDisplayObserver = playerLayer?.observe(\.isReadyForDisplay, options: [.new], changeHandler: _handlers.handleReadyForDisplay) } @@ -139,6 +142,7 @@ class RCTPlayerObserver: NSObject { } func addPlayerTimeObserver() { + guard let _handlers = _handlers else {return} removePlayerTimeObserver() let progressUpdateIntervalMS:Float64 = _progressUpdateInterval / 1000 // @see endScrubbing in AVPlayerDemoPlaybackViewController.m @@ -174,6 +178,7 @@ class RCTPlayerObserver: NSObject { } func attachPlayerEventListeners() { + guard let _handlers = _handlers else {return} NotificationCenter.default.removeObserver(_handlers, name:NSNotification.Name.AVPlayerItemDidPlayToEndTime, @@ -202,6 +207,8 @@ class RCTPlayerObserver: NSObject { func clearPlayer() { player = nil playerItem = nil - NotificationCenter.default.removeObserver(_handlers) + if let _handlers = _handlers { + NotificationCenter.default.removeObserver(_handlers) + } } } diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index fbfd635b..4afeb851 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -246,7 +246,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH // MARK: - Player and source @objc func setSrc(_ source:NSDictionary!) { - DispatchQueue.global(qos: .default).async { + DispatchQueue.global(qos: .default).async { [weak self] in + guard let self = self else {return} self._source = VideoSource(source) if (self._source?.uri == nil || self._source?.uri == "") { self._player?.replaceCurrentItem(with: nil) @@ -670,7 +671,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH self._playerViewController?.removeFromParent() } - viewController.present(playerViewController, animated:true, completion:{ + viewController.present(playerViewController, animated:true, completion:{ [weak self] in + guard let self = self else {return} self._playerViewController?.showsPlaybackControls = self._controls self._fullscreenPlayerPresented = fullscreen self._playerViewController?.autorotate = self._fullscreenAutorotate @@ -682,8 +684,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH } } else if !fullscreen && _fullscreenPlayerPresented, let _playerViewController = _playerViewController { self.videoPlayerViewControllerWillDismiss(playerViewController: _playerViewController) - _presentingViewController?.dismiss(animated: true, completion:{ - self.videoPlayerViewControllerDidDismiss(playerViewController: _playerViewController) + _presentingViewController?.dismiss(animated: true, completion:{[weak self] in + self?.videoPlayerViewControllerDidDismiss(playerViewController: _playerViewController) }) } } diff --git a/ios/Video/RCTVideoPlayerViewController.swift b/ios/Video/RCTVideoPlayerViewController.swift index e398e62f..1abbc384 100644 --- a/ios/Video/RCTVideoPlayerViewController.swift +++ b/ios/Video/RCTVideoPlayerViewController.swift @@ -2,7 +2,7 @@ import AVKit class RCTVideoPlayerViewController: AVPlayerViewController { - var rctDelegate:RCTVideoPlayerViewControllerDelegate! + weak var rctDelegate: RCTVideoPlayerViewControllerDelegate? // Optional paramters var preferredOrientation:String? @@ -19,11 +19,9 @@ class RCTVideoPlayerViewController: AVPlayerViewController { override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) - - if rctDelegate != nil { - rctDelegate.videoPlayerViewControllerWillDismiss(playerViewController: self) - rctDelegate.videoPlayerViewControllerDidDismiss(playerViewController: self) - } + + rctDelegate?.videoPlayerViewControllerWillDismiss(playerViewController: self) + rctDelegate?.videoPlayerViewControllerDidDismiss(playerViewController: self) } #if !TARGET_OS_TV From 238daf8720ab6c1a4a53004b3dbd93c0be47f3ba Mon Sep 17 00:00:00 2001 From: Cedric Guinoiseau Date: Thu, 6 Jul 2023 11:16:49 +0200 Subject: [PATCH 07/12] fix: issue 3085, onFullscreen call backs are never fired --- ios/Video/RCTVideo.swift | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index 4afeb851..f33f5859 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -59,6 +59,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH private var _fullscreenAutorotate:Bool = true private var _fullscreenOrientation:String! = "all" private var _fullscreenPlayerPresented:Bool = false + private var _fullscreenUncontrolPlayerPresented:Bool = false // to call events switching full screen mode from player controls private var _filterName:String! private var _filterEnabled:Bool = false private var _presentingViewController:UIViewController? @@ -1113,12 +1114,27 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH let oldRect = change.oldValue let newRect = change.newValue if !oldRect!.equalTo(newRect!) { + // https://github.com/react-native-video/react-native-video/issues/3085#issuecomment-1557293391 if newRect!.equalTo(UIScreen.main.bounds) { RCTLog("in fullscreen") + if (!_fullscreenUncontrolPlayerPresented) { + _fullscreenUncontrolPlayerPresented = true; - self.reactViewController().view.frame = UIScreen.main.bounds - self.reactViewController().view.setNeedsLayout() - } else {NSLog("not fullscreen")} + self.onVideoFullscreenPlayerWillPresent?(["target": self.reactTag as Any]) + self.onVideoFullscreenPlayerDidPresent?(["target": self.reactTag as Any]) + } + } else { + NSLog("not fullscreen") + if (_fullscreenUncontrolPlayerPresented) { + _fullscreenUncontrolPlayerPresented = false; + + self.onVideoFullscreenPlayerWillDismiss?(["target": self.reactTag as Any]) + self.onVideoFullscreenPlayerDidDismiss?(["target": self.reactTag as Any]) + } + } + + self.reactViewController().view.frame = UIScreen.main.bounds + self.reactViewController().view.setNeedsLayout() } } From 8723114403358f05988b78129406463cf4309adf Mon Sep 17 00:00:00 2001 From: Olivier Bouillet <62574056+freeboub@users.noreply.github.com> Date: Sat, 8 Jul 2023 21:50:20 +0200 Subject: [PATCH 08/12] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 29 ++++++++-------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 223be5ae..61d5de71 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -10,37 +10,24 @@ assignees: '' # Bug ## Platform - Which player are you experiencing the problem on: * iOS * Android -* Windows UWP -* Windows WPF +* Windows ## Environment info - - -React native info output: - -```bash - // paste it here -``` - + Library version: x.x.x +Device: ## Steps To Reproduce From c23bcddc9b898980ff085f22d36bd0872965605f Mon Sep 17 00:00:00 2001 From: olivier Date: Sat, 8 Jul 2023 23:20:09 +0200 Subject: [PATCH 09/12] chore: fix build issue --- ios/Video/RCTVideo-Bridging-Header.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/Video/RCTVideo-Bridging-Header.h b/ios/Video/RCTVideo-Bridging-Header.h index 77815e4e..586eec11 100644 --- a/ios/Video/RCTVideo-Bridging-Header.h +++ b/ios/Video/RCTVideo-Bridging-Header.h @@ -1,5 +1,6 @@ #import #import "RCTVideoSwiftLog.h" +#import "RCTEventDispatcher.h" #if __has_include() #import "RCTVideoCache.h" From 71c3c5c9403a3057f3791689f1482189b39f5eca Mon Sep 17 00:00:00 2001 From: Cedric Guinoiseau Date: Sun, 9 Jul 2023 20:44:58 +0200 Subject: [PATCH 10/12] Revert "fix: issue 2744, call replaceCurrentItem in dispatch thread" This reverts commit 12d7dd6d8b578c3049cbd461882406472af34059. --- ios/Video/RCTVideo.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index f33f5859..baeac2bf 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -312,10 +312,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH } self._player = self._player ?? AVPlayer() - // https://github.com/react-native-video/react-native-video/issues/2744#issuecomment-1237459473 - DispatchQueue.global(qos: .default).async { [weak self] in - self?._player?.replaceCurrentItem(with: playerItem) - } + self._player?.replaceCurrentItem(with: playerItem) self._playerObserver.player = self._player self.applyModifiers() self._player?.actionAtItemEnd = .none From 9e7737dcda2452160052d3919c6e105561909d26 Mon Sep 17 00:00:00 2001 From: atultiwaree <2010344.bca.cbsa@cgc.edu.in> Date: Wed, 26 Jul 2023 14:46:46 +0530 Subject: [PATCH 11/12] Fixed javascript syntax error --- Video.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Video.js b/Video.js index dc451d3e..3db14237 100644 --- a/Video.js +++ b/Video.js @@ -77,7 +77,7 @@ export default class Video extends Component { this.setNativeProps({ fullscreen: false }); }; - save = async (options?) => { + save = async (options) => { return await NativeModules.VideoManager.save(options, findNodeHandle(this._root)); } From 9816ee192bb8f1c30a9145b853801181e42c3bae Mon Sep 17 00:00:00 2001 From: atultiwaree <2010344.bca.cbsa@cgc.edu.in> Date: Wed, 26 Jul 2023 15:35:49 +0530 Subject: [PATCH 12/12] Fixed javascript syntax error --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b94ab4c3..d069ee07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,13 @@ ## Changelog + + ### Version 6.0.0-alpha.6 - Feature: Video range support [#3030](https://github.com/react-native-video/react-native-video/pull/3030) - iOS: remove undocumented `currentTime` property [#3064](https://github.com/react-native-video/react-native-video/pull/3064) - iOS: make sure that the audio in ads is muted when the player is muted. [#3068](https://github.com/react-native-video/react-native-video/pull/3077) - iOS: make IMA build optionnal +- Android: Fixed syntax error [#3182](https://github.com/react-native-video/react-native-video/issues/3182) ### Version 6.0.0-alpha.5