feat(ios): implement onPlaybackStateChanged callback (#3307)

* chore: fix typo

* feat(ios): implement onPlaybackStateChanged

* docs: update onPlaybackStateChanged platforms
This commit is contained in:
Krzysztof Moch 2023-10-23 18:23:57 +02:00 committed by GitHub
parent 0bfbda66e4
commit 9373493d6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 14 additions and 7 deletions

3
API.md
View File

@ -363,6 +363,7 @@ var styles = StyleSheet.create({
| [onLoadStart](#onloadstart) | All | | [onLoadStart](#onloadstart) | All |
| [onPictureInPictureStatusChanged](#onpictureinpicturestatuschanged) | iOS | | [onPictureInPictureStatusChanged](#onpictureinpicturestatuschanged) | iOS |
| [onPlaybackRateChange](#onplaybackratechange) | All | | [onPlaybackRateChange](#onplaybackratechange) | All |
| [onPlaybackStateChanged](#onplaybackstatechanged) | Android, iOS |
| [onProgress](#onprogress) | All | | [onProgress](#onprogress) | All |
| [onReadyForDisplay](#onreadyfordisplay) | Android, iOS, Web | | [onReadyForDisplay](#onreadyfordisplay) | Android, iOS, Web |
| [onReceiveAdEvent](#onreceiveadevent) | Android, iOS | | [onReceiveAdEvent](#onreceiveadevent) | Android, iOS |
@ -1325,7 +1326,7 @@ Example:
} }
``` ```
Platforms: Android Platforms: Android, iOS
#### onPictureInPictureStatusChanged #### onPictureInPictureStatusChanged
Callback function that is called when picture in picture becomes active or inactive. Callback function that is called when picture in picture becomes active or inactive.

View File

@ -74,7 +74,7 @@ class RCTPlayerObserver: NSObject {
private var _timeObserver:Any? private var _timeObserver:Any?
private var _playerRateChangeObserver:NSKeyValueObservation? private var _playerRateChangeObserver:NSKeyValueObservation?
private var _playerExpernalPlaybackActiveObserver:NSKeyValueObservation? private var _playerExternalPlaybackActiveObserver:NSKeyValueObservation?
private var _playerItemStatusObserver:NSKeyValueObservation? private var _playerItemStatusObserver:NSKeyValueObservation?
private var _playerPlaybackBufferEmptyObserver:NSKeyValueObservation? private var _playerPlaybackBufferEmptyObserver:NSKeyValueObservation?
private var _playerPlaybackLikelyToKeepUpObserver:NSKeyValueObservation? private var _playerPlaybackLikelyToKeepUpObserver:NSKeyValueObservation?
@ -95,12 +95,12 @@ class RCTPlayerObserver: NSObject {
} }
_playerRateChangeObserver = player.observe(\.rate, changeHandler: _handlers.handlePlaybackRateChange) _playerRateChangeObserver = player.observe(\.rate, changeHandler: _handlers.handlePlaybackRateChange)
_playerExpernalPlaybackActiveObserver = player.observe(\.isExternalPlaybackActive, changeHandler: _handlers.handleExternalPlaybackActiveChange) _playerExternalPlaybackActiveObserver = player.observe(\.isExternalPlaybackActive, changeHandler: _handlers.handleExternalPlaybackActiveChange)
} }
func removePlayerObservers() { func removePlayerObservers() {
_playerRateChangeObserver?.invalidate() _playerRateChangeObserver?.invalidate()
_playerExpernalPlaybackActiveObserver?.invalidate() _playerExternalPlaybackActiveObserver?.invalidate()
} }
func addPlayerItemObservers() { func addPlayerItemObservers() {

View File

@ -107,6 +107,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
@objc var onPlaybackStalled: RCTDirectEventBlock? @objc var onPlaybackStalled: RCTDirectEventBlock?
@objc var onPlaybackResume: RCTDirectEventBlock? @objc var onPlaybackResume: RCTDirectEventBlock?
@objc var onPlaybackRateChange: RCTDirectEventBlock? @objc var onPlaybackRateChange: RCTDirectEventBlock?
@objc var onVideoPlaybackStateChanged: RCTDirectEventBlock?
@objc var onVideoExternalPlaybackChange: RCTDirectEventBlock? @objc var onVideoExternalPlaybackChange: RCTDirectEventBlock?
@objc var onPictureInPictureStatusChanged: RCTDirectEventBlock? @objc var onPictureInPictureStatusChanged: RCTDirectEventBlock?
@objc var onRestoreUserInterfaceForPictureInPictureStop: RCTDirectEventBlock? @objc var onRestoreUserInterfaceForPictureInPictureStop: RCTDirectEventBlock?
@ -1219,8 +1220,13 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
func handlePlaybackRateChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>) { func handlePlaybackRateChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>) {
guard let _player = _player else { return } guard let _player = _player else { return }
onPlaybackRateChange?(["playbackRate": NSNumber(value: _player.rate), onPlaybackRateChange?(["playbackRate": NSNumber(value: _player.rate),
"target": reactTag as Any]) "target": reactTag as Any])
onVideoPlaybackStateChanged?(["isPlaying": _player.rate != 0,
"target": reactTag as Any])
if _playbackStalled && _player.rate > 0 { if _playbackStalled && _player.rate > 0 {
onPlaybackResume?(["playbackRate": NSNumber(value: _player.rate), onPlaybackResume?(["playbackRate": NSNumber(value: _player.rate),
"target": reactTag as Any]) "target": reactTag as Any])

View File

@ -57,6 +57,7 @@ RCT_EXPORT_VIEW_PROPERTY(onReadyForDisplay, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackStalled, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onPlaybackStalled, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackResume, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onPlaybackResume, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackRateChange, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onPlaybackRateChange, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoPlaybackStateChanged, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoExternalPlaybackChange, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoExternalPlaybackChange, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onGetLicense, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onGetLicense, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPictureInPictureStatusChanged, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onPictureInPictureStatusChanged, RCTDirectEventBlock);

View File

@ -291,7 +291,6 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
[onSeek], [onSeek],
); );
// android only
const onVideoPlaybackStateChanged = useCallback( const onVideoPlaybackStateChanged = useCallback(
(e: NativeSyntheticEvent<OnPlaybackStateChangedData>) => { (e: NativeSyntheticEvent<OnPlaybackStateChangedData>) => {
onPlaybackStateChanged?.(e.nativeEvent); onPlaybackStateChanged?.(e.nativeEvent);

View File

@ -38,11 +38,11 @@ export interface ReactVideoEvents {
) => void; //iOS ) => void; //iOS
onPlaybackRateChange?: (e: OnPlaybackData) => void; //All onPlaybackRateChange?: (e: OnPlaybackData) => void; //All
onProgress?: (e: OnProgressData) => void; //All onProgress?: (e: OnProgressData) => void; //All
onReadyForDisplay?: () => void; //Android, iOS, Web onReadyForDisplay?: () => void; //Android, iOS
onReceiveAdEvent?: (e: OnReceiveAdEventData) => void; //Android, iOS onReceiveAdEvent?: (e: OnReceiveAdEventData) => void; //Android, iOS
onRestoreUserInterfaceForPictureInPictureStop?: () => void; //iOS onRestoreUserInterfaceForPictureInPictureStop?: () => void; //iOS
onSeek?: (e: OnSeekData) => void; //Android, iOS, Windows UWP onSeek?: (e: OnSeekData) => void; //Android, iOS, Windows UWP
onPlaybackStateChanged?: (e: OnPlaybackStateChangedData) => void; // Android onPlaybackStateChanged?: (e: OnPlaybackStateChangedData) => void; // Android, iOS
onTimedMetadata?: (e: OnTimedMetadataData) => void; //Android, iOS onTimedMetadata?: (e: OnTimedMetadataData) => void; //Android, iOS
onAudioTracks?: (e: OnAudioTracksData) => void; // Android onAudioTracks?: (e: OnAudioTracksData) => void; // Android
onTextTracks?: (e: OnTextTracksData) => void; //Android onTextTracks?: (e: OnTextTracksData) => void; //Android