在 ads_manager.js 中,为 IMA SDK StreamManager 定义一个封装容器类,该类用于发出视频流请求、获取广告插播时段清单、监听 IMA 视频流事件,并将 emsg 事件传递给 IMA SDK。
在 ads_manager.js 中,IMA HbbTV 示例应用设置了以下方法:
requestStream()
onStreamEvent()
onEmsgEvent()
loadAdPodManifest()
初始化广告管理器
初始化广告管理器类,并为 IMA 流事件设置监听器。在此调用中,使用 VideoPlayer.setEmsgEventHandler() 方法设置 emsg 事件处理脚本。
/** * Wraps IMA SDK ad stream manager. * @param {!VideoPlayer} videoPlayer Reference an instance of the wrapper from * video_player.js. */varAdManager=function(videoPlayer){this.streamData=null;this.videoPlayer=videoPlayer;// Ad UI is not supported for HBBTV, so no 'adUiElement' is passed in the// StreamManager constructor.this.streamManager=newgoogle.ima.dai.api.StreamManager(this.videoPlayer.videoElement);this.streamManager.addEventListener([google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,google.ima.dai.api.StreamEvent.Type.ERROR,google.ima.dai.api.StreamEvent.Type.CLICK,google.ima.dai.api.StreamEvent.Type.STARTED,google.ima.dai.api.StreamEvent.Type.FIRST_QUARTILE,google.ima.dai.api.StreamEvent.Type.MIDPOINT,google.ima.dai.api.StreamEvent.Type.THIRD_QUARTILE,google.ima.dai.api.StreamEvent.Type.COMPLETE,google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED,google.ima.dai.api.StreamEvent.Type.AD_PROGRESS,google.ima.dai.api.StreamEvent.Type.PAUSED,google.ima.dai.api.StreamEvent.Type.RESUMED],this.onStreamEvent.bind(this),false);this.videoPlayer.setEmsgEventHandler(this.onEmsgEvent,this);};
创建 AdManager.requestStream() 方法,以使用您的 Google Ad Manager 广告资源网代码和视频流的自定义素材资源键来创建 PodStreamRequest 对象。使用 IMA 示例 DASH pod 提供以下串流参数的串流来测试 HbbTV 应用:
广告资源网代码:'21775744923'
自定义资源键:'hbbtv-dash'
/** * Makes a pod stream request. * @param {string} networkCode The network code. * @param {string} customAssetKey The custom asset key. */AdManager.prototype.requestStream=function(networkCode,customAssetKey){varstreamRequest=newgoogle.ima.dai.api.PodStreamRequest();streamRequest.networkCode=networkCode;streamRequest.customAssetKey=customAssetKey;streamRequest.format='dash';debugView.log('AdsManager: make PodStreamRequest');this.streamManager.requestStream(streamRequest);};
创建 AdManager.onStreamEvent() 方法来处理应用对 IMA 流事件 STREAM_INITIALIZED、AD_BREAK_STARTED 和 AD_BREAK_ENDED 的响应。
/** * Handles IMA playback events. * @param {!Event} event The event object. */AdManager.prototype.onStreamEvent=function(event){switch(event.type){// Once the stream response data is received, generate pod manifest url// for the video stream.casegoogle.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:debugView.log('IMA SDK: stream initialized');this.streamData=event.getStreamData();break;casegoogle.ima.dai.api.StreamEvent.Type.ERROR:break;// Hide video controls while ad is playing.casegoogle.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:debugView.log('IMA SDK: ad break started');this.adPlaying=true;this.adBreakStarted=true;break;// Show video controls when ad ends.casegoogle.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:debugView.log('IMA SDK: ad break ended');this.adPlaying=false;this.adBreakStarted=false;break;// Update ad countdown timers.casegoogle.ima.dai.api.StreamEvent.Type.AD_PROGRESS:break;default:debugView.log('IMA SDK: '+event.type);break;}};
/** * Callback on Emsg event. * Instructs IMA SDK to fire back VAST events accordingly. * @param {!Event} event The event object. */AdManager.prototype.onEmsgEvent=function(event){vardata=event.event.messageData;varpts=event.event.calculatedPresentationTime;if((datainstanceofUint8Array) && data.byteLength > 0){this.streamManager.processMetadata('ID3',data,pts);}};
创建 AdManager.loadAdPodManifest() 方法,以使用视频播放器预加载广告连播清单。使用方法:DASH Pod 清单中的结构构建清单网址。
/** * Creates DAI pod url and instructs video player to load manifest. * @param {string} networkCode The network code. * @param {string} customAssetKey The custom asset key. * @param {number} podDuration The duration of the ad pod. */AdManager.prototype.loadAdPodManifest=function(networkCode,customAssetKey,podDuration){if(!this.streamData){debugView.log('IMA SDK: No DAI pod session registered.');return;}varMANIFEST_BASE_URL='https://dai.google.com/linear/pods/v1/dash/network/';// Method: DASH pod manifest reference docs:// https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_dash_pod_manifestvarmanifestUrl=MANIFEST_BASE_URL+networkCode+'/custom_asset/'+customAssetKey+'/stream/'+this.streamData.streamId+'/pod/'+this.getPodId()+'/manifest.mpd?pd='+podDuration;this.videoPlayer.preload(manifestUrl);};
[null,null,["最后更新时间 (UTC):2025-08-31。"],[[["\u003cp\u003eThis guide outlines how to integrate the IMA SDK into an HbbTV app to manage ad streams, including setting up an \u003ccode\u003eAdManager\u003c/code\u003e class to handle stream requests and events.\u003c/p\u003e\n"],["\u003cp\u003eFor HbbTV, it is crucial to omit the \u003ccode\u003eadUiElement\u003c/code\u003e in the \u003ccode\u003eStreamManager\u003c/code\u003e constructor to avoid serving incompatible ads, as the IMA SDK does not support ad UI on this platform.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eAdManager\u003c/code\u003e class defines methods to request ad streams, handle IMA events (like \u003ccode\u003eSTREAM_INITIALIZED\u003c/code\u003e, \u003ccode\u003eAD_BREAK_STARTED\u003c/code\u003e, and \u003ccode\u003eAD_BREAK_ENDED\u003c/code\u003e), and process ad stream metadata using emsg events.\u003c/p\u003e\n"],["\u003cp\u003eAd pod manifests are preloaded by constructing a URL using Google Ad Manager parameters (network code, custom asset key) and stream information (\u003ccode\u003estreamId\u003c/code\u003e, \u003ccode\u003epodId\u003c/code\u003e), ensuring the \u003ccode\u003epodId\u003c/code\u003e remains consistent for viewers of the same ad break.\u003c/p\u003e\n"],["\u003cp\u003eBefore proceeding with these steps, complete the setup outlined in the "Set up the player class" guide to lay the foundation for the HbbTV player.\u003c/p\u003e\n"]]],["The `ads_manager.js` file defines an `AdManager` class to manage IMA SDK stream interactions. This includes `requestStream()` for sending stream requests using a network code and custom asset key, `onStreamEvent()` to handle IMA stream events like `STREAM_INITIALIZED`, `AD_BREAK_STARTED`, and `AD_BREAK_ENDED`. `onEmsgEvent()` passes emsg event data to the IMA SDK, and `loadAdPodManifest()` preloads the ad pod manifest using a constructed URL. The `podId` should be unique for each ad break.\n"],null,["| **Note:** Before moving forward with this guide, you must complete the steps in [Set up the player class](/ad-manager/dynamic-ad-insertion/sdk/html5/hbbtv-player).\n\nIn `ads_manager.js`, define a wrapper class for the IMA SDK StreamManager that\nmakes stream requests, gets the ad pod manifest, listens to IMA stream events,\nand passes emsg events to the IMA SDK.\n\nIn `ads_manager.js`, the IMA HbbTV sample app sets up the following methods:\n\n- `requestStream()`\n- `onStreamEvent()`\n- `onEmsgEvent()`\n- `loadAdPodManifest()`\n\nInitialize ads manager\n\nInitialize the ads manager class and set listeners for the IMA stream events. In\nthis call, set the emsg event handler with the\n`VideoPlayer.setEmsgEventHandler()` method.\n**Key Point:** The IMA SDK does not support ad UI on HbbTV. Don't pass the `adUiElement` parameter in the `StreamManager` constructor. Passing `adUiElement` can lead to Ad Manager serving incompatible ads. \n\n /**\n * Wraps IMA SDK ad stream manager.\n * @param {!VideoPlayer} videoPlayer Reference an instance of the wrapper from\n * video_player.js.\n */\n var AdManager = function(videoPlayer) {\n this.streamData = null;\n this.videoPlayer = videoPlayer;\n // Ad UI is not supported for HBBTV, so no 'adUiElement' is passed in the\n // StreamManager constructor.\n this.streamManager = new google.ima.dai.api.StreamManager(\n this.videoPlayer.videoElement);\n this.streamManager.addEventListener(\n [\n google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,\n google.ima.dai.api.StreamEvent.Type.ERROR,\n google.ima.dai.api.StreamEvent.Type.CLICK,\n google.ima.dai.api.StreamEvent.Type.STARTED,\n google.ima.dai.api.StreamEvent.Type.FIRST_QUARTILE,\n google.ima.dai.api.StreamEvent.Type.MIDPOINT,\n google.ima.dai.api.StreamEvent.Type.THIRD_QUARTILE,\n google.ima.dai.api.StreamEvent.Type.COMPLETE,\n google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,\n google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED,\n google.ima.dai.api.StreamEvent.Type.AD_PROGRESS,\n google.ima.dai.api.StreamEvent.Type.PAUSED,\n google.ima.dai.api.StreamEvent.Type.RESUMED\n ],\n this.onStreamEvent.bind(this),\n false);\n\n this.videoPlayer.setEmsgEventHandler(this.onEmsgEvent, this);\n }; \n https://github.com/googleads/googleads-ima-html5-dai/blob/d215db4a053d12c842e899da470684142ff732f6/hbbtv/ads_manager.js#L18-L50\n\nMake a request for an ad pod stream\n\nCreate the `AdManager.requestStream()` method to create a `PodStreamRequest`\nobject using your Google Ad Manager network code and the stream's custom asset\nkey. Test your HbbTV app using the IMA sample DASH pod serving stream with the\nfollowing stream parameters:\n\n- **Network code** : `'21775744923'`\n- **Custom asset key** : `'hbbtv-dash'`\n\n /**\n * Makes a pod stream request.\n * @param {string} networkCode The network code.\n * @param {string} customAssetKey The custom asset key.\n */\n AdManager.prototype.requestStream = function(networkCode, customAssetKey) {\n var streamRequest = new google.ima.dai.api.PodStreamRequest();\n streamRequest.networkCode = networkCode;\n streamRequest.customAssetKey = customAssetKey;\n streamRequest.format = 'dash';\n debugView.log('AdsManager: make PodStreamRequest');\n this.streamManager.requestStream(streamRequest);\n }; \n https://github.com/googleads/googleads-ima-html5-dai/blob/d215db4a053d12c842e899da470684142ff732f6/hbbtv/ads_manager.js#L54-L66\n\nListen to ad stream events\n\nCreate the `AdManager.onStreamEvent()` method to handle your app's response to\nthe IMA stream events, `STREAM_INITIALIZED`, `AD_BREAK_STARTED`, and\n`AD_BREAK_ENDED`. \n\n /**\n * Handles IMA playback events.\n * @param {!Event} event The event object.\n */\n AdManager.prototype.onStreamEvent = function(event) {\n switch (event.type) {\n // Once the stream response data is received, generate pod manifest url\n // for the video stream.\n case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:\n debugView.log('IMA SDK: stream initialized');\n this.streamData = event.getStreamData();\n break;\n case google.ima.dai.api.StreamEvent.Type.ERROR:\n break;\n // Hide video controls while ad is playing.\n case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:\n debugView.log('IMA SDK: ad break started');\n this.adPlaying = true;\n this.adBreakStarted = true;\n break;\n // Show video controls when ad ends.\n case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:\n debugView.log('IMA SDK: ad break ended');\n this.adPlaying = false;\n this.adBreakStarted = false;\n break;\n // Update ad countdown timers.\n case google.ima.dai.api.StreamEvent.Type.AD_PROGRESS:\n break;\n default:\n debugView.log('IMA SDK: ' + event.type);\n break;\n }\n }; \n https://github.com/googleads/googleads-ima-html5-dai/blob/d215db4a053d12c842e899da470684142ff732f6/hbbtv/ads_manager.js#L70-L103\n\nHandle ad stream metadata\n\nTo pass the emsg event info to IMA, create the `AdManager.onEmsgEvent()` method\nusing the `StreamManager.processMetadata()` method. The video player class calls\nthis method with the `VideoPlayer.setEmsgEventHandler()` method. \n\n /**\n * Callback on Emsg event.\n * Instructs IMA SDK to fire back VAST events accordingly.\n * @param {!Event} event The event object.\n */\n AdManager.prototype.onEmsgEvent = function(event) {\n var data = event.event.messageData;\n var pts = event.event.calculatedPresentationTime;\n if ((data instanceof Uint8Array) && data.byteLength \u003e 0) {\n this.streamManager.processMetadata('ID3', data, pts);\n }\n }; \n https://github.com/googleads/googleads-ima-html5-dai/blob/d215db4a053d12c842e899da470684142ff732f6/hbbtv/ads_manager.js#L107-L118\n\nLoad the ad pod manifest\n\nCreate the `AdManager.loadAdPodManifest()` method to preload the ad pod manifest\nwith the video player. Construct the manifest URL using the structure in\n[Method: DASH pod manifest](/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_dash_pod_manifest). \n\n /**\n * Creates DAI pod url and instructs video player to load manifest.\n * @param {string} networkCode The network code.\n * @param {string} customAssetKey The custom asset key.\n * @param {number} podDuration The duration of the ad pod.\n */\n AdManager.prototype.loadAdPodManifest =\n function(networkCode, customAssetKey, podDuration) {\n if (!this.streamData) {\n debugView.log('IMA SDK: No DAI pod session registered.');\n return;\n }\n\n var MANIFEST_BASE_URL = 'https://dai.google.com/linear/pods/v1/dash/network/';\n // Method: DASH pod manifest reference docs:\n // https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_dash_pod_manifest\n var manifestUrl = MANIFEST_BASE_URL + networkCode + '/custom_asset/' +\n customAssetKey + '/stream/' + this.streamData.streamId + '/pod/' +\n this.getPodId() + '/manifest.mpd?pd=' + podDuration;\n this.videoPlayer.preload(manifestUrl);\n }; \n https://github.com/googleads/googleads-ima-html5-dai/blob/d215db4a053d12c842e899da470684142ff732f6/hbbtv/ads_manager.js#L122-L142\n\nThe\n[HbbTV sample app](//github.com/googleads/googleads-ima-html5-dai/tree/main/hbbtv)\nuses a randomly generated unique `podId`. In production apps, the `podId` is an\ninteger that starts at one, and increments by one for each ad break. Verify the\n`podId` is the same value for all viewers of the ad break. To get a `podId`, we\nrecommend using the\n[Early ad break notifications](/ad-manager/video/Early.ad.break.notification)\n(EABN) API. In a production environment, include the `podId` and `podDuration`\nin the HbbTV stream event `AD_BREAK_ANNOUNCE`.\n\nNext, create the main application class for your HbbTV app that interacts with\nthe HbbTV broadcast."]]