mirror of
https://github.com/videojs/video.js.git
synced 2025-07-13 01:30:17 +02:00
Merge branch 'master' into feature/flash-iframe
This commit is contained in:
@ -1,3 +1,7 @@
|
|||||||
|
* Fixed issue with volume knob position. Improved controls fading.
|
||||||
|
* Fixed ian issue with triggering fullscreen a second time.
|
||||||
|
* Fixed issue with getting attributes in Firefox 3.0
|
||||||
|
* Escaping special characters in source URL for Flash
|
||||||
* Added a check for if Firefox is enabled which fixes a Firefox 9 issue
|
* Added a check for if Firefox is enabled which fixes a Firefox 9 issue
|
||||||
* Stopped spinner from showing on 'stalled' events since browsers sometimes don't show that they've recovered.
|
* Stopped spinner from showing on 'stalled' events since browsers sometimes don't show that they've recovered.
|
||||||
* Fixed CDN Version which was breaking dev.html
|
* Fixed CDN Version which was breaking dev.html
|
||||||
@ -24,3 +28,6 @@ CHANGELOG
|
|||||||
|
|
||||||
---- 3.0.7 / 2012-01-12 / fixing-ie8-poster-bug --------------------------------
|
---- 3.0.7 / 2012-01-12 / fixing-ie8-poster-bug --------------------------------
|
||||||
* Fixed an ie8 breaking bug with the poster
|
* Fixed an ie8 breaking bug with the poster
|
||||||
|
|
||||||
|
---- 3.0.8 / 2012-01-23 / fix-ie-controls-hiding -------------------------------
|
||||||
|
* Fixed issue with controls not hiding in IE due to no opacity support
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
major: 3
|
major: 3
|
||||||
patch: 7
|
patch: 8
|
||||||
minor: 0
|
minor: 0
|
||||||
|
@ -48,10 +48,31 @@ body.vjs-full-window {
|
|||||||
position: relative; width: 100%; max-height: 100%;
|
position: relative; width: 100%; max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Subtiles Styles */
|
/* Subtiles Styles */
|
||||||
.video-js .vjs-subtitles { color: #fff; font-size: 20px; text-align: center; position: absolute; bottom: 40px; left: 0; right: 0; }
|
.video-js .vjs-subtitles { color: #fff; font-size: 20px; text-align: center; position: absolute; bottom: 40px; left: 0; right: 0; }
|
||||||
|
|
||||||
|
/* Fading sytles, used to fade control bar. */
|
||||||
|
.vjs-fade-in {
|
||||||
|
visibility: visible !important; /* Needed to make sure things hide in older browsers too. */
|
||||||
|
opacity: 1 !important;
|
||||||
|
|
||||||
|
-webkit-transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||||
|
-moz-transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||||
|
-ms-transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||||
|
-o-transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||||
|
transition: visibility 0s linear 0s, opacity 0.3s linear;
|
||||||
|
}
|
||||||
|
.vjs-fade-out {
|
||||||
|
visibility: hidden !important;
|
||||||
|
opacity: 0 !important;
|
||||||
|
|
||||||
|
-webkit-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||||
|
-moz-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||||
|
-ms-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||||
|
-o-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||||
|
transition: visibility 0s linear 1.5s,opacity 1.5s linear;
|
||||||
|
}
|
||||||
|
|
||||||
/* DEFAULT SKIN (override in another file to create new skins)
|
/* DEFAULT SKIN (override in another file to create new skins)
|
||||||
================================================================================
|
================================================================================
|
||||||
Instead of editing this file, I recommend creating your own skin CSS file to be included after this file,
|
Instead of editing this file, I recommend creating your own skin CSS file to be included after this file,
|
||||||
@ -62,8 +83,6 @@ so you can upgrade to newer versions easier. You can remove all these styles by
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0; /* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */
|
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 */
|
left: 0; right: 0; /* 100% width of div */
|
||||||
opacity: 0.85;
|
|
||||||
display: none; /* Start hidden */
|
|
||||||
margin: 0; padding: 0; /* Controls are absolutely position, so no padding necessary */
|
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 */
|
height: 2.6em; /* Including any margin you want above or below control items */
|
||||||
color: #fff; border-top: 1px solid #404040;
|
color: #fff; border-top: 1px solid #404040;
|
||||||
@ -80,12 +99,10 @@ so you can upgrade to newer versions easier. You can remove all these styles by
|
|||||||
/*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#242424', endColorstr='#171717',GradientType=0 );*/ /* IE6-9 */
|
/*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#242424', endColorstr='#171717',GradientType=0 );*/ /* IE6-9 */
|
||||||
background: linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* W3C */
|
background: linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* W3C */
|
||||||
|
|
||||||
/* Fade-in using CSS Transitions */
|
/* Start hidden and with 0 opacity. Opacity is used to fade in modern browsers. */
|
||||||
-webkit-transition: opacity 0.3s linear;
|
/* Can't use display block to hide initially because widths of slider handles aren't calculated and avaialbe for positioning correctly. */
|
||||||
-moz-transition: opacity 0.3s linear;
|
visibility: hidden;
|
||||||
-o-transition: opacity 0.3s linear;
|
opacity: 0;
|
||||||
-ms-transition: opacity 0.3s linear;
|
|
||||||
transition: opacity 0.3s linear;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* General styles for individual controls. */
|
/* General styles for individual controls. */
|
||||||
|
@ -45,18 +45,18 @@ _V_.Component = _V_.Class.extend({
|
|||||||
init: function(player, options){
|
init: function(player, options){
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
|
||||||
if (options && options.el) {
|
// Allow for overridding default component options
|
||||||
|
options = this.options = _V_.merge(this.options || {}, options);
|
||||||
|
|
||||||
|
// Create element if one wasn't provided in options
|
||||||
|
if (options.el) {
|
||||||
this.el = options.el;
|
this.el = options.el;
|
||||||
} else {
|
} else {
|
||||||
this.el = this.createElement();
|
this.el = this.createElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array of sub-components
|
// Add any components in options
|
||||||
if (options && options.components) {
|
this.initComponents();
|
||||||
_V_.each.call(this, options.components, function(comp){
|
|
||||||
this.addComponent(comp);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function(){},
|
destroy: function(){},
|
||||||
@ -71,38 +71,47 @@ _V_.Component = _V_.Class.extend({
|
|||||||
return "";
|
return "";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
initComponents: function(){
|
||||||
|
var options = this.options;
|
||||||
|
if (options && options.components) {
|
||||||
|
// Loop through components and add them to the player
|
||||||
|
this.eachProp(options.components, function(name, opts){
|
||||||
|
|
||||||
|
// Allow waiting to add components until a specific event is called
|
||||||
|
var tempAdd = this.proxy(function(){
|
||||||
|
this.addComponent(name, opts);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (opts.loadEvent) {
|
||||||
|
this.one(opts.loadEvent, tempAdd)
|
||||||
|
} else {
|
||||||
|
tempAdd();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Add child components to this component.
|
// Add child components to this component.
|
||||||
// Will generate a new child component and then append child component's element to this component's element.
|
// Will generate a new child component and then append child component's element to this component's element.
|
||||||
// Takes either the name of the UI component class, or an object that contains a name, UI Class, and options.
|
// Takes either the name of the UI component class, or an object that contains a name, UI Class, and options.
|
||||||
addComponent: function(nameORobj){
|
addComponent: function(name, options){
|
||||||
var name, componentClass, options, component;
|
var componentClass, component;
|
||||||
|
|
||||||
if (typeof nameORobj == "string") {
|
// Make sure options is at least an empty object to protect against errors
|
||||||
name = nameORobj;
|
options = options || {};
|
||||||
|
|
||||||
// Can also pass in object to define a different class than the name and add other options
|
|
||||||
} else {
|
|
||||||
name = nameORobj.name;
|
|
||||||
componentClass = nameORobj.componentClass;
|
|
||||||
options = nameORobj.options;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!componentClass) {
|
|
||||||
// Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)
|
// Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)
|
||||||
componentClass = _V_.capitalize(name);
|
componentClass = options.componentClass || _V_.capitalize(name);
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new object & element for this controls set
|
// Create a new object & element for this controls set
|
||||||
// If there's no .player, this is a player
|
// If there's no .player, this is a player
|
||||||
component = new _V_[componentClass](this.player || this, options);
|
component = new _V_[componentClass](this.player || this, options);
|
||||||
|
|
||||||
if (this.components === undefined) {
|
|
||||||
this.components = [];
|
|
||||||
}
|
|
||||||
this.components.push(component);
|
|
||||||
|
|
||||||
// Add the UI object's element to the container div (box)
|
// Add the UI object's element to the container div (box)
|
||||||
this.el.appendChild(component.el);
|
this.el.appendChild(component.el);
|
||||||
|
|
||||||
|
// Set property name on player. Could cause conflicts with other prop names, but it's worth making refs easy.
|
||||||
|
this[name] = component;
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Display
|
/* Display
|
||||||
@ -115,6 +124,16 @@ _V_.Component = _V_.Class.extend({
|
|||||||
this.el.style.display = "none";
|
this.el.style.display = "none";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
fadeIn: function(){
|
||||||
|
this.removeClass("vjs-fade-out");
|
||||||
|
this.addClass("vjs-fade-in");
|
||||||
|
},
|
||||||
|
|
||||||
|
fadeOut: function(){
|
||||||
|
this.removeClass("vjs-fade-in");
|
||||||
|
this.addClass("vjs-fade-out");
|
||||||
|
},
|
||||||
|
|
||||||
addClass: function(classToAdd){
|
addClass: function(classToAdd){
|
||||||
_V_.addClass(this.el, classToAdd);
|
_V_.addClass(this.el, classToAdd);
|
||||||
},
|
},
|
||||||
@ -134,6 +153,9 @@ _V_.Component = _V_.Class.extend({
|
|||||||
triggerEvent: function(type, e){
|
triggerEvent: function(type, e){
|
||||||
return _V_.triggerEvent(this.el, type, e);
|
return _V_.triggerEvent(this.el, type, e);
|
||||||
},
|
},
|
||||||
|
one: function(type, fn) {
|
||||||
|
_V_.one.call(this, this.el, type, fn);
|
||||||
|
},
|
||||||
|
|
||||||
/* Ready - Trigger functions when component is ready
|
/* Ready - Trigger functions when component is ready
|
||||||
================================================================================ */
|
================================================================================ */
|
||||||
@ -174,6 +196,15 @@ _V_.Component = _V_.Class.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
eachProp: function(obj, fn){
|
||||||
|
if (!obj) { return; }
|
||||||
|
for (var name in obj) {
|
||||||
|
if (obj.hasOwnProperty(name)) {
|
||||||
|
fn.call(this, name, obj[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
extend: function(obj){
|
extend: function(obj){
|
||||||
for (var attrname in obj) {
|
for (var attrname in obj) {
|
||||||
if (obj.hasOwnProperty(attrname)) { this[attrname]=obj[attrname]; }
|
if (obj.hasOwnProperty(attrname)) { this[attrname]=obj[attrname]; }
|
||||||
|
94
src/controls.js
vendored
94
src/controls.js
vendored
@ -140,7 +140,7 @@ _V_.FullscreenToggle = _V_.Button.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onClick: function(){
|
onClick: function(){
|
||||||
if (!this.player.videoIsFullScreen) {
|
if (!this.player.isFullScreen) {
|
||||||
this.player.requestFullScreen();
|
this.player.requestFullScreen();
|
||||||
} else {
|
} else {
|
||||||
this.player.cancelFullScreen();
|
this.player.cancelFullScreen();
|
||||||
@ -222,13 +222,30 @@ _V_.LoadingSpinner = _V_.Component.extend({
|
|||||||
/* Control Bar
|
/* Control Bar
|
||||||
================================================================================ */
|
================================================================================ */
|
||||||
_V_.ControlBar = _V_.Component.extend({
|
_V_.ControlBar = _V_.Component.extend({
|
||||||
|
|
||||||
|
options: {
|
||||||
|
loadEvent: "play",
|
||||||
|
components: {
|
||||||
|
"playToggle": {},
|
||||||
|
"fullscreenToggle": {},
|
||||||
|
"currentTimeDisplay": {},
|
||||||
|
"timeDivider": {},
|
||||||
|
"durationDisplay": {},
|
||||||
|
"remainingTimeDisplay": {},
|
||||||
|
"progressControl": {},
|
||||||
|
"volumeControl": {},
|
||||||
|
"muteToggle": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
init: function(player, options){
|
init: function(player, options){
|
||||||
this._super(player, options);
|
this._super(player, options);
|
||||||
|
|
||||||
player.addEvent("play", this.proxy(this.show));
|
player.addEvent("play", this.proxy(function(){
|
||||||
|
this.fadeIn();
|
||||||
player.addEvent("mouseover", this.proxy(this.reveal));
|
this.player.addEvent("mouseover", this.proxy(this.fadeIn));
|
||||||
player.addEvent("mouseout", this.proxy(this.conceal));
|
this.player.addEvent("mouseout", this.proxy(this.fadeOut));
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
createElement: function(){
|
createElement: function(){
|
||||||
@ -237,13 +254,14 @@ _V_.ControlBar = _V_.Component.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Used for transitions (fading out)
|
fadeIn: function(){
|
||||||
reveal: function(){
|
this._super();
|
||||||
this.el.style.opacity = 1;
|
this.player.triggerEvent("controlsvisible");
|
||||||
},
|
},
|
||||||
|
|
||||||
conceal: function(){
|
fadeOut: function(){
|
||||||
this.el.style.opacity = 0;
|
this._super();
|
||||||
|
this.player.triggerEvent("controlshidden");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -358,24 +376,18 @@ _V_.Slider = _V_.Component.extend({
|
|||||||
init: function(player, options){
|
init: function(player, options){
|
||||||
this._super(player, options);
|
this._super(player, options);
|
||||||
|
|
||||||
_V_.each.call(this, this.components, function(comp){
|
|
||||||
if (comp instanceof _V_[this.barClass]) {
|
|
||||||
this.bar = comp;
|
|
||||||
} else if (comp instanceof _V_[this.handleClass]) {
|
|
||||||
this.handle = comp;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
player.addEvent(this.playerEvent, _V_.proxy(this, this.update));
|
player.addEvent(this.playerEvent, _V_.proxy(this, this.update));
|
||||||
|
|
||||||
this.addEvent("mousedown", this.onMouseDown);
|
this.addEvent("mousedown", this.onMouseDown);
|
||||||
this.addEvent("focus", this.onFocus);
|
this.addEvent("focus", this.onFocus);
|
||||||
this.addEvent("blur", this.onBlur);
|
this.addEvent("blur", this.onBlur);
|
||||||
|
|
||||||
// Update Display
|
this.player.addEvent("controlsvisible", this.proxy(this.update));
|
||||||
// Need to wait for styles to be loaded.
|
|
||||||
// TODO - replace setTimeout with stylesReady function.
|
// This is actually to fix the volume handle position. http://twitter.com/#!/gerritvanaaken/status/159046254519787520
|
||||||
setTimeout(this.proxy(this.update), 0);
|
// this.player.one("timeupdate", this.proxy(this.update));
|
||||||
|
|
||||||
|
this.update();
|
||||||
},
|
},
|
||||||
|
|
||||||
createElement: function(type, attrs) {
|
createElement: function(type, attrs) {
|
||||||
@ -426,12 +438,15 @@ _V_.Slider = _V_.Component.extend({
|
|||||||
// If there is a handle, we need to account for the handle in our calculation for progress bar
|
// If there is a handle, we need to account for the handle in our calculation for progress bar
|
||||||
// so that it doesn't fall short of or extend past the handle.
|
// so that it doesn't fall short of or extend past the handle.
|
||||||
if (handle) {
|
if (handle) {
|
||||||
|
|
||||||
var box = this.el,
|
var box = this.el,
|
||||||
boxWidth = box.offsetWidth,
|
boxWidth = box.offsetWidth,
|
||||||
|
|
||||||
|
handleWidth = handle.el.offsetWidth,
|
||||||
|
|
||||||
// The width of the handle in percent of the containing box
|
// The width of the handle in percent of the containing box
|
||||||
// In IE, widths may not be ready yet causing NaN
|
// In IE, widths may not be ready yet causing NaN
|
||||||
handlePercent = (handle.el.offsetWidth) ? handle.el.offsetWidth / boxWidth : 0,
|
handlePercent = (handleWidth) ? handleWidth / boxWidth : 0,
|
||||||
|
|
||||||
// Get the adjusted size of the box, considering that the handle's center never touches the left or right side.
|
// Get the adjusted size of the box, considering that the handle's center never touches the left or right side.
|
||||||
// There is a margin of half the handle's width on both sides.
|
// There is a margin of half the handle's width on both sides.
|
||||||
@ -495,6 +510,12 @@ _V_.Slider = _V_.Component.extend({
|
|||||||
// Progress Control: Seek, Load Progress, and Play Progress
|
// Progress Control: Seek, Load Progress, and Play Progress
|
||||||
_V_.ProgressControl = _V_.Component.extend({
|
_V_.ProgressControl = _V_.Component.extend({
|
||||||
|
|
||||||
|
options: {
|
||||||
|
components: {
|
||||||
|
"seekBar": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
createElement: function(){
|
createElement: function(){
|
||||||
return this._super("div", {
|
return this._super("div", {
|
||||||
className: "vjs-progress-control vjs-control"
|
className: "vjs-progress-control vjs-control"
|
||||||
@ -506,8 +527,16 @@ _V_.ProgressControl = _V_.Component.extend({
|
|||||||
// Seek Bar and holder for the progress bars
|
// Seek Bar and holder for the progress bars
|
||||||
_V_.SeekBar = _V_.Slider.extend({
|
_V_.SeekBar = _V_.Slider.extend({
|
||||||
|
|
||||||
barClass: "PlayProgressBar",
|
options: {
|
||||||
handleClass: "SeekHandle",
|
components: {
|
||||||
|
"loadProgressBar": {},
|
||||||
|
|
||||||
|
// Set property names to bar and handle to match with the parent Slider class is looking for
|
||||||
|
"bar": { componentClass: "PlayProgressBar" },
|
||||||
|
"handle": { componentClass: "SeekHandle" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
playerEvent: "timeupdate",
|
playerEvent: "timeupdate",
|
||||||
|
|
||||||
init: function(player, options){
|
init: function(player, options){
|
||||||
@ -614,6 +643,12 @@ _V_.SeekHandle = _V_.Component.extend({
|
|||||||
// Progress Control: Seek, Load Progress, and Play Progress
|
// Progress Control: Seek, Load Progress, and Play Progress
|
||||||
_V_.VolumeControl = _V_.Component.extend({
|
_V_.VolumeControl = _V_.Component.extend({
|
||||||
|
|
||||||
|
options: {
|
||||||
|
components: {
|
||||||
|
"volumeBar": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
createElement: function(){
|
createElement: function(){
|
||||||
return this._super("div", {
|
return this._super("div", {
|
||||||
className: "vjs-volume-control vjs-control"
|
className: "vjs-volume-control vjs-control"
|
||||||
@ -624,8 +659,13 @@ _V_.VolumeControl = _V_.Component.extend({
|
|||||||
|
|
||||||
_V_.VolumeBar = _V_.Slider.extend({
|
_V_.VolumeBar = _V_.Slider.extend({
|
||||||
|
|
||||||
barClass: "VolumeLevel",
|
options: {
|
||||||
handleClass: "VolumeHandle",
|
components: {
|
||||||
|
"bar": { componentClass: "VolumeLevel" },
|
||||||
|
"handle": { componentClass: "VolumeHandle" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
playerEvent: "volumechange",
|
playerEvent: "volumechange",
|
||||||
|
|
||||||
createElement: function(){
|
createElement: function(){
|
||||||
|
86
src/core.js
86
src/core.js
@ -52,9 +52,7 @@ VideoJS.options = {
|
|||||||
// techOrder: ["flash","html5"],
|
// techOrder: ["flash","html5"],
|
||||||
|
|
||||||
html5: {},
|
html5: {},
|
||||||
flash: {
|
flash: { swf: "http://vjs.zencdn.net/c/video-js.swf" },
|
||||||
swf: "http://vjs.zencdn.net/c/video-js.swf"
|
|
||||||
},
|
|
||||||
|
|
||||||
// Default of web browser is 300x150. Should rely on source width/height.
|
// Default of web browser is 300x150. Should rely on source width/height.
|
||||||
width: "auto",
|
width: "auto",
|
||||||
@ -64,44 +62,52 @@ VideoJS.options = {
|
|||||||
defaultVolume: 0.00, // The freakin seaguls are driving me crazy!
|
defaultVolume: 0.00, // The freakin seaguls are driving me crazy!
|
||||||
|
|
||||||
// Included control sets
|
// Included control sets
|
||||||
components: [
|
components: {
|
||||||
"poster",
|
"poster": {},
|
||||||
"loadingSpinner",
|
"loadingSpinner": {},
|
||||||
"bigPlayButton",
|
"bigPlayButton": {},
|
||||||
{ name: "controlBar", options: {
|
"controlBar": {},
|
||||||
components: [
|
"subtitlesDisplay": {}
|
||||||
"playToggle",
|
|
||||||
"fullscreenToggle",
|
|
||||||
"currentTimeDisplay",
|
|
||||||
"timeDivider",
|
|
||||||
"durationDisplay",
|
|
||||||
"remainingTimeDisplay",
|
|
||||||
{ name: "progressControl", options: {
|
|
||||||
components: [
|
|
||||||
{ name: "seekBar", options: {
|
|
||||||
components: [
|
|
||||||
"loadProgressBar",
|
|
||||||
"playProgressBar",
|
|
||||||
"seekHandle"
|
|
||||||
]}
|
|
||||||
}
|
}
|
||||||
]}
|
|
||||||
},
|
// components: [
|
||||||
{ name: "volumeControl", options: {
|
// "poster",
|
||||||
components: [
|
// "loadingSpinner",
|
||||||
{ name: "volumeBar", options: {
|
// "bigPlayButton",
|
||||||
components: [
|
// { name: "controlBar", options: {
|
||||||
"volumeLevel",
|
// components: [
|
||||||
"volumeHandle"
|
// "playToggle",
|
||||||
]}
|
// "fullscreenToggle",
|
||||||
}
|
// "currentTimeDisplay",
|
||||||
]}
|
// "timeDivider",
|
||||||
},
|
// "durationDisplay",
|
||||||
"muteToggle"
|
// "remainingTimeDisplay",
|
||||||
]
|
// { name: "progressControl", options: {
|
||||||
}},
|
// components: [
|
||||||
"subtitlesDisplay"/*, "replay"*/
|
// { name: "seekBar", options: {
|
||||||
]
|
// components: [
|
||||||
|
// "loadProgressBar",
|
||||||
|
// "playProgressBar",
|
||||||
|
// "seekHandle"
|
||||||
|
// ]}
|
||||||
|
// }
|
||||||
|
// ]}
|
||||||
|
// },
|
||||||
|
// { name: "volumeControl", options: {
|
||||||
|
// components: [
|
||||||
|
// { name: "volumeBar", options: {
|
||||||
|
// components: [
|
||||||
|
// "volumeLevel",
|
||||||
|
// "volumeHandle"
|
||||||
|
// ]}
|
||||||
|
// }
|
||||||
|
// ]}
|
||||||
|
// },
|
||||||
|
// "muteToggle"
|
||||||
|
// ]
|
||||||
|
// }},
|
||||||
|
// "subtitlesDisplay"/*, "replay"*/
|
||||||
|
// ]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set CDN Version of swf
|
// Set CDN Version of swf
|
||||||
|
@ -226,6 +226,13 @@ _V_.extend({
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
},
|
||||||
|
|
||||||
|
one: function(elem, type, fn) {
|
||||||
|
_V_.addEvent(elem, type, function(){
|
||||||
|
_V_.removeEvent(elem, type, arguments.callee)
|
||||||
|
fn.apply(this, arguments);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ _V_.Player = _V_.Component.extend({
|
|||||||
|
|
||||||
var el = this.el = _V_.createElement("div"), // Div to contain video and controls
|
var el = this.el = _V_.createElement("div"), // Div to contain video and controls
|
||||||
options = this.options = {},
|
options = this.options = {},
|
||||||
width = options.width = tag.width,
|
width = options.width = tag.getAttribute('width'),
|
||||||
height = options.height = tag.height,
|
height = options.height = tag.getAttribute('height'),
|
||||||
|
|
||||||
// Browsers default to 300x150 if there's no width/height or video size data.
|
// Browsers default to 300x150 if there's no width/height or video size data.
|
||||||
initWidth = width || 300,
|
initWidth = width || 300,
|
||||||
@ -81,9 +81,7 @@ _V_.Player = _V_.Component.extend({
|
|||||||
// When the API is ready, loop through the components and add to the player.
|
// When the API is ready, loop through the components and add to the player.
|
||||||
if (options.controls) {
|
if (options.controls) {
|
||||||
this.ready(function(){
|
this.ready(function(){
|
||||||
this.each(this.options.components, function(set){
|
this.initComponents();
|
||||||
this.addComponent(set);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,22 +125,23 @@ _V_.Player = _V_.Component.extend({
|
|||||||
tracks: []
|
tracks: []
|
||||||
};
|
};
|
||||||
|
|
||||||
options.src = this.tag.src;
|
options.src = this.tag.getAttribute("src");
|
||||||
options.controls = this.tag.getAttribute("controls") !== null;
|
options.controls = this.tag.getAttribute("controls") !== null;
|
||||||
options.poster = this.tag.poster;
|
options.poster = this.tag.getAttribute("poster");
|
||||||
options.preload = this.tag.preload;
|
options.preload = this.tag.getAttribute("preload");
|
||||||
options.autoplay = this.tag.getAttribute("autoplay") !== null; // hasAttribute not IE <8 compatible
|
options.autoplay = this.tag.getAttribute("autoplay") !== null; // hasAttribute not IE <8 compatible
|
||||||
options.loop = this.tag.getAttribute("loop") !== null;
|
options.loop = this.tag.getAttribute("loop") !== null;
|
||||||
options.muted = this.tag.getAttribute("muted") !== null;
|
options.muted = this.tag.getAttribute("muted") !== null;
|
||||||
|
|
||||||
for (var c,i=0,j=this.tag.children;i<j.length;i++) {
|
if (this.tag.hasChildNodes()) {
|
||||||
|
for (var c,i=0,j=this.tag.childNodes;i<j.length;i++) {
|
||||||
c = j[i];
|
c = j[i];
|
||||||
if (c.nodeName == "SOURCE") {
|
if (c.nodeName == "SOURCE") {
|
||||||
options.sources.push({
|
options.sources.push({
|
||||||
src: c.src,
|
src: c.getAttribute('src'),
|
||||||
type: c.type,
|
type: c.getAttribute('type'),
|
||||||
media: c.media,
|
media: c.getAttribute('media'),
|
||||||
title: c.title
|
title: c.getAttribute('title')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (c.nodeName == "TRACK") {
|
if (c.nodeName == "TRACK") {
|
||||||
@ -157,6 +156,7 @@ _V_.Player = _V_.Component.extend({
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -487,6 +487,11 @@ _V_.Player = _V_.Component.extend({
|
|||||||
this.el[requestFullScreen.requestFn]();
|
this.el[requestFullScreen.requestFn]();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In case the user presses escape to exit fullscreen, we need to update fullscreen status
|
||||||
|
_V_.addEvent(document, requestFullScreen.eventName, this.proxy(function(){
|
||||||
|
this.isFullScreen = document[requestFullScreen.isFullScreen];
|
||||||
|
}));
|
||||||
|
|
||||||
} else if (this.tech.supportsFullScreen()) {
|
} else if (this.tech.supportsFullScreen()) {
|
||||||
this.apiCall("enterFullScreen");
|
this.apiCall("enterFullScreen");
|
||||||
|
|
||||||
@ -494,7 +499,7 @@ _V_.Player = _V_.Component.extend({
|
|||||||
this.enterFullWindow();
|
this.enterFullWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.videoIsFullScreen = true;
|
this.isFullScreen = true;
|
||||||
this.triggerEvent("fullscreenchange");
|
this.triggerEvent("fullscreenchange");
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -515,7 +520,6 @@ _V_.Player = _V_.Component.extend({
|
|||||||
|
|
||||||
_V_.addEvent(document, requestFullScreen.eventName, this.proxy(function(){
|
_V_.addEvent(document, requestFullScreen.eventName, this.proxy(function(){
|
||||||
_V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
|
_V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
|
||||||
_V_.log("document fullscreeneventchange")
|
|
||||||
this.loadTech(this.techName, { src: this.values.src })
|
this.loadTech(this.techName, { src: this.values.src })
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -532,14 +536,14 @@ _V_.Player = _V_.Component.extend({
|
|||||||
this.exitFullWindow();
|
this.exitFullWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.videoIsFullScreen = false;
|
this.isFullScreen = false;
|
||||||
this.triggerEvent("fullscreenchange");
|
this.triggerEvent("fullscreenchange");
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
enterFullWindow: function(){
|
enterFullWindow: function(){
|
||||||
this.videoIsFullWindow = true;
|
this.isFullWindow = true;
|
||||||
|
|
||||||
// Storing original doc overflow value to return to when fullscreen is off
|
// Storing original doc overflow value to return to when fullscreen is off
|
||||||
this.docOrigOverflow = document.documentElement.style.overflow;
|
this.docOrigOverflow = document.documentElement.style.overflow;
|
||||||
@ -559,7 +563,7 @@ _V_.Player = _V_.Component.extend({
|
|||||||
|
|
||||||
fullWindowOnEscKey: function(event){
|
fullWindowOnEscKey: function(event){
|
||||||
if (event.keyCode == 27) {
|
if (event.keyCode == 27) {
|
||||||
if (this.videoIsFullScreen == true) {
|
if (this.isFullScreen == true) {
|
||||||
this.cancelFullScreen();
|
this.cancelFullScreen();
|
||||||
} else {
|
} else {
|
||||||
this.exitFullWindow();
|
this.exitFullWindow();
|
||||||
@ -568,7 +572,7 @@ _V_.Player = _V_.Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
exitFullWindow: function(){
|
exitFullWindow: function(){
|
||||||
this.videoIsFullWindow = false;
|
this.isFullWindow = false;
|
||||||
_V_.removeEvent(document, "keydown", this.fullWindowOnEscKey);
|
_V_.removeEvent(document, "keydown", this.fullWindowOnEscKey);
|
||||||
|
|
||||||
// Unhide scroll bars.
|
// Unhide scroll bars.
|
||||||
@ -729,6 +733,8 @@ _V_.Player = _V_.Component.extend({
|
|||||||
(function(){
|
(function(){
|
||||||
var requestFn,
|
var requestFn,
|
||||||
cancelFn,
|
cancelFn,
|
||||||
|
eventName,
|
||||||
|
isFullScreen,
|
||||||
playerProto = _V_.Player.prototype;
|
playerProto = _V_.Player.prototype;
|
||||||
|
|
||||||
// Current W3C Spec
|
// Current W3C Spec
|
||||||
@ -738,6 +744,7 @@ _V_.Player = _V_.Component.extend({
|
|||||||
requestFn = "requestFullscreen";
|
requestFn = "requestFullscreen";
|
||||||
cancelFn = "exitFullscreen";
|
cancelFn = "exitFullscreen";
|
||||||
eventName = "fullscreenchange";
|
eventName = "fullscreenchange";
|
||||||
|
isFullScreen = "fullScreen";
|
||||||
|
|
||||||
// Webkit (Chrome/Safari) and Mozilla (Firefox) have working implementaitons
|
// 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',
|
// that use prefixes and vary slightly from the new W3C spec. Specifically, using 'exit' instead of 'cancel',
|
||||||
@ -754,6 +761,11 @@ _V_.Player = _V_.Component.extend({
|
|||||||
eventName = prefix + "fullscreenchange";
|
eventName = prefix + "fullscreenchange";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prefix == "webkit") {
|
||||||
|
isFullScreen = prefix + "IsFullScreen";
|
||||||
|
} else {
|
||||||
|
isFullScreen = prefix + "FullScreen";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ _V_.flash = _V_.PlaybackTech.extend({
|
|||||||
|
|
||||||
// If source was supplied pass as a flash var.
|
// If source was supplied pass as a flash var.
|
||||||
if (source) {
|
if (source) {
|
||||||
flashVars.src = source.src;
|
flashVars.src = encodeURIComponent(source.src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to box.
|
// Add to box.
|
||||||
|
Reference in New Issue
Block a user