Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/audiodocs/docs/system/audio-manager.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ and tries to reactivate the audio session as soon as there is "silence", althoug
Internally, the method uses `AVAudioSessionSilenceSecondaryAudioHintNotification` as well as
interval polling to check if other audio is playing.

### `getSystemVolume`

Reads the current system output volume as a 0..1 fraction of its maximum.

#### Returns `number`.

### `observeVolumeChanges`

| Parameter | Type | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ class AudioAPIModule(
MediaSessionManager.observeVolumeChanges(enabled)
}

override fun getSystemVolume(): Double = MediaSessionManager.getSystemVolume()

override fun requestRecordingPermissions(promise: Promise) {
val permissionRequestListener = PermissionRequestListener(promise)
MediaSessionManager.requestRecordingPermissions(permissionRequestListener)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ object MediaSessionManager {
this.notificationRegistry = NotificationRegistry(this.reactContext, this.audioAPIModule)
}

/** The system output volume on the volumeChange event's own scale:
* STREAM_MUSIC volume as a 0..1 fraction of its maximum. */
fun getSystemVolume(): Double {
val current = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC).toDouble()
val max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC).toDouble()
return if (max > 0) current / max else 0.0
}

fun getDevicePreferredSampleRate(): Double {
val sampleRate = this.audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)
return sampleRate.toDouble()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ - (dispatch_queue_t)methodQueue
return [self.audioSessionManager getDevicePreferredSampleRate];
}

RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getSystemVolume)
{
return [self.audioSessionManager getSystemVolume];
}

RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isFfmpegEnabled)
{
#if RN_AUDIO_API_FFMPEG_DISABLED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
- (void)disableSessionManagement;

- (NSNumber *)getDevicePreferredSampleRate;
- (NSNumber *)getSystemVolume;
- (NSString *)inputDiagnosticsSnapshot;

- (void)requestRecordingPermissions:(RCTPromiseResolveBlock)resolve
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ - (NSNumber *)getDevicePreferredSampleRate
return [NSNumber numberWithFloat:[self.audioSession sampleRate]];
}

- (NSNumber *)getSystemVolume
{
return [NSNumber numberWithFloat:[self.audioSession outputVolume]];
}

- (NSString *)inputDiagnosticsSnapshot
{
AVAudioSessionRouteDescription *route = [self.audioSession currentRoute];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface Spec extends TurboModule {
observeAudioInterruptions(focusType: AudioFocusType, enabled: boolean): void;
activelyReclaimSession(enabled: boolean): void;
observeVolumeChanges(enabled: boolean): void;
getSystemVolume(): number;

// Permissions
requestRecordingPermissions(): Promise<PermissionStatus>;
Expand Down
12 changes: 12 additions & 0 deletions packages/react-native-audio-api/src/system/AudioManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ class AudioManager implements IAudioManager {
NativeAudioAPIModule.observeVolumeChanges(enabled);
}

/**
* Synchronously reads the current system output volume as a 0..1 value, on
* the same scale the `volumeChange` event reports
*
* On iOS, a cold read before any volume-change event can report a stale or
* zero value on some OS versions; treat the event stream as the truth once it
* speaks.
*/
getSystemVolume(): number {
return NativeAudioAPIModule.getSystemVolume();
}

addSystemEventListener<Name extends SystemEventName>(
name: Name,
callback: SystemEventCallback<Name>
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-audio-api/src/system/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export interface IAudioManager {
observeAudioInterruptions(enabled: boolean): void;
activelyReclaimSession(enabled: boolean): void;
observeAudioInterruptions(param: AudioFocusType | boolean | null): void;
getSystemVolume(): number;
addSystemEventListener<Name extends SystemEventName>(
name: Name,
callback: SystemEventCallback<Name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const mockSync =

class AudioManager implements IAudioManager {
getDevicePreferredSampleRate = mockSync(44100);
getSystemVolume = mockSync(1);
setAudioSessionActivity = mockAsync(undefined);
setAudioSessionOptions = mockSync({});
disableSessionManagement = mockSync({});
Expand Down
Loading