Skip to content

Commit

Permalink
No public description
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 668574540
  • Loading branch information
google-ima-devrel-bot authored and IMA Developer Relations committed Aug 28, 2024
1 parent 17cbc1d commit 89e67b5
Show file tree
Hide file tree
Showing 8 changed files with 738 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ This project hosts samples for the
Simple example using DASH.js with DAI SDK and Google DAI Pod Serving. For
more information see the
[DAI pod serving guide](https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/html5?service=pod).
* [hbbtv](https://github.com/googleads/googleads-ima-html5-dai/tree/main/hbbtv) -
Simple example for requesting and playing ad pods with
[HbbTV](https://developer.hbbtv.org/).

### Requirements

Expand Down
40 changes: 40 additions & 0 deletions hbbtv/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# HbbTV Linear Sample App with IMA HTML5 DAI SDK

This HbbTV linear sample app demonstrates the IMA HTML5 DAI SDK integration. It
uses HbbTV stream events for detecting ad breaks and
[dash.js](https://github.com/Dash-Industry-Forum/dash.js/)
(version 4.6.0 or later) for ad playback. This application is intended to run
as an HbbTV app on a compatible device.

## Key Features

* **Stream Events:** The app listens for HbbTV broadcast events of upcoming ad
breaks.
* **Preloading:** The app initiates DAI pod serving ad requests and passes the
ad pod manifest to dash.js for preloading.
* **Ad Break Handling:** The app listens for HbbTV events to switch from the
broadcast stream to play the broadband ad break and resumes seamlessly
afterward.

## Requirements

* HbbTV-compliant device
* dash.js version 4.6.0 or later
* Web server to host the application

## Testing Environment Setup

1. **Broadcast Stream:** Prepare an audio/video stream containing custom AIT
(Application Information Table) data.
2. **DVB Modulator:** Configure a DVB modulator to transmit the broadcast stream
for reception by the hybrid terminal.
3. **Web Server:** Host the HbbTV application on a web server accessible by the
hybrid terminal.

For detailed instructions on setting up your testing environment, refer to this
guide on [running an HbbTV application](https://developer.hbbtv.org/tutorials/running-a-hbbtv-application-on-a-hybrid-terminal/).

## How to Run

Set the `stream_event_id` to match your networks event ID in `streamevent.xml`.
The IMA team used the value `1` for testing this app.
135 changes: 135 additions & 0 deletions hbbtv/ads_manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
Copyright 2024 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

var POD_DURATION = 90000; // Ad pod duration in millisecond.

/**
* Wraps IMA SDK ad stream manager.
* @param {!VideoPlayer} videoPlayer Reference an instance of the wrapper from
* video_player.js.
*/
var AdManager = 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 = new google.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);
};

/**
* Makes a pod stream request.
* @param {string} networkCode The network code.
* @param {string} customAssetKey The custom asset key.
*/
AdManager.prototype.requestStream = function(networkCode, customAssetKey) {
var streamRequest = new google.ima.dai.api.PodStreamRequest();
streamRequest.networkCode = networkCode;
streamRequest.customAssetKey = customAssetKey;
debugView.log('AdsManager: make PodStreamRequest');
this.streamManager.requestStream(streamRequest);
};

/**
* 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.
case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
debugView.log('IMA SDK: stream initialized');
this.streamData = event.getStreamData();
break;
case google.ima.dai.api.StreamEvent.Type.ERROR:
break;
// Hide video controls while ad is playing.
case google.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.
case google.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.
case google.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) {
var data = event.event.messageData;
var pts = event.event.calculatedPresentationTime;
if ((data instanceof Uint8Array) && data.byteLength > 0) {
this.streamManager.processMetadata('ID3', data, pts);
}
};

/**
* Creates DAI pod url and instructs video player to load manifest.
*/
AdManager.prototype.loadAdPodManifest = function() {
if (!this.streamData) {
debugView.log('IMA SDK: No DAI pod session registered.');
return;
}

var manifestUrl = this.streamData.getStandalonePodManifestUrl(
this.getPodId(), POD_DURATION);
this.videoPlayer.preload(manifestUrl);
};

/**
* Helper Function to get an unused pod ID.
* In production the pod ID is determined by an Early Break Notification Call.
* @return {string} The ad pod ID.
*/
AdManager.prototype.getPodId = function() {
return Math.trunc(new Date().getTime() / 60000);
};
Loading

0 comments on commit 89e67b5

Please sign in to comment.