Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Updated api and setup docs

  • Loading branch information...
commit 7ef5b15ae27f4aa9077e037e9f2a12b73a1a08b4 1 parent 9678c77
@heff heff authored
View
2  build/Create Release Notes.md
@@ -1,2 +0,0 @@
-Tagging a Release
-git tag -a v[version number] [commit]
View
24 build/Versioning Notes.md
@@ -0,0 +1,24 @@
+Version Numbers
+---------------
+http://en.wikipedia.org/wiki/Software_versioning#Sequence-based_identifiers
+
+### Major Version (Integer, e.g 3.0)
+- Any features where we expect it could break plugins, skins, or any major API integration.
+
+### Minor Version (3.1)
+- Additional non-breaking features
+
+### Revision Versions
+
+- Beta (3.1-b1)
+- Release Candidate (3.1-rc1)
+- Release with revisions (3.1-r1)
+
+Notes:
+The last level of one revision type (beta/release candidate) should match the first level of the next revision type. 4.0-b10 should match 4.0-rc1, assuming b10 is the last beta version.
+
+Release revisions means bug fixes. The CDN url should not reflect the revision number. 4.0-r2 would still be /4.0/.
+
+Tagging a Release
+-----------------
+git tag -a v[version number] [commit]
View
1  compare/compare.js
@@ -1,4 +1,5 @@
_V_.options.flash.swf = "../flash/video-js.swf";
+_V_.options.flash.swf = "http://andylemay.com/dev/videojs/VideoJS.swf";
$(function(){
var tech, i, tname, player,
View
369 design/tube.css
@@ -1,369 +0,0 @@
-/*
-VideoJS YouTube Skin (http://videojs.com)
-Version 3.0
-
-REQUIRED STYLES (be careful overriding)
-================================================================================ */
-/* When loading the player, the video tag is replaced with a DIV,
- that will hold the video tag or object tag for other playback methods.
- The div contains the video playback element (Flash or HTML5) and controls, and sets the width and height of the video.
-
- ** If you want to add some kind of border/padding (e.g. a frame), or special positioning, use another containing element.
- Otherwise you risk messing up control positioning and full window mode. **
-*/
-.video-js {
- background-color: #000; position: relative; padding: 0;
- /* Start with 10px for base font size so other dimensions can be em based and easily calculable. */
- font-size: 10px;
-}
-
-/* Playback technology elements expand to the width/height of the containing div. <video> or <object> */
-.video-js .vjs-tech { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
-
-/* Fullscreen Styles */
-body.vjs-full-window {
- padding: 0; margin: 0;
- height: 100%; overflow-y: auto; /* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html */
-}
-.video-js.vjs-fullscreen {
- position: fixed; overflow: hidden; z-index: 1000; left: 0; top: 0; bottom: 0; right: 0; width: 100% !important; height: 100% !important;
- _position: absolute; /* IE6 Full-window (underscore hack) */
-}
-.video-js:-webkit-full-screen {
- width: 100% !important; height: 100% !important;
-}
-.video-js:-moz-full-screen {
- width: 100% !important; height: 100% !important;
-}
-
-/* Subtiles Style */
-.video-js .vjs-subtitles { color: #fff; font-size: 20px; text-align: center; position: absolute; bottom: 40px; left: 0; right: 0; }
-
-
-
-/* The default control bar. Created by bar.js */
-.tubecss .vjs-controls {
- position: absolute;
- bottom: 0; /* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */
- left: 0; right: 0; /* 100% width of div */
- opacity: 0.85; display: block; /* Start hidden */
- margin: 0; padding: 0; /* Controls are absolutely position, so no padding necessary */
- height: 2.6em; /* Including any margin you want above or below control items */
- color: #fff; border-top: 1px solid #404040;
-
- /* CSS Gradient */
- /* Can use the Ultimate CSS Gradient Generator: http://www.colorzilla.com/gradient-editor/ */
- background: -moz-linear-gradient(top, rgba(51,51,51,0.8) 0%, rgba(0,0,0,1) 100%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(51,51,51,0.8)), color-stop(100%,rgba(0,0,0,1))); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, rgba(51,51,51,0.8) 0%,rgba(0,0,0,1) 100%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, rgba(51,51,51,0.8) 0%,rgba(0,0,0,1) 100%); /* Opera 11.10+ */
- background: -ms-linear-gradient(top, rgba(51,51,51,0.8) 0%,rgba(0,0,0,1) 100%); /* IE10+ */
- background: linear-gradient(top, rgba(51,51,51,0.8) 0%,rgba(0,0,0,1) 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cc333333', endColorstr='#000000',GradientType=0 ); /* IE6-9 */
-
- /* Fade-in using CSS Transitions */
-/* -webkit-transition: opacity 0.3s linear;
- -moz-transition: opacity 0.3s linear;
- -o-transition: opacity 0.3s linear;
- -ms-transition: opacity 0.3s linear;
- transition: opacity 0.3s linear;*/
-}
-
-/* General styles for individual controls. */
-.tubecss .vjs-control {
- position: relative; float: left;
- text-align: center; margin: 0; padding: 0;
- height: 2.6em; width: 2.6em;
-}
-
-.tubecss .vjs-control:focus {
- outline: 0;
-}
-
-/* Hide control text visually, but have it available for screenreaders: h5bp.com/v */
-.tubecss .vjs-control-text { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
-
-
-/* Play/Pause
--------------------------------------------------------------------------------- */
-.tubecss .vjs-play-control { width: 5em; cursor: pointer !important; border-left: 1px solid #333; border-right: 1px solid #222; }
-/* Play Icon */
-.tubecss.vjs-paused .vjs-play-control div { width: 15px; height: 17px; background: url('tubesprite.png'); margin: 0.5em auto 0; }
-.tubecss.vjs-paused .vjs-play-control div:hover {background: url('tubesprite.png') 0 -75px;}
-.tubecss.vjs-playing .vjs-play-control div { width: 15px; height: 17px; background: url('tubesprite.png') -25px 0; margin: 0.5em auto 0; }
-.tubecss.vjs-playing .vjs-play-control div:hover {background: url('tubesprite.png') -25px -75px;}
-
-/* Rewind
--------------------------------------------------------------------------------- */
-.tubecss .vjs-rewind-control { width: 5em; cursor: pointer !important; }
-.tubecss .vjs-rewind-control div { width: 19px; height: 16px; background: url('tubesprite.png'); margin: 0.5em auto 0; }
-
-/* Volume/Mute
--------------------------------------------------------------------------------- */
-.tubecss .vjs-mute-control { width: 3.8em; cursor: pointer !important; float: left; border-left: 1px solid #333;}
-.tubecss .vjs-mute-control div { width: 22px; height: 16px; background: url('tubesprite.png') -75px -25px; margin: 0.5em auto 0; }
-.tubecss .vjs-mute-control.vjs-vol-0 div { background: url('tubesprite.png') 0 -25px; }
-.tubecss .vjs-mute-control.vjs-vol-1 div { background: url('tubesprite.png') -25px -25px; }
-.tubecss .vjs-mute-control.vjs-vol-2 div { background: url('tubesprite.png') -50px -25px; }
-.tubecss .vjs-mute-control div:hover {background: url('tubesprite.png') -75px -100px; }
-.tubecss .vjs-mute-control.vjs-vol-0 div:hover { background: url('tubesprite.png') 0 -100px; }
-.tubecss .vjs-mute-control.vjs-vol-1 div:hover { background: url('tubesprite.png') -25px -100px; }
-.tubecss .vjs-mute-control.vjs-vol-2 div:hover { background: url('tubesprite.png') -50px -100px; }
-
-
-.tubecss .vjs-volume-control { position: absolute; top: -0.1em; left: 9em; width: 6em; padding-right: 8px; border-right: 1px solid #222;}
-.tubecss .vjs-volume-bar {
- position: relative; border-bottom: 1px solid #333; width: 6em; height: 0.6em; margin: 1em auto 0; cursor: pointer !important;
-
- -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em;
-
- background: #111; /* Old browsers */
-}
-.tubecss .vjs-volume-level {
- position: absolute; top: 0; left: 0; height: 0.6em;
-
- -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em;
-
- background: #c61003; /* Old browsers */
- background: -moz-linear-gradient(top, #c61003 0%, #840400 100%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#c61003), color-stop(100%,#840400)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #c61003 0%,#840400 100%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #c61003 0%,#840400 100%); /* Opera 11.10+ */
- background: -ms-linear-gradient(top, #c61003 0%,#840400 100%); /* IE10+ */
- background: linear-gradient(top, #c61003 0%,#840400 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c61003', endColorstr='#840400',GradientType=0 ); /* IE6-9 */
-}
-.tubecss .vjs-volume-handle {
- position: absolute; top: -0.3em; width: 0.5em; height: 1.2em; background: #696969; left: 0;
- border: none;
- border-top: 1px solid #888;
- -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em;
-}
-
-/* Progress
--------------------------------------------------------------------------------- */
-.tubecss div.vjs-progress-control {
- position: absolute;
- left: 0em; right: 0em; /* Leave room for time displays. */
- height: 1em; width: auto;
- top: -1.3em; /* Set above the rest of the controls. And leave room for 2px of borders (progress bottom and controls top). */
- border-bottom: 1px solid #1F1F1F;
- border-top: 1px solid #222;
-
- /* CSS Gradient */
- background: #111;
- -moz-opacity: 0.80;
- opacity: 0.80;
-
-
- /* 1px top shadow */
-/* -webkit-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15);*/
-}
-
-/* Box containing play and load progresses. Also acts as seek scrubber. */
-.tubecss .vjs-progress-holder {
- position: relative; cursor: pointer !important; /*overflow: hidden;*/
- padding: 0; margin: 0; /* Placement within the progress control item */
- height: 1.0em;
- -moz-border-radius: 0em; -webkit-border-radius: 0em; border-radius: 0em;
-
- /* CSS Gradient */
- background: #000
- -moz-opacity: 0.90;
- opacity: 0.90;
-
-
-}
-.tubecss .vjs-progress-holder .vjs-play-progress,
-.tubecss .vjs-progress-holder .vjs-load-progress { /* Progress Bars */
- position: absolute; display: block; height: 1.0em; margin: 0; padding: 0;
- left: 0; top: 0; /*Needed for IE6*/
- -moz-border-radius: 0em; -webkit-border-radius: 0em; border-radius: 0em;
-
- /*width: 0;*/
-}
-
-.tubecss .vjs-play-progress {
-
- background: #ff0505; /* Old browsers */
- background: -moz-linear-gradient(top, #ff0505 0%, #9b0000 100%); /* FF3.6+ */
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff0505), color-stop(100%,#9b0000)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #ff0505 0%,#9b0000 100%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #ff0505 0%,#9b0000 100%); /* Opera 11.10+ */
- background: -ms-linear-gradient(top, #ff0505 0%,#9b0000 100%); /* IE10+ */
- background: linear-gradient(top, #ff0505 0%,#9b0000 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0505', endColorstr='#9b0000',GradientType=0 ); /* IE6-9 */
-}
-
-.tubecss .vjs-load-progress {
- background: #999;
-}
-
-.tubecss div.vjs-seek-handle {
- position: absolute;
- width: 16px; height: 16px; /* Match img pixles */
- margin-top: -0.3em;
- left: 0; top: 0; /*Needed for IE6*/
-
- background: url('tubesprite.png') 0 -50px;
- /* CSS Curved Corners. Needed to make shadows curved. */
- -moz-border-radius: 0.8em; -webkit-border-radius: 0.8em; border-radius: 0.8em;
- /* CSS Shadows */
- -webkit-box-shadow: 0 2px 4px 0 #000; -moz-box-shadow: 0 2px 4px 0 #000; box-shadow: 0 2px 4px 0 #000;
-}
-.tubecss div.vjs-seek-handle:hover {
- background: url('tubesprite.png') -188px -50px;
-}
-
-/* Time Display
--------------------------------------------------------------------------------- */
-.tubecss .vjs-time-controls {
- position: absolute;
- right: 0;
- height: 100%; width: 4em;
- top: 0.0em;
- border-bottom: none;
- border-top: none;
- background: transparent;
-
-
- font-size: 1em; line-height: 1.0em; font-weight: normal; font-family: Helvetica, Arial, sans-serif;
-
- /* 1px top shadow */
-/* -webkit-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15);*/
-}
-
-.tubecss .vjs-current-time {line-height: 2.4em; left: 15.9em; border-left: 1px solid #333; }
-
-.tubecss .vjs-duration {line-height: 2.4em; left: 20.2em; display: inline; color: #999; width: 39.5em; text-align: left; padding-left: 2px; border-right: 1px solid #222;}
-.tubecss .vjs-remaining-time { right: 0; display: none; }
-
-.vjs-time-divider {line-height: 1.6em; display: inline; position: absolute; left: 19.5em; top: 0.5em; color: #999;}
-
-/* Fullscreen
--------------------------------------------------------------------------------- */
-.vjs-secondary-controls { float: right; }
-
-.tubecss .vjs-fullscreen-control { width: 3.8em; cursor: pointer !important; float: right; border-left: 1px solid #333; border-right: 1px solid #222;}
-.tubecss .vjs-fullscreen-control div { width: 16px; height: 16px; background: url('tubesprite.png') -50px 0; margin: 0.5em auto 0; }
-.tubecss .vjs-fullscreen-control div:hover {background: url('tubesprite.png') -50px -75px; }
-
-.tubecss.vjs-fullscreen .vjs-fullscreen-control div { background: url('tubesprite.png') -75px 0; }
-.tubecss.vjs-fullscreen .vjs-fullscreen-control div:hover { background: url('tubesprite.png') -75px -75px; }
-
-
-/* Big Play Button (at start)
----------------------------------------------------------*/
-.tubecss .vjs-big-play-button {
- display: block; /* Start hidden */ z-index: 2;
- position: absolute; top: 50%; left: 50%; width: 8.0em; height: 8.0em; margin: -43px 0 0 -43px; text-align: center; vertical-align: center; cursor: pointer !important;
- border: 0.3em solid #fff; opacity: 0.95;
- -webkit-border-radius: 25px; -moz-border-radius: 25px; border-radius: 25px;
-
- background: #454545;
- background: -moz-linear-gradient(top, #454545 0%, #232323 50%, #161616 50%, #3f3f3f 100%);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#454545), color-stop(50%,#232323), color-stop(50%,#161616), color-stop(100%,#3f3f3f));
- background: -webkit-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
- background: -o-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
- background: -ms-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#454545', endColorstr='#3f3f3f',GradientType=0 );
- background: linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
-
- /* CSS Shadows */
- -webkit-box-shadow: 4px 4px 8px #000; -moz-box-shadow: 4px 4px 8px #000; box-shadow: 4px 4px 8px #000;
-}
-
-.tubecss div.vjs-big-play-button:hover {
- -webkit-box-shadow: 0 0 80px #fff; -moz-box-shadow: 0 0 80px #fff; box-shadow: 0 0 80px #fff;
-}
-
-.tubecss div.vjs-big-play-button span {
- position: absolute; top: 50%; left: 50%;
- display: block; width: 35px; height: 42px;
- margin: -20px 0 0 -15px; /* Using negative margin to center image. */
- background: url('tubesprite.png') -100px 0;
-}
-/* Loading Spinner
----------------------------------------------------------*/
-.vjs-default-skin div.vjs-loading-spinner-fallback {
- display: none;
- position: absolute; top: 50%; left: 50%; width: 30px; height: 30px;
- margin: -15px 0 0 -15px; /* Using negative margin to center image.*/
- background: url('loading.gif');
-}
-
-
-
-/* Spinner Styles
----------------------------------------------------------*/
-/* CSS Spinners by Kilian Valkhof - http://kilianvalkhof.com/2010/css-xhtml/css3-loading-spinners-without-images/ */
-.vjs-loading-spinner {
- display: hidden;
- position: absolute; top: 50%; left: 50%; width: 55px; height: 55px;
- margin: -28px 0 0 -28px;
- -webkit-animation-name: rotatethis;
- -webkit-animation-duration:1s;
- -webkit-animation-iteration-count:infinite;
- -webkit-animation-timing-function:linear;
- -moz-animation-name: rotatethis;
- -moz-animation-duration:1s;
- -moz-animation-iteration-count:infinite;
- -moz-animation-timing-function:linear;
-}
-@-webkit-keyframes rotatethis {
-0% {-webkit-transform:scale(0.6) rotate(0deg);}
-12.5% {-webkit-transform:scale(0.6) rotate(0deg);}
-12.51% {-webkit-transform:scale(0.6) rotate(45deg);}
-25% {-webkit-transform:scale(0.6) rotate(45deg);}
-25.01% {-webkit-transform:scale(0.6) rotate(90deg);}
-37.5% {-webkit-transform:scale(0.6) rotate(90deg);}
-37.51% {-webkit-transform:scale(0.6) rotate(135deg);}
-50% {-webkit-transform:scale(0.6) rotate(135deg);}
-50.01% {-webkit-transform:scale(0.6) rotate(180deg);}
-62.5% {-webkit-transform:scale(0.6) rotate(180deg);}
-62.51% {-webkit-transform:scale(0.6) rotate(225deg);}
-75% {-webkit-transform:scale(0.6) rotate(225deg);}
-75.01% {-webkit-transform:scale(0.6) rotate(270deg);}
-87.5% {-webkit-transform:scale(0.6) rotate(270deg);}
-87.51% {-webkit-transform:scale(0.6) rotate(315deg);}
-100% {-webkit-transform:scale(0.6) rotate(315deg);}
-}
-@-moz-keyframes rotatethis {
-0% {-moz-transform:scale(0.6) rotate(0deg);}
-12.5% {-moz-transform:scale(0.6) rotate(0deg);}
-12.51% {-moz-transform:scale(0.6) rotate(45deg);}
-25% {-moz-transform:scale(0.6) rotate(45deg);}
-25.01% {-moz-transform:scale(0.6) rotate(90deg);}
-37.5% {-moz-transform:scale(0.6) rotate(90deg);}
-37.51% {-moz-transform:scale(0.6) rotate(135deg);}
-50% {-moz-transform:scale(0.6) rotate(135deg);}
-50.01% {-moz-transform:scale(0.6) rotate(180deg);}
-62.5% {-moz-transform:scale(0.6) rotate(180deg);}
-62.51% {-moz-transform:scale(0.6) rotate(225deg);}
-75% {-moz-transform:scale(0.6) rotate(225deg);}
-75.01% {-moz-transform:scale(0.6) rotate(270deg);}
-87.5% {-moz-transform:scale(0.6) rotate(270deg);}
-87.51% {-moz-transform:scale(0.6) rotate(315deg);}
-100% {-moz-transform:scale(0.6) rotate(315deg);}
-}
-/* Each circle */
-div.vjs-loading-spinner .ball1 { opacity: 0.12; position:absolute; left: 20px; top: 0px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball2 { opacity: 0.25; position:absolute; left: 34px; top: 6px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-div.vjs-loading-spinner .ball3 { opacity: 0.37; position:absolute; left: 40px; top: 20px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball4 { opacity: 0.50; position:absolute; left: 34px; top: 34px; width: 13px; height: 13px; background: #fff;
- border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 15px; border: 1px solid #ccc; }
-div.vjs-loading-spinner .ball5 { opacity: 0.62; position:absolute; left: 20px; top: 40px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball6 { opacity: 0.75; position:absolute; left: 6px; top: 34px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-div.vjs-loading-spinner .ball7 { opacity: 0.87; position:absolute; left: 0px; top: 20px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball8 { opacity: 1.00; position:absolute; left: 6px; top: 6px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
View
BIN  design/tubesprite.png
Deleted file not rendered
View
2  design/video-js.css
@@ -19,7 +19,7 @@ REQUIRED STYLES (be careful overriding)
/* Allow poster to be vertially aligned. */
vertical-align: middle;
- display: table-cell;
+ /* display: table-cell; */ /*This works in Safari but not Firefox.*/
}
/* Playback technology elements expand to the width/height of the containing div. <video> or <object> */
View
17 dev/build-source-list.rb
@@ -0,0 +1,17 @@
+#! /usr/bin/env ruby
+# Create javascript file with list of source files for easy inclusion in other development files.
+
+# puts ARGV[0]
+
+File.open("source-list.js", "w+") do |file|
+ file.puts "var vjsSourceList = [];"
+
+
+ Dir.foreach('../src') do |item|
+ next if item == '.' or item == '..' or item == '.DS_Store'
+
+ file.puts "vjsSourceList.push('src/#{item}')"
+
+ end
+
+end
View
0  dev/include-sources.js
No changes.
View
13 dev/source-list.js
@@ -0,0 +1,13 @@
+var vjsSourceList = [];
+vjsSourceList.push('_begin.js')
+vjsSourceList.push('_end.js')
+vjsSourceList.push('component.js')
+vjsSourceList.push('controls.js')
+vjsSourceList.push('core.js')
+vjsSourceList.push('ecma.js')
+vjsSourceList.push('events.js')
+vjsSourceList.push('json.js')
+vjsSourceList.push('lib.js')
+vjsSourceList.push('player.js')
+vjsSourceList.push('tech.js')
+vjsSourceList.push('tracks.js')
View
169 docs/api.md
@@ -1,17 +1,18 @@
---
layout: docs
-title: API
-description: Video.JS API Docs
-body_id: docs
+title: API &mdash; Video.JS &raquo; HTML5 Video Player
+description: Video.JS API Docs - API settings based on the HTML5 video API
+body_id: api
+body_class: docs subpage
---
API
===
-The VideoJS API allows you to interact with the video through Javascript, whether the browser is playing the video through HTML5 video or any other supported playback technologies.
+The Video.js API allows you to interact with the video through Javascript, whether the browser is playing the video through HTML5 video, Flash, or any other supported playback technologies.
Referencing the Player
----------------------
-To use the API functions, you need access to the player object. Luckily this is easy to get. You just need to make sure your video tag has an ID. The example embed code has an ID of "example_video_1". If you have multiple videos on one page, make sure every video tag has a unique ID (example_video_2, example_video_3, etc.).
+To use the API functions, you need access to the player object. Luckily this is easy to get. You just need to make sure your video tag has an ID. The example embed code has an ID of "example_video_1". If you have multiple videos on one page, make sure every video tag has a unique ID.
{% highlight javascript %}
@@ -19,10 +20,11 @@ To use the API functions, you need access to the player object. Luckily this is
{% endhighlight %}
+(If the player hasn't been initialized yet via the data-setup attribute or another method, this will also initialize the player.)
Wait Until the Player is Ready
------------------------------
-The time it takes VideoJS to set up the video and API will vary depending on the playback technology being used (HTML5 will often be much faster to load than Flash). For that reason we want to use the player's 'ready' function to trigger any code that requires the player's API.
+The time it takes Video.js to set up the video and API will vary depending on the playback technology being used (HTML5 will often be much faster to load than Flash). For that reason we want to use the player's 'ready' function to trigger any code that requires the player's API.
{% highlight javascript %}
@@ -39,122 +41,189 @@ The time it takes VideoJS to set up the video and API will vary depending on the
API Methods
-----------
-Now that you have access to a ready player, you can control the video or react to video events using the following functions. The VideoJS API function names follow the HTML5 media API. The main difference is that attributes which you would get or set on a video element directly ( videoElement.currentTime = "120"; ), you would use a function argument syntax for VideoJS ( myPlayer.currentTime(120); )
+Now that you have access to a ready player, you can control the video or respond to video events using the following functions. The Video.js API function names follow the [HTML5 media API](http://www.w3.org/TR/html5/video.html). The main difference is that attributes which you would get or set on a video element using the equals sign ( `myVideoElement.currentTime = "120";` ), you would use a function argument syntax for Video.js ( `myPlayer.currentTime(120);` )
### play()
- Start video playback.
- Returns the player object.
- Example:
+ Start video playback. Returns the player object.
+
+{% highlight javascript %}
+
+ myPlayer.play();
+
+{% endhighlight %}
+
- myPlayer.play();
### pause()
- Pause the video playback.
- Returns: the player object
- Example:
+ Pause the video playback. Returns: the player object
+
+{% highlight javascript %}
- myPlayer.pause();
+ myPlayer.pause();
+
+{% endhighlight %}
### currentTime()
Returns the current time of the video in seconds.
- Example:
- var whereYouAt = myPlayer.currentTime();
+{% highlight javascript %}
+
+ var whereYouAt = myPlayer.currentTime();
+
+{% endhighlight %}
### currentTime(seconds) // Type: Integer or Float
Seek to the supplied time (seconds).
Returns the player object.
- Example:
- myPlayer.currentTime(120); // 2 minutes into the video
+{% highlight javascript %}
+
+ myPlayer.currentTime(120); // 2 minutes into the video
+
+{% endhighlight %}
### duration()
Returns the length in time of the video in seconds. NOTE: The video must have started loading before the duration can be known, and in the case of Flash, may not be known until the video starts playing.
- Example:
- var howLongIsThis = myPlayer.duration();
+
+{% highlight javascript %}
+
+ var howLongIsThis = myPlayer.duration();
+
+{% endhighlight %}
### buffered()
Returns a [TimeRange](http://videojs.com/docs/glossary.html#timerange) with sections of the video that have been downloaded. If you just want the percent of the video that's been downloaded, use bufferedPercent.
- Example:
- var whatHasBeenBuffered = myPlayer.buffered();
+{% highlight javascript %}
+
+ var whatHasBeenBuffered = myPlayer.buffered();
+
+{% endhighlight %}
### bufferedPercent()
Returns the percent (as a decimal) of the video that's been downloaded.
- Example:
- var howMuchIsDownloaded = myPlayer.bufferedPercent();
+{% highlight javascript %}
+
+ var howMuchIsDownloaded = myPlayer.bufferedPercent();
+
+{% endhighlight %}
### volume()
Returns the current volume of the video as a percent in decimal form. 0 is off (muted), 1.0 is all the way up, 0.5 is half way.
- Example:
- var howLoudIsIt = myPlayer.volume();
+{% highlight javascript %}
+
+ var howLoudIsIt = myPlayer.volume();
+
+{% endhighlight %}
### volume(percentAsDecimal)
Set the volume to the supplied percent (as a decimal between 0 and 1).
- Example:
- myPlayer.volume(0.5); // Set volume to half
+{% highlight javascript %}
+
+ myPlayer.volume(0.5); // Set volume to half
+
+{% endhighlight %}
### width()
Returns the current width of the video in pixels.
- Example:
-
+
+{% highlight javascript %}
+
var howWideIsIt = myPlayer.width();
+{% endhighlight %}
+
### width(pixels)
Change the width of the video to the supplied width in pixels.
Returns the player object
- Example:
- myPlayer.width(640);
+{% highlight javascript %}
+
+ myPlayer.width(640);
+
+{% endhighlight %}
+
### height()
Returns the current height of the video in pixels.
- Example:
- var howTallIsIt = myPlayer.height();
+{% highlight javascript %}
+
+ var howTallIsIt = myPlayer.height();
+
+{% endhighlight %}
+
### height(pixels)
Change the height of the video to the supplied height in pixels.
Returns the player object
- myPlayer.height(480);
+{% highlight javascript %}
+
+ myPlayer.height(480);
+
+{% endhighlight %}
+
### size(width, height)
- Changes the width and height of the video to the supplied width and height. This is more efficient if you're changing both width and height.
- Returns the player object.
-
- myPlayer.size(640,480);
+ Changes the width and height of the video to the supplied width and height. This is more efficient if you're changing both width and height (only triggers the player's resize event once). Returns the player object.
+
+{% highlight javascript %}
-### enterFullScreen()
- Increase the size of the video to full screen. In some browsers, full screen is not supported natively, so it enters full window mode, where the fills the browser window. In browsers that support native full screen, typically the browser's default controls will be shown, and not the VideoJS custom skin. In full window mode, the VideoJS controls and skin will always be used.
+ myPlayer.size(640,480);
+
+{% endhighlight %}
+
+
+### requestFullScreen()
+ Increase the size of the video to full screen. In some browsers, full screen is not supported natively, so it enters full window mode, where the fills the browser window. In browsers that support native full screen, typically the browser's default controls will be shown, and not the Video.js custom skin. In full window mode, the Video.js controls and skin will always be used.
Returns the player object.
- myPlayer.enterFullScreen();
+{% highlight javascript %}
+
+ myPlayer.enterFullScreen();
+
+{% endhighlight %}
-### exitFullScreen()
+
+### cancelFullScreen()
Return the video to its normal size after having been in full screen mode.
Returns the player object.
- myPlayer.exitFullScreen();
+{% highlight javascript %}
+
+ myPlayer.exitFullScreen();
+
+{% endhighlight %}
Events
------
You can attach event listeners to the player similarly to how you would for a video element.
- var myFunc = function(){
- // Do something when the event is fired
- };
- myPlayer.addEvent("eventName", myFunc);
+{% highlight javascript %}
+
+ var myFunc = function(){
+ // Do something when the event is fired
+ };
+ myPlayer.addEvent("eventName", myFunc);
+
+{% endhighlight %}
+
You can also remove the listeners later.
- myPlayer.removeEvent("eventName", myFunc);
+{% highlight javascript %}
+
+ myPlayer.removeEvent("eventName", myFunc);
+
+{% endhighlight %}
+
### Event Types
View
59 docs/behaviors.md
@@ -1,59 +0,0 @@
----
-layout: docs
-title: Behvaiors
-description: Video.JS Behaviors
-body_id: docs
----
-
-DEPRECATED
-
-Behaviors
-=========
-Behaviors allow you to make an element on your page act as a video control or a display of video information. The easiest example of this is creating a play button. The following code will make a click on your element play the video.
-
- myPlayer.activateElement(myElement, "playButton");
-
-controlBar
- The controlBar behavior is what's added to the main control bar to make it show/hide depending on the user's mouse and the set preferences. It can also be added to other elements if the same effect is desired.
-
-playButton
- The playButton behavior can be added to an element to make it play the video when clicked. (See also playToggle)
-
-pauseButton
- The pauseButton behavior can be added to an element to make it pause the video when clicked.
-
-playToggle
- The playToggle behavior can be added to an element to make it toggle between play and pause. When the video is playing it will pause the video, and vice versa. The play button in the default control bar works this way.
- The icon in the play button changes to pause (two vertical bars) or play (triangle) depending on the state of the video. This is done through CSS classes. When the video is playing, a class of "vjs-playing" will be added to the playToggle element. When the video is paused, a class of "vjs-paused" will be added to the element. If you are using an image for the icon, set it as a background image of the element (or a sub element) and change the background image accordingly.
-
- #my_play_toggle.vjs-playing { background-image: url("my-pause-icon.png") }
- #my_play_toggle.vjs-paused { background-image: url("my-play-icon.png") }
-
-playProgressBar
- With the playProgressBar behavior, you can make an element grow like a progress bar as the video plays. The width of the element is set as a percent, and uses the video's current time divided by the video's total duration. For this reason, you may also need a container element to get the desired effect. In this example the width of the playProgressBar will be based on the width of myPlayProgressHolder.
- <div id="myPlayProgressHolder">
- <div id="myPlayProgressBar"></div>
- </div>
-
-loadProgressBar
- The loadProgressBar behavior works similarly to the playProgressBar behavior, except that it's based on the amount of video data that's been downloaded to the users machine.
-
-currentTimeDisplay
- The currentTimeDisplay behavior will make an element display the video's current playback time in the format of 00:00. It does so by changing the innerHTML of the element to the time.
-
-durationDisplay
- The durationDisplay behavior will make an element display the video's duration in the format of 00:00. It does so by changing the innerHTML of the element to the duration.
-
-currentTimeScrubber
- The currentTimeScrubber behavior allows you to make an element that controls the current time of the video by clicking and dragging on the element. The current time will be set based on where the user clicks or drags to, in relation to the width of the element.
-
-volumeDisplay
-...
-
-volumeScrubber
- The volumeScrubber behavior allows you to make an element that controls the volume of the video by clicking and dragging on the element. The volume will be set based on where the user clicks or drags to, in relation to the width of the element.
-
-fullscreenToggle
-...
-
-(Note to self: Have a video that is fixed position beside the behavior docs, that all examples are tied to)
View
3  docs/glossary.md
@@ -2,7 +2,8 @@
layout: docs
title: VideoJS Glossary
description: Video.JS Glossary
-body_id: docs
+body_id: glossary
+body_class: docs subpage
---
View
23 docs/index.md
@@ -3,6 +3,27 @@ layout: docs
title: Docs
description: Video.JS Docs
body_id: docs
+body_class: docs subpage
---
-Intro
+<h1>Start</h1>
+
+The Video.js documentation is here to help you setup and use the player. These docs can be found and contributed to in the [Video.js library repository](https://github.com/zencoder/video-js/tree/master/docs).
+
+### [Setup](/docs/setup)
+Check out the [5 second setup](/#setup) if you're just getting started. The setup documentation gives a deeper view of the additional methods you can use to trigger the player setup.
+
+### [Options](/docs/options/)
+There are a number of options that can be used to change how the player behaves, starting with the HTML5 media options like autoplay and preload, and expanding to Video.JS specific options.
+
+### [API](/docs/api/)
+The Video.js API allows you to control the video through javascript or trigger event listeners, whether the video is playing through HTML5, flash, or another playback technology.
+
+### [Skins](/docs/skins/)
+You can change the look of the player across playback technologies just by editing a CSS file. The skins documentation gives you a intro to how the HTML and CSS of the default skin is put together.
+
+### [Tech](/docs/tech/)
+A 'playback technology' is the term we're using to represent HTML5 video, Flash, and other video plugins, as well as other players like the YouTube player. Basically anything that has a unique API to audio or video. Additional playback technologies can be added relatively easily.
+
+### [Glossary](/docs/glossary/)
+Some helpful definitions.
View
3  docs/options.md
@@ -2,7 +2,8 @@
layout: docs
title: Options
description: Player Options
-body_id: docs
+body_id: options
+body_class: docs subpage
---
Options
View
44 docs/setup.md
@@ -2,35 +2,51 @@
layout: docs
title: Setup
description: Setup
-body_id: docs
+body_id: setup
+body_class: docs subpage
---
Setup
=====
-Step 1: Include the VideoJS Javascript and CSS files in the head of your page.
+Video.js is pretty easy to set up. It can take a matter of seconds to get the player up and working on your web page.
+
+Step 1: Include the Video.js Javascript and CSS files in the head of your page.
------------------------------------------------------------------------------
-You can download the VideoJS source and host it on your own servers, or use the free CDN hosted version (thanks to Zencoder).
+You can download the Video.js source and host it on your own servers, or use the free CDN hosted version (thanks to Zencoder). It's often recommended now to put JavaScript before the end \</body\> tag instead of the head but Video.js includes an 'HTML5 Shiv', which needs to be in the \<head\> for older IE versions. If you
+
+{% highlight html %}
+
+<script src="http://vjs.zencdn.com/c/video.js"></script>
+<link href="http://vjs.zencdn.com/c/video-js.css" rel="stylesheet">
+
+{% endhighlight %}
- <script src="http://video-js.zencoder.com/3.0/video.min.js"></script>
- <link href="http://video-js.zencoder.com/3.0/video-js.css" rel="stylesheet">
+It's often recommended now to include JavaScript before the end \</body\> tag instead of the \<head\>, but Video.js includes an 'HTML5 Shiv', which needs to be in the \<head\> for older IE versions.
Step 2: Add an HTML5 video tag to your page.
--------------------------------------------
-Use the video tag as normal, with a few extra pieces for VideoJS:
+Use the video tag as normal, with a few extra pieces for Video.js:
- 1. The 'data-setup' Atrribute tells VideoJS to automatically set up the video when the page is ready, and read any options (in JSON format) from the attribute (see ['options'](http://videojs.com/docs/options.html)).
+ 1. The 'data-setup' Atrribute tells Video.js to automatically set up the video when the page is ready, and read any options (in JSON format) from the attribute (see ['options'](http://videojs.com/docs/options.html)).
2. The 'id' Attribute: Should be used and unique for every video on the same page.
3. The 'class' attribute contains two classes:
- - 'video-js' applies styles that are required for VideoJS functionality, like fullscreen and subtitles.
+ - 'video-js' applies styles that are required for Video.js functionality, like fullscreen and subtitles.
- 'vjs-default-skin' applies the default skin to the HTML controls, and can be removed or overridden to create your own controls design.
Otherwise include/exclude attributes, settings, sources, and tracks exactly as you would for HTML5 video (see ['video-tag'](http://videojs.com/docs/video-tag.html)).
- <video id="example_video_1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264" poster="http://video-js.zencoder.com/oceans-clip.png"
- data-setup='{"example_option":true}'>
- <source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
- <source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
- <source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
- </video>
+{% highlight html %}
+
+<video id="example_video_1" class="video-js vjs-default-skin"
+ controls preload="auto" width="640" height="264"
+ poster="http://video-js.zencoder.com/oceans-clip.png"
+ data-setup='{"example_option":true}'>
+ <source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
+ <source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
+ <source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
+</video>
+
+{% endhighlight %}
+
View
0  docs/skins.md
No changes.
View
3  docs/tech.md
@@ -2,7 +2,8 @@
layout: docs
title: Playback Technology
description: Video.JS Playback Technology
-body_id: docs
+body_id: tech
+body_class: docs subpage
---
Playback Technology ("Tech")
View
4 src/component.js
@@ -138,7 +138,7 @@ _V_.Component = _V_.Class.extend({
/* Ready - Trigger functions when component is ready
================================================================================ */
ready: function(fn){
- if (!fn) return;
+ if (!fn) return this;
if (this.isReady) {
fn.call(this);
@@ -148,6 +148,8 @@ _V_.Component = _V_.Class.extend({
}
this.readyQueue.push(fn);
}
+
+ return this;
},
triggerReady: function(){
View
10 src/controls.js
@@ -28,8 +28,6 @@ _V_.Button = _V_.Control.extend({
role: "button",
tabIndex: 0
}, attrs);
-
- _V_.log(attrs)
return this._super(type, attrs);
},
@@ -143,9 +141,9 @@ _V_.FullscreenToggle = _V_.Button.extend({
onClick: function(){
if (!this.player.videoIsFullScreen) {
- this.player.enterFullScreen();
+ this.player.requestFullScreen();
} else {
- this.player.exitFullScreen();
+ this.player.cancelFullScreen();
}
}
@@ -717,6 +715,10 @@ _V_.Poster = _V_.Button.extend({
init: function(player, options){
this._super(player, options);
+ if (!this.player.options.poster) {
+ this.hide();
+ }
+
player.addEvent("play", _V_.proxy(this, this.hide));
},
View
16 src/lib.js
@@ -13,17 +13,6 @@ _V_.extend({
tech: {}, // Holder for playback technology settings
controlSets: {}, // Holder for control set definitions
- techSupports: function(tech, type, name){
- if (_V_[tech].supports[type]) {
- return _V_[tech].supports[type][name];
- }
- return false;
- },
- updateTechSupport: function(tech, type, name, value){
- if (_V_[tech].supports[type] === undefined) { _V_[tech].supports[type] = {}; }
- _V_[tech].supports[type][name] = value;
- },
-
// Device Checks
isIE: function(){ return !+"\v1"; },
isIPad: function(){ return navigator.userAgent.match(/iPad/i) !== null; },
@@ -38,7 +27,10 @@ _V_.extend({
var match = navigator.userAgent.match(/Android (\d+)\./i);
if (match && match[1]) { return match[1]; }
},
- //isAndroidBrowser
+
+ testVid: document.createElement("video"),
+ ua: navigator.userAgent,
+ support: {},
each: function(arr, fn){
if (!arr || arr.length === 0) { return; }
View
205 src/player.js
@@ -168,20 +168,13 @@ _V_.Player = _V_.Component.extend({
// Pause and remove current playback technology
if (this.tech) {
-
- this.tech.destroy();
-
- // Turn off any manual progress or timeupdate tracking
- if (this.manualProgress) { this.manualProgressOff(); }
-
- if (this.manualTimeUpdates) { this.manualTimeUpdatesOff(); }
-
- this.tech = false;
+ this.unloadTech();
// If the first time loading, HTML5 tag will exist but won't be initialized
// So we need to remove it if we're not loading HTML5
- } else if (techName != "html5") {
+ } else if (techName != "html5" && this.tag) {
this.el.removeChild(this.tag);
+ this.tag = false;
}
this.techName = techName;
@@ -190,17 +183,15 @@ _V_.Player = _V_.Component.extend({
this.isReady = false;
var techReady = function(){
- _V_.log("ready")
-
this.player.triggerReady();
// Manually track progress in cases where the browser/flash player doesn't report it.
- if (!_V_.techSupports(this.player.techName, "event", "progress")) {
+ if (!this.support.progressEvent) {
this.player.manualProgressOn();
}
// Manually track timeudpates in cases where the browser/flash player doesn't report it.
- if (!_V_.techSupports(this.player.techName, "event", "timeupdate")) {
+ if (!this.support.timeupdateEvent) {
this.player.manualTimeUpdatesOn();
}
}
@@ -208,11 +199,44 @@ _V_.Player = _V_.Component.extend({
// Grab tech-specific options from player options and add source and parent element to use.
var techOptions = _V_.merge({ source: source, parentEl: this.el }, this.options[techName])
+ if (source.src == this.values.src && this.values.currentTime > 0) {
+ techOptions.startTime = this.values.currentTime;
+ }
+
+ if (source) {
+ this.values.src = source.src;
+ }
+
// Initialize tech instance
this.tech = new _V_[techName](this, techOptions);
this.tech.ready(techReady);
},
+ unloadTech: function(){
+ this.tech.destroy();
+
+ // Turn off any manual progress or timeupdate tracking
+ if (this.manualProgress) { this.manualProgressOff(); }
+
+ if (this.manualTimeUpdates) { this.manualTimeUpdatesOff(); }
+
+ this.tech = false;
+ },
+
+ // There's many issues around changing the size of a Flash (or other plugin) object.
+ // First is a plugin reload issue in Firefox that has been around for 11 years: https://bugzilla.mozilla.org/show_bug.cgi?id=90268
+ // Then with the new fullscreen API, Mozilla and webkit browsers will reload the flash object after going to fullscreen.
+ // To get around this, we're unloading the tech, caching source and currentTime values, and reloading the tech once the plugin is resized.
+ reloadTech: function(betweenFn){
+ _V_.log("unloadingTech")
+ this.unloadTech();
+ _V_.log("unloadedTech")
+ if (betweenFn) { betweenFn.call(); }
+ _V_.log("LoadingTech")
+ this.loadTech(this.techName, { src: this.values.src })
+ _V_.log("loadedTech")
+ },
+
/* Fallbacks for unsupported event types
================================================================================ */
// Manually trigger progress events based on changes to the buffered amount
@@ -232,7 +256,7 @@ _V_.Player = _V_.Component.extend({
this.removeEvent("progress", arguments.callee);
// Update known progress support for this playback technology
- _V_.updateTechSupport(this.player.techName, "event", "progress", true);
+ this.support.progressEvent = true;
// Turn off manual progress tracking
this.player.manualProgressOff();
@@ -274,7 +298,7 @@ _V_.Player = _V_.Component.extend({
this.removeEvent("timeupdate", arguments.callee);
// Update known progress support for this playback technology
- _V_.updateTechSupport(this.player.techName, "event", "timeupdate", true);
+ this.support.timeupdateEvent = true;
// Turn off manual progress tracking
this.player.manualTimeUpdatesOff();
@@ -323,19 +347,16 @@ _V_.Player = _V_.Component.extend({
onError: function(e) {
_V_.log("Video Error", e);
- }
-
-});
+ },
/* Player API
================================================================================ */
-_V_.Player.prototype.extend({
apiCall: function(method, arg){
if (this.isReady) {
return this.tech[method](arg);
} else {
- _V_.log("The playback technology API is not ready yet. Use player.ready(myFunction)."+" ["+method+"]")
+ _V_.log("The playback technology API is not ready yet. Use player.ready(myFunction)."+" ["+method+"]", arguments.callee.caller.arguments.callee.caller.arguments.callee.caller)
return false;
// throw new Error("The playback technology API is not ready yet. Use player.ready(myFunction)."+" ["+method+"]");
}
@@ -355,7 +376,7 @@ _V_.Player.prototype.extend({
if (seconds !== undefined) {
// Cache the last set value for smoother scrubbing.
- this.values.currentTime = seconds;
+ this.values.lastSetCurrentTime = seconds;
this.apiCall("setCurrentTime", seconds);
@@ -364,7 +385,9 @@ _V_.Player.prototype.extend({
}
return this;
}
- return this.apiCall("currentTime");
+
+ // Cache last currentTime and return
+ return this.values.currentTime = this.apiCall("currentTime");
},
duration: function(){
return this.apiCall("duration");
@@ -437,33 +460,81 @@ _V_.Player.prototype.extend({
supportsFullScreen: function(){ return this.apiCall("supportsFullScreen"); },
// Turn on fullscreen (or window) mode
- enterFullScreen: function(){
- this.videoIsFullScreen = true;
- if (typeof this.el.webkitRequestFullScreen == 'function') {
- this.el.webkitRequestFullScreen();
- } else if (typeof this.el.mozRequestFullScreen == 'function') {
- this.el.mozRequestFullScreen();
- } else if (this.supportsFullScreen()) {
- this.apiCall("enterFullScreen");
- } else {
- this.enterFullWindow();
- }
- this.triggerEvent("enterFullScreen");
+ requestFullScreen: function(){
+ var requestFullScreen = _V_.support.requestFullScreen;
+
+ // Check for browser element fullscreen support
+ if (requestFullScreen) {
+ // Flash and other plugins get reloaded when you take their parent to fullscreen.
+ // To fix that we'll remove the tech, and reload it after the resize has finished.
+ if (this.tech.support.fullscreenResize === false) {
+
+ this.pause();
+ this.unloadTech();
+
+ _V_.addEvent(document, "keydown", _V_.proxy(this, function(e){
+ _V_.log("asdf", e)
+ }));
+
+ _V_.addEvent(document, requestFullScreen.eventName, this.proxy(function(){
+ _V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
+ this.loadTech(this.techName, { src: this.values.src });
+ }));
+
+ this.el[requestFullScreen.requestFn]();
+
+ } else {
+ this.el[requestFullScreen.requestFn]();
+ }
+
+ } else if (this.tech.supportsFullScreen()) {
+ this.apiCall("enterFullScreen");
+
+ } else {
+ this.enterFullWindow();
+ }
+
+ this.videoIsFullScreen = true;
+ this.triggerEvent("fullscreenchange");
+
return this;
},
- exitFullScreen: function(){
- this.videoIsFullScreen = false;
- if (typeof this.el.webkitRequestFullScreen == 'function') {
- document.webkitCancelFullScreen();
- } else if (this.supportsFullScreen()) {
- document.webkitExitFullScreen();
+ cancelFullScreen: function(){
+ var requestFullScreen = _V_.support.requestFullScreen;
+
+ // Check for browser element fullscreen support
+ if (requestFullScreen) {
+
+ // Flash and other plugins get reloaded when you take their parent to fullscreen.
+ // To fix that we'll remove the tech, and reload it after the resize has finished.
+ if (this.tech.support.fullscreenResize === false) {
+
+ this.pause();
+ this.unloadTech();
+
+ _V_.addEvent(document, requestFullScreen.eventName, this.proxy(function(){
+ _V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
+ _V_.log("document fullscreeneventchange")
+ this.loadTech(this.techName, { src: this.values.src })
+ }));
+
+ document[requestFullScreen.cancelFn]();
+
} else {
- this.exitFullWindow();
+ document[requestFullScreen.cancelFn]();
}
- this.triggerEvent("exitFullScreen");
- // Otherwise Shouldn't be called since native fullscreen uses own controls.
+ } else if (this.tech.supportsFullScreen()) {
+ this.apiCall("exitFullScreen");
+
+ } else {
+ this.exitFullWindow();
+ }
+
+ this.videoIsFullScreen = false;
+ this.triggerEvent("fullscreenchange");
+
return this;
},
@@ -488,7 +559,7 @@ _V_.Player.prototype.extend({
fullWindowOnEscKey: function(event){
if (event.keyCode == 27) {
- this.exitFullScreen();
+ this.cancelFullScreen();
}
},
@@ -561,6 +632,9 @@ _V_.Player.prototype.extend({
}
// Case: URL String (http://myvideo...)
} else {
+ // Cache for getting last set source
+ this.values.src = source;
+
if (!this.isReady) {
this.ready(function(){
this.src(source);
@@ -647,3 +721,44 @@ _V_.Player.prototype.extend({
defaultMuted: function(){ return this.apiCall("defaultMuted"); }
});
+// RequestFullscreen API
+(function(){
+ var requestFn,
+ cancelFn,
+ playerProto = _V_.Player.prototype;
+
+ // Current W3C Spec
+ // http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#api
+ // Mozilla Draft: https://wiki.mozilla.org/Gecko:FullScreenAPI#fullscreenchange_event
+ if (document.cancelFullscreen !== undefined) {
+ requestFn = "requestFullscreen";
+ cancelFn = "exitFullscreen";
+ eventName = "fullscreenchange";
+
+ // Webkit (Chrome/Safari) and Mozilla (Firefox) have working implementaitons
+ // that use prefixes and vary slightly from the new W3C spec. Specifically, using 'exit' instead of 'cancel',
+ // and lowercasing the 'S' in Fullscreen.
+ // Other browsers don't have any hints of which version they might follow yet, so not going to try to predict by loopeing through all prefixes.
+ } else {
+
+ _V_.each(["moz", "webkit"], function(prefix){
+
+ if (document[prefix + "CancelFullScreen"] !== undefined) {
+ requestFn = prefix + "RequestFullScreen";
+ cancelFn = prefix + "CancelFullScreen";
+ eventName = prefix + "fullscreenchange";
+ }
+
+ });
+
+ }
+
+ if (requestFn) {
+ _V_.support.requestFullScreen = {
+ requestFn: requestFn,
+ cancelFn: cancelFn,
+ eventName: eventName
+ };
+ }
+
+})();
View
105 src/tech.js
@@ -7,10 +7,17 @@ _V_.PlaybackTech = _V_.Component.extend({
// Make playback element clickable
// _V_.addEvent(this.el, "click", _V_.proxy(this, _V_.PlayToggle.prototype.onClick));
+ // this.addEvent("click", this.proxy(this.onClick));
+
// player.triggerEvent("techready");
- }
+ },
// destroy: function(){},
// createElement: function(){},
+ onClick: function(){
+ if (this.player.options.controls) {
+ _V_.PlayToggle.prototype.onClick.call(this);
+ }
+ }
});
// Create placeholder methods for each that warn when a method isn't supported by the current playback technology
@@ -29,7 +36,8 @@ _V_.html5 = _V_.PlaybackTech.extend({
this.player = player;
this.el = this.createElement();
this.ready(ready);
- _V_.addEvent(this.el, "click", _V_.proxy(this, _V_.PlayToggle.prototype.onClick));
+
+ this.addEvent("click", this.proxy(this.onClick));
var source = options.source;
@@ -61,6 +69,7 @@ _V_.html5 = _V_.PlaybackTech.extend({
destroy: function(){
this.player.tag = false;
+ this.removeTriggers();
this.el.parentNode.removeChild(this.el);
},
@@ -75,7 +84,7 @@ _V_.html5 = _V_.PlaybackTech.extend({
// Check if this browser supports moving the element into the box.
// On the iPhone video will break if you move the element,
// So we have to create a brand new element.
- if (!el || html5.supports.movingElementInDOM === false) {
+ if (!el || this.support.movingElementInDOM === false) {
// If the original tag is still there, remove it.
if (el) {
@@ -99,21 +108,22 @@ _V_.html5 = _V_.PlaybackTech.extend({
return el;
},
+ // Make video events trigger player events
+ // May seem verbose here, but makes other APIs possible.
setupTriggers: function(){
- // Make video events trigger player events
- // May seem verbose here, but makes other APIs possible.
-
- // ["play", "playing", "pause", "ended", "volumechange", "error", "progress", "seeking", "timeupdate"]
- var types = _V_.html5.events,
- i;
- for (i = 0;i<types.length; i++) {
- _V_.addEvent(this.el, types[i], _V_.proxy(this.player, function(e){
- e.stopPropagation();
- this.triggerEvent(e);
- }));
- }
+ _V_.each.call(this, _V_.html5.events, function(type){
+ _V_.addEvent(this.el, type, _V_.proxy(this.player, this.eventHandler));
+ });
+ },
+ removeTriggers: function(){
+ _V_.each.call(this, _V_.html5.events, function(type){
+ _V_.removeEvent(this.el, type, _V_.proxy(this.player, this.eventHandler));
+ });
+ },
+ eventHandler: function(e){
+ e.stopPropagation();
+ this.triggerEvent(e);
},
- removeTriggers: function(){},
play: function(){ this.el.play(); },
pause: function(){ this.el.pause(); },
@@ -148,8 +158,9 @@ _V_.html5 = _V_.PlaybackTech.extend({
return true;
}
}
- return false;
+ return false;
},
+
enterFullScreen: function(){
try {
this.el.webkitEnterFullScreen();
@@ -206,18 +217,22 @@ _V_.html5.canPlaySource = function(srcObj){
// Check Media Type
};
-_V_.html5.supports = {};
-
// List of all HTML5 events (various uses).
_V_.html5.events = "loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange".split(",");
/* HTML5 Device Fixes ---------------------------------------------------------- */
-// iOS
-if (_V_.isIOS()) {
- // If you move a video element in the DOM, it breaks video playback.
- _V_.html5.supports.movingElementInDOM = false;
-}
+_V_.html5.prototype.support = {
+
+ // Support for tech specific full screen. (webkitEnterFullScreen, not requestFullscreen)
+ // http://developer.apple.com/library/safari/#documentation/AudioVideo/Reference/HTMLVideoElementClassReference/HTMLVideoElement/HTMLVideoElement.html
+ // Seems to be broken in Chromium/Chrome && Safari in Leopard
+ fullscreen: (typeof _V_.testVid.webkitEnterFullScreen !== undefined) ? (!_V_.ua.match("Chrome") && !_V_.ua.match("Mac OS X 10.5") ? true : false) : false,
+
+ // In iOS, if you move a video element in the DOM, it breaks video playback.
+ movingElementInDOM: !_V_.isIOS()
+
+};
// Android
if (_V_.isAndroid()) {
@@ -285,6 +300,14 @@ _V_.flash = _V_.PlaybackTech.extend({
// Add to box.
_V_.insertFirst(placeHolder, parentEl);
+ if (options.startTime) {
+ this.ready(function(){
+ this.load();
+ this.play();
+ this.currentTime(options.startTime);
+ });
+ }
+
swfobject.embedSWF(options.swf, placeHolder.id, "480", "270", "9.0.124", "", flashVars, params, attributes);
},
@@ -310,7 +333,11 @@ _V_.flash = _V_.PlaybackTech.extend({
poster: function(){ this.el.vjs_getProperty("poster"); },
buffered: function(){
- return _V_.createTimeRange(0, this.el.vjs_getProperty("buffered"));
+ try {
+ return _V_.createTimeRange(0, this.el.vjs_getProperty("buffered"));
+ } catch(e) {
+ _V_.log(e, arguments.callee.caller.arguments.callee.caller)
+ }
},
supportsFullScreen: function(){
@@ -353,15 +380,15 @@ _V_.flash = _V_.PlaybackTech.extend({
/* Flash Support Testing -------------------------------------------------------- */
_V_.flash.isSupported = function(){
- return swfobject.hasFlashPlayerVersion("9");
+ return swfobject.hasFlashPlayerVersion("10");
};
_V_.flash.canPlaySource = function(srcObj){
- if (srcObj.type in _V_.flash.supports.format) { return "maybe"; }
+ if (srcObj.type in _V_.flash.prototype.support.formats) { return "maybe"; }
};
-_V_.flash.supports = {
- format: {
+_V_.flash.prototype.support = {
+ formats: {
"video/flv": "FLV",
"video/x-flv": "FLV",
"video/mp4": "MP4",
@@ -369,15 +396,19 @@ _V_.flash.supports = {
},
// Optional events that we can manually mimic with timers
- event: {
- progress: false,
- timeupdate: false
- }
+ progressEvent: false,
+ timeupdateEvent: false,
+
+ // Resizing plugins using request fullscreen reloads the plugin
+ fullscreenResize: false,
+
+ // Resizing plugins in Firefox always reloads the plugin (e.g. full window mode)
+ parentResize: !(_V_.ua.match("Firefox"))
};
_V_.flash.onSWFReady = function(currSwf){
- _V_.log(currSwf, "currSwf")
+ _V_.log("swfReady", currSwf)
var el = _V_.el(currSwf);
@@ -392,8 +423,8 @@ _V_.flash.onSWFReady = function(currSwf){
// Update reference to playback technology element
tech.el = el;
- // Make a click on the swf play the video
- _V_.addEvent(el, "click", _V_.proxy(player, _V_.PlayToggle.prototype.onClick));
+ // Now that the element is ready, make a click on the swf play the video
+ tech.addEvent("click", tech.onClick);
_V_.flash.checkReady(tech);
};
@@ -413,7 +444,7 @@ _V_.flash.checkReady = function(tech){
_V_.flash.onSWFEvent = function(swfID, eventName, other){
try {
var player = _V_.el(swfID).player;
- if (player) {
+ if (player && player.techName == "flash") {
player.triggerEvent(eventName);
}
} catch(err) {
Please sign in to comment.
Something went wrong with that request. Please try again.