Skip to content

Commit

Permalink
feat(video): add support for video ad volume control
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrienLefaure committed Jul 22, 2024
1 parent bc9649b commit cc7a2b9
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 0 deletions.
16 changes: 16 additions & 0 deletions __tests__/googleMobileAds.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,22 @@ describe('Admob', function () {
admob().openDebugMenu('');
}).toThrowError('openDebugMenu expected a non-empty string value');
});

it('does call native setAppVolume method', () => {
admob().setAppVolume(0.5);
expect(RNGoogleMobileAdsModule.setAppVolume).toBeCalledTimes(1);
});

it('throws if setAppVolume is greater then 1', function () {
expect(() => {
admob().setAppVolume(2);
}).toThrowError('The app volume must be a value between 0 and 1 inclusice.');
});

it('does call native setAppMuted method', () => {
admob().setAppMuted(true);
expect(RNGoogleMobileAdsModule.setAppMuted).toBeCalledTimes(1);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,14 @@ public void openDebugMenu(final String adUnit) {
.runOnUiThread(() -> MobileAds.openDebugMenu(getCurrentActivity(), adUnit));
}
}

@ReactMethod
public void setAppVolume(final Float volume) {
MobileAds.setAppVolume(volume);
}

@ReactMethod
public void setAppMuted(final Boolean muted) {
MobileAds.setAppMuted(muted);
}
}
35 changes: 35 additions & 0 deletions docs/displaying-ads.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -484,3 +484,38 @@ function App() {
```
The `sizes` prop takes an array of [`BannerAdSize`](/reference/admob/banneradsize) types.
### Video ad volume control
If your app has its own volume controls, such as custom music or sound effect volumes, disclosing app volume to the Google Mobile Ads SDK enables video ads to respect app volume settings. This ensures users receive video ads with the expected audio volume.
The device volume, controlled through volume buttons or OS-level volume slider, determines the volume for device audio output. However, apps can independently adjust volume levels relative to the device volume to tailor the audio experience.
For App Open, Banner, Interstitial, Rewarded, and Rewarded Interstitial ad formats you can report the relative app volume to the Google Mobile Ads SDK by calling the setAppVolume function. Valid ad volume values range from 0.0 (silent) to 1.0 (current device volume). Here's an example of how to report the relative app volume to the SDK:
```js
import React from 'react';
import MobileAds, { GAMBannerAd, BannerAdSize, TestIds } from 'react-native-google-mobile-ads';

const adUnitId = __DEV__ ? TestIds.GAM_BANNER : '/xxx/yyyy';

function App() {
MobileAds().setAppVolume(0.5);

return <GAMBannerAd unitId={adUnitId} sizes={[BannerAdSize.FULL_BANNER]} />;
}
```
For App Open, Banner, Interstitial, Rewarded, and Rewarded Interstitial ad formats, you can inform the Google Mobile Ads SDK that the app volume has been muted by calling the setAppMuted function:
```js
import React from 'react';
import MobileAds, { GAMBannerAd, BannerAdSize, TestIds } from 'react-native-google-mobile-ads';

const adUnitId = __DEV__ ? TestIds.GAM_BANNER : '/xxx/yyyy';

function App() {
MobileAds().setMuted(true);

return <GAMBannerAd unitId={adUnitId} sizes={[BannerAdSize.FULL_BANNER]} />;
}
12 changes: 12 additions & 0 deletions ios/RNGoogleMobileAds/RNGoogleMobileAdsModule.mm
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ - (dispatch_queue_t)methodQueue {
#endif
}

RCT_EXPORT_METHOD(setAppVolume : (float)volume) {
#if !TARGET_OS_MACCATALYST
GADMobileAds.sharedInstance.applicationVolume = volume;
#endif
}

RCT_EXPORT_METHOD(setAppMuted : (BOOL *)muted) {
#if !TARGET_OS_MACCATALYST
GADMobileAds.sharedInstance.applicationMuted = muted;
#endif
}

#ifdef RCT_NEW_ARCH_ENABLED
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params {
Expand Down
2 changes: 2 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ jest.doMock('react-native', () => {
setRequestConfiguration: jest.fn(),
openAdInspector: jest.fn(),
openDebugMenu: jest.fn(),
setAppVolume: jest.fn(),
setAppMuted: jest.fn(),
};
},
},
Expand Down
10 changes: 10 additions & 0 deletions src/MobileAds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ class MobileAdsModule implements MobileAdsModuleInterface {
if (!adUnit) throw new Error('googleMobileAds.openDebugMenu expected a non-empty string value');
RNGoogleMobileAdsModule.openDebugMenu(adUnit);
}

setAppVolume(volume: number) {
if (volume < 0 || volume > 1)
throw new Error('The app volume must be a value between 0 and 1 inclusice.');
RNGoogleMobileAdsModule.setAppVolume(volume);
}

setAppMuted(muted: boolean) {
RNGoogleMobileAdsModule.setAppMuted(muted);
}
}

const MobileAdsInstance = new MobileAdsModule();
Expand Down
2 changes: 2 additions & 0 deletions src/NativeGoogleMobileAdsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export interface Spec extends TurboModule {
setRequestConfiguration(requestConfiguration?: UnsafeObject): Promise<void>;
openAdInspector(): Promise<void>;
openDebugMenu(adUnit: string): void;
setAppVolume(volume: number): void;
setAppMuted(muted: boolean): void;
}

export default TurboModuleRegistry.getEnforcing<Spec>('RNGoogleMobileAdsModule');
28 changes: 28 additions & 0 deletions src/types/MobileAdsModule.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,32 @@ export interface MobileAdsModuleInterface {
* @param adUnit Any valid ad unit from your Ad Manager account is sufficient to open the debug options menu.
*/
openDebugMenu(adUnit: string): void;

/**
* Sets the application's audio volume. Affects audio volumes of all ads relative to other audio output.
*
* Warning: Lowering your app's audio volume reduces video ad eligibility and may reduce your app's ad revenue.
* You should only utilize this API if your app provides custom volume controls to the user, and you should reflect
* the user's volume choice in this API.
*
* @see https://developers.google.com/ad-manager/mobile-ads-sdk/android/global-settings
* @see https://developers.google.com/ad-manager/mobile-ads-sdk/ios/global-settings
*
* @param volume the volume as a float from 0 (muted) to 1.0 (full media volume). Defaults to 1.0
*/
setAppVolume(volume: number): void;

/**
* Indicates whether the application's audio is muted. Affects initial mute state for all ads.
*
* Warning: Muting your application reduces video ad eligibility and may reduce your app's ad revenue.
* You should only utilize this API if your app provides a custom mute control to the user, and you should
* reflect the user's mute decision in this API.
*
* @see https://developers.google.com/ad-manager/mobile-ads-sdk/android/global-settings
* @see https://developers.google.com/ad-manager/mobile-ads-sdk/ios/global-settings
*
* @param muted true if the app is muted, false otherwise. Defaults to false.
*/
setAppMuted(muted: boolean): void;
}

0 comments on commit cc7a2b9

Please sign in to comment.