Merge pull request #236 from thoblr/master

Added possibility to play video in background and when app is inactive.
This commit is contained in:
Stanisław Chmiela 2016-06-08 11:05:58 +02:00
commit 24c24cd962
6 changed files with 73 additions and 4 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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
---

View File

@ -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,

View File

@ -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() {
}
}

View File

@ -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);
}
}