Address some of the feedback from the pull reqeust

This commit is contained in:
Abdulrahman Alzenki 2018-11-26 14:23:04 -08:00 committed by Abdulrahman Alzenki
parent 4a16151195
commit 62dc913cb3
5 changed files with 79 additions and 107 deletions

101
README.md
View File

@ -271,6 +271,7 @@ var styles = StyleSheet.create({
* [maxBitRate](#maxbitrate) * [maxBitRate](#maxbitrate)
* [muted](#muted) * [muted](#muted)
* [paused](#paused) * [paused](#paused)
* [pictureInPicture](#pictureinpicture)
* [playInBackground](#playinbackground) * [playInBackground](#playinbackground)
* [playWhenInactive](#playwheninactive) * [playWhenInactive](#playwheninactive)
* [poster](#poster) * [poster](#poster)
@ -298,12 +299,12 @@ var styles = StyleSheet.create({
* [onFullscreenPlayerDidPresent](#onfullscreenplayerdidpresent) * [onFullscreenPlayerDidPresent](#onfullscreenplayerdidpresent)
* [onFullscreenPlayerWillDismiss](#onfullscreenplayerwilldismiss) * [onFullscreenPlayerWillDismiss](#onfullscreenplayerwilldismiss)
* [onFullscreenPlayerDidDismiss](#onfullscreenplayerdiddismiss) * [onFullscreenPlayerDidDismiss](#onfullscreenplayerdiddismiss)
* [onIsPictureInPictureActive](#onispictureinpictureactive)
* [onIsPictureInPictureSupported](#onispictureinpicturesupported)
* [onLoad](#onload) * [onLoad](#onload)
* [onLoadStart](#onloadstart) * [onLoadStart](#onloadstart)
* [onPictureInPictureStatusChanged](#onpictureinpicturestatuschanged)
* [onProgress](#onprogress) * [onProgress](#onprogress)
* [onSeek](#onseek) * [onSeek](#onseek)
* [onRestoreUserInterfaceForPictureInPictureStop](#onrestoreuserinterfaceforpictureinpicturestop)
* [onTimedMetadata](#ontimedmetadata) * [onTimedMetadata](#ontimedmetadata)
### Methods ### Methods
@ -311,9 +312,7 @@ var styles = StyleSheet.create({
* [presentFullscreenPlayer](#presentfullscreenplayer) * [presentFullscreenPlayer](#presentfullscreenplayer)
* [save](#save) * [save](#save)
* [restoreUserInterfaceForPictureInPictureStop](#restoreuserinterfaceforpictureinpicturestop) * [restoreUserInterfaceForPictureInPictureStop](#restoreuserinterfaceforpictureinpicturestop)
* [startPictureInPicture](#startpictureinpicture)
* [seek](#seek) * [seek](#seek)
* [stopPictureInPicture](#stoppictureinpicture)
### Configurable props ### Configurable props
@ -491,6 +490,13 @@ Controls whether the media is paused
Platforms: all Platforms: all
#### pictureInPicture
Determine whether the media should played as picture in picture.
* **false (default)** - Don't not play as picture in picture
* **true** - Play the media as picture in picture
Platforms: iOS
#### playInBackground #### playInBackground
Determine whether the media should continue playing while the app is in the background. This allows customers to continue listening to the audio. Determine whether the media should continue playing while the app is in the background. This allows customers to continue listening to the audio.
* **false (default)** - Don't continue playing the media * **false (default)** - Don't continue playing the media
@ -866,38 +872,6 @@ Payload: none
Platforms: Android ExoPlayer, Android MediaPlayer, iOS Platforms: Android ExoPlayer, Android MediaPlayer, iOS
#### onIsPictureInPictureActive
Callback function that is called when picture in picture becomes active or inactive.
Property | Type | Description
--- | --- | ---
active | boolean | Boolean indicating whether picture in picture is active
Example:
```
{
active: true
}
```
Platforms: iOS
#### onIsPictureInPictureSupported
Callback function that is called initially to determine whether or not picture in picture is supported.
Property | Type | Description
--- | --- | ---
supported | boolean | Boolean indicating whether picture in picture is supported
Example:
```
{
supported: true
}
```
Platforms: iOS
#### onLoad #### onLoad
Callback function that is called when the media is loaded and ready to play. Callback function that is called when the media is loaded and ready to play.
@ -963,6 +937,22 @@ Example:
Platforms: all Platforms: all
#### onPictureInPictureStatusChanged
Callback function that is called when picture in picture becomes active or inactive.
Property | Type | Description
--- | --- | ---
isActive | boolean | Boolean indicating whether picture in picture is active
Example:
```
{
isActive: true
}
```
Platforms: iOS
#### 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.
@ -1006,6 +996,13 @@ Both the currentTime & seekTime are reported because the video player may not se
Platforms: Android ExoPlayer, Android MediaPlayer, iOS, Windows UWP Platforms: Android ExoPlayer, Android MediaPlayer, iOS, Windows UWP
#### onRestoreUserInterfaceForPictureInPictureStop
Callback function that corresponds to Apple's [`restoreUserInterfaceForPictureInPictureStopWithCompletionHandler`](https://developer.apple.com/documentation/avkit/avpictureinpicturecontrollerdelegate/1614703-pictureinpicturecontroller?language=objc). Call `restoreUserInterfaceForPictureInPictureStopCompleted` inside of this function when done restoring the user interface.
Payload: none
Platforms: iOS
#### onTimedMetadata #### onTimedMetadata
Callback function that is called when timed metadata becomes available Callback function that is called when timed metadata becomes available
@ -1094,26 +1091,14 @@ Future:
Platforms: iOS Platforms: iOS
#### restoreUserInterfaceForPictureInPictureStop #### restoreUserInterfaceForPictureInPictureStopCompleted
`restoreUserInterfaceForPictureInPictureStop(restore)` `restoreUserInterfaceForPictureInPictureStopCompleted(restored)`
This function corresponds to Apple's [restoreUserInterfaceForPictureInPictureStop](https://developer.apple.com/documentation/avkit/avpictureinpicturecontrollerdelegate/1614703-pictureinpicturecontroller?language=objc). IMPORTANT: After picture in picture stops, this function must be called. This function corresponds to the completion handler in Apple's [restoreUserInterfaceForPictureInPictureStop](https://developer.apple.com/documentation/avkit/avpictureinpicturecontrollerdelegate/1614703-pictureinpicturecontroller?language=objc). IMPORTANT: This function must be called after `onRestoreUserInterfaceForPictureInPictureStop` is called.
Example: Example:
``` ```
this.player.restoreUserInterfaceForPictureInPictureStop(true); this.player.restoreUserInterfaceForPictureInPictureStopCompleted(true);
```
Platforms: iOS
#### startPictureInPicture
`startPictureInPicture()`
Calling this function will start picture in picture if it is supported.
Example:
```
this.player.startPictureInPicture();
``` ```
Platforms: iOS Platforms: iOS
@ -1147,18 +1132,6 @@ this.player.seek(120, 50); // Seek to 2 minutes with +/- 50 milliseconds accurac
Platforms: iOS Platforms: iOS
#### stopPictureInPicture
`stopPictureInPicture()`
Calling this function will stop picture in picture if it is currently active.
Example:
```
this.player.stopPictureInPicture();
```
Platforms: iOS

View File

@ -78,16 +78,8 @@ export default class Video extends Component {
return await NativeModules.VideoManager.save(options, findNodeHandle(this._root)); return await NativeModules.VideoManager.save(options, findNodeHandle(this._root));
} }
startPictureInPicture = () => { restoreUserInterfaceForPictureInPictureStopCompleted = (restored) => {
this.setNativeProps({ pictureInPicture: true }); this.setNativeProps({ restoreUserInterfaceForPIPStopCompletionHandler: restored });
};
stopPictureInPicture = () => {
this.setNativeProps({ pictureInPicture: false });
};
restoreUserInterfaceForPictureInPictureStop = (restore) => {
this.setNativeProps({ restoreUserInterfaceForPIPStopCompletionHandler: restore });
}; };
_assignRoot = (component) => { _assignRoot = (component) => {
@ -210,15 +202,15 @@ export default class Video extends Component {
} }
}; };
_onIsPictureInPictureSupported = (event) => { _onPictureInPictureStatusChanged = (event) => {
if (this.props.onIsPictureInPictureSupported) { if (this.props.onPictureInPictureStatusChanged) {
this.props.onIsPictureInPictureSupported(event.nativeEvent); this.props.onPictureInPictureStatusChanged(event.nativeEvent);
} }
}; };
_onIsPictureInPictureActive = (event) => { _onRestoreUserInterfaceForPictureInPictureStop = (event) => {
if (this.props.onIsPictureInPictureActive) { if (this.props.onRestoreUserInterfaceForPictureInPictureStop) {
this.props.onIsPictureInPictureActive(event.nativeEvent); this.props.onRestoreUserInterfaceForPictureInPictureStop();
} }
}; };
@ -291,8 +283,8 @@ export default class Video extends Component {
onPlaybackRateChange: this._onPlaybackRateChange, onPlaybackRateChange: this._onPlaybackRateChange,
onAudioFocusChanged: this._onAudioFocusChanged, onAudioFocusChanged: this._onAudioFocusChanged,
onAudioBecomingNoisy: this._onAudioBecomingNoisy, onAudioBecomingNoisy: this._onAudioBecomingNoisy,
onIsPictureInPictureSupported: this._onIsPictureInPictureSupported, onPictureInPictureStatusChanged: this._onPictureInPictureStatusChanged,
onIsPictureInPictureActive: this._onIsPictureInPictureActive, onRestoreUserInterfaceForPictureInPictureStop: this._onRestoreUserInterfaceForPictureInPictureStop,
}); });
const posterStyle = { const posterStyle = {
@ -415,6 +407,7 @@ Video.propTypes = {
}), }),
stereoPan: PropTypes.number, stereoPan: PropTypes.number,
rate: PropTypes.number, rate: PropTypes.number,
pictureInPicture: PropTypes.bool,
playInBackground: PropTypes.bool, playInBackground: PropTypes.bool,
playWhenInactive: PropTypes.bool, playWhenInactive: PropTypes.bool,
ignoreSilentSwitch: PropTypes.oneOf(['ignore', 'obey']), ignoreSilentSwitch: PropTypes.oneOf(['ignore', 'obey']),
@ -446,8 +439,8 @@ Video.propTypes = {
onPlaybackRateChange: PropTypes.func, onPlaybackRateChange: PropTypes.func,
onAudioFocusChanged: PropTypes.func, onAudioFocusChanged: PropTypes.func,
onAudioBecomingNoisy: PropTypes.func, onAudioBecomingNoisy: PropTypes.func,
onIsPictureInPictureSupported: PropTypes.func, onPictureInPictureStatusChanged: PropTypes.func,
onIsPictureInPictureActive: PropTypes.func, needsToRestoreUserInterfaceForPictureInPictureStop: PropTypes.func,
onExternalPlaybackChange: PropTypes.func, onExternalPlaybackChange: PropTypes.func,
/* Required by react-native */ /* Required by react-native */

View File

@ -38,8 +38,8 @@
@property (nonatomic, copy) RCTBubblingEventBlock onPlaybackResume; @property (nonatomic, copy) RCTBubblingEventBlock onPlaybackResume;
@property (nonatomic, copy) RCTBubblingEventBlock onPlaybackRateChange; @property (nonatomic, copy) RCTBubblingEventBlock onPlaybackRateChange;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoExternalPlaybackChange; @property (nonatomic, copy) RCTBubblingEventBlock onVideoExternalPlaybackChange;
@property (nonatomic, copy) RCTBubblingEventBlock onIsPictureInPictureSupported; @property (nonatomic, copy) RCTBubblingEventBlock onPictureInPictureStatusChanged;
@property (nonatomic, copy) RCTBubblingEventBlock onIsPictureInPictureActive; @property (nonatomic, copy) RCTBubblingEventBlock onRestoreUserInterfaceForPictureInPictureStop;
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER; - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;

View File

@ -66,6 +66,7 @@ static int const RCTVideoUnset = -1;
BOOL _playbackStalled; BOOL _playbackStalled;
BOOL _playInBackground; BOOL _playInBackground;
BOOL _playWhenInactive; BOOL _playWhenInactive;
BOOL _pictureInPicture;
NSString * _ignoreSilentSwitch; NSString * _ignoreSilentSwitch;
NSString * _resizeMode; NSString * _resizeMode;
BOOL _fullscreen; BOOL _fullscreen;
@ -102,6 +103,7 @@ static int const RCTVideoUnset = -1;
_playInBackground = false; _playInBackground = false;
_allowsExternalPlayback = YES; _allowsExternalPlayback = YES;
_playWhenInactive = false; _playWhenInactive = false;
_pictureInPicture = false;
_ignoreSilentSwitch = @"inherit"; // inherit, ignore, obey _ignoreSilentSwitch = @"inherit"; // inherit, ignore, obey
_restoreUserInterfaceForPIPStopCompletionHandler = NULL; _restoreUserInterfaceForPIPStopCompletionHandler = NULL;
#if __has_include(<react-native-video/RCTVideoCache.h>) #if __has_include(<react-native-video/RCTVideoCache.h>)
@ -382,12 +384,6 @@ static int const RCTVideoUnset = -1;
@"target": self.reactTag @"target": self.reactTag
}); });
} }
if (@available(iOS 9, *)) {
if (self.onIsPictureInPictureSupported) {
self.onIsPictureInPictureSupported(@{@"supported": [NSNumber numberWithBool:(bool)[AVPictureInPictureController isPictureInPictureSupported]]});
}
}
}]; }];
}); });
_videoLoadStarted = YES; _videoLoadStarted = YES;
@ -791,11 +787,16 @@ static int const RCTVideoUnset = -1;
- (void)setPictureInPicture:(BOOL)pictureInPicture - (void)setPictureInPicture:(BOOL)pictureInPicture
{ {
if (_pipController && pictureInPicture && ![_pipController isPictureInPictureActive]) { if (_pictureInPicture == pictureInPicture) {
return;
}
_pictureInPicture = pictureInPicture;
if (_pipController && _pictureInPicture && ![_pipController isPictureInPictureActive]) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[_pipController startPictureInPicture]; [_pipController startPictureInPicture];
}); });
} else if (_pipController && !pictureInPicture && [_pipController isPictureInPictureActive]) { } else if (_pipController && !_pictureInPicture && [_pipController isPictureInPictureActive]) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[_pipController stopPictureInPicture]; [_pipController stopPictureInPicture];
}); });
@ -811,14 +812,12 @@ static int const RCTVideoUnset = -1;
} }
- (void)setupPipController { - (void)setupPipController {
if (@available(iOS 9, *)) {
if (!_pipController && _playerLayer && [AVPictureInPictureController isPictureInPictureSupported]) { if (!_pipController && _playerLayer && [AVPictureInPictureController isPictureInPictureSupported]) {
// Create new controller passing reference to the AVPlayerLayer // Create new controller passing reference to the AVPlayerLayer
_pipController = [[AVPictureInPictureController alloc] initWithPlayerLayer:_playerLayer]; _pipController = [[AVPictureInPictureController alloc] initWithPlayerLayer:_playerLayer];
_pipController.delegate = self; _pipController.delegate = self;
} }
} }
}
- (void)setIgnoreSilentSwitch:(NSString *)ignoreSilentSwitch - (void)setIgnoreSilentSwitch:(NSString *)ignoreSilentSwitch
{ {
@ -1535,14 +1534,18 @@ static int const RCTVideoUnset = -1;
#pragma mark - Picture in Picture #pragma mark - Picture in Picture
- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController { - (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
if (self.onIsPictureInPictureActive && _pipController) { if (self.onPictureInPictureStatusChanged) {
self.onIsPictureInPictureActive(@{@"active": [NSNumber numberWithBool:false]}); self.onPictureInPictureStatusChanged(@{
@"isActive": [NSNumber numberWithBool:false]
});
} }
} }
- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController { - (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
if (self.onIsPictureInPictureActive && _pipController) { if (self.onPictureInPictureStatusChanged) {
self.onIsPictureInPictureActive(@{@"active": [NSNumber numberWithBool:true]}); self.onPictureInPictureStatusChanged(@{
@"isActive": [NSNumber numberWithBool:true]
});
} }
} }
@ -1560,6 +1563,9 @@ static int const RCTVideoUnset = -1;
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL))completionHandler { - (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL))completionHandler {
NSAssert(_restoreUserInterfaceForPIPStopCompletionHandler == NULL, @"restoreUserInterfaceForPIPStopCompletionHandler was not called after picture in picture was exited."); NSAssert(_restoreUserInterfaceForPIPStopCompletionHandler == NULL, @"restoreUserInterfaceForPIPStopCompletionHandler was not called after picture in picture was exited.");
if (self.onRestoreUserInterfaceForPictureInPictureStop) {
self.onRestoreUserInterfaceForPictureInPictureStop(@{});
}
_restoreUserInterfaceForPIPStopCompletionHandler = completionHandler; _restoreUserInterfaceForPIPStopCompletionHandler = completionHandler;
} }

View File

@ -32,6 +32,7 @@ RCT_EXPORT_VIEW_PROPERTY(controls, BOOL);
RCT_EXPORT_VIEW_PROPERTY(volume, float); RCT_EXPORT_VIEW_PROPERTY(volume, float);
RCT_EXPORT_VIEW_PROPERTY(playInBackground, BOOL); RCT_EXPORT_VIEW_PROPERTY(playInBackground, BOOL);
RCT_EXPORT_VIEW_PROPERTY(playWhenInactive, BOOL); RCT_EXPORT_VIEW_PROPERTY(playWhenInactive, BOOL);
RCT_EXPORT_VIEW_PROPERTY(pictureInPicture, BOOL);
RCT_EXPORT_VIEW_PROPERTY(ignoreSilentSwitch, NSString); RCT_EXPORT_VIEW_PROPERTY(ignoreSilentSwitch, NSString);
RCT_EXPORT_VIEW_PROPERTY(rate, float); RCT_EXPORT_VIEW_PROPERTY(rate, float);
RCT_EXPORT_VIEW_PROPERTY(seek, NSDictionary); RCT_EXPORT_VIEW_PROPERTY(seek, NSDictionary);
@ -42,7 +43,6 @@ RCT_EXPORT_VIEW_PROPERTY(fullscreenOrientation, NSString);
RCT_EXPORT_VIEW_PROPERTY(filter, NSString); RCT_EXPORT_VIEW_PROPERTY(filter, NSString);
RCT_EXPORT_VIEW_PROPERTY(filterEnabled, BOOL); RCT_EXPORT_VIEW_PROPERTY(filterEnabled, BOOL);
RCT_EXPORT_VIEW_PROPERTY(progressUpdateInterval, float); RCT_EXPORT_VIEW_PROPERTY(progressUpdateInterval, float);
RCT_EXPORT_VIEW_PROPERTY(pictureInPicture, BOOL);
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, RCTBubblingEventBlock);
@ -79,8 +79,8 @@ RCT_REMAP_METHOD(save,
} }
}]; }];
} }
RCT_EXPORT_VIEW_PROPERTY(onIsPictureInPictureSupported, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onPictureInPictureStatusChanged, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onIsPictureInPictureActive, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onRestoreUserInterfaceForPictureInPictureStop, RCTBubblingEventBlock);
- (NSDictionary *)constantsToExport - (NSDictionary *)constantsToExport
{ {