diff --git a/README.md b/README.md index 19b4371d..cac87ad2 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,7 @@ var styles = StyleSheet.create({ * [volume](#volume) ### Event props +* [onAudioBecomingNoisy](#onaudiobecomingnoisy) * [onLoad](#onload) * [onLoadStart](#onloadstart) * [onProgress](#onprogress) @@ -452,6 +453,13 @@ Platforms: all ### Event props +#### onAudioBecomingNoisy +Callback function that is called when the audio is about to become 'noisy' due to a change in audio outputs. Typically this is called when audio output is being switched from an external source like headphones back to the internal speaker. It's a good idea to pause the media when this happens so the speaker doesn't start blasting sound. + +Payload: none + +Platforms: Android ExoPlayer, iOS + #### onLoad Callback function that is called when the media is loaded and ready to play. diff --git a/Video.js b/Video.js index 7a0d7a39..dda530d3 100644 --- a/Video.js +++ b/Video.js @@ -235,6 +235,7 @@ export default class Video extends Component { onVideoEnd: this._onEnd, onVideoBuffer: this._onBuffer, onTimedMetadata: this._onTimedMetadata, + onVideoAudioBecomingNoisy: this._onAudioBecomingNoisy, onVideoFullscreenPlayerWillPresent: this._onFullscreenPlayerWillPresent, onVideoFullscreenPlayerDidPresent: this._onFullscreenPlayerDidPresent, onVideoFullscreenPlayerWillDismiss: this._onFullscreenPlayerWillDismiss, @@ -296,6 +297,7 @@ Video.propTypes = { onVideoSeek: PropTypes.func, onVideoEnd: PropTypes.func, onTimedMetadata: PropTypes.func, + onVideoAudioBecomingNoisy: PropTypes.func, onVideoFullscreenPlayerWillPresent: PropTypes.func, onVideoFullscreenPlayerDidPresent: PropTypes.func, onVideoFullscreenPlayerWillDismiss: PropTypes.func, diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/VideoEventEmitter.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/VideoEventEmitter.java index a447a734..ff1fc563 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/VideoEventEmitter.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/VideoEventEmitter.java @@ -42,7 +42,7 @@ class VideoEventEmitter { private static final String EVENT_BUFFER = "onVideoBuffer"; private static final String EVENT_IDLE = "onVideoIdle"; private static final String EVENT_TIMED_METADATA = "onTimedMetadata"; - private static final String EVENT_AUDIO_BECOMING_NOISY = "onAudioBecomingNoisy"; + private static final String EVENT_AUDIO_BECOMING_NOISY = "onVideoAudioBecomingNoisy"; private static final String EVENT_AUDIO_FOCUS_CHANGE = "onAudioFocusChanged"; private static final String EVENT_PLAYBACK_RATE_CHANGE = "onPlaybackRateChange"; diff --git a/ios/RCTVideo.h b/ios/RCTVideo.h index 38d2ab4e..1c471236 100644 --- a/ios/RCTVideo.h +++ b/ios/RCTVideo.h @@ -17,6 +17,7 @@ @property (nonatomic, copy) RCTBubblingEventBlock onVideoSeek; @property (nonatomic, copy) RCTBubblingEventBlock onVideoEnd; @property (nonatomic, copy) RCTBubblingEventBlock onTimedMetadata; +@property (nonatomic, copy) RCTBubblingEventBlock onVideoAudioBecomingNoisy; @property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerWillPresent; @property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerDidPresent; @property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerWillDismiss; diff --git a/ios/RCTVideo.m b/ios/RCTVideo.m index e155e7d2..c1bf66dd 100644 --- a/ios/RCTVideo.m +++ b/ios/RCTVideo.m @@ -91,6 +91,11 @@ static NSString *const timedMetadata = @"timedMetadata"; selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(audioRouteChanged:) + name:AVAudioSessionRouteChangeNotification + object:nil]; } return self; @@ -190,6 +195,17 @@ static NSString *const timedMetadata = @"timedMetadata"; } } +#pragma mark - Audio events + +- (void)audioRouteChanged:(NSNotification *)notification +{ + NSNumber *reason = [[notification userInfo] objectForKey:AVAudioSessionRouteChangeReasonKey]; + NSNumber *previousRoute = [[notification userInfo] objectForKey:AVAudioSessionRouteChangePreviousRouteKey]; + if (reason.unsignedIntValue == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) { + self.onVideoAudioBecomingNoisy(@{@"target": self.reactTag}); + } +} + #pragma mark - Progress - (void)sendProgressUpdate diff --git a/ios/RCTVideoManager.m b/ios/RCTVideoManager.m index 308d49e8..8e566602 100644 --- a/ios/RCTVideoManager.m +++ b/ios/RCTVideoManager.m @@ -46,6 +46,7 @@ RCT_EXPORT_VIEW_PROPERTY(onVideoProgress, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoSeek, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoEnd, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onTimedMetadata, RCTBubblingEventBlock); +RCT_EXPORT_VIEW_PROPERTY(onVideoAudioBecomingNoisy, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerWillPresent, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerDidPresent, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerWillDismiss, RCTBubblingEventBlock);