Merge pull request #1978 from euharrison/master
Audio mix with other apps for iOS
This commit is contained in:
commit
c4385090ab
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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}>
|
<>
|
||||||
{this.renderIgnoreSilentSwitchControl('ignore')}
|
<View style={styles.ignoreSilentSwitchControl}>
|
||||||
{this.renderIgnoreSilentSwitchControl('obey')}
|
{this.renderIgnoreSilentSwitchControl('ignore')}
|
||||||
</View> : null
|
{this.renderIgnoreSilentSwitchControl('obey')}
|
||||||
|
</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}>
|
<>
|
||||||
{this.renderIgnoreSilentSwitchControl('ignore')}
|
<View style={styles.ignoreSilentSwitchControl}>
|
||||||
{this.renderIgnoreSilentSwitchControl('obey')}
|
{this.renderIgnoreSilentSwitchControl('ignore')}
|
||||||
</View> : null
|
{this.renderIgnoreSilentSwitchControl('obey')}
|
||||||
|
</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,
|
||||||
|
@ -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,18 +863,42 @@ 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) {
|
||||||
[_player playImmediatelyAtRate:_rate];
|
[_player playImmediatelyAtRate:_rate];
|
||||||
} else {
|
} else {
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user