-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[interactive_media_ads] Updates README with a usage section and fix some interface docs
#6988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9f02730
5f767fb
b3317a0
631c1e0
35a4445
8ac0311
bc4d770
1f74ead
4320f50
e85027d
6739d7f
e803962
0d59a8e
6b22ebc
957e2ba
d0be873
875d6be
0122f6c
d0971db
6b8ee3a
b1ace40
cc728d2
f345071
90965aa
93c239b
c1b00f1
dce1723
76af339
c2d6f67
9dde9d6
15aa049
7c3dc18
48c7a42
c5842ad
8157448
37fce6f
f00caf2
979ad8c
bdac900
9250e8d
1dc6a07
713bdbd
828ea3a
b4e8cda
c25d360
849ca63
b182af5
e2fb27e
48fb4de
0bbba9a
1ce77c1
c7a320e
a558a54
1c3a2c2
428ecec
e8d822c
5311d85
ba23b1d
52a2c49
f32e74f
75957f2
6743d69
3edc221
3893efe
1c5fac7
a30c9fc
8fa430b
220e2f0
f55805f
284098a
69e088c
48828e3
891f4d4
9ada3ef
84d1ff5
1abcabc
b4b2152
519c68e
f7d25c6
8923d5f
9145273
c3ce374
5e11462
24f0baa
dc6f38a
819441a
eda9cac
6a18fac
4829c85
463bfe4
ca22c23
0a7bebd
98bb920
1605042
f8677d3
c939551
fa53978
de84612
b37e4f6
9aea125
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,12 +4,274 @@ Flutter plugin for the [Interactive Media Ads SDKs][1]. | |
|
|
||
| [](https://pub.dev/packages/interactive_media_ads) | ||
|
|
||
| A Flutter plugin for using the Interactive Media Ads SDKs on Android and iOS. | ||
| IMA SDKs make it easy to integrate multimedia ads into your websites and apps. IMA SDKs can request | ||
| ads from any [VAST-compliant][2] 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 19+ | 12.0+ | | ||
|
|
||
| **This package is still in development.** | ||
|
|
||
| ## IMA client-side overview | ||
|
|
||
| Implementing IMA client-side involves five main SDK components, which are demonstrated in this | ||
| guide: | ||
|
|
||
| * [AdDisplayContainer][3]: A container object where ads are rendered. | ||
| * [AdsLoader][4]: 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][5]: 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][6]: Contains the response to the ads request, controls ad playback, | ||
| and listens for ad events fired by the SDK. | ||
| * [AdsManagerDelegate][8]: 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][7] | ||
| 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 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you are going to use a bulleted list for the headings, I would make all of the content part of the list (by indenting everything in this entire section by two spaces), so that the content of each section isn't offset further left than its heading. Alternatively, you could do |
||
| `android/app/src/main/AndroidManifest.xml`. | ||
|
|
||
| <?code-excerpt "example/android/app/src/main/AndroidManifest.xml (android_manifest)"?> | ||
| ```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"/> | ||
| ``` | ||
|
|
||
| ### 2. Add Imports | ||
|
|
||
| Add the import statements for the `interactive_media_ads` and [video_player][7]. Both plugins should | ||
| already be added to your `pubspec.yaml`. | ||
|
|
||
| <?code-excerpt "example/lib/main.dart (imports)"?> | ||
| ```dart | ||
| import 'package:interactive_media_ads/interactive_media_ads.dart'; | ||
| import 'package:video_player/video_player.dart'; | ||
| ``` | ||
|
|
||
| ### 3. Create a New Widget | ||
|
|
||
| Create a new [StatefulWidget](https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html) | ||
| that handles displaying Ads and playing content. | ||
|
|
||
| <?code-excerpt "example/lib/main.dart (example_widget)"?> | ||
| ```dart | ||
| /// 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> { | ||
| // 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) { | ||
| // ··· | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### 4. Add the Video Players | ||
|
|
||
| Instantiate the [AdDisplayContainer][3] for playing Ads and the | ||
| [VideoPlayerController](https://pub.dev/documentation/video_player/latest/video_player/VideoPlayerController-class.html) | ||
| for playing content. | ||
|
|
||
| <?code-excerpt "example/lib/main.dart (ad_and_content_players)"?> | ||
| ```dart | ||
| 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(() {}); | ||
| }); | ||
| } | ||
| ``` | ||
|
|
||
| ### 5. Implement the `build` Method | ||
|
|
||
| Return a `Widget` that contains the ad player and the content player. | ||
|
|
||
| <?code-excerpt "example/lib/main.dart (widget_build)"?> | ||
| ```dart | ||
| @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, | ||
| ); | ||
| } | ||
| ``` | ||
|
|
||
| ### 6. Request Ads | ||
|
|
||
| Handle requesting ads and add event listeners to handle when content should be displayed or hidden. | ||
|
|
||
| <?code-excerpt "example/lib/main.dart (request_ads)"?> | ||
| ```dart | ||
| 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}'); | ||
| 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: | ||
| } | ||
| }, | ||
| 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(); | ||
| } | ||
| ``` | ||
|
|
||
| ### 7. Dispose Resources | ||
|
|
||
| Dispose the content player and the destroy the [AdsManager][6]. | ||
|
|
||
| <?code-excerpt "example/lib/main.dart (dispose)"?> | ||
| ```dart | ||
| @override | ||
| void dispose() { | ||
| super.dispose(); | ||
| _contentVideoController.dispose(); | ||
| _adsManager?.destroy(); | ||
| } | ||
| ``` | ||
|
|
||
| That's it! You're now requesting and displaying ads with the IMA SDK. To learn about additional SDK | ||
| features, see the [API reference](https://pub.dev/documentation/interactive_media_ads/latest/). | ||
|
|
||
| [1]: https://developers.google.com/interactive-media-ads | ||
| [2]: https://www.iab.com/guidelines/vast/ | ||
| [3]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdDisplayContainer-class.html | ||
| [4]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdsLoader-class.html | ||
| [5]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdsRequest-class.html | ||
| [6]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdsManager-class.html | ||
| [7]: https://pub.dev/packages/video_player | ||
| [8]: https://pub.dev/documentation/interactive_media_ads/latest/interactive_media_ads/AdsManagerDelegate-class.html | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Convenience link to see preview: https://github.com/bparrishMines/packages/blob/ima_readme/packages/interactive_media_ads/README.md