Merge pull request #1978 from euharrison/master

Audio mix with other apps for iOS
This commit is contained in:
Jens Andersson 2020-05-07 09:52:34 +02:00 committed by GitHub
commit c4385090ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 11 deletions

View File

@ -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 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) - 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 ### Version 5.1.0-alpha5

View File

@ -289,6 +289,7 @@ var styles = StyleSheet.create({
* [ignoreSilentSwitch](#ignoresilentswitch) * [ignoreSilentSwitch](#ignoresilentswitch)
* [maxBitRate](#maxbitrate) * [maxBitRate](#maxbitrate)
* [minLoadRetryCount](#minLoadRetryCount) * [minLoadRetryCount](#minLoadRetryCount)
* [mixWithOthers](#mixWithOthers)
* [muted](#muted) * [muted](#muted)
* [paused](#paused) * [paused](#paused)
* [pictureInPicture](#pictureinpicture) * [pictureInPicture](#pictureinpicture)
@ -531,6 +532,14 @@ minLoadRetryCount={5} // retry 5 times
Platforms: Android ExoPlayer 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 #### muted
Controls whether the audio is muted Controls whether the audio is muted
* **false (default)** - Don't mute audio * **false (default)** - Don't mute audio

View File

@ -52,6 +52,7 @@ class VideoPlayer extends Component {
paused: true, paused: true,
skin: 'custom', skin: 'custom',
ignoreSilentSwitch: null, ignoreSilentSwitch: null,
mixWithOthers: null,
isBuffering: false, isBuffering: false,
filter: FilterType.NONE, filter: FilterType.NONE,
filterEnabled: true filterEnabled: true
@ -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() { renderCustomSkin() {
const flexCompleted = this.getCurrentTimePercentage() * 100; const flexCompleted = this.getCurrentTimePercentage() * 100;
const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100; const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100;
@ -170,6 +183,7 @@ class VideoPlayer extends Component {
volume={this.state.volume} volume={this.state.volume}
muted={this.state.muted} muted={this.state.muted}
ignoreSilentSwitch={this.state.ignoreSilentSwitch} ignoreSilentSwitch={this.state.ignoreSilentSwitch}
mixWithOthers={this.state.mixWithOthers}
resizeMode={this.state.resizeMode} resizeMode={this.state.resizeMode}
onLoad={this.onLoad} onLoad={this.onLoad}
onBuffer={this.onBuffer} onBuffer={this.onBuffer}
@ -226,10 +240,16 @@ class VideoPlayer extends Component {
<View style={styles.generalControls}> <View style={styles.generalControls}>
{ {
(Platform.OS === 'ios') ? (Platform.OS === 'ios') ?
<>
<View style={styles.ignoreSilentSwitchControl}> <View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')} {this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')} {this.renderIgnoreSilentSwitchControl('obey')}
</View> : null </View>
<View style={styles.mixWithOthersControl}>
{this.renderMixWithOthersControl('mix')}
{this.renderMixWithOthersControl('duck')}
</View>
</> : null
} }
</View> </View>
@ -257,6 +277,7 @@ class VideoPlayer extends Component {
volume={this.state.volume} volume={this.state.volume}
muted={this.state.muted} muted={this.state.muted}
ignoreSilentSwitch={this.state.ignoreSilentSwitch} ignoreSilentSwitch={this.state.ignoreSilentSwitch}
mixWithOthers={this.state.mixWithOthers}
resizeMode={this.state.resizeMode} resizeMode={this.state.resizeMode}
onLoad={this.onLoad} onLoad={this.onLoad}
onBuffer={this.onBuffer} onBuffer={this.onBuffer}
@ -313,10 +334,16 @@ class VideoPlayer extends Component {
<View style={styles.generalControls}> <View style={styles.generalControls}>
{ {
(Platform.OS === 'ios') ? (Platform.OS === 'ios') ?
<>
<View style={styles.ignoreSilentSwitchControl}> <View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')} {this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')} {this.renderIgnoreSilentSwitchControl('obey')}
</View> : null </View>
<View style={styles.mixWithOthersControl}>
{this.renderMixWithOthersControl('mix')}
{this.renderMixWithOthersControl('duck')}
</View>
</> : null
} }
</View> </View>
</View> </View>
@ -399,6 +426,12 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
justifyContent: 'center' justifyContent: 'center'
}, },
mixWithOthersControl: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
},
controlOption: { controlOption: {
alignSelf: 'center', alignSelf: 'center',
fontSize: 11, fontSize: 11,

View File

@ -67,6 +67,7 @@ static int const RCTVideoUnset = -1;
BOOL _playWhenInactive; BOOL _playWhenInactive;
BOOL _pictureInPicture; BOOL _pictureInPicture;
NSString * _ignoreSilentSwitch; NSString * _ignoreSilentSwitch;
NSString * _mixWithOthers;
NSString * _resizeMode; NSString * _resizeMode;
BOOL _fullscreen; BOOL _fullscreen;
BOOL _fullscreenAutorotate; BOOL _fullscreenAutorotate;
@ -108,6 +109,7 @@ static int const RCTVideoUnset = -1;
_playWhenInactive = false; _playWhenInactive = false;
_pictureInPicture = false; _pictureInPicture = false;
_ignoreSilentSwitch = @"inherit"; // inherit, ignore, obey _ignoreSilentSwitch = @"inherit"; // inherit, ignore, obey
_mixWithOthers = @"inherit"; // inherit, mix, duck
#if TARGET_OS_IOS #if TARGET_OS_IOS
_restoreUserInterfaceForPIPStopCompletionHandler = NULL; _restoreUserInterfaceForPIPStopCompletionHandler = NULL;
#endif #endif
@ -861,16 +863,40 @@ static int const RCTVideoUnset = -1;
[self applyModifiers]; [self applyModifiers];
} }
- (void)setMixWithOthers:(NSString *)mixWithOthers
{
_mixWithOthers = mixWithOthers;
[self applyModifiers];
}
- (void)setPaused:(BOOL)paused - (void)setPaused:(BOOL)paused
{ {
if (paused) { if (paused) {
[_player pause]; [_player pause];
[_player setRate:0.0]; [_player setRate:0.0];
} else { } else {
AVAudioSession *session = [AVAudioSession sharedInstance];
AVAudioSessionCategory category = nil;
AVAudioSessionCategoryOptions options = nil;
if([_ignoreSilentSwitch isEqualToString:@"ignore"]) { if([_ignoreSilentSwitch isEqualToString:@"ignore"]) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; category = AVAudioSessionCategoryPlayback;
} else if([_ignoreSilentSwitch isEqualToString:@"obey"]) { } 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) { if (@available(iOS 10.0, *) && !_automaticallyWaitsToMinimizeStalling) {

View File

@ -35,6 +35,7 @@ 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(pictureInPicture, BOOL);
RCT_EXPORT_VIEW_PROPERTY(ignoreSilentSwitch, NSString); RCT_EXPORT_VIEW_PROPERTY(ignoreSilentSwitch, NSString);
RCT_EXPORT_VIEW_PROPERTY(mixWithOthers, 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);
RCT_EXPORT_VIEW_PROPERTY(currentTime, float); RCT_EXPORT_VIEW_PROPERTY(currentTime, float);