Ad frequency control
Ad frequency control (AFC) lets you gate ad opportunities based on content
consumption and ad-break exposure. AFC is opt-in: all ad opportunities are
allowed when you omit the configuration or set enable to false. This page
shows how to configure AFC for IMA CSAI, IMA DAI, and MediaTailor, and how to
evaluate an SSAI preroll request in your app.
Configure AFC
The AdFrequencyControlConfiguration enables AFC and defines its thresholds.
The following table lists the default values. Set enable to true to enforce
AFC.
| Property | Default | Description |
|---|---|---|
enable | false | Enables AFC enforcement. |
minimumContentConsumptionMs | 180_000 (3 minutes) | Minimum content consumption threshold in ms. |
adBreakExposureThreshold | 0.66 | Ad-break exposure threshold (e.g. 66% exposure). |
allowFirstOpportunity | true | Whether AFC allows the first ad opportunity. |
How AFC works
AFC suppresses ad breaks when the user has recently seen ads, so viewers don't see ads too often.
- Ad opportunity check: The player evaluates whether AFC is enabled.
- First opportunity: If
allowFirstOpportunityistrue, the first ad opportunity in a playback session can play. - Exposure check: After an ad break plays, AFC checks whether the user
watched at least
adBreakExposureThresholdof it cumulatively across the ad break. With the default0.66, the user must watch 66% or more for the ad break to count as exposed. - Suppression window: After an exposed ad break, AFC resets the content
counter and suppresses upcoming ad breaks until the user has watched
minimumContentConsumptionMsof content. With the default value, ad breaks are suppressed for the next 3 minutes of content. - Next ad break: Once the user completes
minimumContentConsumptionMsof content, the next ad break is allowed to play.
If the user doesn't watch an ad break up to adBreakExposureThreshold, it
doesn't count as exposed, so AFC doesn't start a suppression window for it.
Use AFC with IMA CSAI
Pass adFrequencyControl when constructing the ad player via
FLAdvertisingGoogleIMAFactory:
import FLPlayer
import FLAdvertisingGoogleIMA
let adPlayer = FLAdvertisingGoogleIMAFactory.adPlayer(
contentPlayer: contentPlayer,
request: request,
shouldSupportPIP: shouldSupportPIP,
playerViewControllerCallback: playerViewControllerCallback,
adFrequencyControl: .init(
enable: true,
minimumContentConsumptionMs: 180_000,
adBreakExposureThreshold: 0.66,
allowFirstOpportunity: true
)
)
let adComposedPlayer = FLAdvertisingGoogleIMAFactory.adComposablePlayer(contentPlayer: contentPlayer, adPlayer: adPlayer)
Use AFC with IMA DAI
For Google DAI streams initialized through FLAdvertisingGoogleIMAFactory, pass
adFrequencyControl during ad player instantiation:
import FLPlayer
import FLAdvertisingGoogleIMA
let adPlayer = FLAdvertisingGoogleIMAFactory.adPlayer(
contentPlayer: contentPlayer,
request: daiAdRequest,
shouldSupportPIP: shouldSupportPIP,
playerViewControllerCallback: playerViewControllerCallback,
adFrequencyControl: .init(
enable: true,
minimumContentConsumptionMs: 180_000,
adBreakExposureThreshold: 0.66,
allowFirstOpportunity: true
)
)
let adComposedPlayer = FLAdvertisingGoogleIMAFactory.adComposablePlayer(contentPlayer: contentPlayer, adPlayer: adPlayer)
Use AFC with MediaTailor
The MediaTailorPlayerBuilder supports AFC on both custom and Datazoom
MediaTailor player modes. Configure AFC on MediaTailorPlayerBuilder using the
.adFrequencyControl(configuration:) method:
import FLPlayer
import FLAdvertisingMediatailor
var builder = FLMediatailorFactory.createPlayerBuilder(mediatailorSession: session, fallbackAsset: urlAsset)
builder.adFrequencyControl(configuration: .init(
enable: true,
minimumContentConsumptionMs: 180_000,
adBreakExposureThreshold: 0.66,
allowFirstOpportunity: true
))
let player = builder.build()
Gate SSAI preroll requests
Call AdFrequencyControl.shared.evaluateOpportunity() from your content
authorization flow when deciding whether to request an SSAI preroll. It returns
true to request the preroll or false to skip it. When AFC is disabled, it
returns true.
import FLPlayer
if AdFrequencyControl.shared.evaluateOpportunity() {
// Request the SSAI preroll from content authorization.
}
Logging and diagnostics
AFC logs diagnostic events under the com.quickplay.FLPlayer subsystem with the
AFC category. Filter for category:AFC in Xcode Console or macOS Console to
monitor:
- Configuration updates and parameter values
- Content consumption accumulation ticks and seek discards
- Ad opportunity evaluations (allowed vs. suppressed)
- Exposure threshold completions and counter resets
Ad Suppression Event
When AFC blocks an ad opportunity, the player emits the adSkipAfcPolicy event. Applications can use this event to identify when an ad is skipped due to AFC policy and report it to analytics for tracking and downstream analysis.