Skip to content

Commit

Permalink
issue 310 - Added a new property, ignoreSilentSwitch. (TheWidlarzGrou…
Browse files Browse the repository at this point in the history
…p#403)

* issue 310 - Added a new property, ignoreSilentSwitch. When true, audio will play even when the silent switch on an iOS device is set to silent. When false, the audio will toggle with the silent switch. Sets the AVAudioSession to either playback or ambient.

* Added ignoreSilentSwitch usage to example app and to readme

* Changed ignoreSilentSwitch to accept two string values, ignore and obey.
This accounts for the case where the user does not want to modify the audio session from a particular video instance. The user would not use the ignoreSilentSwitch property at all in that case.
Also, the audio session will only be updated when the video is unpaused, instead of whenever the video component has updated props. This allows for multiple videos to be on the screen, with the most recent video unpaused (aka played) being the video that has control over the audio session.
  • Loading branch information
duhseekoh authored and cmcewen committed Apr 27, 2017
1 parent a855ea3 commit e2d31f4
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ If you would like to allow other apps to play music over your video component, a
...
}
```
Note: you can also use the `ignoreSilentSwitch` prop, shown below.

#### Android

Expand Down Expand Up @@ -134,6 +135,7 @@ using System.Collections.Generic;
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.
ignoreSilentSwitch={"ignore"} // [iOS] ignore | obey - When 'ignore', audio will still play with the iOS hard silent switch set to silent. When 'obey', audio will toggle with the switch. When not specified, will inherit audio settings as usual.
progressUpdateInterval={250.0} // [iOS] Interval to fire onProgress (default to ~250ms)
onLoadStart={this.loadStart} // Callback when video starts to load
onLoad={this.setDuration} // Callback when video loads
Expand Down
1 change: 1 addition & 0 deletions Video.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ Video.propTypes = {
rate: PropTypes.number,
playInBackground: PropTypes.bool,
playWhenInactive: PropTypes.bool,
ignoreSilentSwitch: PropTypes.oneOf(['ignore', 'obey']),
disableFocus: PropTypes.bool,
controls: PropTypes.bool,
currentTime: PropTypes.number,
Expand Down
40 changes: 40 additions & 0 deletions example/index.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import React, {
import {
AlertIOS,
AppRegistry,
Platform,
StyleSheet,
Text,
TouchableOpacity,
Expand All @@ -31,6 +32,7 @@ class VideoPlayer extends Component {
controls: false,
paused: true,
skin: 'custom',
ignoreSilentSwitch: null,
isBuffering: false,
};

Expand Down Expand Up @@ -106,6 +108,18 @@ class VideoPlayer extends Component {
)
}

renderIgnoreSilentSwitchControl(ignoreSilentSwitch) {
const isSelected = (this.state.ignoreSilentSwitch == ignoreSilentSwitch);

return (
<TouchableOpacity onPress={() => { this.setState({ignoreSilentSwitch: ignoreSilentSwitch}) }}>
<Text style={[styles.controlOption, {fontWeight: isSelected ? "bold" : "normal"}]}>
{ignoreSilentSwitch}
</Text>
</TouchableOpacity>
)
}

renderCustomSkin() {
const flexCompleted = this.getCurrentTimePercentage() * 100;
const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100;
Expand All @@ -120,6 +134,7 @@ class VideoPlayer extends Component {
paused={this.state.paused}
volume={this.state.volume}
muted={this.state.muted}
ignoreSilentSwitch={this.state.ignoreSilentSwitch}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onBuffer={this.onBuffer}
Expand Down Expand Up @@ -156,6 +171,15 @@ class VideoPlayer extends Component {
{this.renderResizeModeControl('stretch')}
</View>
</View>
<View style={styles.generalControls}>
{
(Platform.OS === 'ios') ?
<View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')}
</View> : null
}
</View>

<View style={styles.trackingControls}>
<View style={styles.progress}>
Expand All @@ -180,6 +204,7 @@ class VideoPlayer extends Component {
paused={this.state.paused}
volume={this.state.volume}
muted={this.state.muted}
ignoreSilentSwitch={this.state.ignoreSilentSwitch}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onBuffer={this.onBuffer}
Expand Down Expand Up @@ -216,6 +241,15 @@ class VideoPlayer extends Component {
{this.renderResizeModeControl('stretch')}
</View>
</View>
<View style={styles.generalControls}>
{
(Platform.OS === 'ios') ?
<View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')}
</View> : null
}
</View>
</View>

</View>
Expand Down Expand Up @@ -290,6 +324,12 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center'
},
ignoreSilentSwitchControl: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
},
controlOption: {
alignSelf: 'center',
fontSize: 11,
Expand Down
17 changes: 15 additions & 2 deletions ios/RCTVideo.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ @implementation RCTVideo
BOOL _playbackStalled;
BOOL _playInBackground;
BOOL _playWhenInactive;
NSString * _ignoreSilentSwitch;
NSString * _resizeMode;
BOOL _fullscreenPlayerPresented;
UIViewController * _presentingViewController;
Expand All @@ -66,6 +67,7 @@ - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
_playerBufferEmpty = YES;
_playInBackground = false;
_playWhenInactive = false;
_ignoreSilentSwitch = @"inherit"; // inherit, ignore, obey

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillResignActive:)
Expand Down Expand Up @@ -118,7 +120,7 @@ - (CMTimeRange)playerItemSeekableTimeRange
{
return [playerItem seekableTimeRanges].firstObject.CMTimeRangeValue;
}

return (kCMTimeRangeZero);
}

Expand Down Expand Up @@ -376,7 +378,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
} else
orientation = @"portrait";
}

if(self.onVideoLoad) {
self.onVideoLoad(@{@"duration": [NSNumber numberWithFloat:duration],
@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(_playerItem.currentTime)],
Expand Down Expand Up @@ -497,12 +499,23 @@ - (void)setPlayWhenInactive:(BOOL)playWhenInactive
_playWhenInactive = playWhenInactive;
}

- (void)setIgnoreSilentSwitch:(NSString *)ignoreSilentSwitch
{
_ignoreSilentSwitch = ignoreSilentSwitch;
[self applyModifiers];
}

- (void)setPaused:(BOOL)paused
{
if (paused) {
[_player pause];
[_player setRate:0.0];
} else {
if([_ignoreSilentSwitch isEqualToString:@"ignore"]) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
} else if([_ignoreSilentSwitch isEqualToString:@"obey"]) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
}
[_player play];
[_player setRate:_rate];
}
Expand Down
1 change: 1 addition & 0 deletions ios/RCTVideoManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ - (dispatch_queue_t)methodQueue
RCT_EXPORT_VIEW_PROPERTY(volume, float);
RCT_EXPORT_VIEW_PROPERTY(playInBackground, BOOL);
RCT_EXPORT_VIEW_PROPERTY(playWhenInactive, BOOL);
RCT_EXPORT_VIEW_PROPERTY(ignoreSilentSwitch, NSString);
RCT_EXPORT_VIEW_PROPERTY(rate, float);
RCT_EXPORT_VIEW_PROPERTY(seek, float);
RCT_EXPORT_VIEW_PROPERTY(currentTime, float);
Expand Down

0 comments on commit e2d31f4

Please sign in to comment.