Skip to content

Commit

Permalink
Merge pull request #1978 from euharrison/master
Browse files Browse the repository at this point in the history
Audio mix with other apps for iOS
  • Loading branch information
jenshandersson authored May 7, 2020
2 parents c579d3c + b8234f8 commit c438509
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Fix iOS bug which would break size of views when video is displayed with controls on a non full-screen React view. [#1931](https://github.com/react-native-community/react-native-video/pull/1931)
- Fix video dimensions being undefined when playing HLS in ios. [#1992](https://github.com/react-native-community/react-native-video/pull/1992)
- Add support for audio mix with other apps for iOS. [#1978](https://github.com/react-native-community/react-native-video/pull/1978)

### Version 5.1.0-alpha5

Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ var styles = StyleSheet.create({
* [ignoreSilentSwitch](#ignoresilentswitch)
* [maxBitRate](#maxbitrate)
* [minLoadRetryCount](#minLoadRetryCount)
* [mixWithOthers](#mixWithOthers)
* [muted](#muted)
* [paused](#paused)
* [pictureInPicture](#pictureinpicture)
Expand Down Expand Up @@ -531,6 +532,14 @@ minLoadRetryCount={5} // retry 5 times

Platforms: Android ExoPlayer

#### mixWithOthers
Controls how Audio mix with other apps.
* **"inherit" (default)** - Use the default AVPlayer behavior
* **"mix"** - Audio from this video mixes with audio from other apps.
* **"duck"** - Reduces the volume of other apps while audio from this video plays.

Platforms: iOS

#### muted
Controls whether the audio is muted
* **false (default)** - Don't mute audio
Expand Down
49 changes: 41 additions & 8 deletions examples/basic/index.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class VideoPlayer extends Component {
paused: true,
skin: 'custom',
ignoreSilentSwitch: null,
mixWithOthers: null,
isBuffering: false,
filter: FilterType.NONE,
filterEnabled: true
Expand Down Expand Up @@ -155,6 +156,18 @@ class VideoPlayer extends Component {
)
}

renderMixWithOthersControl(mixWithOthers) {
const isSelected = (this.state.mixWithOthers == mixWithOthers);

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

renderCustomSkin() {
const flexCompleted = this.getCurrentTimePercentage() * 100;
const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100;
Expand All @@ -170,6 +183,7 @@ class VideoPlayer extends Component {
volume={this.state.volume}
muted={this.state.muted}
ignoreSilentSwitch={this.state.ignoreSilentSwitch}
mixWithOthers={this.state.mixWithOthers}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onBuffer={this.onBuffer}
Expand Down Expand Up @@ -226,10 +240,16 @@ class VideoPlayer extends Component {
<View style={styles.generalControls}>
{
(Platform.OS === 'ios') ?
<View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')}
</View> : null
<>
<View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')}
</View>
<View style={styles.mixWithOthersControl}>
{this.renderMixWithOthersControl('mix')}
{this.renderMixWithOthersControl('duck')}
</View>
</> : null
}
</View>

Expand Down Expand Up @@ -257,6 +277,7 @@ class VideoPlayer extends Component {
volume={this.state.volume}
muted={this.state.muted}
ignoreSilentSwitch={this.state.ignoreSilentSwitch}
mixWithOthers={this.state.mixWithOthers}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onBuffer={this.onBuffer}
Expand Down Expand Up @@ -313,10 +334,16 @@ class VideoPlayer extends Component {
<View style={styles.generalControls}>
{
(Platform.OS === 'ios') ?
<View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')}
</View> : null
<>
<View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')}
</View>
<View style={styles.mixWithOthersControl}>
{this.renderMixWithOthersControl('mix')}
{this.renderMixWithOthersControl('duck')}
</View>
</> : null
}
</View>
</View>
Expand Down Expand Up @@ -399,6 +426,12 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center'
},
mixWithOthersControl: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
},
controlOption: {
alignSelf: 'center',
fontSize: 11,
Expand Down
32 changes: 29 additions & 3 deletions ios/Video/RCTVideo.m
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ @implementation RCTVideo
BOOL _playWhenInactive;
BOOL _pictureInPicture;
NSString * _ignoreSilentSwitch;
NSString * _mixWithOthers;
NSString * _resizeMode;
BOOL _fullscreen;
BOOL _fullscreenAutorotate;
Expand Down Expand Up @@ -108,6 +109,7 @@ - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
_playWhenInactive = false;
_pictureInPicture = false;
_ignoreSilentSwitch = @"inherit"; // inherit, ignore, obey
_mixWithOthers = @"inherit"; // inherit, mix, duck
#if TARGET_OS_IOS
_restoreUserInterfaceForPIPStopCompletionHandler = NULL;
#endif
Expand Down Expand Up @@ -861,18 +863,42 @@ - (void)setIgnoreSilentSwitch:(NSString *)ignoreSilentSwitch
[self applyModifiers];
}

- (void)setMixWithOthers:(NSString *)mixWithOthers
{
_mixWithOthers = mixWithOthers;
[self applyModifiers];
}

- (void)setPaused:(BOOL)paused
{
if (paused) {
[_player pause];
[_player setRate:0.0];
} else {
AVAudioSession *session = [AVAudioSession sharedInstance];
AVAudioSessionCategory category = nil;
AVAudioSessionCategoryOptions options = nil;

if([_ignoreSilentSwitch isEqualToString:@"ignore"]) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
category = AVAudioSessionCategoryPlayback;
} else if([_ignoreSilentSwitch isEqualToString:@"obey"]) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
category = AVAudioSessionCategoryAmbient;
}


if([_mixWithOthers isEqualToString:@"mix"]) {
options = AVAudioSessionCategoryOptionMixWithOthers;
} else if([_mixWithOthers isEqualToString:@"duck"]) {
options = AVAudioSessionCategoryOptionDuckOthers;
}

if (category != nil && options != nil) {
[session setCategory:category withOptions:options error:nil];
} else if (category != nil && options == nil) {
[session setCategory:category error:nil];
} else if (category == nil && options != nil) {
[session setCategory:session.category withOptions:options error:nil];
}

if (@available(iOS 10.0, *) && !_automaticallyWaitsToMinimizeStalling) {
[_player playImmediatelyAtRate:_rate];
} else {
Expand Down
1 change: 1 addition & 0 deletions ios/Video/RCTVideoManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ - (dispatch_queue_t)methodQueue
RCT_EXPORT_VIEW_PROPERTY(playWhenInactive, BOOL);
RCT_EXPORT_VIEW_PROPERTY(pictureInPicture, BOOL);
RCT_EXPORT_VIEW_PROPERTY(ignoreSilentSwitch, NSString);
RCT_EXPORT_VIEW_PROPERTY(mixWithOthers, NSString);
RCT_EXPORT_VIEW_PROPERTY(rate, float);
RCT_EXPORT_VIEW_PROPERTY(seek, NSDictionary);
RCT_EXPORT_VIEW_PROPERTY(currentTime, float);
Expand Down

0 comments on commit c438509

Please # to comment.