diff --git a/ios/Video/Features/RCTPlayerObserver.swift b/ios/Video/Features/RCTPlayerObserver.swift index 0e19571f..4f88b23d 100644 --- a/ios/Video/Features/RCTPlayerObserver.swift +++ b/ios/Video/Features/RCTPlayerObserver.swift @@ -22,6 +22,7 @@ protocol RCTPlayerObserverHandler: RCTPlayerObserverHandlerObjc { func handlePlaybackBufferKeyEmpty(playerItem: AVPlayerItem, change: NSKeyValueObservedChange) func handlePlaybackLikelyToKeepUp(playerItem: AVPlayerItem, change: NSKeyValueObservedChange) func handlePlaybackRateChange(player: AVPlayer, change: NSKeyValueObservedChange) + func handleTimeControlStatusChange(player: AVPlayer, change: NSKeyValueObservedChange) func handleVolumeChange(player: AVPlayer, change: NSKeyValueObservedChange) func handleExternalPlaybackActiveChange(player: AVPlayer, change: NSKeyValueObservedChange) func handleViewControllerOverlayViewFrameChange(overlayView: UIView, change: NSKeyValueObservedChange) @@ -99,6 +100,7 @@ class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPla private var _playerRateChangeObserver: NSKeyValueObservation? private var _playerVolumeChangeObserver: NSKeyValueObservation? + private var _playerTimeControlStatusChangeObserver: NSKeyValueObservation? private var _playerExternalPlaybackActiveObserver: NSKeyValueObservation? private var _playerItemStatusObserver: NSKeyValueObservation? private var _playerPlaybackBufferEmptyObserver: NSKeyValueObservation? @@ -139,6 +141,7 @@ class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPla _playerRateChangeObserver = player.observe(\.rate, options: [.old], changeHandler: _handlers.handlePlaybackRateChange) _playerVolumeChangeObserver = player.observe(\.volume, options: [.old], changeHandler: _handlers.handleVolumeChange) + _playerTimeControlStatusChangeObserver = player.observe(\.timeControlStatus, options: [.old], changeHandler: _handlers.handleTimeControlStatusChange) #if !os(visionOS) _playerExternalPlaybackActiveObserver = player.observe(\.isExternalPlaybackActive, changeHandler: _handlers.handleExternalPlaybackActiveChange) #endif @@ -148,6 +151,7 @@ class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPla _playerRateChangeObserver?.invalidate() _playerExternalPlaybackActiveObserver?.invalidate() _playerVolumeChangeObserver?.invalidate() + _playerTimeControlStatusChangeObserver?.invalidate() } func addPlayerItemObservers() { diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index 5d3700b4..1b4e8166 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -44,6 +44,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH private var _muted = false private var _paused = false private var _repeat = false + private var _isPlaying: Bool? private var _allowsExternalPlayback = true private var _textTracks: [TextTrack]? private var _selectedTextTrackCriteria: SelectedTrackCriteria? @@ -1378,6 +1379,20 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH onVideoBuffer?(["isBuffering": false, "target": reactTag as Any]) } + func handleTimeControlStatusChange(player: AVPlayer, change: NSKeyValueObservedChange) { + if player.timeControlStatus == change.oldValue && change.oldValue != nil { + return + } + guard [.paused, .playing].contains(player.timeControlStatus) else { + return + } + let isPlaying = player.timeControlStatus == .playing + + guard _isPlaying == nil || _isPlaying! != isPlaying else { return } + _isPlaying = isPlaying + onVideoPlaybackStateChanged?(["isPlaying": isPlaying, "target": reactTag as Any]) + } + func handlePlaybackRateChange(player: AVPlayer, change: NSKeyValueObservedChange) { guard let _player else { return } @@ -1388,9 +1403,6 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH onPlaybackRateChange?(["playbackRate": NSNumber(value: _player.rate), "target": reactTag as Any]) - onVideoPlaybackStateChanged?(["isPlaying": _player.rate != 0, - "target": reactTag as Any]) - if _playbackStalled && _player.rate > 0 { onPlaybackResume?(["playbackRate": NSNumber(value: _player.rate), "target": reactTag as Any])