Merge branch 'master' into bugfix/android-disablefocus-audio

This commit is contained in:
Kurt Johnson 2019-07-03 16:43:37 -04:00 committed by GitHub
commit 2b067f1978
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 138 additions and 82 deletions

View File

@ -3,6 +3,19 @@
### next ### next
* Fix Android videos being able to play with background music/audio from other apps. * Fix Android videos being able to play with background music/audio from other apps.
### Version 4.4.2
* Change compileOnly to implementation on gradle (for newer gradle versions and react-native 0.59 support) [#1592](https://github.com/react-native-community/react-native-video/pull/1592)
* Replaced RCTBubblingEventBlock events by RCTDirectEventBlock to avoid event name collisions [#1625](https://github.com/react-native-community/react-native-video/pull/1625)
* Added `onPlaybackRateChange` to README [#1578](https://github.com/react-native-community/react-native-video/pull/1578)
* Added `onReadyForDisplay` to README [#1627](https://github.com/react-native-community/react-native-video/pull/1627)
* Improved handling of poster image. Fixes bug with displaying video and poster simultaneously. [#1627](https://github.com/react-native-community/react-native-video/pull/1627)
* Fix background audio stopping on iOS when using `controls` [#1614](https://github.com/react-native-community/react-native-video/pull/1614)
### Version 4.4.1
* Fix tvOS picture-in-picture compilation regression [#1518](https://github.com/react-native-community/react-native-video/pull/1518)
* fullscreen rotation issues with iOS built-in controls [#1441](https://github.com/react-native-community/react-native-video/pull/1441)
* Fix player freeze when playing audio files on ExoPlayer [#1529](https://github.com/react-native-community/react-native-video/pull/1529)
### Version 4.4.0 ### Version 4.4.0
* Fix runtime warning by replacing `UIManager.RCTVideo` with `UIManager.getViewManagerConfig('RCTVideo')` (and ensuring backwards compat) [#1487](https://github.com/react-native-community/react-native-video/pull/1487) * Fix runtime warning by replacing `UIManager.RCTVideo` with `UIManager.getViewManagerConfig('RCTVideo')` (and ensuring backwards compat) [#1487](https://github.com/react-native-community/react-native-video/pull/1487)
* Fix loading package resolved videos when using video-caching [#1438](https://github.com/react-native-community/react-native-video/pull/1438) * Fix loading package resolved videos when using video-caching [#1438](https://github.com/react-native-community/react-native-video/pull/1438)

View File

@ -302,7 +302,9 @@ var styles = StyleSheet.create({
* [onFullscreenPlayerDidDismiss](#onfullscreenplayerdiddismiss) * [onFullscreenPlayerDidDismiss](#onfullscreenplayerdiddismiss)
* [onLoad](#onload) * [onLoad](#onload)
* [onLoadStart](#onloadstart) * [onLoadStart](#onloadstart)
* [onReadyForDisplay](#onreadyfordisplay)
* [onPictureInPictureStatusChanged](#onpictureinpicturestatuschanged) * [onPictureInPictureStatusChanged](#onpictureinpicturestatuschanged)
* [onPlaybackRateChange](#onplaybackratechange)
* [onProgress](#onprogress) * [onProgress](#onprogress)
* [onSeek](#onseek) * [onSeek](#onseek)
* [onRestoreUserInterfaceForPictureInPictureStop](#onrestoreuserinterfaceforpictureinpicturestop) * [onRestoreUserInterfaceForPictureInPictureStop](#onrestoreuserinterfaceforpictureinpicturestop)
@ -960,6 +962,17 @@ Example:
Platforms: all Platforms: all
#### onReadyForDisplay
Callback function that is called when the first video frame is ready for display. This is when the poster is removed.
Payload: none
* iOS: [readyForDisplay](https://developer.apple.com/documentation/avkit/avplayerviewcontroller/1615830-readyfordisplay?language=objc)
* Android: [MEDIA_INFO_VIDEO_RENDERING_START](https://developer.android.com/reference/android/media/MediaPlayer#MEDIA_INFO_VIDEO_RENDERING_START)
* Android ExoPlayer [STATE_READY](https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/Player.html#STATE_READY)
Platforms: Android ExoPlayer, Android MediaPlayer, iOS, Web
#### 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.
@ -976,6 +989,23 @@ isActive: true
Platforms: iOS Platforms: iOS
#### onPlaybackRateChange
Callback function that is called when the rate of playback changes - either paused or starts/resumes.
Property | Type | Description
--- | --- | ---
playbackRate | number | 0 when playback is paused, 1 when playing at normal speed. Other values when playback is slowed down or sped up
Example:
```
{
playbackRate: 0, // indicates paused
}
```
Platforms: all
#### onProgress #### onProgress
Callback function that is called every progressUpdateInterval seconds with info about which position the media is currently playing. Callback function that is called every progressUpdateInterval seconds with info about which position the media is currently playing.

View File

@ -20,7 +20,7 @@ export default class Video extends Component {
super(props); super(props);
this.state = { this.state = {
showPoster: true, showPoster: !!props.poster
}; };
} }
@ -86,6 +86,12 @@ export default class Video extends Component {
this._root = component; this._root = component;
}; };
_hidePoster = () => {
if (this.state.showPoster) {
this.setState({showPoster: false});
}
}
_onLoadStart = (event) => { _onLoadStart = (event) => {
if (this.props.onLoadStart) { if (this.props.onLoadStart) {
this.props.onLoadStart(event.nativeEvent); this.props.onLoadStart(event.nativeEvent);
@ -93,6 +99,10 @@ export default class Video extends Component {
}; };
_onLoad = (event) => { _onLoad = (event) => {
// Need to hide poster here for windows as onReadyForDisplay is not implemented
if (Platform.OS === 'windows') {
this._hidePoster();
}
if (this.props.onLoad) { if (this.props.onLoad) {
this.props.onLoad(event.nativeEvent); this.props.onLoad(event.nativeEvent);
} }
@ -117,10 +127,6 @@ export default class Video extends Component {
}; };
_onSeek = (event) => { _onSeek = (event) => {
if (this.state.showPoster && !this.props.audioOnly) {
this.setState({showPoster: false});
}
if (this.props.onSeek) { if (this.props.onSeek) {
this.props.onSeek(event.nativeEvent); this.props.onSeek(event.nativeEvent);
} }
@ -163,6 +169,7 @@ export default class Video extends Component {
}; };
_onReadyForDisplay = (event) => { _onReadyForDisplay = (event) => {
this._hidePoster();
if (this.props.onReadyForDisplay) { if (this.props.onReadyForDisplay) {
this.props.onReadyForDisplay(event.nativeEvent); this.props.onReadyForDisplay(event.nativeEvent);
} }
@ -181,10 +188,6 @@ export default class Video extends Component {
}; };
_onPlaybackRateChange = (event) => { _onPlaybackRateChange = (event) => {
if (this.state.showPoster && event.nativeEvent.playbackRate !== 0 && !this.props.audioOnly) {
this.setState({showPoster: false});
}
if (this.props.onPlaybackRateChange) { if (this.props.onPlaybackRateChange) {
this.props.onPlaybackRateChange(event.nativeEvent); this.props.onPlaybackRateChange(event.nativeEvent);
} }
@ -308,15 +311,16 @@ export default class Video extends Component {
}; };
return ( return (
<React.Fragment> <View style={nativeProps.style}>
<RCTVideo ref={this._assignRoot} {...nativeProps} /> <RCTVideo
{this.props.poster && ref={this._assignRoot}
this.state.showPoster && ( {...nativeProps}
<View style={nativeProps.style}> style={StyleSheet.absoluteFill}
<Image style={posterStyle} source={{ uri: this.props.poster }} /> />
</View> {this.state.showPoster && (
)} <Image style={posterStyle} source={{ uri: this.props.poster }} />
</React.Fragment> )}
</View>
); );
} }
} }

View File

@ -22,7 +22,7 @@ android {
} }
dependencies { dependencies {
compileOnly "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}" implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
implementation('com.google.android.exoplayer:exoplayer:2.9.3') { implementation('com.google.android.exoplayer:exoplayer:2.9.3') {
exclude group: 'com.android.support' exclude group: 'com.android.support'
} }

View File

@ -975,16 +975,17 @@ class ReactExoplayerView extends FrameLayout implements
groupIndex = getGroupIndexForDefaultLocale(groups); groupIndex = getGroupIndexForDefaultLocale(groups);
} }
if (groupIndex == C.INDEX_UNSET && trackType == C.TRACK_TYPE_VIDEO) { // Video auto if (groupIndex == C.INDEX_UNSET && trackType == C.TRACK_TYPE_VIDEO && groups.length != 0) { // Video auto
if (groups.length != 0) { // Add all tracks as valid options for ABR to choose from
TrackGroup group = groups.get(0); TrackGroup group = groups.get(0);
tracks = new int[group.length]; tracks = new int[group.length];
groupIndex = 0; groupIndex = 0;
for (int j = 0; j < group.length; j++) { for (int j = 0; j < group.length; j++) {
tracks[j] = j; tracks[j] = j;
}
} }
} else if (groupIndex == C.INDEX_UNSET) { }
if (groupIndex == C.INDEX_UNSET) {
trackSelector.setParameters(disableParameters); trackSelector.setParameters(disableParameters);
return; return;
} }

View File

@ -21,6 +21,6 @@ android {
dependencies { dependencies {
//noinspection GradleDynamicVersion //noinspection GradleDynamicVersion
compileOnly "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}" implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
implementation 'com.yqritc:android-scalablevideoview:1.0.4' implementation 'com.yqritc:android-scalablevideoview:1.0.4'
} }

View File

@ -37,6 +37,7 @@ class RCTVideo extends RCTView {
this.videoElement = this.initializeVideoElement(); this.videoElement = this.initializeVideoElement();
this.videoElement.addEventListener("ended", this.onEnd); this.videoElement.addEventListener("ended", this.onEnd);
this.videoElement.addEventListener("loadeddata", this.onLoad); this.videoElement.addEventListener("loadeddata", this.onLoad);
this.videoElement.addEventListener("canplay", this.onReadyForDisplay);
this.videoElement.addEventListener("loadstart", this.onLoadStart); this.videoElement.addEventListener("loadstart", this.onLoadStart);
this.videoElement.addEventListener("pause", this.onPause); this.videoElement.addEventListener("pause", this.onPause);
this.videoElement.addEventListener("play", this.onPlay); this.videoElement.addEventListener("play", this.onPlay);
@ -51,6 +52,7 @@ class RCTVideo extends RCTView {
detachFromView(view: UIView) { detachFromView(view: UIView) {
this.videoElement.removeEventListener("ended", this.onEnd); this.videoElement.removeEventListener("ended", this.onEnd);
this.videoElement.removeEventListener("loadeddata", this.onLoad); this.videoElement.removeEventListener("loadeddata", this.onLoad);
this.videoElement.removeEventListener("canplay", this.onReadyForDisplay);
this.videoElement.removeEventListener("loadstart", this.onLoadStart); this.videoElement.removeEventListener("loadstart", this.onLoadStart);
this.videoElement.removeEventListener("pause", this.onPause); this.videoElement.removeEventListener("pause", this.onPause);
this.videoElement.removeEventListener("play", this.onPlay); this.videoElement.removeEventListener("play", this.onPlay);
@ -203,6 +205,10 @@ class RCTVideo extends RCTView {
this.sendEvent("topVideoLoad", payload); this.sendEvent("topVideoLoad", payload);
} }
onReadyForDisplay = () => {
this.sendEvent("onReadyForDisplay");
}
onLoadStart = () => { onLoadStart = () => {
const src = this.videoElement.currentSrc; const src = this.videoElement.currentSrc;
const payload = { const payload = {

View File

@ -21,27 +21,27 @@
@interface RCTVideo : UIView <RCTVideoPlayerViewControllerDelegate, AVPictureInPictureControllerDelegate> @interface RCTVideo : UIView <RCTVideoPlayerViewControllerDelegate, AVPictureInPictureControllerDelegate>
#endif #endif
@property (nonatomic, copy) RCTBubblingEventBlock onVideoLoadStart; @property (nonatomic, copy) RCTDirectEventBlock onVideoLoadStart;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoLoad; @property (nonatomic, copy) RCTDirectEventBlock onVideoLoad;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoBuffer; @property (nonatomic, copy) RCTDirectEventBlock onVideoBuffer;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoError; @property (nonatomic, copy) RCTDirectEventBlock onVideoError;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoProgress; @property (nonatomic, copy) RCTDirectEventBlock onVideoProgress;
@property (nonatomic, copy) RCTBubblingEventBlock onBandwidthUpdate; @property (nonatomic, copy) RCTDirectEventBlock onBandwidthUpdate;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoSeek; @property (nonatomic, copy) RCTDirectEventBlock onVideoSeek;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoEnd; @property (nonatomic, copy) RCTDirectEventBlock onVideoEnd;
@property (nonatomic, copy) RCTBubblingEventBlock onTimedMetadata; @property (nonatomic, copy) RCTDirectEventBlock onTimedMetadata;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoAudioBecomingNoisy; @property (nonatomic, copy) RCTDirectEventBlock onVideoAudioBecomingNoisy;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerWillPresent; @property (nonatomic, copy) RCTDirectEventBlock onVideoFullscreenPlayerWillPresent;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerDidPresent; @property (nonatomic, copy) RCTDirectEventBlock onVideoFullscreenPlayerDidPresent;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerWillDismiss; @property (nonatomic, copy) RCTDirectEventBlock onVideoFullscreenPlayerWillDismiss;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerDidDismiss; @property (nonatomic, copy) RCTDirectEventBlock onVideoFullscreenPlayerDidDismiss;
@property (nonatomic, copy) RCTBubblingEventBlock onReadyForDisplay; @property (nonatomic, copy) RCTDirectEventBlock onReadyForDisplay;
@property (nonatomic, copy) RCTBubblingEventBlock onPlaybackStalled; @property (nonatomic, copy) RCTDirectEventBlock onPlaybackStalled;
@property (nonatomic, copy) RCTBubblingEventBlock onPlaybackResume; @property (nonatomic, copy) RCTDirectEventBlock onPlaybackResume;
@property (nonatomic, copy) RCTBubblingEventBlock onPlaybackRateChange; @property (nonatomic, copy) RCTDirectEventBlock onPlaybackRateChange;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoExternalPlaybackChange; @property (nonatomic, copy) RCTDirectEventBlock onVideoExternalPlaybackChange;
@property (nonatomic, copy) RCTBubblingEventBlock onPictureInPictureStatusChanged; @property (nonatomic, copy) RCTDirectEventBlock onPictureInPictureStatusChanged;
@property (nonatomic, copy) RCTBubblingEventBlock onRestoreUserInterfaceForPictureInPictureStop; @property (nonatomic, copy) RCTDirectEventBlock onRestoreUserInterfaceForPictureInPictureStop;
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER; - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;

View File

@ -223,6 +223,7 @@ static int const RCTVideoUnset = -1;
if (_playInBackground) { if (_playInBackground) {
// Needed to play sound in background. See https://developer.apple.com/library/ios/qa/qa1668/_index.html // Needed to play sound in background. See https://developer.apple.com/library/ios/qa/qa1668/_index.html
[_playerLayer setPlayer:nil]; [_playerLayer setPlayer:nil];
[_playerViewController setPlayer:nil];
} }
} }
@ -231,6 +232,7 @@ static int const RCTVideoUnset = -1;
[self applyModifiers]; [self applyModifiers];
if (_playInBackground) { if (_playInBackground) {
[_playerLayer setPlayer:_player]; [_playerLayer setPlayer:_player];
[_playerViewController setPlayer:_player];
} }
} }
@ -354,8 +356,6 @@ static int const RCTVideoUnset = -1;
[self setMaxBitRate:_maxBitRate]; [self setMaxBitRate:_maxBitRate];
[_player pause]; [_player pause];
[_playerViewController.view removeFromSuperview];
_playerViewController = nil;
if (_playbackRateObserverRegistered) { if (_playbackRateObserverRegistered) {
[_player removeObserver:self forKeyPath:playbackRate context:nil]; [_player removeObserver:self forKeyPath:playbackRate context:nil];
@ -598,7 +598,10 @@ static int const RCTVideoUnset = -1;
} else } else
return [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; return [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
} }
if([keyPath isEqualToString:readyForDisplayKeyPath] && [change objectForKey:NSKeyValueChangeNewKey] && self.onReadyForDisplay) {
self.onReadyForDisplay(@{@"target": self.reactTag});
return;
}
if (object == _playerItem) { if (object == _playerItem) {
// When timeMetadata is read the event onTimedMetadata is triggered // When timeMetadata is read the event onTimedMetadata is triggered
if ([keyPath isEqualToString:timedMetadata]) { if ([keyPath isEqualToString:timedMetadata]) {
@ -690,12 +693,6 @@ static int const RCTVideoUnset = -1;
_playerBufferEmpty = NO; _playerBufferEmpty = NO;
self.onVideoBuffer(@{@"isBuffering": @(NO), @"target": self.reactTag}); self.onVideoBuffer(@{@"isBuffering": @(NO), @"target": self.reactTag});
} }
} else if (object == _playerLayer) {
if([keyPath isEqualToString:readyForDisplayKeyPath] && [change objectForKey:NSKeyValueChangeNewKey]) {
if([change objectForKey:NSKeyValueChangeNewKey] && self.onReadyForDisplay) {
self.onReadyForDisplay(@{@"target": self.reactTag});
}
}
} else if (object == _player) { } else if (object == _player) {
if([keyPath isEqualToString:playbackRate]) { if([keyPath isEqualToString:playbackRate]) {
if(self.onPlaybackRateChange) { if(self.onPlaybackRateChange) {
@ -1283,7 +1280,9 @@ static int const RCTVideoUnset = -1;
{ {
if( _player ) if( _player )
{ {
_playerViewController = [self createPlayerViewController:_player withPlayerItem:_playerItem]; if (!_playerViewController) {
_playerViewController = [self createPlayerViewController:_player withPlayerItem:_playerItem];
}
// to prevent video from being animated when resizeMode is 'cover' // to prevent video from being animated when resizeMode is 'cover'
// resize mode must be set before subview is added // resize mode must be set before subview is added
[self setResizeMode:_resizeMode]; [self setResizeMode:_resizeMode];
@ -1293,6 +1292,8 @@ static int const RCTVideoUnset = -1;
[viewController addChildViewController:_playerViewController]; [viewController addChildViewController:_playerViewController];
[self addSubview:_playerViewController.view]; [self addSubview:_playerViewController.view];
} }
[_playerViewController addObserver:self forKeyPath:readyForDisplayKeyPath options:NSKeyValueObservingOptionNew context:nil];
[_playerViewController.contentOverlayView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL]; [_playerViewController.contentOverlayView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
} }
@ -1488,6 +1489,7 @@ static int const RCTVideoUnset = -1;
[self removePlayerLayer]; [self removePlayerLayer];
[_playerViewController.contentOverlayView removeObserver:self forKeyPath:@"frame"]; [_playerViewController.contentOverlayView removeObserver:self forKeyPath:@"frame"];
[_playerViewController removeObserver:self forKeyPath:readyForDisplayKeyPath];
[_playerViewController.view removeFromSuperview]; [_playerViewController.view removeFromSuperview];
_playerViewController = nil; _playerViewController = nil;

View File

@ -45,25 +45,25 @@ RCT_EXPORT_VIEW_PROPERTY(filterEnabled, BOOL);
RCT_EXPORT_VIEW_PROPERTY(progressUpdateInterval, float); RCT_EXPORT_VIEW_PROPERTY(progressUpdateInterval, float);
RCT_EXPORT_VIEW_PROPERTY(restoreUserInterfaceForPIPStopCompletionHandler, BOOL); RCT_EXPORT_VIEW_PROPERTY(restoreUserInterfaceForPIPStopCompletionHandler, BOOL);
/* Should support: onLoadStart, onLoad, and onError to stay consistent with Image */ /* Should support: onLoadStart, onLoad, and onError to stay consistent with Image */
RCT_EXPORT_VIEW_PROPERTY(onVideoLoadStart, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoLoadStart, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoLoad, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoLoad, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoBuffer, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoBuffer, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoError, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoError, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoProgress, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoProgress, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onBandwidthUpdate, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onBandwidthUpdate, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoSeek, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoSeek, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoEnd, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoEnd, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onTimedMetadata, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onTimedMetadata, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoAudioBecomingNoisy, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoAudioBecomingNoisy, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerWillPresent, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerWillPresent, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerDidPresent, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerDidPresent, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerWillDismiss, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerWillDismiss, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerDidDismiss, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerDidDismiss, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onReadyForDisplay, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onReadyForDisplay, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackStalled, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onPlaybackStalled, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackResume, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onPlaybackResume, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackRateChange, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onPlaybackRateChange, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoExternalPlaybackChange, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoExternalPlaybackChange, RCTDirectEventBlock);
RCT_REMAP_METHOD(save, RCT_REMAP_METHOD(save,
options:(NSDictionary *)options options:(NSDictionary *)options
reactTag:(nonnull NSNumber *)reactTag reactTag:(nonnull NSNumber *)reactTag
@ -79,8 +79,8 @@ RCT_REMAP_METHOD(save,
} }
}]; }];
} }
RCT_EXPORT_VIEW_PROPERTY(onPictureInPictureStatusChanged, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onPictureInPictureStatusChanged, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onRestoreUserInterfaceForPictureInPictureStop, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onRestoreUserInterfaceForPictureInPictureStop, RCTDirectEventBlock);
- (NSDictionary *)constantsToExport - (NSDictionary *)constantsToExport
{ {

View File

@ -1,6 +1,6 @@
{ {
"name": "react-native-video", "name": "react-native-video",
"version": "4.3.1", "version": "4.4.2",
"description": "A <Video /> element for react-native", "description": "A <Video /> element for react-native",
"main": "Video.js", "main": "Video.js",
"license": "MIT", "license": "MIT",