Commit e7486528 by Muhammad Ammar Committed by GitHub

Merge pull request #15199 from edx/ammar/edu-211-html5-player-overlay-play-button

show play button overlay
parents f59dbc9c e89c08d8
...@@ -149,6 +149,16 @@ $cool-dark: rgb(79, 89, 93); // UXPL cool dark ...@@ -149,6 +149,16 @@ $cool-dark: rgb(79, 89, 93); // UXPL cool dark
background-color: black; background-color: black;
position: relative; position: relative;
&:hover {
.btn-play {
color: $uxpl-blue-base;
}
.btn-play:after {
background: $white;
}
}
.video-player-pre, .video-player-pre,
.video-player-post { .video-player-post {
height: 50px; height: 50px;
...@@ -182,21 +192,23 @@ $cool-dark: rgb(79, 89, 93); // UXPL cool dark ...@@ -182,21 +192,23 @@ $cool-dark: rgb(79, 89, 93); // UXPL cool dark
@include transform(translate(-50%, -50%)); @include transform(translate(-50%, -50%));
position: absolute; position: absolute;
z-index: 1; z-index: 1;
background: rgba(0, 0, 0, 0.7); top: 46%;
top: 50%;
left: 50%; left: 50%;
padding: 30px; font-size: 4em;
border-radius: 25%; cursor: pointer;
&:after{ &:after {
background: $white;
position: absolute;
width: 50%;
height: 50%;
content: ''; content: '';
display: block; left: 0;
width: 0px; top: 0;
height: 0px; bottom: 0;
border-style: solid; right: 0;
border-width: 30px 0 30px 50px; margin: auto;
border-color: transparent transparent transparent $white; z-index: -1;
position: relative;
} }
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
<span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span> <span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span>
<span tabindex="-1" class="btn-play is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span> <span tabindex="-1" class="btn-play fa fa-youtube-play fa-2x is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span>
<div class="video-player-pre"></div> <div class="video-player-pre"></div>
<section class="video-player"> <section class="video-player">
<iframe id="id"></iframe> <iframe id="id"></iframe>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
<span tabindex="0" class="spinner" aria-hidden="false" aria-label="Loading video player"></span> <span tabindex="0" class="spinner" aria-hidden="false" aria-label="Loading video player"></span>
<span tabindex="-1" class="btn-play is-hidden" aria-hidden="true" aria-label="Play video"></span> <span tabindex="-1" class="btn-play fa fa-youtube-play fa-2x is-hidden" aria-hidden="true" aria-label="Play video"></span>
<div class="video-player-pre"></div> <div class="video-player-pre"></div>
<section class="video-player"> <section class="video-player">
<div id="id"></div> <div id="id"></div>
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
</div> </div>
<div class="focus_grabber last"></div> <div class="focus_grabber last"></div>
<h3 class="hd hd-4 downloads-heading sr" id="video-download-transcripts">Downloads and transcripts</h3> <h3 class="hd hd-4 downloads-heading sr" id="video-download-transcripts">Downloads and transcripts</h3>
<div class="wrapper-downloads" role="region" aria-labelledby="video-download-transcripts"> <div class="wrapper-downloads" role="region" aria-labelledby="video-download-transcripts">
<div class="wrapper-download-video"> <div class="wrapper-download-video">
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
<span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span> <span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span>
<span tabindex="-1" class="btn-play is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span> <span tabindex="-1" class="btn-play fa fa-youtube-play fa-2x is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span>
<section class="video-player"> <section class="video-player">
<div id="id"></div> <div id="id"></div>
<h4 class="hd hd-4 video-hls-error is-hidden"> <h4 class="hd hd-4 video-hls-error is-hidden">
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
<span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span> <span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span>
<span tabindex="-1" class="btn-play is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span> <span tabindex="-1" class="btn-play fa fa-youtube-play fa-2x is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span>
<section class="video-player"> <section class="video-player">
<div id="id"></div> <div id="id"></div>
</section> </section>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
<span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span> <span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span>
<span tabindex="-1" class="btn-play is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span> <span tabindex="-1" class="btn-play fa fa-youtube-play fa-2x is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span>
<section class="video-player"> <section class="video-player">
<iframe id="id"></iframe> <iframe id="id"></iframe>
</section> </section>
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
<span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span> <span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span>
<span tabindex="-1" class="btn-play is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span> <span tabindex="-1" class="btn-play fa fa-youtube-play fa-2x is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span>
<div class="video-player-pre"></div> <div class="video-player-pre"></div>
<section class="video-player"> <section class="video-player">
<iframe id="id"></iframe> <iframe id="id"></iframe>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
<span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span> <span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span>
<span tabindex="-1" class="btn-play is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span> <span tabindex="-1" class="btn-play fa fa-youtube-play fa-2x is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span>
<div class="video-player-pre"></div> <div class="video-player-pre"></div>
<section class="video-player"> <section class="video-player">
<iframe id="id1"></iframe> <iframe id="id1"></iframe>
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
['video/03_video_player.js', 'hls'], ['video/03_video_player.js', 'hls'],
function(VideoPlayer, HLS) { function(VideoPlayer, HLS) {
describe('VideoPlayer', function() { describe('VideoPlayer', function() {
var state, oldOTBD, empty_arguments; var STATUS = window.STATUS,
state,
oldOTBD,
emptyArguments;
(function() { (function() {
empty_arguments = arguments; emptyArguments = arguments;
})(); })();
beforeEach(function() { beforeEach(function() {
...@@ -219,8 +222,8 @@ function(VideoPlayer, HLS) { ...@@ -219,8 +222,8 @@ function(VideoPlayer, HLS) {
}); });
it('trigger pause and ended events', function() { it('trigger pause and ended events', function() {
expect($.fn.trigger).toHaveBeenCalledWith('pause', empty_arguments); expect($.fn.trigger).toHaveBeenCalledWith('pause', emptyArguments);
expect($.fn.trigger).toHaveBeenCalledWith('ended', empty_arguments); expect($.fn.trigger).toHaveBeenCalledWith('ended', emptyArguments);
}); });
}); });
}); });
...@@ -242,7 +245,7 @@ function(VideoPlayer, HLS) { ...@@ -242,7 +245,7 @@ function(VideoPlayer, HLS) {
}); });
it('pause the video caption', function() { it('pause the video caption', function() {
expect($.fn.trigger).toHaveBeenCalledWith('pause', empty_arguments); expect($.fn.trigger).toHaveBeenCalledWith('pause', emptyArguments);
}); });
}); });
...@@ -281,7 +284,7 @@ function(VideoPlayer, HLS) { ...@@ -281,7 +284,7 @@ function(VideoPlayer, HLS) {
}); });
it('play the video caption', function() { it('play the video caption', function() {
expect($.fn.trigger).toHaveBeenCalledWith('play', empty_arguments); expect($.fn.trigger).toHaveBeenCalledWith('play', emptyArguments);
}); });
}); });
...@@ -314,7 +317,7 @@ function(VideoPlayer, HLS) { ...@@ -314,7 +317,7 @@ function(VideoPlayer, HLS) {
}); });
it('pause the video caption', function() { it('pause the video caption', function() {
expect($.fn.trigger).toHaveBeenCalledWith('pause', empty_arguments); expect($.fn.trigger).toHaveBeenCalledWith('pause', emptyArguments);
}); });
}); });
...@@ -334,7 +337,7 @@ function(VideoPlayer, HLS) { ...@@ -334,7 +337,7 @@ function(VideoPlayer, HLS) {
}); });
it('pause the video caption', function() { it('pause the video caption', function() {
expect($.fn.trigger).toHaveBeenCalledWith('ended', empty_arguments); expect($.fn.trigger).toHaveBeenCalledWith('ended', emptyArguments);
}); });
}); });
}); });
...@@ -1011,6 +1014,49 @@ function(VideoPlayer, HLS) { ...@@ -1011,6 +1014,49 @@ function(VideoPlayer, HLS) {
); );
}); });
}); });
describe('Overlay Play Button', function() {
var playButtonOverlaySelector = '.video-wrapper .btn-play.fa.fa-youtube-play.fa-2x';
beforeEach(function() {
state = jasmine.initializePlayer();
});
it('shows the play button after player is ready', function(done) {
jasmine.waitUntil(function() {
return state.videoPlayer.player.getPlayerState() !== STATUS.UNSTARTED;
}).then(function() {
expect($(playButtonOverlaySelector)).not.toHaveClass('is-hidden');
}).always(done);
});
it('hides the play button on play', function(done) {
$(state.videoPlayer.player.videoEl).trigger('click'); // play
jasmine.waitUntil(function() {
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
}).then(function() {
expect($(playButtonOverlaySelector)).toHaveClass('is-hidden');
}).always(done);
});
it('plays the video when overlay button is clicked', function() {
$('.video-wrapper .btn-play').trigger('click'); // play
expect(state.videoPlayer.player.getPlayerState()).toEqual(STATUS.PLAYING);
expect($(playButtonOverlaySelector)).toHaveClass('is-hidden');
});
it('shows the play button on pause', function(done) {
$(state.videoPlayer.player.videoEl).trigger('click'); // play
expect(state.videoPlayer.player.getPlayerState()).toEqual(STATUS.PLAYING);
$(state.videoPlayer.player.videoEl).trigger('click'); // pause
expect(state.videoPlayer.player.getPlayerState()).toEqual(STATUS.PAUSED);
jasmine.waitUntil(function() {
return $(playButtonOverlaySelector).attr('class').split(' ')
.indexOf('is-hidden') === -1;
}).then(function() {
expect($(playButtonOverlaySelector)).not.toHaveClass('is-hidden');
}).always(done);
});
});
}); });
}); });
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); }(RequireJS.requirejs, RequireJS.require, RequireJS.define));
...@@ -212,22 +212,26 @@ function(_) { ...@@ -212,22 +212,26 @@ function(_) {
this.playerState = HTML5Video.PlayerState.PAUSED; this.playerState = HTML5Video.PlayerState.PAUSED;
if ($.isFunction(this.config.events.onReady)) { if ($.isFunction(this.config.events.onReady)) {
this.config.events.onReady(null); this.config.events.onReady(null);
this.videoOverlayEl.removeClass('is-hidden');
} }
}; };
Player.prototype.onPlay = function() { Player.prototype.onPlay = function() {
this.playerState = HTML5Video.PlayerState.BUFFERING; this.playerState = HTML5Video.PlayerState.BUFFERING;
this.callStateChangeCallback(); this.callStateChangeCallback();
this.videoOverlayEl.addClass('is-hidden');
}; };
Player.prototype.onPlaying = function() { Player.prototype.onPlaying = function() {
this.playerState = HTML5Video.PlayerState.PLAYING; this.playerState = HTML5Video.PlayerState.PLAYING;
this.callStateChangeCallback(); this.callStateChangeCallback();
this.videoOverlayEl.addClass('is-hidden');
}; };
Player.prototype.onPause = function() { Player.prototype.onPause = function() {
this.playerState = HTML5Video.PlayerState.PAUSED; this.playerState = HTML5Video.PlayerState.PAUSED;
this.callStateChangeCallback(); this.callStateChangeCallback();
this.videoOverlayEl.removeClass('is-hidden');
}; };
Player.prototype.onEnded = function() { Player.prototype.onEnded = function() {
...@@ -244,7 +248,7 @@ function(_) { ...@@ -244,7 +248,7 @@ function(_) {
'durationchange', 'volumechange' 'durationchange', 'volumechange'
], ],
self = this, self = this,
errorMessage; callback;
this.config = config; this.config = config;
this.logs = []; this.logs = [];
...@@ -257,6 +261,9 @@ function(_) { ...@@ -257,6 +261,9 @@ function(_) {
// Get the jQuery object and set error event handlers // Get the jQuery object and set error event handlers
this.videoEl = $(this.video); this.videoEl = $(this.video);
// Video player overlay play button
this.videoOverlayEl = this.el.find('.video-wrapper .btn-play');
// The player state is used by other parts of the VideoPlayer to // The player state is used by other parts of the VideoPlayer to
// determine what the video is currently doing. // determine what the video is currently doing.
this.playerState = HTML5Video.PlayerState.UNSTARTED; this.playerState = HTML5Video.PlayerState.UNSTARTED;
...@@ -265,7 +272,7 @@ function(_) { ...@@ -265,7 +272,7 @@ function(_) {
// Attach a 'click' event on the <video> element. It will cause the // Attach a 'click' event on the <video> element. It will cause the
// video to pause/play. // video to pause/play.
this.videoEl.on('click', function() { callback = function() {
var PlayerState = HTML5Video.PlayerState; var PlayerState = HTML5Video.PlayerState;
if (self.playerState === PlayerState.PLAYING) { if (self.playerState === PlayerState.PLAYING) {
...@@ -275,7 +282,9 @@ function(_) { ...@@ -275,7 +282,9 @@ function(_) {
self.playerState = PlayerState.PLAYING; self.playerState = PlayerState.PLAYING;
self.playVideo(); self.playVideo();
} }
}); };
this.videoEl.on('click', callback);
this.videoOverlayEl.on('click', callback);
this.debug = false; this.debug = false;
$.each(events, function(index, eventName) { $.each(events, function(index, eventName) {
......
...@@ -21,7 +21,7 @@ from openedx.core.djangolib.js_utils import js_escaped_string ...@@ -21,7 +21,7 @@ from openedx.core.djangolib.js_utils import js_escaped_string
<div class="tc-wrapper"> <div class="tc-wrapper">
<div class="video-wrapper"> <div class="video-wrapper">
<span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span> <span tabindex="0" class="spinner" aria-hidden="false" aria-label="${_('Loading video player')}"></span>
<span tabindex="-1" class="btn-play is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span> <span tabindex="-1" class="btn-play fa fa-youtube-play fa-2x is-hidden" aria-hidden="true" aria-label="${_('Play video')}"></span>
<div class="video-player-pre"></div> <div class="video-player-pre"></div>
<div class="video-player"> <div class="video-player">
<div id="${id}"></div> <div id="${id}"></div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment