InStream API integration
The InStream API is an advanced API for setting up and managing ad loading and playing InStream ads. It lets you support playing any type of ad break and use your own implementation of a player. InStream ads consist of video ads that are played automatically and manually.
Use the InstreamAdBinder API to automatically play Pre-roll, Mid-roll, and Post-roll ad breaks. Use the InstreamAdBreak API to trigger ad breaks manually.
Note
You can use the InstreamAdBinder API and the InstreamAdBreak API concurrently under specific conditions:
- Use different instances of the ad player.
- Don't trigger playback using the InstreamAdBreak API while the main video is paused via the InstreamAdBinder API.
- When using
InstreamAdwith the InstreamAdBreak API, use onlyInstreamAdBreakType.inrollorInstreamAdBreakType.pauserollad breaks. InstreamAdBinder automatically handles rendering for all other types.
App requirements
- Use Xcode 16.4 or higher.
How it works
A loaded InStream ad object contains a schedule for playing ad breaks. Each ad break is described by an InstreamAdBreak object. An ad break may have one of the following types: Pre / Mid / Post / In / Pause-roll. You can play Pre-/Mid-/Post-Roll ad breaks using the InstreamAdBinder API. You can display ad breaks manually, including Pause-roll and In-roll video ads, using the InstreamAdBreak API.
The VideoPlayer protocol is used to interact with the main video content. To play an ad break inside an ad placement, use the InstreamAdPlayer protocol.
InstreamAdBinder tracks the progress of playing the main video and automatically shows ad breaks based on their schedule from a video resource in the Yandex Advertising Network interface.
InstreamAdBinder does not directly control the rendering of a video ad in PlayerView. Video ads must be played on the app side based on signals from player interfaces transmitted to InstreamAdBinder. InstreamAdBinder signals the start of playing an ad break by calling VideoPlayer.pauseVideo() and the end by calling VideoPlayer.resumeVideo().
When calling VideoPlayer.pauseVideo() on the app side, it's necessary to hide the main video controls, pause the main video, and start playing the video ad. On the ad SDK side, after calling the method, advertising controls are displayed inside the InstreamAdView container and the InstreamAdPlayer.playAd() method is called to start playing the video ad.
When calling VideoPlayer.resumeVideo() on the app side, it's necessary to return the main video controls and resume playing the main video. On the ad SDK side, ad controls inside the InstreamAdView container are removed before calling the method.
InstreamAdBreak API doesn't directly control the rendering of a video ad in PlayerView. Video ads must be played on the app side based on signals from player interfaces transmitted to InstreamAdBreak. In/Pause-Roll signals the start of playing an ad break by calling InstreamAdBreakDelegate.instreamAdBreakDidStart() and the end by calling InstreamAdBreakDelegate.instreamAdBreakDidComplete() or InstreamAdBreakDelegate.instreamAdBreakDidError().
When calling InstreamAdBreakDelegate.instreamAdBreakDidStart() on the app side, it's necessary to hide the main video controls and pause the main video. On the ad SDK side, after calling the method, advertising controls are displayed inside the InstreamAdView container and the InstreamAdPlayer.playAd() method is called to start playing the video ad.
When calling InstreamAdBreakDelegate.instreamAdBreakDidComplete() or InstreamAdBreakDelegate.instreamAdBreakDidError() on the app side, it's necessary to return the main video controls and resume playing the main video. On the ad SDK side, ad controls are removed from the InstreamAdView container before calling the methods.
Loading ads
-
Create an instance of the
InstreamAdLoaderclass to get InStream ads. -
Configure your request using the
InstreamAdRequestConfigurationclass. Pass thePage IDfrom the Yandex Advertising Network interface as a request parameter. -
Load ads using the
loadInstreamAd(configuration:completion:)method.
To test the integration, use the demo Page ID: R-M-DEMO-instream-vmap.
let adLoader = InstreamAdLoader()
let configuration = InstreamAdRequestConfiguration(pageID: PAGE_ID)
do {
let ad = try await adLoader.loadInstreamAd(configuration: configuration)
// Use the loaded InstreamAd object
} catch {
// Loading error
}
let adLoader = InstreamAdLoader()
let configuration = InstreamAdRequestConfiguration(pageID: PAGE_ID)
adLoader.loadInstreamAd(configuration: configuration) { result in
switch result {
case .success(let ad):
// Use the loaded InstreamAd object
break
case .failure(let info):
// Load error: info.reason
break
}
}
Rendering ads
-
Implement the
InstreamAdPlayerandVideoPlayerinterfaces.The reference provides detailed information about the methods and their implementation. Additionally, see a test implementation example.
Tip
To make implementation easier, we recommend using different instances of players to play video ads and content.
-
Add InstreamAdView to the View hierarchy of the app. InstreamAdView must contain PlayerView to play video ads in.
Warning
A container must be at least 300dp x 160dp in size.
-
Create an InstreamAdBinder object: pass the loaded
InstreamAdobject and theInstreamAdPlayerandVideoPlayerimplementations to the builder.Set up notifications about the ad's progress (ready to play the video ad, the video ad played or failed to play): set a delegate that conforms to the
InstreamAdBinderDelegateprotocol.adBinder = InstreamAdBinder(ad: ad, adPlayer: adPlayer, videoPlayer: contentPlayer) adBinder.delegate = self -
To start playing a Pre-roll ad break faster, preload it in advance by calling the
InstreamAdBinder.prepareAd()method.func preparePrerollAd(adBinder: InstreamAdBinder) { adBinder.delegate = self adBinder.prepareAd() } extension InstreamViewController: InstreamAdBinderDelegate { func instreamAdBinder(_ binder: InstreamAdBinder, didPrepare instreamAd: InstreamAd){ addInstreamAdBinderToPreloadedAdQueue(binder) } //... } -
Call the
InstreamAdBinder.bind(with adView: InstreamAdView)method for the created InstreamAdBinder object. PassInstreamAdView, which was previously added to the hierarchy, as a parameter. After that, the InStream SDK starts to automatically track the progress of playing the main video and manage the way video ads are played.adBinder.bind(with: instreamAdView) -
When playing InStream ads in the list, use the
InStreamBinder.unbind()method when the cell with the ad is invalidated in the list. To implement a reused pool of players for scrolling, callInstreamAdbinder.invalidateAdPlayer()when reusing the ad player linked to InstreamAdBinder andInstreamAdBinder.invalidateVideoPlayer()when reusing the main content player. -
When you stop using InStreamAdBinder, reset the state.
deinit { adBinder.unbind() adBinder.invalidateVideoPlayer() adBinder.invalidateAdPlayer() }
Note
You can configure playback of any ad break similar to In-roll video ads. When filtering ad breaks, simply replace InstreamAdBreakType.inroll with the type you need — for example, InstreamAdBreakType.pauseroll.
-
Implement the InstreamAdPlayer interface.
The reference provides detailed information about the methods and their implementation. Additionally, see a test implementation example.
Tip
To make implementation easier, we recommend using different instances of players to play video ads and content.
-
Add InstreamAdView to the View hierarchy of the app. InstreamAdView must contain PlayerView to play video ads in.
Warning
A container must be at least 300dp x 160dp in size.
-
Use the InstreamAdLoader to load the InstreamAd object using the
Page IDfrom the Yandex Advertising Network interface. -
InstreamAd contains a collection of various ad break types in its
adBreaksproperty. To retrieve In-roll ad breaks, filter the array byInstreamAdBreakType.inroll. The breaks are returned in their intended playback order.adLoader.loadInstreamAd(configuration: configuration) { result in if case .success(let ad) = result { inrollQueue = ad.adBreaks.filter{ $0.adBreakData.type == InstreamAdBreakType.inroll } } } -
To launch the received In-roll object, you need to prepare it. Unprepared In-roll video ads won't start. To track if the In-Roll video ad is ready, set the
InstreamAdBreakDelegate, callInroll.prepare(with: adPlayer), and pass an instance of the created InstreamAdPlayer implementation to it.private func prepareNextAd() { guard !inrollQueue.isEmpty else { return } currentAdBreak = inrollQueue.removeFirst() currentAdBreak?.delegate = self currentAdBreak?.prepare(with: adPlayer) } -
Once the In-roll video ad is prepared,
InstreamAdBreakDelegate.instreamAdBreakDidPrepare()is called. The prepared In-roll video ad is ready to play.Tip
Play video ads in the order they're received from the
adBreaks. Playing ad breaks in a different order may reduce your app's revenue. -
To display a ready ad break, call
InstreamAdBreak.play(with: adView), passing the InstreamAdView you've already added to your view hierarchy.func instreamAdBreakDidPrepare(_ adBreak: InstreamAdBreak) { currentAdBreak?.play(with: instreamAdView) } -
After the ad break starts playing, the
InstreamAdBreakDelegate.instreamAdBreakDidStart()method is called. After calling this method, pause the main video and hide its controls.func instreamAdBreakDidStart(_ adBreak: InstreamAdBreak) { contentVideoPlayer?.pauseVideo() } -
Once the ad break is played, resume playing the main video. A video ad may play successfully or fail. Both situations need to be handled.
func instreamAdBreakDidComplete(_ adBreak: InstreamAdBreak) { handleAdBreakCompleted() } func instreamAdBreakDidError(_ adBreak: InstreamAdBreak) { handleAdBreakCompleted() } private func handleAdBreakCompleted() { currentAdBreak = nil contentVideoPlayer?.resumeVideo() } -
When the current ad break ends, prepare the next one from the queue.
private func prepareNextAd() { guard !inrollQueue.isEmpty else { return } currentAdBreak = inrollQueue.removeFirst() currentAdBreak?.delegate = self currentAdBreak?.prepare(with: adPlayer) } -
When you stop using an In-roll video ad, reset its state.
deinit { currentAdBreak?.invalidate() }