Merge pull request #236 from thoblr/master
Added possibility to play video in background and when app is inactive.
This commit is contained in:
		
							
								
								
									
										32
									
								
								RCTVideo.m
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								RCTVideo.m
									
									
									
									
									
								
							| @@ -40,6 +40,8 @@ static NSString *const playbackRate = @"rate"; | ||||
|   BOOL _paused; | ||||
|   BOOL _repeat; | ||||
|   BOOL _playbackStalled; | ||||
|   BOOL _playInBackground; | ||||
|   BOOL _playWhenInactive; | ||||
|   NSString * _resizeMode; | ||||
|   BOOL _fullscreenPlayerPresented; | ||||
|   UIViewController * _presentingViewController; | ||||
| @@ -61,12 +63,19 @@ static NSString *const playbackRate = @"rate"; | ||||
|     _progressUpdateInterval = 250; | ||||
|     _controls = NO; | ||||
|     _playerBufferEmpty = YES; | ||||
|     _playInBackground = false; | ||||
|     _playWhenInactive = false; | ||||
|  | ||||
|     [[NSNotificationCenter defaultCenter] addObserver:self | ||||
|                                              selector:@selector(applicationWillResignActive:) | ||||
|                                                  name:UIApplicationWillResignActiveNotification | ||||
|                                                object:nil]; | ||||
|  | ||||
|     [[NSNotificationCenter defaultCenter] addObserver:self | ||||
|                                              selector:@selector(applicationDidEnterBackground:) | ||||
|                                                  name:UIApplicationDidEnterBackgroundNotification | ||||
|                                                object:nil]; | ||||
|  | ||||
|     [[NSNotificationCenter defaultCenter] addObserver:self | ||||
|                                              selector:@selector(applicationWillEnterForeground:) | ||||
|                                                  name:UIApplicationWillEnterForegroundNotification | ||||
| @@ -123,15 +132,26 @@ static NSString *const playbackRate = @"rate"; | ||||
|  | ||||
| - (void)applicationWillResignActive:(NSNotification *)notification | ||||
| { | ||||
|   if (!_paused) { | ||||
|   if (_playInBackground || _playWhenInactive || _paused) return; | ||||
|  | ||||
|   [_player pause]; | ||||
|   [_player setRate:0.0]; | ||||
| } | ||||
|  | ||||
| - (void)applicationDidEnterBackground:(NSNotification *)notification | ||||
| { | ||||
|   if (_playInBackground) { | ||||
|     // Needed to play sound in background. See https://developer.apple.com/library/ios/qa/qa1668/_index.html | ||||
|     [_playerLayer setPlayer:nil]; | ||||
|   } | ||||
| } | ||||
|  | ||||
| - (void)applicationWillEnterForeground:(NSNotification *)notification | ||||
| { | ||||
|   [self applyModifiers]; | ||||
|   if (_playInBackground) { | ||||
|     [_playerLayer setPlayer:_player]; | ||||
|   } | ||||
| } | ||||
|  | ||||
| #pragma mark - Progress | ||||
| @@ -403,6 +423,16 @@ static NSString *const playbackRate = @"rate"; | ||||
|   _resizeMode = mode; | ||||
| } | ||||
|  | ||||
| - (void)setPlayInBackground:(BOOL)playInBackground | ||||
| { | ||||
|   _playInBackground = playInBackground; | ||||
| } | ||||
|  | ||||
| - (void)setPlayWhenInactive:(BOOL)playWhenInactive | ||||
| { | ||||
|   _playWhenInactive = playWhenInactive; | ||||
| } | ||||
|  | ||||
| - (void)setPaused:(BOOL)paused | ||||
| { | ||||
|   if (paused) { | ||||
|   | ||||
| @@ -48,6 +48,8 @@ RCT_EXPORT_VIEW_PROPERTY(paused, BOOL); | ||||
| RCT_EXPORT_VIEW_PROPERTY(muted, BOOL); | ||||
| RCT_EXPORT_VIEW_PROPERTY(controls, BOOL); | ||||
| RCT_EXPORT_VIEW_PROPERTY(volume, float); | ||||
| RCT_EXPORT_VIEW_PROPERTY(playInBackground, BOOL); | ||||
| RCT_EXPORT_VIEW_PROPERTY(playWhenInactive, BOOL); | ||||
| RCT_EXPORT_VIEW_PROPERTY(rate, float); | ||||
| RCT_EXPORT_VIEW_PROPERTY(seek, float); | ||||
| RCT_EXPORT_VIEW_PROPERTY(currentTime, float); | ||||
|   | ||||
| @@ -71,6 +71,8 @@ Under `.addPackage(new MainReactPackage())`: | ||||
|        paused={false}               // Pauses playback entirely. | ||||
|        resizeMode="cover"           // Fill the whole screen at aspect ratio. | ||||
|        repeat={true}                // Repeat forever. | ||||
|        playInBackground={false}     // Audio continues to play when app entering background. | ||||
|        playWhenInactive={false}     // [iOS] Video continues to play when control or notification center are shown. | ||||
|        onLoadStart={this.loadStart} // Callback when video starts to load | ||||
|        onLoad={this.setDuration}    // Callback when video loads | ||||
|        onProgress={this.setTime}    // Callback every ~250ms with currentTime | ||||
| @@ -90,6 +92,10 @@ var styles = StyleSheet.create({ | ||||
| }); | ||||
| ``` | ||||
|  | ||||
| ### Play in background on iOS | ||||
|  | ||||
| To enable audio to play in background on iOS the audio session needs to be set to `AVAudioSessionCategoryPlayback`. See [Apple documentation][3]. | ||||
|  | ||||
| ## Static Methods | ||||
|  | ||||
| `seek(seconds)` | ||||
| @@ -120,6 +126,7 @@ Seeks the video to the specified time (in seconds). Access using a ref to the co | ||||
|  | ||||
| [1]: https://github.com/brentvatne/react-native-login/blob/56c47a5d1e23781e86e19b27e10427fd6391f666/App/Screens/UserInfoScreen.js#L32-L35 | ||||
| [2]: https://github.com/brentvatne/react-native-video/tree/master/Examples/VideoPlayer | ||||
| [3]: https://developer.apple.com/library/ios/qa/qa1668/_index.html | ||||
|  | ||||
| --- | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								Video.js
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Video.js
									
									
									
									
									
								
							| @@ -222,6 +222,8 @@ Video.propTypes = { | ||||
|   muted: PropTypes.bool, | ||||
|   volume: PropTypes.number, | ||||
|   rate: PropTypes.number, | ||||
|   playInBackground: PropTypes.bool, | ||||
|   playWhenInactive: PropTypes.bool, | ||||
|   controls: PropTypes.bool, | ||||
|   currentTime: PropTypes.number, | ||||
|   onLoadStart: PropTypes.func, | ||||
|   | ||||
| @@ -9,13 +9,14 @@ import java.util.Map; | ||||
| import java.util.HashMap; | ||||
| import com.facebook.react.bridge.Arguments; | ||||
| import com.facebook.react.bridge.WritableMap; | ||||
| import com.facebook.react.bridge.LifecycleEventListener; | ||||
| import com.facebook.react.uimanager.ThemedReactContext; | ||||
| import com.facebook.react.uimanager.events.RCTEventEmitter; | ||||
| import com.yqritc.scalablevideoview.ScalableType; | ||||
| import com.yqritc.scalablevideoview.ScalableVideoView; | ||||
|  | ||||
| public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnPreparedListener, MediaPlayer | ||||
|         .OnErrorListener, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener { | ||||
|         .OnErrorListener, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener, LifecycleEventListener { | ||||
|  | ||||
|     public enum Events { | ||||
|         EVENT_LOAD_START("onVideoLoadStart"), | ||||
| @@ -73,6 +74,7 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP | ||||
|     private boolean mMuted = false; | ||||
|     private float mVolume = 1.0f; | ||||
|     private float mRate = 1.0f; | ||||
|     private boolean mPlayInBackground = false; | ||||
|  | ||||
|     private boolean mMediaPlayerValid = false; // True if mMediaPlayer is in prepared, started, or paused state. | ||||
|     private int mVideoDuration = 0; | ||||
| @@ -83,6 +85,7 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP | ||||
|  | ||||
|         mThemedReactContext = themedReactContext; | ||||
|         mEventEmitter = themedReactContext.getJSModule(RCTEventEmitter.class); | ||||
|         themedReactContext.addLifecycleEventListener(this); | ||||
|  | ||||
|         initializeMediaPlayerIfNeeded(); | ||||
|         setSurfaceTextureListener(this); | ||||
| @@ -248,6 +251,10 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP | ||||
| //        setRateModifier(mRate); | ||||
|     } | ||||
|  | ||||
|     public void setPlayInBackground(final boolean playInBackground) { | ||||
|         mPlayInBackground = playInBackground; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onPrepared(MediaPlayer mp) { | ||||
|         mMediaPlayerValid = true; | ||||
| @@ -324,4 +331,19 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP | ||||
|         super.onAttachedToWindow(); | ||||
|         setSrc(mSrcUriString, mSrcType, mSrcIsNetwork, mSrcIsAsset); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onHostPause() { | ||||
|         if (mMediaPlayer != null && !mPlayInBackground) { | ||||
|             mMediaPlayer.pause(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override  | ||||
|     public void onHostResume() { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onHostDestroy() { | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -30,6 +30,7 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> { | ||||
|     public static final String PROP_VOLUME = "volume"; | ||||
|     public static final String PROP_SEEK = "seek"; | ||||
|     public static final String PROP_RATE = "rate"; | ||||
|     public static final String PROP_PLAY_IN_BACKGROUND = "playInBackground"; | ||||
|  | ||||
|     @Override | ||||
|     public String getName() { | ||||
| @@ -106,4 +107,9 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> { | ||||
|     public void setRate(final ReactVideoView videoView, final float rate) { | ||||
|         videoView.setRateModifier(rate); | ||||
|     } | ||||
|  | ||||
|     @ReactProp(name = PROP_PLAY_IN_BACKGROUND, defaultBoolean = false) | ||||
|     public void setPlayInBackground(final ReactVideoView videoView, final boolean playInBackground) { | ||||
|         videoView.setPlayInBackground(playInBackground); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user