Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
e7486528
Commit
e7486528
authored
Jun 08, 2017
by
Muhammad Ammar
Committed by
GitHub
Jun 08, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #15199 from edx/ammar/edu-211-html5-player-overlay-play-button
show play button overlay
parents
f59dbc9c
e89c08d8
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
99 additions
and
32 deletions
+99
-32
common/lib/xmodule/xmodule/css/video/display.scss
+24
-12
common/lib/xmodule/xmodule/js/fixtures/video.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_all.html
+2
-2
common/lib/xmodule/xmodule/js/fixtures/video_hls.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_html5.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_no_captions.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_with_bumper.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_yt_multiple.html
+1
-1
common/lib/xmodule/xmodule/js/spec/video/video_player_spec.js
+54
-8
common/lib/xmodule/xmodule/js/src/video/02_html5_video.js
+12
-3
lms/templates/video.html
+1
-1
No files found.
common/lib/xmodule/xmodule/css/video/display.scss
View file @
e7486528
...
...
@@ -149,6 +149,16 @@ $cool-dark: rgb(79, 89, 93); // UXPL cool dark
background-color
:
black
;
position
:
relative
;
&
:hover
{
.btn-play
{
color
:
$uxpl-blue-base
;
}
.btn-play
:after
{
background
:
$white
;
}
}
.video-player-pre
,
.video-player-post
{
height
:
50px
;
...
...
@@ -182,21 +192,23 @@ $cool-dark: rgb(79, 89, 93); // UXPL cool dark
@include
transform
(
translate
(
-50%
,
-50%
));
position
:
absolute
;
z-index
:
1
;
background
:
rgba
(
0
,
0
,
0
,
0
.7
);
top
:
50%
;
top
:
46%
;
left
:
50%
;
padding
:
30px
;
border-radius
:
25%
;
font-size
:
4em
;
cursor
:
pointer
;
&
:after
{
&
:after
{
background
:
$white
;
position
:
absolute
;
width
:
50%
;
height
:
50%
;
content
:
''
;
display
:
block
;
width
:
0px
;
height
:
0px
;
border-style
:
solid
;
border-width
:
30px
0
30px
50px
;
border-color
:
transparent
transparent
transparent
$white
;
position
:
relative
;
left
:
0
;
top
:
0
;
bottom
:
0
;
right
:
0
;
margin
:
auto
;
z-index
:
-1
;
}
}
...
...
common/lib/xmodule/xmodule/js/fixtures/video.html
View file @
e7486528
...
...
@@ -11,7 +11,7 @@
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
<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>
<section
class=
"video-player"
>
<iframe
id=
"id"
></iframe>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_all.html
View file @
e7486528
...
...
@@ -11,7 +11,7 @@
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
<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>
<section
class=
"video-player"
>
<div
id=
"id"
></div>
...
...
@@ -29,7 +29,7 @@
</div>
<div
class=
"focus_grabber last"
></div>
<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-download-video"
>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_hls.html
View file @
e7486528
...
...
@@ -11,7 +11,7 @@
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
<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"
>
<div
id=
"id"
></div>
<h4
class=
"hd hd-4 video-hls-error is-hidden"
>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_html5.html
View file @
e7486528
...
...
@@ -11,7 +11,7 @@
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
<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"
>
<div
id=
"id"
></div>
</section>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_no_captions.html
View file @
e7486528
...
...
@@ -11,7 +11,7 @@
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
<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"
>
<iframe
id=
"id"
></iframe>
</section>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_with_bumper.html
View file @
e7486528
...
...
@@ -13,7 +13,7 @@
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
<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>
<section
class=
"video-player"
>
<iframe
id=
"id"
></iframe>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_yt_multiple.html
View file @
e7486528
...
...
@@ -11,7 +11,7 @@
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
<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>
<section
class=
"video-player"
>
<iframe
id=
"id1"
></iframe>
...
...
common/lib/xmodule/xmodule/js/spec/video/video_player_spec.js
View file @
e7486528
...
...
@@ -5,10 +5,13 @@
[
'video/03_video_player.js'
,
'hls'
],
function
(
VideoPlayer
,
HLS
)
{
describe
(
'VideoPlayer'
,
function
()
{
var
state
,
oldOTBD
,
empty_arguments
;
var
STATUS
=
window
.
STATUS
,
state
,
oldOTBD
,
emptyArguments
;
(
function
()
{
empty
_a
rguments
=
arguments
;
empty
A
rguments
=
arguments
;
})();
beforeEach
(
function
()
{
...
...
@@ -219,8 +222,8 @@ function(VideoPlayer, HLS) {
});
it
(
'trigger pause and ended events'
,
function
()
{
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'pause'
,
empty
_a
rguments
);
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'ended'
,
empty
_a
rguments
);
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'pause'
,
empty
A
rguments
);
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'ended'
,
empty
A
rguments
);
});
});
});
...
...
@@ -242,7 +245,7 @@ function(VideoPlayer, HLS) {
});
it
(
'pause the video caption'
,
function
()
{
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'pause'
,
empty
_a
rguments
);
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'pause'
,
empty
A
rguments
);
});
});
...
...
@@ -281,7 +284,7 @@ function(VideoPlayer, HLS) {
});
it
(
'play the video caption'
,
function
()
{
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'play'
,
empty
_a
rguments
);
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'play'
,
empty
A
rguments
);
});
});
...
...
@@ -314,7 +317,7 @@ function(VideoPlayer, HLS) {
});
it
(
'pause the video caption'
,
function
()
{
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'pause'
,
empty
_a
rguments
);
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'pause'
,
empty
A
rguments
);
});
});
...
...
@@ -334,7 +337,7 @@ function(VideoPlayer, HLS) {
});
it
(
'pause the video caption'
,
function
()
{
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'ended'
,
empty
_a
rguments
);
expect
(
$
.
fn
.
trigger
).
toHaveBeenCalledWith
(
'ended'
,
empty
A
rguments
);
});
});
});
...
...
@@ -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
));
common/lib/xmodule/xmodule/js/src/video/02_html5_video.js
View file @
e7486528
...
...
@@ -212,22 +212,26 @@ function(_) {
this
.
playerState
=
HTML5Video
.
PlayerState
.
PAUSED
;
if
(
$
.
isFunction
(
this
.
config
.
events
.
onReady
))
{
this
.
config
.
events
.
onReady
(
null
);
this
.
videoOverlayEl
.
removeClass
(
'is-hidden'
);
}
};
Player
.
prototype
.
onPlay
=
function
()
{
this
.
playerState
=
HTML5Video
.
PlayerState
.
BUFFERING
;
this
.
callStateChangeCallback
();
this
.
videoOverlayEl
.
addClass
(
'is-hidden'
);
};
Player
.
prototype
.
onPlaying
=
function
()
{
this
.
playerState
=
HTML5Video
.
PlayerState
.
PLAYING
;
this
.
callStateChangeCallback
();
this
.
videoOverlayEl
.
addClass
(
'is-hidden'
);
};
Player
.
prototype
.
onPause
=
function
()
{
this
.
playerState
=
HTML5Video
.
PlayerState
.
PAUSED
;
this
.
callStateChangeCallback
();
this
.
videoOverlayEl
.
removeClass
(
'is-hidden'
);
};
Player
.
prototype
.
onEnded
=
function
()
{
...
...
@@ -244,7 +248,7 @@ function(_) {
'durationchange'
,
'volumechange'
],
self
=
this
,
errorMessage
;
callback
;
this
.
config
=
config
;
this
.
logs
=
[];
...
...
@@ -257,6 +261,9 @@ function(_) {
// Get the jQuery object and set error event handlers
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
// determine what the video is currently doing.
this
.
playerState
=
HTML5Video
.
PlayerState
.
UNSTARTED
;
...
...
@@ -265,7 +272,7 @@ function(_) {
// Attach a 'click' event on the <video> element. It will cause the
// video to pause/play.
this
.
videoEl
.
on
(
'click'
,
function
()
{
callback
=
function
()
{
var
PlayerState
=
HTML5Video
.
PlayerState
;
if
(
self
.
playerState
===
PlayerState
.
PLAYING
)
{
...
...
@@ -275,7 +282,9 @@ function(_) {
self
.
playerState
=
PlayerState
.
PLAYING
;
self
.
playVideo
();
}
});
};
this
.
videoEl
.
on
(
'click'
,
callback
);
this
.
videoOverlayEl
.
on
(
'click'
,
callback
);
this
.
debug
=
false
;
$
.
each
(
events
,
function
(
index
,
eventName
)
{
...
...
lms/templates/video.html
View file @
e7486528
...
...
@@ -21,7 +21,7 @@ from openedx.core.djangolib.js_utils import js_escaped_string
<div
class=
"tc-wrapper"
>
<div
class=
"video-wrapper"
>
<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"
>
<div
id=
"${id}"
></div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment