Last updated:
0 purchases
interactive media ads
interactive_media_ads #
Flutter plugin for the Interactive Media Ads SDKs.
IMA SDKs make it easy to integrate multimedia ads into your websites and apps. IMA SDKs can request
ads from any VAST-compliant ad server and manage ad playback in your apps. With IMA client-side
SDKs, you maintain control of content video playback, while the SDK handles ad playback. Ads play in
a separate video player positioned on top of the app's content video player.
Android
iOS
Support
SDK 21+
12.0+
NOTE:
The initial release for this package supports linear pre-roll video ads on iOS and Android
platforms.
Companion ads, Background Audio ads and Google Dynamic Ad Insertion methods are currently not
supported.
IMA client-side overview #
Implementing IMA client-side involves five main SDK components, which are demonstrated in this
guide:
AdDisplayContainer: A container object where ads are rendered.
AdsLoader: Requests ads and handles events from ads request responses. You should only
instantiate one ads loader, which can be reused throughout the life of the application.
AdsRequest: An object that defines an ads request. Ads requests specify the URL for the VAST
ad tag, as well as additional parameters, such as ad dimensions.
AdsManager: Contains the response to the ads request, controls ad playback,
and listens for ad events fired by the SDK.
AdsManagerDelegate: Handles ad events and errors that occur during ad or stream
initialization and playback.
Usage #
This guide demonstrates how to integrate the IMA SDK into a new Widget using the video_player
plugin to display content.
1. Add Android Required Permissions #
If building on Android, add the user permissions required by the IMA SDK for requesting ads in
android/app/src/main/AndroidManifest.xml.
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Required permissions for the IMA SDK -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
copied to clipboard
2. Add Imports #
Add the import statements for the interactive_media_ads and video_player. Both plugins should
already be added to your pubspec.yaml.
import 'package:interactive_media_ads/interactive_media_ads.dart';
import 'package:video_player/video_player.dart';
copied to clipboard
3. Create a New Widget #
Create a new StatefulWidget
that handles displaying Ads and playing content.
/// Example widget displaying an Ad before a video.
class AdExampleWidget extends StatefulWidget {
/// Constructs an [AdExampleWidget].
const AdExampleWidget({super.key});
@override
State<AdExampleWidget> createState() => _AdExampleWidgetState();
}
class _AdExampleWidgetState extends State<AdExampleWidget>
with WidgetsBindingObserver {
// IMA sample tag for a single skippable inline video ad. See more IMA sample
// tags at https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags
static const String _adTagUrl =
'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_preroll_skippable&sz=640x480&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=';
// The AdsLoader instance exposes the request ads method.
late final AdsLoader _adsLoader;
// AdsManager exposes methods to control ad playback and listen to ad events.
AdsManager? _adsManager;
// ···
// Whether the widget should be displaying the content video. The content
// player is hidden while Ads are playing.
bool _shouldShowContentVideo = true;
// Controls the content video player.
late final VideoPlayerController _contentVideoController;
// ···
@override
Widget build(BuildContext context) {
// ···
}
}
copied to clipboard
4. Add the Video Players #
Instantiate the AdDisplayContainer for playing Ads and the
VideoPlayerController
for playing content.
late final AdDisplayContainer _adDisplayContainer = AdDisplayContainer(
onContainerAdded: (AdDisplayContainer container) {
// Ads can't be requested until the `AdDisplayContainer` has been added to
// the native View hierarchy.
_requestAds(container);
},
);
@override
void initState() {
super.initState();
// ···
_contentVideoController = VideoPlayerController.networkUrl(
Uri.parse(
'https://storage.googleapis.com/gvabox/media/samples/stock.mp4',
),
)
..addListener(() {
if (_contentVideoController.value.isCompleted) {
_adsLoader.contentComplete();
}
setState(() {});
})
..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {});
});
}
copied to clipboard
5. Implement the build Method #
Return a Widget that contains the ad player and the content player.
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SizedBox(
width: 300,
child: !_contentVideoController.value.isInitialized
? Container()
: AspectRatio(
aspectRatio: _contentVideoController.value.aspectRatio,
child: Stack(
children: <Widget>[
// The display container must be on screen before any Ads can be
// loaded and can't be removed between ads. This handles clicks for
// ads.
_adDisplayContainer,
if (_shouldShowContentVideo)
VideoPlayer(_contentVideoController)
],
),
),
),
),
floatingActionButton:
_contentVideoController.value.isInitialized && _shouldShowContentVideo
? FloatingActionButton(
onPressed: () {
setState(() {
_contentVideoController.value.isPlaying
? _contentVideoController.pause()
: _contentVideoController.play();
});
},
child: Icon(
_contentVideoController.value.isPlaying
? Icons.pause
: Icons.play_arrow,
),
)
: null,
);
}
copied to clipboard
6. Request Ads #
Handle requesting ads and add event listeners to handle when content should be displayed or hidden.
Future<void> _requestAds(AdDisplayContainer container) {
_adsLoader = AdsLoader(
container: container,
onAdsLoaded: (OnAdsLoadedData data) {
final AdsManager manager = data.manager;
_adsManager = data.manager;
manager.setAdsManagerDelegate(AdsManagerDelegate(
onAdEvent: (AdEvent event) {
debugPrint('OnAdEvent: ${event.type} => ${event.adData}');
switch (event.type) {
case AdEventType.loaded:
manager.start();
case AdEventType.contentPauseRequested:
_pauseContent();
case AdEventType.contentResumeRequested:
_resumeContent();
case AdEventType.allAdsCompleted:
manager.destroy();
_adsManager = null;
case AdEventType.clicked:
case AdEventType.complete:
case _:
}
},
onAdErrorEvent: (AdErrorEvent event) {
debugPrint('AdErrorEvent: ${event.error.message}');
_resumeContent();
},
));
manager.init();
},
onAdsLoadError: (AdsLoadErrorData data) {
debugPrint('OnAdsLoadError: ${data.error.message}');
_resumeContent();
},
);
return _adsLoader.requestAds(AdsRequest(adTagUrl: _adTagUrl));
}
Future<void> _resumeContent() {
setState(() {
_shouldShowContentVideo = true;
});
return _contentVideoController.play();
}
Future<void> _pauseContent() {
setState(() {
_shouldShowContentVideo = false;
});
return _contentVideoController.pause();
}
copied to clipboard
7. Dispose Resources #
Dispose the content player and destroy the AdsManager.
@override
void dispose() {
super.dispose();
_contentVideoController.dispose();
_adsManager?.destroy();
// ···
}
copied to clipboard
That's it! You're now requesting and displaying ads with the IMA SDK. To learn about additional SDK
features, see the API reference.
Contributing #
For information on contributing to this plugin, see CONTRIBUTING.md.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.