Skip to main content

In-stream Video Ad

Step-1:Integration Reference

  • In-stream video ad, also known as bumper ads, or pre-rolls.
  • Supported types include VAST and VMAP. VAST is commonly used as a standalone pre-roll. VMAP, on the other hand, is a type of interrupted ad that can include pre-roll, mid-roll, and post-roll ads.
  • When the in-stream ad is loaded, the container displaying the ad and the view controller containing the ad container need to be passed in.

STEPS

v12.2.0 and above

  • Create TradPlusAdMediaVideo object.
  • Load the in-stream video ad loadAdWithRootViewController:mute:
  • Register callback TradPlusADMediaVideoDelegate to listen the status of loading、playing、pause、clicking,close etc.
  • Obtain TradPlusMediaVideoAdObject cache through [TradPlusAdMediaVideo getReadyMediaVideoObject] after receiving loaded: callback.
  • After obtaining the TradPlusMediaVideoAdObject get adView and add it to the interface
  • After obtaining the TradPlusMediaVideoAdObject, you can determine whether it is a VAST or VMAP ad based on the videoProtocol.
  • For VAST, you can start playback by calling [TradPlusMediaVideoAdObject startWithSceneId:nil].
  • For VMAP, you can control the video and play ads based on various callback events.

Before v12.2.0

  • Create TradPlusAdMediaVideo object.
  • Load the in-stream video ad loadAd:viewController:mute:
  • Register callback TradPlusADMediaVideoDelegate to listen the status of loading、playing、pause、clicking,close etc.
  • Obtain TradPlusMediaVideoAdObject cache through [TradPlusAdMediaVideo getReadyMediaVideoObject] after receiving loaded: callback.
  • After obtaining the TradPlusMediaVideoAdObject, you can determine whether it is a VAST or VMAP ad based on the videoProtocol.
  • For VAST, you can start playback by calling [TradPlusMediaVideoAdObject startWithViewController:viewController sceneId:nil].
  • For VMAP, you can control the video and play ads based on various callback events.

NOTES

  • It's not recommended to execute the ad loading method in the tpMediaVideoAdOneLayerLoad : didFailWithError: callback. For the ad platform side, it is not easy to get filled if there are multiple requests in a short period of time, which will lead to many invalid requests and may also cause the application to freeze If the product logic needs to initiate a request here, the developer needs to control the time interval and frequency, for example, initiate the request after 10S, 30S, and 60S respectively.
  • TradPlusMediaVideoAdObject object need to be released in the main thread.
  • The video ad will pause when the app is running in background. To resume the playing in foreground, you can run [TradPlusMediaVideoAdObject resume] through the callback UIApplicationWillEnterForegroundNotification.
  • You need to manually call the destroy method before releasing and destroying

Step-2:TradPlusAdMediaVideo API

1. Loading & Displaying Ad

  • Params & Explanation
ParamsExplanation
adUnitIDadUnitID is the adID that created on TradPlus platform. SDK is requesting ads following the adID and configurations.
adContainercontainer for ad
viewControllerview controller for ad
customView*(TradPlusAdxInStreamView )custom in-stream floating layer view, only supports TPADX
mutemute/unmute(YES-mute;NO-unmute)
sceneIdsceneId is AD's scene IDoptional,default:nil,developers should have a joint usage with - (void)showAdWithSceneId:(nullable NSString *)sceneId;
  • Methods & Explanation
MethodsExplanation
- (void)setAdUnitID:(NSString *)adUnitID;Set up Ad unit ID
- (void)loadAdWithRootViewController:(UIViewController *)viewController mute:(BOOL)mute;v12.2.0+ new Request video ad API
- (void)loadAd:(UIView *)adContainer viewController:(UIViewController *)viewController mute:(BOOL)mute;Request video ad
- (BOOL)isAdReady;Check the ad is ready or not
true-ready
flase-NOT ready
- (nullable TradPlusMediaVideoAdObject *)getReadyMediaVideoObject;Obtain TradPlusMediaVideoAdObject Object
- (void)entryAdScenario:(nullable NSString *)sceneId;Enter into Ad scene
Scene is the main gauge of data collection which includs number of entry and appearances,you have to make use of the scene ID correctly.
@property (nonatomic,strong)id contentPlayhead;v10.0.0+ is used to support VMAP, and the incoming object must support GoogleIMA's IMAContentPlayhead protocol
  • TradPlusMediaVideoAdObject API
MethodsExplanation
- (void)startWithViewController:(nullable UIViewController *)viewController sceneId:(nullable NSString *)sceneId;Play
- (void)startWithViewController:(nullable UIViewController *)viewController inStreamView:(nullable TradPlusAdxInStreamView *)customView sceneId:(nullable NSString *)sceneId;v9.8.0+ Play
customView:custom in-stream floating layer view, only supports TPADX
- (void)startWithSceneId(nullable NSString *)sceneId;v12.2.0+ new Play API
- (void)startWithInStreamView:(nullable UIView *)customView sceneId:(nullable NSString *)sceneId;v12.2.0+ new Play API
customView:ustom in-stream floating layer view, only supports TPADX
@property (nonatomic,readonly)UIView *adViewv12.2.0+ get adView;default size 100/100,hidden=YES;
@property (nonatomic,readonly)id contentPlayheadv12.2.0+ contentPlayhead(vmap)
- (void)pause;Pause
- (void)resume;Resume
- (void)destory;Distroy
- (void)contentCompletev10.0.0+ needs to be called manually when using IMA post-posting
@property (nonatomic,readonly)id _Nullable getCustomNetworkObjGet the resource object of the third party. The GoogleIMA object is IMAAd
@property (nonatomic,readonly)id _Nullable getAdsManagerv10.0.0+ Gets the IMAAdsManager object of GoogleIMA
@property (nonatomic,readonly)TPMediaVideoProtocol videoProtocolv10.0.0+ video protocol type
@property (nonatomic,weak) id <TradPlusADMediaVideoDelegate> delegatev10.0.0+ sets the callback of the current advertisement (optional)

2. Listeners & Callbacks

  • Params & Explanation
ParamsExplanation
adInfoInformation like AD ID, 3rd-party ad-network etc.
errorreturn error information from TP.
  • TradPlusADMediaVideoDelegate Callback
MethodsExplanation
- (void)tpMediaVideoAdLoaded:(NSDictionary *)adInfo;This callback is triggered when any one of the source of ads is successfully loaded. Note,this callback only triger once in each single loading process.
- (void)tpMediaVideoAdLoadFailWithError:(NSError *)error;TP returns error information when video ad is failed to load.
tpMediaVideoAdOneLayerLoad:didFailWithError:Error information from 3rd-party ad-network.
- (void)tpMediaVideoAdStart:(NSDictionary *)adInfo;VideoAd has Started
- (void)tpMediaVideoAdError:(NSDictionary *)adInfo error:(NSError *)error;VideoAd Playing Error
- (void)tpMediaVideoAdClicked:(NSDictionary *)adInfo;VideoAd is clicked and jumping to other page.
- (void)tpMediaVideoAdEnd:(NSDictionary *)adInfo;VideoAd Played to End
  • TradPlusADMediaVideoDelegate callback & expalantion(optional)
MethodsExplanation
- (void)tpMediaVideoAdStartLoad:(NSDictionary *)adInfo;New added method in v7.6.0+ Start loading process
- (void)tpMediaVideoAdOneLayerStartLoad:(NSDictionary *)adInfo;This method will be triggered once when each of the source of ads start loading.
- (void)tpMediaVideoAdIsLoading:(NSDictionary *)adInfo;New added method in v8.7.0+ If you are still receiving this callback after calling 'load', the ad slot is still in loading status. So you have to trigger a new request after the last loading completed.
- (void)tpMediaVideoAdOneLayerLoaded:(NSDictionary *)adInfo;This mentod will be triggered once when each source of ad-networks is successfully loaded.
- (void)tpMediaVideoAdOneLayerLoad:(NSDictionary *)adInfo didFailWithError:(NSError *)error;Each of the failed loading will trigger the method and return errors that's from 3rd-party ad-networks.
- (void)tpMediaVideoAdAllLoaded:(BOOL)success;The loading process is completed.
- (void)tpMediaVideoAdBidStart:(NSDictionary *)adInfo;Bidding Starts
- (void)tpMediaVideoAdBidEnd:(NSDictionary *)adInfo error:(nullable NSError *)error;Bidding End,error = nil means success
- (void)tpMediaVideoAdDidProgress:(NSDictionary *)adInfo mediaTime:(NSTimeInterval)mediaTime totalTime:(NSTimeInterval)totalTime;Playing process
- (void)tpMediaVideoAdPause:(NSDictionary *)adInfo;VideoAd Paused
- (void)tpMediaVideoAdResume:(NSDictionary *)adInfo;VideoAd Resume
- (void)tpMediaVideoAdSkiped:(NSDictionary *)adInfo;VideoAd has Skipped.
- (void)tpMediaVideoAdTapped:(NSDictionary *)adInfo;VideoAd Tapped
- (void)tpMediaVideoAdEvent:(id)event adInfo:(NSDictionary *)adInfo;v9.4.0+ IMA Events
event: IMAAdEvent Event Object
- (void)tpMediaVideoAdDidStartBuffering:(NSDictionary *)adInfo;v9.4.0+ IMA StartBuffering Event
Called when the current ad media buffer is empty and playback did stall.
- (void)tpMediaVideoAdDidBufferToMediaTime:(NSTimeInterval)mediaTime adInfo:(NSDictionary *)adInfo;v9.4.0+ IMA adDidBufferToMediaTime Event
Called as the current ad media buffers.
- (void)tpMediaVideoAdPlaybackReady:(NSDictionary *);v9.4.0+ IMA PlaybackReady Event
Called when the current ad is sufficiently buffered and playback is likely to keep up.
- (void)tpMediaVideoAdRequestContentPause:(NSDictionary *)adInfo;v10.0.0+ returns IMA RequestContentPause event
- (void)tpMediaVideoAdRequestContentResume:(NSDictionary *)adInfo;v10.0.0+ returns IMA RequestContentPause event
- (void)tpMediaVideoAdBreakReady:(NSDictionary *)adInfo;v10.0.0+ returns IMA kIMAAdEvent_AD_BREAK_READY event

3. Other Settings

  • Before loading ads, configure the settings through params.
  • Allow SDK to open a link in app. YES-allow;NO-NOT allow(default:open in Safari)
  • Hide the Ad countdown element.YES-Hide;NO-Display(Default)
    [TradPlus sharedInstance].settingDataParam = @{
@"GoogleIMA_MediaVideo_isAppBrowser":@(YES), //YES:open link in app.
@"GoogleIMA_MediaVideo_hideCountDown":@(YES) //YES:hide the Ad countdown element.
};
  • v9.3.0 and above, set a custom url parameters(need to be set before loading)
NSDictionary *parameters = @{@"description_url":@"https://www.tradplusad.com"};
self.mediaVideo.localParams = @{@"ima_url_parameters":parameters};
  • v11.1.0 and above, sub-platform set a custom url parameters(need to be set before loading)
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
//GoogleAdManager
parameters[@"platform_48"] = @{@"description_url":@"https://www.tradplusad.com",
@"platform":@"GoogleAdManager"};
//PremiumAds
parameters[@"platform_64"] = @{@"description_url":@"https://www.tradplusad.com",
@"platform":@"PremiumAds"};
//BeesAds
parameters[@"platform_69"] = @{@"description_url":@"https://www.tradplusad.com",
@"platform":@"BeesAds"};
//MangoX
parameters[@"platform_71"] = @{@"description_url":@"https://www.tradplusad.com",
@"platform":@"MangoX"};
localParams[@"ima_url_parameters"] = parameters;
self.mediaVideo.localParams = localParams;
  • v9.6.0+ supports custom timeout. Unit: seconds (default is 8 seconds)
NSMutableDictionary *localParams = [[NSMutableDictionary alloc] init];
localParams[@"ima_load_video_timeout"] = @"6";
[TPMediaVideoManger sharedInstance].mediaVideo.localParams = localParams;
  • v10.2.0 Set autoPlayAdBreaks to on. The default is off.
// To turn it on, you can set it as follows:
[TradPlus sharedInstance].settingDataParam = @{
@"GoogleIMA_MediaVideo_autoPlayAdBreaks":@(YES),
};
  • v10.2.0 Set control center MPNowPlayingInfoCenter. The default is off.
// To turn it on, you can set it as follows:
[TradPlus sharedInstance].settingDataParam = @{
@"GoogleIMA_MediaVideo_disableNowPlayingInfo":@(NO),
};

Vast Ads

  • Both Google IMA and TradPlus Exchange support this VAST ad.
  • Preload interstitial ads so that when the opportunity to display an interstitial ad arrives, you can call Play API to play the interstitial ad.
  • Due to the buffering of interstitial ad videos being affected by network stability or other factors, you can hide the ad container when calling Play API, and then show the ad container for display after receiving the tpMediaVideoAdStart: playback start callback.

Sample Codes

Refernence:TradPlusAdMediaVideoViewController

v12.2.0 and above new API (support multiple caches)

#import <TradPlusAds/TradPlusAdMediaVideo.h>
@property (nonatomic,strong)TradPlusAdMediaVideo *mediaVideo;
@property (nonatomic,strong)TradPlusMediaVideoAdObject *mediaVideoObject;
@property (nonatomic,strong)UIView *myAdView;
@end

@implementation TradPlusAdMediaVideoViewController

- (void)viewDidLoad
{
[super viewDidLoad];
self.mediaVideo = [[TradPlusAdMediaVideo alloc] init];
//set up ad unit id
[self.mediaVideo setAdUnitID:@"在TP平台创建的广告位ID"];
//set up delegate
self.mediaVideo.delegate = self;
//It takes some time to load the ad, you can load the ad in advance before showing the ad
[self.mediaVideo loadAdWithRootViewController:self mute:NO];
}

- (void)showMediaVideoAd
{
//Call the isAdReady method to check if an ad is available
if (self.mediaVideo.isAdReady)
{
//Obtain TradPlusMediaVideoAdObject object
TradPlusMediaVideoAdObject * mediaVideo = [self.mediaVideo getReadyMediaVideoObject];
if (mediaVideo != nil) {
self.mediaVideoObject = mediaVideo;
self.mediaVideoObject.delegate = self;
if(self.mediaVideoObject.adView != nil)
{
self.mediaVideoObject.adView.hidden = NO;
self.mediaVideoObject.adView.frame = self.myAdView.bounds;
[self.myAdView addSubview:self.mediaVideoObject.adView];
[self.mediaVideoObject startWithSceneId:nil];
}
}
}
}

#pragma mark - TradPlusADMediaVideoDelegate

//VideoAd Loaded
- (void)tpMediaVideoAdLoaded:(NSDictionary *)adInfo
{
}
//VideoAd loading error
- (void)tpMediaVideoAdLoadFailWithError:(NSError *)error
{
}
//VideoAd has Started
- (void)tpMediaVideoAdStart:(NSDictionary *)adInfo
{
}
//VideoAd Playing Error
- (void)tpMediaVideoAdError:(NSDictionary *)adInfo error:(NSError *)error
{
}
//VideoAd Clicked
- (void)tpMediaVideoAdClicked:(NSDictionary *)adInfo
{
}
//VideoAd Played to End
- (void)tpMediaVideoAdEnd:(NSDictionary *)adInfo
{
}
//VideoAd Paused.
- (void)tpMediaVideoAdPause:(NSDictionary *)adInfo
{
}
//VideoAd Resume
- (void)tpMediaVideoAdResume:(NSDictionary *)adInfo
{
}
//VideoAd has Skipped.
- (void)tpMediaVideoAdSkiped:(NSDictionary *)adInfo
{
}
//VideoAd Tapped
- (void)tpMediaVideoAdTapped:(NSDictionary *)adInfo
{
}

Before v12.2.0

#import <TradPlusAds/TradPlusAdMediaVideo.h>

@interface TradPlusAdMediaVideoViewController ()<TradPlusADMediaVideoDelegate >
@property (nonatomic,strong)TradPlusAdMediaVideo *mediaVideo;
@property (nonatomic,strong)TradPlusMediaVideoAdObject *mediaVideoObject;
@property (nonatomic,strong)UIView *adView;
@end

@implementation TradPlusAdMediaVideoViewController

- (void)viewDidLoad
{
[super viewDidLoad];
self.mediaVideo = [[TradPlusAdMediaVideo alloc] init];
//set up ad unit id
[self.mediaVideo setAdUnitID:@"Your Ad Unit ID"];
//set up delegate
self.mediaVideo.delegate = self;
//It takes some time to load the ad, you can load the ad in advance before showing the ad
[self.mediaVideo loadAd:self.adView viewController:self mute:NO];
}

- (void)showMediaVideoAd
{
//Call the isAdReady method to check if an ad is available
if (self.mediaVideo.isAdReady)
{
//Obtain TradPlusMediaVideoAdObject object
TradPlusMediaVideoAdObject * mediaVideo = [self.mediaVideo getReadyMediaVideoObject];
if (mediaVideo != nil) {
self.mediaVideoObject = mediaVideo;
//viewController is a view controller(nil if you have no sceneId)
[self.mediaVideoObject startWithViewController:self sceneId:nil];
}
}
}

#pragma mark - TradPlusADMediaVideoDelegate

//VideoAd Loaded
- (void)tpMediaVideoAdLoaded:(NSDictionary *)adInfo
{
}
//VideoAd loading error
- (void)tpMediaVideoAdLoadFailWithError:(NSError *)error
{
}
//VideoAd has Started
- (void)tpMediaVideoAdStart:(NSDictionary *)adInfo
{
}
//VideoAd Playing Error
- (void)tpMediaVideoAdError:(NSDictionary *)adInfo error:(NSError *)error
{
}
//VideoAd Clicked
- (void)tpMediaVideoAdClicked:(NSDictionary *)adInfo
{
}
//VideoAd Played to End
- (void)tpMediaVideoAdEnd:(NSDictionary *)adInfo
{
}
//VideoAd Paused.
- (void)tpMediaVideoAdPause:(NSDictionary *)adInfo
{
}
//VideoAd Resume
- (void)tpMediaVideoAdResume:(NSDictionary *)adInfo
{
}
//VideoAd has Skipped.
- (void)tpMediaVideoAdSkiped:(NSDictionary *)adInfo
{
}
//VideoAd Tapped
- (void)tpMediaVideoAdTapped:(NSDictionary *)adInfo
{
}

VMAP Ads

  • VMAP is supported since v10.2.0 with GoogleIMA integration.

  • To use VMAP, contentPlayheadset before loading (which requires support for the GoogleIMA's IMAContentPlayhead protocol).For v12.2.0 and later versions, you do not need to set the SDK, which will be implemented internally. For earlier versions, you must set the SDK

  • Usually, VMAP is loaded on the presenting page. Once the loaded callback is received, the ad object can be obtained.

  • When autoPlayAdBreaks is disabled, developers need to manually call [self.mediaVideoObject start] to play the ad after receiving AdBreakReady.

  • Developers need to manually call [self.mediaVideoObject contentComplete] to activate the post-roll ads in VMAP after the video finishes playing.

  • Developers need to control the video play/pause when receiving tpMediaVideoAdRequestContentPause or tpMediaVideoAdRequestContentResume.

⚠️Note

As the loaded timing of VMAP and VAST ads are different, when setting up ads on the TP backend platform, make sure to select the VMAP tag when using VMAP ads.

Sample Code

Reference: TradPlusAdMediaVMAPViewController

v12.2.0 and above new API (support multiple caches)

#import <TradPlusAds/TradPlusAdMediaVideo.h>
#import <TPGoogleIMAAdapter/TPGooogleIMAPlayhead.h>

@interface TradPlusAdMediaVideoViewController ()<TradPlusADMediaVideoDelegate >
@property (nonatomic,strong)TradPlusAdMediaVideo *mediaVideo;
@property (nonatomic,strong)TradPlusMediaVideoAdObject *mediaVideoObject;
@property (nonatomic,strong) UIView *adView;
@property (nonatomic,strong) AVPlayer *contentPlayer;
@property (nonatomic,strong) AVPlayerItem *playerItem;
@end

@implementation TradPlusAdMediaVideoViewController

- (void)viewDidLoad
{
[super viewDidLoad];
self.mediaVideo = [[TradPlusAdMediaVideo alloc] init];
// Set the ad unit ID.
[self.mediaVideo setAdUnitID:@"Your ad unit ID created in the TP platform"];
// Set up the delegate.
self.mediaVideo.delegate = self;
// It takes some time to load ads. You can preload ads before showing them.
[self.mediaVideo loadAdWithRootViewController:self mute:NO];
// Listen for playback completion.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFinish:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
}

- (void)playFinish:(NSNotification *)notification
{
AVPlayerItem *notificationItem = (AVPlayerItem *)notification.object;
if (notificationItem != self.playerItem)
{
return;
}
// Call contentComplete after playback completes to show post-roll ads.
if(self.mediaVideoObject != nil)
{
[self.mediaVideoObject contentComplete];
}
}

#pragma mark - TradPlusADMediaVideoDelegate

- (void)tpMediaVideoAdLoaded:(NSDictionary *)adInfo
{
//get a ad object
self.mediaVideoObject = [self.mediaVideo getReadyMediaVideoObject];
if (self.mediaVideoObject != nil) {
self.mediaVideoObject.delegate = self;
//set contentPlayhead
id contentPlayhead = mediaVideo.contentPlayhead;
if(contentPlayhead != nil && [contentPlayhead isKindOfClass:[TPGooogleIMAPlayhead class]])
{
TPGooogleIMAPlayhead *tpContentPlayhead = contentPlayhead;
__weak typeof(self) weakSelf = self;
tpContentPlayhead.currentTimeCallBack = ^NSTimeInterval{
return CMTimeGetSeconds(weakSelf.contentPlayer.currentTime);
};
}
if(self.mediaVideoObject.adView != nil)
{
self.mediaVideoObject.adView.hidden = NO;
self.mediaVideoObject.adView.frame = self.myAdView.bounds;
[self.myAdView addSubview:self.mediaVideoObject.adView];
}
}
}

- (void)tpMediaVideoAdRequestContentPause:(NSDictionary *)adInfo
{
if(self.contentPlayer != nil)
{
// Pause the video.
[self.contentPlayer pause];
}
}

- (void)tpMediaVideoAdRequestContentResume:(NSDictionary *)adInfo
{
if(self.contentPlayer != nil)
{
// Play the video.
[self.contentPlayer play];
}
}

- (void)tpMediaVideoAdBreakReady:(NSDictionary *)adInfo
{
// Call start after receiving AdBreakReady to show the ad.
if(self.mediaVideoObject != nil)
{
[self.mediaVideoObject start];
}
}

// The interstitial ad load failed.
- (void)tpMediaVideoAdLoadFailWithError:(NSError *)error
{
}
// The interstitial ad playback started.
- (void)tpMediaVideoAdStart:(NSDictionary *)adInfo
{
}
// The interstitial ad playback failed.
- (void)tpMediaVideoAdError:(NSDictionary *)adInfo error:(NSError *)error
{
}
// The interstitial ad was clicked and redirected.
- (void)tpMediaVideoAdClicked:(NSDictionary *)adInfo
{
}
// The interstitial ad playback ended.
- (void)tpMediaVideoAdEnd:(NSDictionary *)adInfo
{
}
// The interstitial ad playback was paused.
- (void)tpMediaVideoAdPause:(NSDictionary *)adInfo
{
}
// The interstitial ad playback resumed.
- (void)tpMediaVideoAdResume:(NSDictionary *)adInfo
{
}
// The interstitial ad was skipped.
- (void)tpMediaVideoAdSkiped:(NSDictionary *)adInfo
{
}
// The video area of the interstitial ad was clicked.
- (void)tpMediaVideoAdTapped:(NSDictionary *)adInfo
{
}

Before v12.2.0

#import <TradPlusAds/TradPlusAdMediaVideo.h>

@interface TradPlusAdMediaVideoViewController ()<TradPlusADMediaVideoDelegate >
@property (nonatomic,strong)TradPlusAdMediaVideo *mediaVideo;
@property (nonatomic,strong)TradPlusMediaVideoAdObject *mediaVideoObject;
@property (nonatomic,strong) UIView *adView;
@property (nonatomic,strong) AVPlayer *contentPlayer;
@property (nonatomic,strong) AVPlayerItem *playerItem;
@property (nonatomic,strong)VideoPlayhead *videoPlayhead;
@end

@implementation TradPlusAdMediaVideoViewController

- (void)viewDidLoad
{
[super viewDidLoad];
self.mediaVideo = [[TradPlusAdMediaVideo alloc] init];
// Set the ad unit ID.
[self.mediaVideo setAdUnitID:@"Your ad unit ID created in the TP platform"];
// Set up the delegate.
self.mediaVideo.delegate = self;
// Set up contentPlayhead.
self.videoPlayhead = [[VideoPlayhead alloc] init];
self.mediaVideo.contentPlayhead = self.videoPlayhead;
// It takes some time to load ads. You can preload ads before showing them.
[self.mediaVideo loadAd:self.adView viewController:self mute:NO];
// Listen for playback completion.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFinish:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
}

- (void)playFinish:(NSNotification *)notification
{
AVPlayerItem *notificationItem = (AVPlayerItem *)notification.object;
if (notificationItem != self.playerItem)
{
return;
}
// Call contentComplete after playback completes to show post-roll ads.
if(self.mediaVideoObject != nil)
{
[self.mediaVideoObject contentComplete];
}
}

#pragma mark - TradPlusADMediaVideoDelegate

- (void)tpMediaVideoAdLoaded:(NSDictionary *)adInfo
{
// Get the ad object.
self.mediaVideoObject = [self.mediaVideo getReadyMediaVideoObject];
}

- (void)tpMediaVideoAdRequestContentPause:(NSDictionary *)adInfo
{
if(self.contentPlayer != nil)
{
// Pause the video.
[self.contentPlayer pause];
}
}

- (void)tpMediaVideoAdRequestContentResume:(NSDictionary *)adInfo
{
if(self.contentPlayer != nil)
{
// Play the video.
[self.contentPlayer play];
}
}

- (void)tpMediaVideoAdBreakReady:(NSDictionary *)adInfo
{
// Call start after receiving AdBreakReady to show the ad.
if(self.mediaVideoObject != nil)
{
[self.mediaVideoObject start];
}
}

// The interstitial ad load failed.
- (void)tpMediaVideoAdLoadFailWithError:(NSError *)error
{
}
// The interstitial ad playback started.
- (void)tpMediaVideoAdStart:(NSDictionary *)adInfo
{
}
// The interstitial ad playback failed.
- (void)tpMediaVideoAdError:(NSDictionary *)adInfo error:(NSError *)error
{
}
// The interstitial ad was clicked and redirected.
- (void)tpMediaVideoAdClicked:(NSDictionary *)adInfo
{
}
// The interstitial ad playback ended.
- (void)tpMediaVideoAdEnd:(NSDictionary *)adInfo
{
}
// The interstitial ad playback was paused.
- (void)tpMediaVideoAdPause:(NSDictionary *)adInfo
{
}
// The interstitial ad playback resumed.
- (void)tpMediaVideoAdResume:(NSDictionary *)adInfo
{
}
// The interstitial ad was skipped.
- (void)tpMediaVideoAdSkiped:(NSDictionary *)adInfo
{
}
// The video area of the interstitial ad was clicked.
- (void)tpMediaVideoAdTapped:(NSDictionary *)adInfo
{
}