1
0
mirror of https://github.com/videojs/video.js.git synced 2024-12-21 01:39:04 +02:00

Created site.

This commit is contained in:
Steve Heffernan 2010-05-18 17:23:19 -07:00
parent 4f14efb288
commit 368aab9d74
22 changed files with 696 additions and 36 deletions

34
demo.html Normal file
View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>HTML5 Video Player</title>
<script src="video.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
var bodyLoaded = function(){
VideoJS.setup();
}
</script>
<link rel="stylesheet" href="video-js.css" type="text/css" media="screen" title="Video JS" charset="utf-8">
</head>
<body id="body" onload="bodyLoaded()">
<div class="video-box">
<!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody -->
<video id="video" class="video-js" width="640" height="360" poster="http://zencoder-demo.s3.amazonaws.com/poster.jpg" autobuffer>
<source src="http://zencoder-demo.s3.amazonaws.com/trailer_test.mp4" type="video/mp4"></source>
<source src="http://zencoder-demo.s3.amazonaws.com/trailer_test.ogg" type="video/ogg"></source>
<object width="640" height="360" type="application/x-shockwave-flash"
data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
<param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
<param name="allowfullscreen" value="true" />
<param name="flashvars" value='config={"clip":"http://zencoder-demo.s3.amazonaws.com/trailer_test.mp4"}' />
<img src="http://zencoder-demo.s3.amazonaws.com/poster.jpg" width="640" height="360" alt="Poster Image" title="No video playback capabilities." />
</object>
</video>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

BIN
images/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

BIN
images/footer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
images/icons/check.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
images/icons/chrome.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
images/icons/firefox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
images/icons/h264.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
images/icons/ie.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
images/icons/ipad.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
images/icons/iphone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
images/icons/ogg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/icons/opera.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
images/icons/safari.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
images/icons/tar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
images/icons/webm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/icons/zip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,40 +1,129 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8" />
<title>Video JS | HTML5 Video Player</title>
<script src="video-js/video.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
<title>zencoder/video-js @ GitHub</title>
<style type="text/css">
body {
margin-top: 1.0em;
background-color: #920e14;
font-family: "Helvetica,Arial,FreeSans";
color: #ffffff;
var bodyLoaded = function(){
VideoJS.setup();
}
#container {
margin: 0 auto;
width: 700px;
}
h1 { font-size: 3.8em; color: #6df1eb; margin-bottom: 3px; }
h1 .small { font-size: 0.4em; }
h1 a { text-decoration: none }
h2 { font-size: 1.5em; color: #6df1eb; }
h3 { text-align: center; color: #6df1eb; }
a { color: #6df1eb; }
.description { font-size: 1.2em; margin-bottom: 30px; margin-top: 30px; font-style: italic;}
.download { float: right; }
pre { background: #000; color: #fff; padding: 15px;}
hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
.footer { text-align:center; padding-top:30px; font-style: italic; }
</style>
</script>
<link rel="stylesheet" href="stylesheets/base.css" type="text/css" media="all" charset="utf-8" />
<link rel="stylesheet" href="video-js/video-js.css" type="text/css" media="all" charset="utf-8" />
<link rel="stylesheet" href="stylesheets/site.css" type="text/css" media="all" charset="utf-8" />
<!--[if !IE 7]>
<style type="text/css">
#wrap {display:table;height:100%}
</style>
<![endif]-->
</head>
<body onload="bodyLoaded()">
<body>
<a href="http://github.com/zencoder/video-js"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
<div id="wrap">
<div id="main">
<ul id="nav">
<li><a href="http://github.com/zencoder/video-js">Source</a></li>
<li><a href="http://github.com/zencoder/video-js/issues">Issue Tracker</a></li>
<li><a href="http://wiki.github.com/zencoder/video-js/">Wiki</a></li>
</ul>
<h1>Video JS</h1>
<p class="tagline">Open Source HTML5 Video Player</p>
<div class="video-box">
<!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody -->
<video id="video" class="video-js" width="640" height="264" poster="http://zencoder-demo.s3.amazonaws.com/poster.jpg" autobuffer>
<source src="http://video-js.s3.amazonaws.com/oceans-clip.mp4" type="video/mp4"></source>
<source src="http://video-js.s3.amazonaws.com/oceans-clip.ogg" type="video/ogg"></source>
<source src="http://video-js.s3.amazonaws.com/oceans-clip.webm" type="video/webm"></source>
<object width="640" height="264" type="application/x-shockwave-flash"
data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
<param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
<param name="allowfullscreen" value="true" />
<param name="flashvars" value='config={"clip":"http://video-js.s3.amazonaws.com/oceans-clip.mp4"}' />
<img src="http://zencoder-demo.s3.amazonaws.com/poster.jpg" width="640" height="264" alt="Poster Image" title="No video playback capabilities." />
</object>
</video>
</div>
<p id="video_note">Video clip is from <a href="http://disney.go.com/disneynature/oceans/" title="Oceans">Disney&rsquo;s Oceans</a></p>
<p>Video JS is a javascript-based video player that uses the HTML5 video functionality built into advanced browsers. In general, the benefit of using and HTML5 player is a consisten look between browsers.</p>
<div id="features_and_support">
<div id="features">
<h6>Features</h6>
<ul id="feature_list">
<li>Free &amp; Open Source</li>
<li>Lightweight. <strong>NO IMAGES USED</strong></li>
<li>100% skinnable using CSS</li>
<li>Library independant</li>
<li>Easy to use</li>
<li>Easy to understand &amp; extend</li>
<li>Consistent look between browsers</li>
<li>Full Window Mode</li>
<li>Volume Control</li>
<li></li>
</ul>
</div>
<div id="supported" class="clearfix">
<h6>Download</h6>
<div class="supported-section">
<a href="http://github.com/zencoder/video-js/zipball/master" title="Zip Download"><img src="images/icons/zip.png" alt="Zip Download"></a>
<a href="http://github.com/zencoder/video-js/tarball/master" title="Tar Download"><img src="images/icons/tar.png" alt="Tar Download"></a>
</div>
<h6>Supported Browsers</h6>
<div class="supported-section">
<a href="http://www.mozilla.com/en-US/firefox/firefox.html" title="Firefox"><img src="images/icons/firefox.png" alt="Firefox"></a>
<a href="http://www.apple.com/safari/" title="Safari"><img src="images/icons/safari.png" alt="Safari"></a>
<a href="http://www.google.com/chrome" title="Chrome"><img src="images/icons/chrome.png" alt="Chrome"></a>
</div>
<h6>Fallback Support For</h6>
<div class="supported-section">
<a href="http://www.microsoft.com/windows/Internet-explorer/default.aspx" title="IE"><img src="images/icons/ie.png" alt="IE"></a>
<a href="http://www.opera.com/" title="Opera"><img src="images/icons/opera.png" alt="Opera"></a>
</div>
<h6>Supported Formats</h6>
<div class="supported-section">
<a href="http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC" title="h264"><img src="images/icons/h264.png" alt="h264"></a>
<a href="http://www.theora.org/" title="Ogg"><img src="images/icons/ogg.png" alt="Ogg"></a>
<a href="http://www.webmproject.org/" title="WebM"><img src="images/icons/webm.png" alt="WebM"></a>
</div>
<h6>Compatible With</h6>
<div class="supported-section">
<a href="http://www.apple.com/iphone/" title="iPhone"><img src="images/icons/iphone.png" alt="iPhone"></a>
<a href="http://www.apple.com/ipad/" title="iPad"><img src="images/icons/ipad.png" alt="iPad"></a>
</div>
</div>
<div id="disqus_thread"></div>
<script type="text/javascript">
/**
* var disqus_identifier; [Optional but recommended: Define a unique identifier (e.g. post id or slug) for this thread]
*/
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://videojs.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript=videojs">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</div>
</div>
<div id="footer">
Hosting &amp; Repository supplied by Zencoder - <a href="http://zencoder.com">Video encoding for your app</a>.
</div>
</div>
<!-- <a href="http://github.com/zencoder/video-js"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
<div id="container">
@ -52,8 +141,6 @@
Universal video embed.
</div>
<h2>Download</h2>
<p>
You can download this project in either
@ -69,8 +156,22 @@
get the source code on GitHub : <a href="http://github.com/zencoder/video-js">zencoder/video-js</a>
</div>
</div>
</div> -->
<script type="text/javascript">
//<![CDATA[
(function() {
var links = document.getElementsByTagName('a');
var query = '?';
for(var i = 0; i < links.length; i++) {
if(links[i].href.indexOf('#disqus_thread') >= 0) {
query += 'url' + i + '=' + encodeURIComponent(links[i].href) + '&';
}
}
document.write('<script charset="utf-8" type="text/javascript" src="http://disqus.com/forums/videojs/get_num_replies.js' + query + '"></' + 'script>');
})();
//]]>
</script>
</body>
</html>

51
stylesheets/base.css Normal file
View File

@ -0,0 +1,51 @@
/* Reset - http://developer.yahoo.com/yui/3/cssreset/
---------------------------------------------------------*/
html{ color:#000; background:#FFF; }
body { line-height: 1; }
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,label,input,textarea,p,blockquote,th,td { margin:0; padding:0; }
table { border-collapse:collapse; border-spacing:0; }
fieldset,img { border:0; }
address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; }
li { list-style:none; }
caption,th { text-align:left; }
h1,h2,h3,h4,h5,h6 { font-size:100%; font-weight:normal; }
q:before,q:after { content:''; }
abbr,acronym { border:0; font-variant:normal; }
sup { vertical-align:text-top; }
sub { vertical-align:text-bottom; }
input,textarea,select { font-family:inherit; font-size:inherit; font-weight:inherit; }
input,textarea,select { *font-size:100%; }
legend { color:#000; }
/* Base - http://developer.yahoo.com/yui/3/cssbase/
---------------------------------------------------------*/
h1 { font-size:138.5%; }
h2 { font-size:123.1%; }
h3 { font-size:108%; }
h1,h2,h3 { margin:0 0 1em; }
h1,h2,h3,h4,h5,h6,strong { font-weight:bold; }
abbr,acronym { border-bottom:1px dotted #000; cursor:help; }
em { font-style:italic; }
blockquote,ul,ol,dl { margin-bottom:1em; }
ol,ul,dl { margin-left:2em; }
ol li { list-style:decimal outside; }
ul li { list-style:disc outside; }
dl dd { margin-left:1em; }
th,td { border:1px solid #000; padding: 0; }
th { font-weight:bold; text-align:center; }
caption { margin-bottom:.5em; text-align:center; }
p,fieldset,table,pre { margin-bottom:1em; }
input[type=text],input[type=password],textarea { width:12.25em; *width:11.9em; background-color: #fff; }
/* Fonts - http://developer.yahoo.com/yui/3/cssfonts/
---------------------------------------------------------*/
html { font:13px/1.231 arial,helvetica,clean,sans-serif; *font-size:small; *font:x-small; }
select,input,button,textarea { font:119% arial,helvetica,clean,sans-serif; }
table { font-size:inherit; font:100%; }
pre,code,kbd,samp,tt { font-family:monospace; *font-size:108%; line-height:100%; }
/* Clear Fix - http://perishablepress.com/press/2009/12/06/new-clearfix-hack/
---------------------------------------------------------*/
.clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }
* html .clearfix { zoom: 1; } /* IE6 */
*:first-child+html .clearfix { zoom: 1; } /* IE7 */

31
stylesheets/site.css Normal file
View File

@ -0,0 +1,31 @@
html { background: #152B38 url('../images/background.png') top left repeat-x; }
body { font-size: 10px; line-height: 1; color: #fff; text-align: center; }
#wrap { background: url("../images/background-highlights.png") center 20px no-repeat; }
#main { position: relative; width: 640px; margin: 0px auto; text-align: left; padding-bottom: 20px; }
h1 { font-size: 360%; line-height: 1; margin-bottom: 10px; text-align: center; letter-spacing: 5px; }
h6 { font-size: 100%; text-transform: uppercase; margin-bottom: 10px; color: #999; }
p.tagline { text-align: center; font-size: 120%; line-height: 1; }
p { font-size: 1.4em; line-height: 1.5; margin-bottom: 20px; }
a { color: #fff; }
a img { border: 0; }
ul#nav { list-style: none; margin: 0; padding: 0; height: 20px; text-align: right; margin-bottom: 20px; }
ul#nav li { display: inline; list-style: none; margin: 0; padding: 0; padding-left: 20px; font-size: 120%; line-height: 20px; }
ul#nav li a { color: #fff; text-decoration: none; }
.video-box { margin-bottom: 0; background-color: #000; }
p#video_note { margin-bottom: 20px; font-size: 100%; line-height: 20px; color: #999; text-align: center; }
#features { width: 300px; float: left; }
ul#feature_list { display: block; margin: 0; padding: 0; }
ul#feature_list li { list-style: none; padding-left: 25px; font-size: 140%; line-height: 20px; margin-bottom: 25px; background: url("../images/icons/check.png") left top no-repeat; }
#supported { float: right; width: 320px; }
.supported-section { margin-bottom: 20px; }
.supported-section a { padding-right: 10px; }
.supported-section a:last-child { padding-right: 0; }
#disqus_thread { clear: both; }
#footer { clear: both; }

54
video-js/video-js.css Normal file
View File

@ -0,0 +1,54 @@
.video-box { text-align: left; position: relative; }
.video-js { background-color: #000; }
/* General controls styles */
.vjs-controls { display: none; list-style: none; margin: 0; padding: 0; position: absolute; height: 30px; opacity: 0.85; color: #fff; }
.vjs-controls > li { list-style: none; float: left; height: 25px; width: 25px; margin: 0 5px 0 0; padding: 0; text-align: center;
background-color: #0B151A; border-radius: 5px; box-shadow: 0px 2px 2px #000;
/* Webkit */
-webkit-border-radius: 5px;
background: #1F3744 -webkit-gradient(linear, left top, left bottom, from(#0B151A), to(#1F3744)) left 12px;
-webkit-box-shadow: 0px 1px 3px #000;
/* Firefox */
-moz-border-radius: 5px;
background: #1F3744 -moz-linear-gradient(top, #0B151A, #1F3744) left 12px;
-moz-box-shadow: 0px 1px 3px #000;
}
.vjs-controls > li:last-child { margin-right: 0; }
.vjs-controls > li:first-child { margin-left: 5px; }
/* Play/Pause */
.vjs-play-control span { display: block; font-size: 0px; line-height: 0; text-decoration: none; }
.vjs-play-control.vjs-play span { width: 0; height: 0; margin: 8px 0 0 8px; border-top: 5px solid #273F3E; border-left: 10px solid #fff; border-bottom: 5px solid #273F3E; }
.vjs-play-control.vjs-pause span { width: 3px; height: 10px; margin: 8px auto 0; border-top: 0px; border-left: 3px solid #fff; border-bottom: 0px; border-right: 3px solid #fff; }
/* Progress */
.vjs-progress-control { width: 190px; }
.vjs-progress-control ul { list-style: none; margin: 0; padding: 0; }
.vjs-progress-control .vjs-progress-holder { list-style: none; position: relative; float: left; width: 100px; height: 9px; border: 1px solid #777; margin: 7px 0 0 5px; padding: 0; background-color: #112129; overflow:hidden; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }
.vjs-progress-control .vjs-play-progress { position: absolute; display: block; width: 0px; height: 9px; background-color: #fff; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }
.vjs-progress-control .vjs-load-progress { position: absolute; display: block; width: 0px; height: 9px; background-color: #777; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }
.vjs-progress-control .vjs-progress-time { list-style: none; float: left; margin: 7px 0 0 5px; padding: 0; font-size: 10px; line-height: 1; font-weight: normal; font-family: Helvetica, Arial, sans-serif; }
/* Volume */
.vjs-volume-control { width: 50px !important; }
.vjs-volume-control ul { display: block; margin: 0; padding: 4px 0 0 5px; list-style: none; }
.vjs-volume-control ul li { float: left; margin: 0; padding: 0; list-style: none; width: 5px; margin-right: 2px; height: 0px; border-bottom: 18px solid #555; }
.vjs-volume-control ul li:nth-child(1) { border-bottom-width: 2px; height: 16px; }
.vjs-volume-control ul li:nth-child(2) { border-bottom-width: 4px; height: 14px; }
.vjs-volume-control ul li:nth-child(3) { border-bottom-width: 7px; height: 11px; }
.vjs-volume-control ul li:nth-child(4) { border-bottom-width: 10px; height: 8px; }
.vjs-volume-control ul li:nth-child(5) { border-bottom-width: 14px; height: 4px; }
/* Fullscreen */
.vjs-fullscreen-control ul { list-style: none; margin: 5px 0 0 5px; padding: 0; width: 20px; height: 20px; text-align: left; vertical-align: top; }
.vjs-fullscreen-control ul li { list-style: none; float: left; margin: 0; padding: 0; font-size: 0; line-height: 0; width: 0; text-align: left; vertical-align: top; }
.vjs-fullscreen-control ul li:nth-child(1) { margin: 0 3px 3px 0; border: none; border-top: 6px solid #fff; border-right: 6px solid #273F3E; }
.vjs-fullscreen-control ul li:nth-child(2) { border: none; border-top: 6px solid #fff; border-left: 6px solid #273F3E; }
.vjs-fullscreen-control ul li:nth-child(3) { clear: both; margin: 0 3px 0 0; border: none; border-bottom: 6px solid #fff; border-right: 6px solid #112129; }
.vjs-fullscreen-control ul li:nth-child(4) { border: none; border-bottom: 6px solid #fff; border-left: 6px solid #112129; }
.vjs-fullscreen-control.vjs-fs-active ul li:nth-child(1) { border: none; border-bottom: 6px solid #fff; border-left: 6px solid #273F3E; }
.vjs-fullscreen-control.vjs-fs-active ul li:nth-child(2) { border: none; border-bottom: 6px solid #fff; border-right: 6px solid #273F3E; }
.vjs-fullscreen-control.vjs-fs-active ul li:nth-child(3) { border: none; border-top: 6px solid #fff; border-left: 6px solid #112129; }
.vjs-fullscreen-control.vjs-fs-active ul li:nth-child(4) { border: none; border-top: 6px solid #fff; border-right: 6px solid #112129; }

389
video-js/video.js Normal file
View File

@ -0,0 +1,389 @@
// Using jresig's Class implementation http://ejohn.org/blog/simple-javascript-inheritance/
(function(){var initializing=false, fnTest=/xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; this.Class = function(){}; Class.extend = function(prop) { var _super = this.prototype; initializing = true; var prototype = new this(); initializing = false; for (var name in prop) { prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn){ return function() { var tmp = this._super; this._super = _super[name]; var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } function Class() { if ( !initializing && this.init ) this.init.apply(this, arguments); } Class.prototype = prototype; Class.constructor = Class; Class.extend = arguments.callee; return Class;};})();
// Store a list of players on the page for reference by event listeners
var videoJSPlayers = new Array();
// Video JS Player Class
var VideoJS = Class.extend({
// Initialize the player for the supplied video tag element
// element: video tag
// num: the current player's position in the videoJSPlayers array
init: function(element, num){
this.video = element;
// Default the player number to 0
this.num = (num) ? num : 0;
this.buildController();
this.showController(); // has to come before positioning
this.positionController();
// Listen for clicks on the play/pause button
this.playControl.addEventListener("click", this.onPlayControlClick, true);
// Listen for drags on the progress bar
this.progressHolder.addEventListener("mousedown", this.onProgressHolderMouseDown, true);
// Listen for a release on the progress bar
this.progressHolder.addEventListener("mouseup", this.onProgressHolderMouseUp, true);
// Listen for a drag on the volume control
this.volumeControl.addEventListener("mousedown", this.onVolumeControlMouseDown, true);
// Listen for a release on the volume control
this.volumeControl.addEventListener("mouseup", this.onVolumeControlMouseUp, true);
// Set the display to the initial volume
this.updateVolumeDisplay();
// Listen for clicks on the fullscreen button
this.fullscreenControl.addEventListener("click", this.onFullscreenControlClick, true);
},
buildController: function(){
/* Creating this HTML
<ul class="vjs-controls">
<li class="vjs-play-control vjs-play">
<span></span>
</li>
<li class="vjs-progress-control">
<ul>
<li class="vjs-progress-holder">
<span class="vjs-load-progress"></span><span class="vjs-play-progress"></span>
</li>
<li class="vjs-progress-time">
<span class="vjs-current-time-display">00:00</span> / <span class="vjs-duration-display">00:00</span>
</li>
</ul>
</li>
<li class="vjs-volume-control">
<ul>
<li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
</li>
<li class="vjs-fullscreen-control">
<ul>
<li></li><li></li><li></li><li></li>
</ul>
</li>
</ul>
*/
// Create a list element to hold the different controls
this.controls = document.createElement("ul");
// Add the controls to the video's container
this.video.parentNode.appendChild(this.controls);
this.controls.className = "vjs-controls";
// Store the current video player's number
// For referencing in event listeners
this.controls.setAttribute("data-video-js", this.num);
// Build the play control
this.playControl = document.createElement("li");
this.controls.appendChild(this.playControl);
this.playControl.className = "vjs-play-control vjs-play";
this.playControl.innerHTML = "<span></span>";
// Build the progress control
this.progressControl = document.createElement("li");
this.controls.appendChild(this.progressControl);
this.progressControl.className = "vjs-progress-control";
// Create a list for the different progress elements
this.progressList = document.createElement("ul");
this.progressControl.appendChild(this.progressList);
// Create a holder for the progress bars
this.progressHolder = document.createElement("li");
this.progressList.appendChild(this.progressHolder);
this.progressHolder.className = "vjs-progress-holder";
// Create the loading progress display
this.loadProgress = document.createElement("span");
this.progressHolder.appendChild(this.loadProgress)
this.loadProgress.className = "vjs-load-progress";
// Create the playing progress display
this.playProgress = document.createElement("span");
this.progressHolder.appendChild(this.playProgress);
this.playProgress.className = "vjs-play-progress";
// Create the progress time display (00:00 / 00:00)
this.progressTime = document.createElement("li");
this.progressList.appendChild(this.progressTime);
this.progressTime.className = "vjs-progress-time";
// Create the current play time display
this.currentTimeDisplay = document.createElement("span");
this.progressTime.appendChild(this.currentTimeDisplay);
this.currentTimeDisplay.className = "vjs-current-time-display";
this.currentTimeDisplay.innerHTML = '00:00';
// Adding a slash for visual separation
this.progressTime.innerHTML += " / ";
// Create the total duration display
this.durationDisplay = document.createElement("span");
this.progressTime.appendChild(this.durationDisplay);
this.durationDisplay.className = "vjs-duration-display";
this.durationDisplay.innerHTML = '00:00';
// Create the volumne control
this.volumeControl = document.createElement("li");
this.controls.appendChild(this.volumeControl);
this.volumeControl.className = "vjs-volume-control";
this.volumeControl.innerHTML = "<ul><li></li><li></li><li></li><li></li><li></li><li></li></ul>";
this.volumeDisplay = this.volumeControl.children[0]
// Crete the fullscreen control
this.fullscreenControl = document.createElement("li");
this.controls.appendChild(this.fullscreenControl);
this.fullscreenControl.className = "vjs-fullscreen-control";
this.fullscreenControl.innerHTML = "<ul><li></li><li></li><li></li><li></li></ul>";
},
// Show the controller
showController: function(){
this.controls.style.display = "block";
},
// Place controller relative to the video's position
positionController: function(){
this.controls.style.top = (this.video.offsetHeight - this.controls.offsetHeight) + "px";
this.controls.style.left = "0px";
this.controls.style.width = this.video.offsetWidth + "px";
this.sizeProgressBar();
},
// Hide the controller
hideController: function(){
this.controls.style.display = "none";
},
// React to clicks on the play/pause button
onPlayControlClick: function(e){
var player = videoJSPlayers[this.parentNode.getAttribute("data-video-js")];
if (player.video.paused) {
player.playVideo();
} else {
player.pauseVideo();
}
},
// Adjust the play position when the user drags on the progress bar
onProgressHolderMouseDown: function(e){
var player = videoJSPlayers[this.parentNode.parentNode.parentNode.getAttribute("data-video-js")];
player.stopTrackingPlayProgress();
if (player.video.paused) {
player.videoWasPlaying = false;
} else {
player.videoWasPlaying = true;
player.video.pause();
}
player.blockTextSelection();
document.onmousemove = function(e) {
player.setPlayProgress(e.pageX);
}
document.onmouseup = function() {
player.unblockTextSelection();
document.onmousemove = null;
document.onmouseup = null;
if (player.videoWasPlaying) {
player.video.play();
player.trackPlayProgress();
}
}
},
// When the user stops dragging on the progress bar, update play position
// Backup for when the user only clicks and doesn't drag
onProgressHolderMouseUp: function(e){
var player = videoJSPlayers[this.parentNode.parentNode.parentNode.getAttribute("data-video-js")];
player.setPlayProgress(e.pageX);
},
// Adjust the volume when the user drags on the volume control
onVolumeControlMouseDown: function(e){
var player = videoJSPlayers[this.parentNode.getAttribute("data-video-js")];
player.blockTextSelection();
document.onmousemove = function(e) {
player.setVolume(e.pageX);
}
document.onmouseup = function() {
player.unblockTextSelection();
document.onmousemove = null;
document.onmouseup = null;
}
},
// When the user stops dragging, set a new volume
// Backup for when the user only clicks and doesn't drag
onVolumeControlMouseUp: function(e){
var player = videoJSPlayers[this.parentNode.getAttribute("data-video-js")];
player.setVolume(e.pageX);
},
// When the user clicks on the fullscreen button, update fullscreen setting
onFullscreenControlClick: function(e){
var player = videoJSPlayers[this.parentNode.getAttribute("data-video-js")];
if (!player.videoIsFullScreen) {
player.fullscreenOn();
} else {
player.fullscreenOff();
}
},
// Play the video
playVideo: function(){
this.video.play();
this.playControl.className = "vjs-play-control vjs-pause";
this.trackPlayProgress();
},
// Pause the video
pauseVideo: function(){
this.video.pause();
this.playControl.className = "vjs-play-control vjs-play";
this.stopTrackingPlayProgress();
},
// Adjust the width of the progress bar to fill the controls width
sizeProgressBar: function(){
this.progressControl.style.width = (this.controls.offsetWidth - 125) + "px";
this.progressHolder.style.width = (this.progressControl.offsetWidth - 80) + "px";
this.updatePlayProgress();
},
// Track & display the current play progress
trackPlayProgress: function(){
context = this;
this.playProgressInterval = setInterval(function(){ context.updatePlayProgress(); }, 33);
},
// Turn off play progress tracking (when paused)
stopTrackingPlayProgress: function(){
clearInterval(this.playProgressInterval);
},
// Ajust the play progress bar's width based on the current play time
updatePlayProgress: function(){
this.playProgress.style.width = ((this.video.currentTime / this.video.duration) * (this.progressHolder.offsetWidth - 2)) + "px";
this.updateTimeDisplay();
},
// Update the play position based on where the user clicked on the progresss bar
setPlayProgress: function(clickX) {
var newPercent = Math.max(0, Math.min(1, (clickX - this.findPosX(this.progressHolder)) / this.progressHolder.offsetWidth));
this.video.currentTime = newPercent * this.video.duration
this.playProgress.style.width = newPercent * (this.progressHolder.offsetWidth - 2) + "px";
this.updateTimeDisplay();
},
// Update the displayed time (00:00)
updateTimeDisplay: function(){
this.currentTimeDisplay.innerHTML = this.formatTime(this.video.currentTime);
if (this.video.duration) this.durationDisplay.innerHTML = this.formatTime(this.video.duration);
},
// Set a new volume based on where the user clicked on the volume control
setVolume: function(clickX) {
var newVol = (clickX - this.findPosX(this.volumeControl)) / this.volumeControl.offsetWidth;
if (newVol > 1) {
newVol = 1;
} else if (newVol < 0) {
newVol = 0;
}
this.video.volume = newVol;
this.updateVolumeDisplay();
},
// Update the volume control display
// Unique to these default controls. Uses borders to create the look of bars.
updateVolumeDisplay: function(){
var volNum = Math.floor(this.video.volume * 6);
for(var i=0; i<6; i++) {
if (i < volNum) {
this.volumeDisplay.children[i].style.borderColor = "#fff";
} else {
this.volumeDisplay.children[i].style.borderColor = "#555";
}
}
},
// Turn on fullscreen (window) mode
// Real fullscreen isn't available in browsers quite yet.
fullscreenOn: function(){
this.videoIsFullScreen = true;
this.videoOrigWidth = this.video.offsetWidth;
this.videoOrigHeight = this.video.offsetHeight;
this.video.style.width = window.innerWidth + "px";
this.video.style.height = window.innerHeight + "px";
this.video.style.position = "fixed";
this.video.style.left = 0;
this.video.style.top = 0;
this.controls.style.position = "fixed";
this.positionController();
this.fullscreenControl.className = "vjs-fullscreen-control vjs-fs-active";
},
// Turn off fullscreen (window) mode
fullscreenOff: function(){
this.videoIsFullScreen = false;
this.video.style.width = this.videoOrigWidth + "px";
this.video.style.height = this.videoOrigHeight + "px";
this.video.style.position = "static";
this.controls.style.position = "absolute";
this.positionController();
this.fullscreenControl.className = "vjs-fullscreen-control";
},
// Attempt to block the ability to select text while dragging controls
blockTextSelection: function(){
document.body.focus();
document.onselectstart = function () { return false; };
},
// Turn off text selection blocking
unblockTextSelection: function(){
document.onselectstart = function () { return true; };
},
// Return seconds as MM:SS
formatTime: function(seconds) {
seconds = Math.round(seconds);
minutes = Math.floor(seconds / 60);
minutes = (minutes >= 10) ? minutes : "0" + minutes;
seconds = Math.floor(seconds % 60);
seconds = (seconds >= 10) ? seconds : "0" + seconds;
return minutes + ":" + seconds;
},
// Get an objects position on the page
findPosX: function(obj) {
var curleft = obj.offsetLeft;
while(obj = obj.offsetParent) {
curleft += obj.offsetLeft;
}
return curleft;
}
})
// Class Methods
// Add video-js to any video tag with the class
VideoJS.setup = function(){
var videoTags = document.getElementsByTagName("video");
for (var i=0;i<videoTags.length;i++) {
if (videoTags[i].className.indexOf("video-js") != -1) {
videoJSPlayers[i] = new VideoJS(document.getElementById("video"), i);
}
}
}