Preroll Ads
Preroll ads are video ads that play before your content. The SDK manages playback automatically using Google IMA — the ad auto-plays with no user-visible controls. Users can skip the ad when the VAST creative allows it.
After the ad completes, is skipped, or fails, your content can start playing automatically. No additional handling is needed.
Each ad format uses a Zone ID to identify the ad placement. Zone IDs are configured in the Empower dashboard.
Note: All ad listeners are optional. The SDK handles ad loading, playback, and fallback automatically. Use listeners only if you need to track ad states for analytics or UI updates.
Platform Differences
Preroll ads use different native player components per platform:
| Platform | Player Component | Container |
|---|---|---|
| Android | PlayerView (Media3/ExoPlayer) | androidx.media3.ui.PlayerView |
| iOS | IMA SDK | UIView container |
Using the EmpowerPrerollView Widget
Use the EmpowerPrerollView widget for inline video ad placement:
import 'package:empower_mobile_ads/empower_mobile_ads.dart';class VideoScreen extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(body: Column(children: [EmpowerPrerollView(zoneId: 'YOUR_PREROLL_ZONE_ID',contentUrl: 'https://example.com/your-content-video.mp4',muted: false,width: double.infinity,height: 220,onStatusChanged: (AdStatus status, String zoneId) {print('Preroll status: $status');},onAdEvent: (String type, String zoneId, String? error) {print('IMA event: $type');},),Padding(padding: const EdgeInsets.all(16),child: Text('Video Title',style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),),],),);}}
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
zoneId | String | Yes | — | Zone ID for the preroll placement |
androidZoneId | String? | No | null | Android-specific zone ID (overrides zoneId) |
iosZoneId | String? | No | null | iOS-specific zone ID (overrides zoneId) |
contentUrl | String | Yes | — | URL of the content video |
muted | bool | No | false | Mute ad audio |
width | double? | No | double.infinity | Width of the preroll view |
height | double? | No | null | Height of the preroll view |
onStatusChanged | Function(AdStatus, String)? | No | null | Called when preroll ad status changes |
onAdEvent | Function(String, String, String?)? | No | null | Called for IMA ad events (quartile progress, etc.) |
backgroundColor | Color | No | Color(0xFF000000) | Background color while loading |
Zone ID Options
Single Zone ID
EmpowerPrerollView(zoneId: 'YOUR_PREROLL_ZONE_ID',contentUrl: 'https://example.com/video.mp4',)
Per-Platform Zone IDs
EmpowerPrerollView(zoneId: '', // fallbackandroidZoneId: 'ANDROID_PREROLL_ZONE_ID',iosZoneId: 'IOS_PREROLL_ZONE_ID',contentUrl: 'https://example.com/video.mp4',)
Using Platform Check
import 'dart:io';EmpowerPrerollView(zoneId: Platform.isAndroid ? 'ANDROID_ZONE_ID' : 'IOS_ZONE_ID',contentUrl: 'https://example.com/video.mp4',)
Lifecycle Management
The SDK automatically manages the ad lifecycle based on the widget's visibility. For special cases like scrolling the video player off-screen in a ListView, use the control methods:
import 'package:empower_mobile_ads/empower_mobile_ads.dart';const zoneId = 'YOUR_PREROLL_ZONE_ID';// Pause playback (e.g., view scrolled off-screen)EmpowerAds.pausePreroll(zoneId);// Resume playback (e.g., view scrolled back)EmpowerAds.resumePreroll(zoneId);// Release all resources when doneEmpowerAds.destroyPreroll(zoneId);
| Method | Description |
|---|---|
EmpowerAds.pausePreroll(zoneId) | Pauses ad or content playback |
EmpowerAds.resumePreroll(zoneId) | Resumes playback |
EmpowerAds.destroyPreroll(zoneId) | Releases player resources |
Tip: Call
destroyPrerollwhen the screen is disposed to free native resources.
Complete Example
import 'dart:io';import 'package:flutter/material.dart';import 'package:empower_mobile_ads/empower_mobile_ads.dart';class VideoScreen extends StatefulWidget {@overrideState<VideoScreen> createState() => _VideoScreenState();}class _VideoScreenState extends State<VideoScreen> {final String _zoneId = Platform.isAndroid? 'ANDROID_PREROLL_ZONE_ID': 'IOS_PREROLL_ZONE_ID';@overridevoid dispose() {EmpowerAds.destroyPreroll(_zoneId);super.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(backgroundColor: Colors.black,body: Column(children: [EmpowerPrerollView(zoneId: _zoneId,contentUrl: 'https://example.com/content-video.mp4',width: double.infinity,height: MediaQuery.of(context).size.width * 9 / 16,onStatusChanged: (AdStatus status, String zoneId) {print('Preroll status: $status');},onAdEvent: (String type, String zoneId, String? error) {print('IMA event: $type');},),Padding(padding: const EdgeInsets.all(16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: const [Text('Video Title',style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.bold)),SizedBox(height: 8),Text('Video description goes here...',style: TextStyle(color: Colors.grey, fontSize: 14)),],),),],),);}}
Best Practices
- Set explicit dimensions — Provide
widthandheightor use aspect ratio calculations for standard video proportions (16:9) - Mute when appropriate — Set
muted: trueif the video auto-plays in a feed or silent context - Destroy on dispose — Always call
EmpowerAds.destroyPrerollin thedisposemethod to release native player resources - Frequency capping — The SDK respects server-configured session frequency caps
- Content URL required — Always provide a valid
contentUrl. The ad plays first, then transitions to your content video automatically
Ad Status Reference
| Status | Description |
|---|---|
READY | Ad is loaded and about to play |
ACTIVE | Ad is playing |
COMPLETE_PLAYING | Ad finished playing, content video is now playing |
SKIPPED | User skipped the ad, content video is now playing |
FAILED | Ad failed, content video plays automatically |
PAUSED | Ad playback paused |
Troubleshooting
Preroll Not Playing on iOS
Ensure SDK is initialized before loading preroll
Check zone ID is correct and active in the Empower dashboard
Enable debug logs to verify:
EmpowerAds.setLogLevel('all');
Preroll Not Playing on Android
Ensure Media3 (ExoPlayer) dependency is available — the SDK includes it transitively, but verify no version conflicts exist
Check the content URL is accessible — the SDK needs a valid video URL to transition to after the ad
Video Playback Issues
- Black screen: Verify container dimensions are set correctly (non-zero width and height)
- Audio issues: Check the
mutedprop and device volume settings - Memory leaks: Always call
EmpowerAds.destroyPrerollwhen navigating away from the video screen