Skip to content

Commit

Permalink
Integrate ad experience into the demo page.
Browse files Browse the repository at this point in the history
Different ads have been added to three assets.
Demo search CSS has been adjusted a bit for better
experience.
Feature name has been changed from "AD" to "ADS" to
reflect the fact that a single asset can have more
than one ad.

Issue shaka-project#2222:

Change-Id: I12a63b813fb4bac79362f1689b485a824f5a9682
  • Loading branch information
ismena committed Jan 29, 2020
1 parent 37a5e4a commit a38f61b
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 16 deletions.
2 changes: 1 addition & 1 deletion demo/asset_card.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ shakaDemo.AssetCard = class {
.set(Feature.ULTRA_HIGH_DEFINITION, 'ultra_high_definition')
.set(Feature.SURROUND, 'surround_sound')
.set(Feature.MULTIPLE_LANGUAGES, 'multiple_languages')
.set(Feature.AD, 'ad')
.set(Feature.ADS, 'ad')
.set(Feature.AUDIO_ONLY, 'audio_only');

for (const feature of asset.features) {
Expand Down
12 changes: 12 additions & 0 deletions demo/common/asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ const ShakaDemoAssetInfo = class {
this.clearKeys = new Map(); // TODO: Setter method?
/** @type {?Object} */
this.extraConfig = null;
/** @type {?string} */
this.adTagUri = null;

// Offline storage values.
/** @type {?function()} */
Expand Down Expand Up @@ -178,6 +180,16 @@ const ShakaDemoAssetInfo = class {
return this;
}

/**
* @param {string} uri
* @return {!ShakaDemoAssetInfo}
*/
setAdTagUri(uri) {
this.adTagUri = uri;
this.addFeature(shakaAssets.Feature.ADS);
return this;
}

/**
* @param {string} keySystem
* @param {string} licenseRequestHeader
Expand Down
66 changes: 63 additions & 3 deletions demo/common/assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,25 @@ shakaAssets.KeySystem = {
};


/** @enum {string} */
shakaAssets.AdTag = {
SINGLE_LINEAR_AD: 'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480' +
'&iu=/124319096/external/' +
'single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&' +
'unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%' +
'3Dlinear&correlator=',
SINGLE_SKIPPABLE_AD: 'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/' +
'124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&' +
'gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=' +
'deployment%3Ddevsite%26sample_ct%3Dskippablelinear&correlator=',
AD_POD_PREROLL_MIDROLL_POSTROLL: 'https://pubads.g.doubleclick.net/gampad/ads?' +
'sz=640x480&iu=/124319096/external/ad_rule_samples&' +
'ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=' +
'vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite' +
'%26sample_ar%3Dpremidpostpod&cmsid=496&vid=short_onecue&correlator=',
};


/**
* @param {!shakaAssets.KeySystem} keySystem
* @return {string}
Expand Down Expand Up @@ -79,8 +98,9 @@ shakaAssets.Feature = {
OFFLINE: shakaDemo.MessageIds.OFFLINE,
// A synthetic property used in the search tab. Should not be given to assets.
STORED: shakaDemo.MessageIds.STORED,
// Set if the asset has an ad.
AD: shakaDemo.MessageIds.AD,
// Set if the asset has ads. Autoset by calling setAdTagUri() on an asset.
// Does not need to be set manually.
ADS: shakaDemo.MessageIds.ADS,

// Set if the asset is a livestream.
LIVE: shakaDemo.MessageIds.LIVE,
Expand Down Expand Up @@ -269,6 +289,20 @@ shakaAssets.testAssets = [
.addFeature(shakaAssets.Feature.SURROUND)
.addFeature(shakaAssets.Feature.OFFLINE)
.addLicenseServer('com.widevine.alpha', 'https://cwip-shaka-proxy.appspot.com/no_auth'),
new ShakaDemoAssetInfo(
/* name= */ 'Angel One (HLS, MP4, multilingual, Widevine, single linear ad)',
/* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/angel_one.png',
/* manifestUri= */ 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8',
/* source= */ shakaAssets.Source.SHAKA)
.addKeySystem(shakaAssets.KeySystem.WIDEVINE)
.setAdTagUri(shakaAssets.AdTag.SINGLE_LINEAR_AD)
.addFeature(shakaAssets.Feature.HLS)
.addFeature(shakaAssets.Feature.MP4)
.addFeature(shakaAssets.Feature.MULTIPLE_LANGUAGES)
.addFeature(shakaAssets.Feature.SUBTITLES)
.addFeature(shakaAssets.Feature.SURROUND)
.addFeature(shakaAssets.Feature.OFFLINE)
.addLicenseServer('com.widevine.alpha', 'https://cwip-shaka-proxy.appspot.com/no_auth'),
new ShakaDemoAssetInfo(
/* name= */ 'Sintel 4k (multicodec)',
/* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/sintel.png',
Expand Down Expand Up @@ -317,8 +351,23 @@ shakaAssets.testAssets = [
/* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/sintel.png',
/* manifestUri= */ 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd',
/* source= */ shakaAssets.Source.SHAKA)
.addDescription('A Blender Foundation short film, protected by Widevine encryption.')
.addKeySystem(shakaAssets.KeySystem.WIDEVINE)
.addFeature(shakaAssets.Feature.DASH)
.addFeature(shakaAssets.Feature.HIGH_DEFINITION)
.addFeature(shakaAssets.Feature.MP4)
.addFeature(shakaAssets.Feature.SUBTITLES)
.addFeature(shakaAssets.Feature.WEBM)
.addFeature(shakaAssets.Feature.OFFLINE)
.addLicenseServer('com.widevine.alpha', 'https://cwip-shaka-proxy.appspot.com/no_auth'),
new ShakaDemoAssetInfo(
/* name= */ 'Sintel 4k (multicodec, Widevine, ads)',
/* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/sintel.png',
/* manifestUri= */ 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd',
/* source= */ shakaAssets.Source.SHAKA)
.addDescription('A Blender Foundation short film, protected by Widevine encryption ' +
' with pre-roll, mid-roll, and post-roll ads.')
.markAsFeatured('Sintel')
.setAdTagUri(shakaAssets.AdTag.AD_POD_PREROLL_MIDROLL_POSTROLL)
.addKeySystem(shakaAssets.KeySystem.WIDEVINE)
.addFeature(shakaAssets.Feature.DASH)
.addFeature(shakaAssets.Feature.HIGH_DEFINITION)
Expand Down Expand Up @@ -419,6 +468,17 @@ shakaAssets.testAssets = [
.addFeature(shakaAssets.Feature.SURROUND)
.addFeature(shakaAssets.Feature.WEBM)
.addFeature(shakaAssets.Feature.OFFLINE),
new ShakaDemoAssetInfo(
/* name= */ 'Tears of Steel (multicodec, surround + stereo, single skippable ad)',
/* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/tears_of_steel.png',
/* manifestUri= */ 'https://storage.googleapis.com/shaka-demo-assets/tos-surround/dash.mpd',
/* source= */ shakaAssets.Source.SHAKA)
.setAdTagUri(shakaAssets.AdTag.SINGLE_SKIPPABLE_AD)
.addFeature(shakaAssets.Feature.DASH)
.addFeature(shakaAssets.Feature.MP4)
.addFeature(shakaAssets.Feature.SURROUND)
.addFeature(shakaAssets.Feature.WEBM)
.addFeature(shakaAssets.Feature.OFFLINE),
new ShakaDemoAssetInfo(
/* name= */ 'Shaka Player History (multicodec, live, DASH)',
/* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/shaka.png',
Expand Down
2 changes: 1 addition & 1 deletion demo/common/message_ids.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ shakaDemo.MessageIds = {
AUDIO_ONLY: 'DEMO_AUDIO_ONLY',
OFFLINE: 'DEMO_OFFLINE',
STORED: 'DEMO_STORED',
AD: 'DEMO_AD',
ADS: 'DEMO_ADS',
LIVE: 'DEMO_LIVE',
WEBM: 'DEMO_WEBM',
MP4: 'DEMO_MP4',
Expand Down
2 changes: 1 addition & 1 deletion demo/demo.less
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ html, body {
}

.significant-right-padding {
padding-right: 5.5em;
padding-right: 5em;
}

.mdl-dialog {
Expand Down
2 changes: 1 addition & 1 deletion demo/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"DEMO_AUDIO_ONLY": "Audio only",
"DEMO_OFFLINE": "Downloadable",
"DEMO_STORED": "Downloaded",
"DEMO_AD": "Ad",
"DEMO_ADS": "Ads",
"DEMO_MANIFEST_SEARCH": "Manifest",
"DEMO_CONTAINER_SEARCH": "Container",
"DEMO_DRM_SEARCH": "DRM",
Expand Down
6 changes: 3 additions & 3 deletions demo/locales/source.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
"message": "Downloaded",
"description": "A tag that marks an asset as being downloaded by the user."
},
"DEMO_AD": {
"message": "Ad",
"description": "A tag that marks an asset as having an advertisement."
"DEMO_ADS": {
"message": "Ads",
"description": "A tag that marks an asset as having one or more advertisements."
},
"DEMO_MANIFEST_SEARCH": {
"message": "Manifest",
Expand Down
19 changes: 19 additions & 0 deletions demo/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,25 @@ shakaDemo.Main = class {
this.video_.poster = shakaDemo.Main.audioOnlyPoster_;
}

// If the asset has an ad tag attached to it, load the ads
const adManager = this.player_.getAdManager();
if (adManager && asset.adTagUri) {
try {
// If IMA is blocked by an AdBlocker, init() will throw.
// If that happens, just proceed to load.
goog.asserts.assert(this.video_ != null, 'this.video should exist!');
adManager.initClientSide(
this.controls_.getAdContainer(), this.video_);
const adRequest = new google.ima.AdsRequest();
adRequest.adTagUrl = asset.adTagUri;
adManager.requestClientSideAds(adRequest);
} catch (error) {
console.log(error);
console.warn('Ads code has been prevented from running. ' +
'Proceeding with the load without ads.');
}
}

// Set media session title, but only if the browser supports that API.
if (navigator.mediaSession) {
const metadata = {
Expand Down
2 changes: 1 addition & 1 deletion demo/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ shakaDemo.Search = class {
shakaDemo.MessageIds.OFFLINE_SEARCH);
this.makeBooleanInput_(specialContainer, Feature.STORED, FEATURE,
shakaDemo.MessageIds.STORED_SEARCH);
this.makeBooleanInput_(specialContainer, Feature.AD, FEATURE,
this.makeBooleanInput_(specialContainer, Feature.ADS, FEATURE,
shakaDemo.MessageIds.AD_SEARCH);
this.makeBooleanInput_(specialContainer, Feature.AUDIO_ONLY, FEATURE,
shakaDemo.MessageIds.AUDIO_ONLY_SEARCH);
Expand Down
11 changes: 11 additions & 0 deletions externs/shaka/ads.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@
*/
shaka.extern.IAdManager = class extends EventTarget {
onAssetUnload() {}

/**
* @param {!HTMLElement} adContainer
* @param {!HTMLMediaElement} video
*/
initClientSide(adContainer, video) {}

/**
* @param {!google.ima.AdsRequest} imaRequest
*/
requestClientSideAds(imaRequest) {}
};


Expand Down
5 changes: 2 additions & 3 deletions lib/ads/ad_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
}

/**
* @param {!HTMLElement} adContainer
* @param {!HTMLMediaElement} video
* @override
* @export
*/
initClientSide(adContainer, video) {
Expand Down Expand Up @@ -85,7 +84,7 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {


/**
* @param {!google.ima.AdsRequest} imaRequest
* @override
* @export
*/
requestClientSideAds(imaRequest) {
Expand Down
9 changes: 8 additions & 1 deletion lib/ads/client_side_ad_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,18 @@ shaka.ads.ClientSideAdManager = class {

try {
const viewMode = document.fullscreenElement ?
google.ima.ViewMode.FULLSCREEN : google.ima.ViewMode.NORMAL;
google.ima.ViewMode.FULLSCREEN : google.ima.ViewMode.NORMAL;

this.imaAdsManager_.init(this.video_.offsetWidth,
this.video_.offsetHeight, viewMode);

this.eventManager_.listen(this.video_, 'loadedmetadata', () => {
const viewMode = document.fullscreenElement ?
google.ima.ViewMode.FULLSCREEN : google.ima.ViewMode.NORMAL;
this.imaAdsManager_.resize(this.video_.offsetWidth,
this.video_.offsetHeight, viewMode);
});

// Single video and overlay ads will start at this time
// TODO (ismena): Need a better inderstanding of what this does.
// The docs say it's called to 'start playing the ads,' but I haven't
Expand Down
3 changes: 2 additions & 1 deletion ui/skip_ad_button.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ shaka.ui.SkipAdButton = class extends shaka.ui.Element {
/** @private {!HTMLElement} */
this.counter_ = shaka.util.Dom.createHTMLElement('div');
this.counter_.classList.add('shaka-skip-ad-counter');
shaka.ui.Utils.setDisplay(this.counter_, false);
this.container_.appendChild(this.counter_);

/** @private {!HTMLElement} */
Expand All @@ -41,7 +42,7 @@ shaka.ui.SkipAdButton = class extends shaka.ui.Element {
this.button_.disabled = true;
shaka.ui.Utils.setDisplay(this.button_, false);
this.button_.classList.add('shaka-no-propagation');
this.parent.appendChild(this.button_);
this.container_.appendChild(this.button_);
this.updateAriaLabel_();
this.updateLocalizedStrings_();

Expand Down

0 comments on commit a38f61b

Please sign in to comment.