Skip to content

Commit

Permalink
🐛Added Mute/Unmute Controls to <amp-ima-video> (ampproject#18611)
Browse files Browse the repository at this point in the history
* Fixed the ima video example

* Finished the Mute/UnMute

* Fixed all testing and liniting errors
  • Loading branch information
torch2424 authored and Enriqe committed Nov 28, 2018
1 parent 39df31b commit 4e9b8d3
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 31 deletions.
95 changes: 78 additions & 17 deletions ads/google/imaVideo.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ const PlayerStates = {
PAUSED: 2,
};

/*eslint-disable */
/**
* Icons from Google Material Icons
* https://material.io/tools/icons
*/
/*eslint-disable*/
const icons = {
'play':
`<path d="M8 5v14l11-7z"></path>
Expand Down Expand Up @@ -91,6 +95,9 @@ let progressMarkerDiv;
// Div for fullscreen icon.
let fullscreenDiv;

// Div for mute/unmute icon.
let muteUnmuteDiv;

// Div for ad container.
let adContainerDiv;

Expand Down Expand Up @@ -313,6 +320,19 @@ export function imaVideo(global, data) {
progressBarWrapperDiv.appendChild(progressMarkerDiv);
progressBarWrapperDiv.appendChild(totalTimeLine);
controlsDiv.appendChild(progressBarWrapperDiv);

// Mute/Unmute button
muteUnmuteDiv = createIcon(global, 'volume_max');
muteUnmuteDiv.id = 'ima-mute-unmute';
setStyles(muteUnmuteDiv, {
'width': '30px',
'height': '30px',
'margin-right': '20px',
'font-size': '1.25em',
'cursor': 'pointer',
});
controlsDiv.appendChild(muteUnmuteDiv);

// Fullscreen button
fullscreenDiv = createIcon(global, 'fullscreen');
fullscreenDiv.id = 'ima-fullscreen';
Expand Down Expand Up @@ -414,6 +434,7 @@ export function imaVideo(global, data) {
}
playPauseDiv.addEventListener(interactEvent, onPlayPauseClick);
progressBarWrapperDiv.addEventListener(mouseDownEvent, onProgressClick);
muteUnmuteDiv.addEventListener(interactEvent, onMuteUnmuteClick);
fullscreenDiv.addEventListener(interactEvent,
toggleFullscreen.bind(null, global));

Expand Down Expand Up @@ -954,6 +975,51 @@ export function pauseVideo(event = null) {
}
}

/**
* Handler when the mute/unmute button is clicked
*/
export function onMuteUnmuteClick() {
if (videoPlayer.muted) {
unmuteVideo();
} else {
muteVideo();
}
}

/**
* Function to mute the video
*/
export function muteVideo() {
if (!videoPlayer.muted) {
videoPlayer.volume = 0;
videoPlayer.muted = true;
if (adsManager) {
adsManager.setVolume(0);
} else {
muteAdsManagerOnLoaded = true;
}
changeIcon(muteUnmuteDiv, 'mute');
postMessage({event: VideoEvents.MUTED});
}
}

/**
* Function to unmute the video
*/
export function unmuteVideo() {
if (videoPlayer.muted) {
videoPlayer.volume = 1;
videoPlayer.muted = false;
if (adsManager) {
adsManager.setVolume(1);
} else {
muteAdsManagerOnLoaded = false;
}
changeIcon(muteUnmuteDiv, 'volume_max');
postMessage({event: VideoEvents.UNMUTED});
}
}


/**
* @param {Object} global
Expand Down Expand Up @@ -1107,24 +1173,10 @@ function onMessage(global, event) {
}
break;
case 'mute':
videoPlayer.volume = 0;
videoPlayer.muted = true;
if (adsManager) {
adsManager.setVolume(0);
} else {
muteAdsManagerOnLoaded = true;
}
postMessage({event: VideoEvents.MUTED});
muteVideo();
break;
case 'unMute':
videoPlayer.volume = 1;
videoPlayer.muted = false;
if (adsManager) {
adsManager.setVolume(1);
} else {
muteAdsManagerOnLoaded = false;
}
postMessage({event: VideoEvents.UNMUTED});
unmuteVideo();
break;
case 'hideControls':
if (!adsActive) {
Expand Down Expand Up @@ -1228,6 +1280,15 @@ export function setVideoWidthAndHeightForTesting(width, height) {
videoHeight = height;
}

/**
* Sets the video muted state
* @param {boolean} shouldMute
* @visibleForTesting
*/
export function setVideoPlayerMutedForTesting(shouldMute) {
videoPlayer.muted = shouldMute;
}

/**
* Sets the ad request failed flag.
* @param {boolean} newValue
Expand Down
51 changes: 37 additions & 14 deletions examples/ima-video.amp.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,53 @@
<script async custom-element="amp-ima-video" src="https://cdn.ampproject.org/v0/amp-ima-video-0.1.js"></script>
<style amp-custom>
.spacer {
height: 100vh;
height: 50px;
}
</style>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
<style>
#player-wrapper {
.player-wrapper {
max-width: 600px;
}
.description {
margin-top: 5px;
margin-bottom: 5px;
}
</style>
</head>
<body>
<h2>amp-ima-video</h2>
<div id="player-wrapper1">
<h1>amp-ima-video</h1>
<h3>Resources</h3>
<ul>
<li><a href="https://developers.google.com/interactive-media-ads/docs/sdks/html5/tags">IMA Sample Tags</a></li>
</ul>
<h2>myVideo1</h2>
<div class="description">
Uses the Post roll IMA Sample Tag.
</div>
<div id="player-wrapper1" class="player-wrapper">
<amp-ima-video id="myVideo1"
width="640" height="360" layout="responsive"
data-tag="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%3Dpremidpost&cmsid=496&vid=short_onecue&correlator="
data-tag="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%3Dpostonly&cmsid=496&vid=short_onecue&correlator="
data-poster="/examples/img/ima-poster.png">
<source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4">
</amp-ima-video>
</div>
<h3>Actions</h3>
<button on="tap:myVideo.play">Play</button>
<button on="tap:myVideo.pause">Pause</button>
<button on="tap:myVideo.mute">Mute</button>
<button on="tap:myVideo.unmute">Unmute</button>
<button on="tap:myVideo.fullscreen">Fullscreen</button>
<h2>Autoplay</h2>
<div id="player-wrapper2">
<h3>myVideo1 Actions</h3>
<button on="tap:myVideo1.play">Play</button>
<button on="tap:myVideo1.pause">Pause</button>
<button on="tap:myVideo1.mute">Mute</button>
<button on="tap:myVideo1.unmute">Unmute</button>
<button on="tap:myVideo1.fullscreen">Fullscreen</button>

<div class="spacer"></div>

<h2>myVideo2</h2>
<div class="description">
Uses the Pre-, Mid-, and Post Roll IMA Sample Tag. Also, this video with autoplay
</div>
<div id="player-wrapper2" class="player-wrapper">
<amp-ima-video id="myVideo2"
autoplay
width="640" height="360" layout="responsive"
Expand All @@ -46,6 +64,11 @@ <h2>Autoplay</h2>
<source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4">
</amp-ima-video>
</div>
<div class="spacer"></div>
<h3>myVideo2 Actions</h3>
<button on="tap:myVideo2.play">Play</button>
<button on="tap:myVideo2.pause">Pause</button>
<button on="tap:myVideo2.mute">Mute</button>
<button on="tap:myVideo2.unmute">Unmute</button>
<button on="tap:myVideo2.fullscreen">Fullscreen</button>
</body>
</html>
58 changes: 58 additions & 0 deletions extensions/amp-ima-video/0.1/test/test-amp-ima-video.js
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,64 @@ describes.realWin('amp-ima-video', {
//expect(showControlsSpy).to.have.been.called;
});

it('mutes on click', () => {
const div = doc.createElement('div');
div.setAttribute('id', 'c');
doc.body.appendChild(div);

imaVideoObj.imaVideo(win, {
width: 640,
height: 360,
src: srcUrl,
tag: adTagUrl,
});
const videoMock = {};
videoMock.muted = false;
imaVideoObj.setVideoPlayerForTesting(videoMock);
const adsManagerMock = {};
adsManagerMock.setVolume = () => {};
imaVideoObj.setAdsManagerForTesting(adsManagerMock);
imaVideoObj.setVideoPlayerMutedForTesting(false);
//const pauseVideoSpy = sandbox.spy(imaVideoObj, 'pauseVideo');

imaVideoObj.onMuteUnmuteClick();

const isMuted = imaVideoObj.getPropertiesForTesting().videoPlayer.muted;

//expect(pauseVideoSpy).to.have.been.called;
expect(isMuted).to.be.true;
});

it('unmutes on click', () => {
const div = doc.createElement('div');
div.setAttribute('id', 'c');
doc.body.appendChild(div);

imaVideoObj.imaVideo(win, {
width: 640,
height: 360,
src: srcUrl,
tag: adTagUrl,
});
const videoMock = {};
videoMock.muted = false;
imaVideoObj.setVideoPlayerForTesting(videoMock);
const adsManagerMock = {};
adsManagerMock.setVolume = () => {};
imaVideoObj.setAdsManagerForTesting(adsManagerMock);
imaVideoObj.setVideoPlayerMutedForTesting(true);
//const pauseVideoSpy = sandbox.spy(imaVideoObj, 'pauseVideo');

imaVideoObj.onMuteUnmuteClick();

const isMuted = imaVideoObj.getPropertiesForTesting().videoPlayer.muted;

//expect(pauseVideoSpy).to.have.been.called;
expect(isMuted).to.be.false;
});



it('pauses video after webkit end fullscreen', () => {
const div = doc.createElement('div');
div.setAttribute('id', 'c');
Expand Down

0 comments on commit 4e9b8d3

Please sign in to comment.