Kaltura 视频播放器具有有效的 VAST 前置和后置广告以及自定义视频 URL,但不适用于 DoubleClick

Kaltura video player with a working VAST pre and postroll ad and custom video URLs, but not for DoubleClick

有人知道如何将 kaltura 视频播放器与自定义视频 url 嵌入吗? 它应该看起来像这样:

<script>
  var $ = jQuery;
</script>
<!-- Substitute {partner_id} for your Kaltura partner id, {uiconf_id} for uiconf player id -->
<script src="//OUR_LOCAL_SERVER/p/101/sp/10100/embedIframeJs/uiconf_id/23448200/partner_id/101"></script>

<div class="kaltura-player-wrap">
    <!--  inner pusher div defines aspect ratio: in this case 16:9 ~ 56.25% -->
    <div id="dummy" style="margin-top: 56.25%;"></div>
    <!--  the player embed target, set to take up available absolute space   -->    
    <div id="videoPlayer" itemprop="video" intemscope itemtype="http://schema.org/VideoObject"></div>
</div>

<script>
(function($) {

var enableAds = true; 
var enablePreroll = true;
var enableMidroll = false; //not implemented yet since kaltura doesn't really support it
var enablePostroll = false;

var adlimit = 2;

dbug = true; 
var flashvars = {}; 
var adlock = 0;    
var faillock = 0;

var adtimeout = 20000; 
var playlist = sfp.nextVideo !== undefined;

var mediaProxy = {
    'entry': {
        "thumbnailUrl": sfp.thumbnail,
        "name": sfp.title,
        "description": "The+Mediterranean+diet+has+long+been+promoted+as+a+heart+healthy+way+of+eating.+But%2C+for+women%2C+ther",
        "duration": sfp.duration
    },
    'sources': [{
        "src": "http://v1.SOME_SITE.com/822ece3c-52f0-4daa-b2da-7ebf1c0ba354.ogg",
        "type": "video/ogg;"
    }, {
        "src": "http://v1.SOME_SITE.com/822ece3c-52f0-4daa-b2da-7ebf1c0ba354.webm",
        "width": "624",
        "height": "352",
        "bandwidth": "740352",
        "type": "video/webm; codecs='vp8, vorbis'",
    }, {
        "src": "http://v1.SOME_SITE.com/822ece3c-52f0-4daa-b2da-7ebf1c0ba354.mp4",
        "width": "640",
        "height": "360",
        "bandwidth": "1101824",
        "type": "video/mp4; codecs='avc1.42E01E, mp4a.40.2'", 
    }]
}



/*
Append pre or post roll ad parameters to the flashvars.vast object
obj: has to be the flashvars.vast object
uri: the ad tag url, parsed from the XML response
*/ 
function appendAdsVAST(obj,uri){

    if(enablePreroll){ 

        var temp = { 
            "prerollUrl" : uri,
            "prerollUrlJs" : uri, //enable support for mobile ads
            "numPreroll" : "1",
            "prerollStartWith" : "1",
            "prerollInterval" : "1",
            "preSequence" : "1",  
        }

    }else if(enablePostroll){

        var temp = { 
            "postrollUrl" : uri,
            "postrollUrlJs" : uri, //enable support for mobile ads
            "numPostroll" : "1",
            "postrollStartWith" : "1",
            "postrollInterval" : "1",
            "postSequence" : "1", 
        } 
    }
    for(var val in temp)
      obj[val] = temp[val]; 

    return obj;
}

/*
To be reworked
uri-link to the ad to be passed into optimatic
type - optimatic 
       yumenetworks  
       bnmla           
       doubleclick  
*/
function buildVideoPlayer(uri, type) {

    //overload to default ad type - doubleclick
    if(type==null || type===undefined || type==false)
        type = "doubleclick";

    if (type=="bnmla") {

        flashvars = { 

            "vast": {
                "plugin" : true, 
                "position" : "before", 
                "timeout" : "30",  
                "relativeTo" : "PlayerHolder", 
            },
            "skipBtn": {
                "skipOffset" : "5",
                "label" : "Skip Ad"
            },

            "adsOnReplay" : true,
            "inlineScript" : false,
            "ForceFlashOnDesktopSafari" : false,   
        }

        flashvars.vast = appendAdsVAST(flashvars.vast,uri); 
        flashvars.noticeMessage = {};

    } else if (type=="yumenetworks" || type=="optimatic") {

        /*
        VAST DoubleClick Ad and Companion
        Link: http://player.kaltura.com/docs/kvast
        */
        flashvars = { 

            "vast": {
                "plugin" : true, 
                "position" : "before", 
                "timeout" : "30",  
                "relativeTo" : "PlayerHolder", 
            },
            "skipBtn": {
                "skipOffset" : "5",
                "label" : "Skip Ad"
            },

            "adsOnReplay" : true,
            "inlineScript" : false,
            "ForceFlashOnDesktopSafari" : false,   
        }

        flashvars.vast = appendAdsVAST(flashvars.vast,uri);

        // mobile already defines time remaining until ad finishes, so no need to specify it again
        // if(!kWidget.isMobileDevice())
        //   flashvars.noticeMessage = {  
        //       "plugin" : true,
        //       "position" : "before",
        //       "text" : "Time remaining {sequenceProxy.timeRemaining|timeFormat}"
        //   }

        // disable any message overlays on the ad
        flashvars.noticeMessage = {};

    } else if(false){ //disbale doubleclick for now
        /*
        DoubleClick for the DFP plugin
        http://player.kaltura.com/docs/DoubleClick
        */


        flashvars = {
          /*
           * Doubleclick not working with mediaproxy, use generic vast instead
           */
          "doubleClick": {
              "plugin": true,
              "path": "http://cdnbakmi.kaltura.com/content/uiconf/ps/veria/kdp3.9.1/plugins/doubleclickPlugin.swf",
              "adTagUrl": uri,
              "leadWithFlash": true,
              "disableCompanionAds": true,
          },


          // "vast": {
          //   "prerollUrl": uri,
          //   "numPreroll": "1",
          //   "prerollStartWith": "1",
          //   "prerollInterval": "1",
          //   "postSequence": "1",
          //   "timeout": "4",
          //   "storeSession": false,
          // },
        } 


    }else{

        /*
        Generic VAST for other providers
        */  
        flashvars = { 

            "vast": {
                "plugin" : true, 
                "position" : "before", 
                "timeout" : "30",  
                "relativeTo" : "PlayerHolder", 
            },
            "skipBtn": {
                "skipOffset" : "5",
                "label" : "Skip Ad"
            },

            "adsOnReplay" : true,
            "inlineScript" : false,
            "ForceFlashOnDesktopSafari" : false,   
        }

        flashvars.vast = appendAdsVAST(flashvars.vast,uri);
    }

    /*
    For now diable ads on mobile, unless the type is optimatic, which does work now
    Kaltura's Tremor, Adap.tv, YuMe, and FreeWheel plugins are not currently HTML5-compatible.
    */ 
    if (kWidget.isMobileDevice() && type!="optimatic"){
      flashvars = {};
      dbug && console.log("Ads disabled on mobile, unless it's optimatic. Disabling ads");
    } 

    /*
    Ad response is empty, dont load any ads
    */ 
    if(uri==""){
      flashvars = {};
      dbug && console.log("Ads link empty. Disabling ads");
    }

    /*
    Erase left bottom corner watermark on the video
    */
    flashvars.watermark = {
        plugin: false
    }
    // flashvars.skipBtn = {
    //   "skipOffset": "1",
    //   "label": "Skip Ad"
    // }

    /*
    * ads seem to have their own timers
    */
    // flashvars.noticeMessage = {
    //     "text": "Advertisment {sequenceProxy.timeRemaining|timeFormat}"
    // }

    flashvars.forceMobileHTML5 = true;
    /*
    Set up custom video sources
    */
    mediaProxy.preferedFlavorBR = -1; 
    flashvars.mediaProxy = mediaProxy;


    /*
    Enable hover controls
    */        
    flashvars.controlBarContainer = {
      "plugin" : true,
      "hover" : true
    }

    /*
    Disable autoplay on mobile only
    */ 
    flashvars.autoPlay = !kWidget.isMobileDevice();

    /*
    Enable debugging when needed,
    send cross domain headers to prevent console warnings,
    prevent ads form playing after video starts from beginning
    */
    flashvars.adsOnReplay = true;
    flashvars.enableCORS = true;
    flashvars.debugMode = false;
    flashvars.debugLevel = 0;
    flashvars.autoMute = false;

    kWidget.embed({

        'targetId': 'videoPlayer',
        'wid': '_101',
        'uiconf_id': '23448200', 

        'KalturaSupport.LeadWithHTML5':true, 
        'EmbedPlayer.NativeControls':true,
        'EmbedPlayer.CodecPreference' : 'webm',

        'flashvars': flashvars,
        'readyCallback': function(playerId) {

            //initiate click events for the next video on the playlist page
            if(playlist)
              initiateNextVideo(playerId);

            //initiate click events for the dropdown on the playlist page 
            if(playlist)
              initiatePlaylistDropdown(playerId);

            var kdp = $('#' + playerId).get(0);

            /*
            Force autoplay in case of an error on page
            Only if it is a preroll ad
            */
            if(!kWidget.isMobileDevice() && enablePreroll)
              kdp.sendNotification("doPlay");

            /*
            Ad error events catches
            Ads will be skipped automatically on this event, but need to disable the timeout
            function [faillock] from rebuilding the player.
            */
            kdp.kBind('adErrorEvent', function( qPoint ){

                dbug && console.log("\n\n\n\nadErrorEvent\n\n\n\n"); 
                faillock = 0; 
                // rebuildPlayerWithoutAds(playerId);
            }); 
            kdp.kBind('adLoadError', function( qPoint ){

                dbug && console.log("\n\n\n\adLoadError\n\n\n\n"); 
                faillock = 0; 
                rebuildPlayerWithoutAds(playerId);
            });  
            kdp.kBind('mediaError', function( qPoint ){

              dbug && console.log("\n\n\nmediaError\n\n\n");
            });
            kdp.kBind('entryFailed', function( qPoint ){

              dbug && console.log("\n\n\nentryFailed\n\n\n");
            }); 

            /*
            Safeguard against failure - skip to the video if ads fail to play
            Enable ad lock check if the ad did start. Wait for it to start playing for 10
            seconds and skip it if it doesn't start in this time (since it probably failed to load)
            */ 
            if(!kWidget.isMobileDevice() || type=="optimatic")
              kdp.kBind('adStart', function( qPoint ){

                  dbug && console.log("\n\n\nAd started buffering");

                  adlimit -= 1;

                  faillock = 1;
                  setTimeout(function(){

                    if(faillock==1){

                      dbug && console.log("Ad failed, skipping"); 


                      // in case if it is a postroll ad and a playlist page, we skip to the next 
                      // video and hope that this time the ad plays.
                      // else reload the video with no ads
                      if(playlist && enablePostroll){
                        rebuildNextVideoElement();  
                        rebuildCurrentVideoElement();
                        rebuildPlayer(playerId);
                      }else
                        rebuildPlayerWithoutAds(playerId);
                    }

                  },adtimeout);
              }); 


            // enable ad lock check if the ad did start
            if(!kWidget.isMobileDevice() || type=="optimatic")
              kdp.kBind('onAdPlay', function( start ){

                  dbug && console.log("Ad started playing");
                  //disable timeout that will rebuild the video player
                  faillock = 0;
              });


            // fire when ad is finished playing
            if(enablePreroll)
              kdp.kBind('adEnd', function( qPoint ){

                  adlock += 1; 
                  dbug && console.log("Ad ended. Initiating playlist dropdown.");

              });

            /*
            Since kaltura doesnt have a way to distinuish between 
            the start of a video or an ad, we need a workaround with counters. ALso
            we need to have 2 ways of distinuishing video/ad start end events, 
            for pre and post roll ads.
            */
            kdp.kBind('playbackComplete', function(eventData) {

                if(playlist && enablePreroll){

                  //ad finished playing, and then the video
                  if(adlock==3){
                    dbug && console.log("Ad and video finished. Rebuilding player");

                    adlock = 0;

                    //update current video element
                    rebuildCurrentVideoElement();
                    rebuildNextVideoElement();
                    rebuildPlayer(playerId);
                    return;

                  //there was no ad on this page, so only the video played
                  }else if(adlock==0){
                    dbug && console.log("Video finished. Rebuilding player");

                    adlock = 0;

                    //update current video element 
                    rebuildNextVideoElement();  
                    rebuildCurrentVideoElement();
                    rebuildPlayer(playerId);
                    return;

                  //the ad finished
                  }else if(adlock==1){

                    dbug && console.log("Ad finished.");
                  }

                  adlock += 2;

                }else if(playlist && enablePostroll){


                  adlock += 2; 

                  //ad finished playing, and then the video
                  if(adlock==3){ 
                    dbug && console.log("Ad ad video finished. Rebuilding player");

                    adlock = 0;

                    //update current video element
                    rebuildCurrentVideoElement();
                    rebuildNextVideoElement();
                    rebuildPlayer(playerId);
                    return;

                  //there was no ad on this page, so only the video played
                  }else if(adlock==2){
                    dbug && console.log("Video finished. Rebuilding player");

                    // only rebuild the video if we reached the ad limit because
                    // in this case noa ds will be loaded after the video, which 
                    // will prevent it from catching the ad end event and reloading the player

                    adlock = 0;

                    //update current video element 
                    rebuildNextVideoElement();  
                    rebuildCurrentVideoElement();
                    rebuildPlayer(playerId);
                    return; 
                  }  
                }

            });

            // fire when ad starts playing
            if(enablePostroll) 
              kdp.kBind('adEnd', function( qPoint ){

                  adlock += 1; 
              });

        }
    });  

    // delete the video element from DOM and reinitiate later because it 
    // looked like it made the ads break less often
    kWidget.destroy("videoPlayer");

    /*
    We have reached the max number of times we can display an ad
    */ 
    if(adlimit <= 0){
      flashvars.vast = {};
      dbug && console.log("Ads play count reached their limit. Disabling ads");
    }

    // reinitiate kWIdget video player with new settings
    kWidget.embed({
      'targetId': "videoPlayer",
      'wid': '_101',
      'uiconf_id': '23448200',

      'flashvars': flashvars,
    });
} 



/*
Sort ad types so that the least broken ones are served first
*/
function sortAdTypes(data){

  $xml = $(data);
  var types = {};

  $xml.find("VASTAdTagURI").each(function(){

      var link = $(this).text();
      var url = $.getQuery(link,"pageURL"); 

      var isOptimatic = link.indexOf("optimatic.com") != -1;
      var isYume = link.indexOf("yumenetworks.com") != -1;
      var isBNMLA = link.indexOf("bnmlaX.com") != -1 || link.indexOf("bnmla.com") != -1;

      if(isYume)
        types.yumenetworks = link;  
      else if(isBNMLA)
        types.bnmla = link; 
      else if(isOptimatic && url != 0 && url != "[INSERT_PAGE_URL]")
        types.optimatic = link; 
      else 
        types.other = link;
  });

  return types;
}

/*
Get the least broken ad type from the sorted at types
types: array of ad links
*/ 
function selectAdType(types){

  if(types==null)
    return false;

  return  types.yumenetworks ? "yumenetworks" : 
          types.bnmla ? "bnmla" : 
          types.optimatic ? "optimatic" :
          types.other ? "other" :
          false; 
}

/*
Get the least broken ad link from the sorted at types
types: array of ad links
*/ 
function selectAdLink(types){

  if(types==null)
    return false;

  return  types.yumenetworks ? types.yumenetworks : 
          types.bnmla ? types.bnmla : 
          types.optimatic ? types.optimatic :
          types.other ? types.other :
          false; 
}


$.ajax({
    type: "GET",
    dataType: "XML",
    url: 'http://pubads.g.doubleclick.net/gampad/ads?sz=560x315&iu=/14312752/FlashPreRoll&impl=s&gdfp_req=1&env=vp&output=xml_vast2&unviewed_position_start=1&url=http%3A%2F%2Fwww.SOME_SITE.com%2Fnews-article%2Fmediterranean-diet-high-olive-oil-linked-breast-cancer-risk-reduction&correlator=1453083948&description_url=http%253A%252F%252Fwww.SOME_SITE.com%252Fnews-article%252Fmediterranean-diet-high-olive-oil-linked-breast-cancer-risk-reduction&cust_params=PR_URL%3Db4cc6582-c9c1-4a70-9d42-be2e1a49889d%26PR_PageTyp%3Dnews_story%26Gender%3DFemale%26PR_Age%3DSeniors%26PR_Cndtns%3DObesity%2CBreast+Cancer+Female%2CCancer%2CCard' + decodeURIComponent(utcParams),
    success: function(data) {

        var types = sortAdTypes(data);
        var type = selectAdType(types);
        var link = selectAdLink(types); 

        dbug && console.log("Ad link: "+link);
        dbug && console.log("Ad type: "+type); 

        // skip ads if there are no ads in the XML response
        if(link==false)   
          buildVideoPlayer();
        else
          buildVideoPlayer(link, type);
    },
    error: function(MLHttpRequest, textStatus, errorThrown) {

        dbug && console.log(errorThrown);
    }
});

})(jQuery);
</script> 

根据您设置全局变量的方式,这将创建一个带有自定义视频 url 的播放器,并显示前贴片广告或后贴片广告(如果广告提供商支持,也可以是移动广告)。我们托管我们自己的 kaltura 服务器。

有额外的功能可以启用带有广告的播放列表、用于跳过视频的按钮和我在广告失败时设置的超时,这样播放器在播放视频之前不会停顿 30 秒(因为 Kaltura 不是能够捕捉到这个特定的错误)。

工作方式:我对 pubads.com 进行 ajax 调用,从那里解析 AdVastTag 并确定广告提供商以决定稍后设置哪些参数。它适用于所有投放 VAST 和 VPAID 广告的广告服务器,也适用于支持它的提供商的移动广告。让我们的视频与 DoubleClick 广告一起显示是行不通的。 Kaltura 上的示例确实有效,但他们将视频传递到带有 KMS ID 的播放器(他们将视频上传到他们的管理系统),但我们希望将视频作为 URL,而不是 ID 传递。

似乎很多人对此有疑问,我听到有人说您需要修改后端以允许 Kaltura 通过双击播放自定义 urls。想出一个解决办法给大家看看就好了。

它的工作方式(理想情况下)是将自定义视频 URL 传递到 mediaProxy 并将双击广告代码传递到 flashvars。 此部分设置 doubleClick 广告 url.

"doubleClick": {
              "plugin": true,
              "path": "http://cdnbakmi.kaltura.com/content/uiconf/ps/veria/kdp3.9.1/plugins/doubleclickPlugin.swf",
              "adTagUrl": uri,
              "leadWithFlash": true,
              "disableCompanionAds": true,
          },

有没有人让这个工作?非常感谢任何 help/suggestions。

将“'entryId' : 'url-to-my-video.mp4'”和 sourceType 移动到根对象,它应该可以工作。

事实证明,Kaltura 不支持带有自定义视频 urls 的 DoubleClick。但有一种解决方法 - 为您的广告使用通用 VAST 插件,它可以与 mediaProxy 一起用于大多数广告提供商。

请记住,通用插件不支持瀑布广告(这是一个提供程序调用另一个提供程序的地方,另一个提供程序调用另一个提供程序最终给我们 XML 一个广告 flash/html5/mp4 文件)。要解决此问题,我建议您提供一个包含嵌套广告的提供商列表,然后在每次 ajax 调用 pubads.com 服务器时,查看 XML 并获取adTagUrl。如果此元素存在,递归地转到 url 并重复该过程,直到它不再存在。为到达广告文件之前要遵循的前一个 adTagUrl 保留一个变量 - 这是将进入通用 VAST preRollUrl/postRollUrl 参数的 adTagUrl

除此之外,某些提供商(如 optimatic)会因为 Kaltura 不支持的错误而中断播放器 - 在这种情况下,广告和播放器都会中断。发生这种情况时,最好重新加载播放器。

一旦广告开始缓冲 (adStart) 就启动超时,并在 onAdPlay 取消它(当广告实际开始播放时触发)。如果在 12 秒内未达到此点,请通过 kWidget.embed() 调用重新加载没有广告的播放器。