{"id":3444,"date":"2012-08-13T09:31:09","date_gmt":"2012-08-13T05:31:09","guid":{"rendered":"http:\/\/blog.denivip.ru\/?p=3444"},"modified":"2013-08-05T14:10:56","modified_gmt":"2013-08-05T10:10:56","slug":"ios-player-with-vast-video-ad-support","status":"publish","type":"post","link":"http:\/\/blog.denivip.ru\/index.php\/2012\/08\/ios-player-with-vast-video-ad-support\/?lang=en","title":{"rendered":"iOS Player with VAST Video Ad Support"},"content":{"rendered":"<p><center><a href=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/apple-iad_616.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/apple-iad_616.jpg\" alt=\"apple-advertising\" title=\"apple-advertising\" width=\"500\" height=\"268\" class=\"alignnone size-full wp-image-3442\" srcset=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/apple-iad_616.jpg 500w, http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/apple-iad_616-300x160.jpg 300w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/a><\/center><\/p>\n<p>Ads based monetization has been widely adopted by the developers of free-of-charge iOS applications. To support banner ads in such applications, Apple offers a ready solution. However if your application is built around a video player, you may prefer inline ads shown in video pauses. As far as we know, no widely used free solution yet exists for this. In this post, we&#8217;ll tell you how you can easily add video ads to your app. For this purpose, you&#8217;ll have to add our free  <a href=\"https:\/\/github.com\/denivip\/ios-vast-player\">iOS VAST Player<\/a> library to the OpenX ad server. <!--more--><\/p>\n<p>The server part of our video ad solution for iOS applications constitutes the OpenX Source ad server and an ad plugin we wrote for it. To get started with OpenX Source, please first download its source code, deploy it on your server and create an ad campaign in the administrator&#8217;s Web interface. To learn how to do this, please read our previous posts:<\/p>\n<ol>\n<li><a href=\"http:\/\/blog.denivip.ru\/index.php\/2010\/07\/%D0%BF%D0%BE%D0%BA%D0%B0%D0%B7-%D1%80%D0%B5%D0%BA%D0%BB%D0%B0%D0%BC%D1%8B-%D0%B2-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B5-openx\/\">Displaying Ads in OpenX<\/a><\/li>\n<li><a href=\"http:\/\/blog.denivip.ru\/index.php\/2010\/10\/openx-highload\/\">Creating a High Load Ads Delivery System Based on OpenX<\/a><\/li>\n<li><a href=\"http:\/\/blog.denivip.ru\/index.php\/2010\/11\/openx-features\/\">More on OpenX Features<\/a><\/li>\n<\/ol>\n<p>However, there is an aspect to be kept in mind that has not been underscored in the above posts: video ads should be in a format playable on the Apple mobile devices. This may be either a separate MP4 file compressed with H.264 and AAC or an HTTP Live Streaming playlist.<\/p>\n<p>The client part is a video player based on the AVFoundation framework (see our previous post <a href=\"http:\/\/blog.denivip.ru\/index.php\/2012\/07\/apple-ios-video-development\/\">Video Playback in iOS Applications<\/a>). The <a href=\"https:\/\/github.com\/denivip\/ios-vast-player\">iOS VAST Player <\/a> library empowers developers with a ready<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">DVIABPlayer<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>iOS class enhancing the standard<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">AVPlayer<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>component with loading of VAST templates and scheduled video ad playback. The schedule specifies ad time and type, i.e. pre-roll, post-roll or  mid-roll.<\/p>\n<p>To connect the library to your project, follow these steps:<\/p>\n<ol>\n<li>Add AVFoundation and CoreMedia to the list of frameworks used by the application.<\/li>\n<li>Drag the library folder to your Xcode project.<\/li>\n<li>Download and add the <a href=\"https:\/\/github.com\/robbiehanson\/KissXML\">KissXML<\/a> library to the project. You&#8217;ll need it to parse VAST templates.<\/li>\n<\/ol>\n<p>The library comes with a sample project to demonstrate its use. Let&#8217;s discuss this sample in detail. The sample has a single View Controller element containing a view container for the player layer, several information labels and playback control buttons.<\/p>\n<p>The<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">DVIABPlayer<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>class is used similarly to<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">AVPlayer<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>:  using the<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">viewDidLoad<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>player class, we initialize it and link it to the view container. Then we initialize it and link to the player an<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">AVPlayerItem<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>containing a link to the main content. On change of the<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">status<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>property of this item, automatic playback is launched. <\/p>\n<p><center><a href=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/iOS-Simulator-Screen-shot-Aug-10-2012-7.50.54-PM.png\"><img decoding=\"async\" src=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/iOS-Simulator-Screen-shot-Aug-10-2012-7.50.54-PM.png\" alt=\"\" title=\"Main Contentdth=\"320\" height=\"480\" class=\"aligncenter size-full wp-image-3421\" srcset=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/iOS-Simulator-Screen-shot-Aug-10-2012-7.50.54-PM.png 320w, http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/iOS-Simulator-Screen-shot-Aug-10-2012-7.50.54-PM-200x300.png 200w\" sizes=\"(max-width: 320px) 100vw, 320px\" \/><\/a><\/center><\/p>\n<p>The differences from the<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">AVPlayer<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>are as follows. First, the<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">playerLayer<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>property is used to store the video playback layer. It is necessary, as for each played back video,<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">DVIABPlayer<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>creates a new<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">AVPlayer<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>within itself. Second, you have to set the ad schedule<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">DVVideoMultipleAdPlaylist<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>containing the list of inline ads and relevant references to the VAST templates:<\/p>\n<pre>\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/><\/div><\/td><td><div class=\"text codecolorer\">DVVideoMultipleAdPlaylist *adPlaylist =<br \/>\n&nbsp; &nbsp; [[DVVideoMultipleAdPlaylist alloc] init];<br \/>\nadPlaylist.playBreaks = [NSArray arrayWithObjects:<br \/>\n&nbsp; &nbsp; [DVVideoPlayBreak playBreakBeforeStartWithAdTemplateURL:<br \/>\n&nbsp; &nbsp; &nbsp;OPENX_AD_TAG_WITH_ZONE(18)],<br \/>\n&nbsp; &nbsp; [DVVideoPlayBreak playBreakAtTimeFromStart:CMTimeMake(10, 1)<br \/>\n&nbsp; &nbsp; &nbsp;withAdTemplateURL:OPENX_AD_TAG_WITH_ZONE(19)],<br \/>\n&nbsp; &nbsp; [DVVideoPlayBreak playBreakAfterEndWithAdTemplateURL:<br \/>\n&nbsp; &nbsp; &nbsp;OPENX_AD_TAG_WITH_ZONE(20)],<br \/>\n&nbsp; &nbsp; nil];<br \/>\nself.player.adPlaylist = adPlaylist;<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n<\/pre>\n<p>The<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">OPENX_AD_TAG_WITH_ZONE<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>macro submits to OpenX a link to the VAST descriptions of the ad created for a zone with a preset identifier.<\/p>\n<p>This is a sequence of actions needed to enable OpenX inline ads within your main video content.<\/p>\n<p><center><a href=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/iOS-Simulator-Screen-shot-Aug-10-2012-7.51.07-PM.png\"><img decoding=\"async\" src=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/iOS-Simulator-Screen-shot-Aug-10-2012-7.51.07-PM.png\" alt=\"\" title=\"Ad Snapshotth=\"320\" height=\"480\" class=\"aligncenter size-full wp-image-3423\" srcset=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/iOS-Simulator-Screen-shot-Aug-10-2012-7.51.07-PM.png 320w, http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/08\/iOS-Simulator-Screen-shot-Aug-10-2012-7.51.07-PM-200x300.png 200w\" sizes=\"(max-width: 320px) 100vw, 320px\" \/><\/a><\/center><\/p>\n<p>Moreover, your View Controller can implement some optional methods of the<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">DVIABPlayerDelegate<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>protocol to alert of ad playback events. The current version of the protocol provides the following methods:<\/p>\n<ul>\n<li>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">- (BOOL)player:(DVIABPlayer *)player shouldPauseForAdBreak:(DVVideoPlayBreak *)playBreak<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>is called before the ad so it can be skipped. By default, the method returns NO.<\/li>\n<li>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">- (void)player:(DVIABPlayer *)player didFailPlayBreak:(DVVideoPlayBreak *)playBreak withError:(NSError *)error<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>is invoked if the ad can not be shown by the VAST template load error.<\/li>\n<\/ul>\n<p>We hope that the classes described here will be helpful to you in developing of your applications. Currently, the <a href=\"https:\/\/github.com\/denivip\/ios-vast-player\">iOS VAST Player<\/a> library only supports the core functionality of video advertising. We would like it to be more extensively standardized, including support of VAST, VMAP, and maybe even VPAID. So we are welcoming your bug reports and pull requests at the project GitHub page.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>avfoundation, iOS, OpenX, VAST, video player, development, mobile application development, Advertising<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,407],"tags":[422,447,448,390,207,413],"_links":{"self":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts\/3444"}],"collection":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/comments?post=3444"}],"version-history":[{"count":11,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts\/3444\/revisions"}],"predecessor-version":[{"id":4845,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts\/3444\/revisions\/4845"}],"wp:attachment":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/media?parent=3444"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/categories?post=3444"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/tags?post=3444"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}