1
0
mirror of https://github.com/videojs/video.js.git synced 2024-12-31 03:11:11 +02:00

Attempting new UI organization.

This commit is contained in:
Steve Heffernan 2011-11-21 17:19:31 -08:00
parent 193172498c
commit a314c0a242
10 changed files with 353 additions and 49 deletions

View File

@ -59,14 +59,14 @@
<tr><th colspan="2">HTML5</th><th colspan="2">H5Swf</th><th colspan="2">YouTube</th></tr>
<tr>
<td colspan="2">
<video id="vid1" class="video-js vjs-default-skin" controls preload="none" width="480" height="198"
<video id="vid1" class="video-js vjs-default-skin" controls preload="auto" width="480" height="198"
poster="http://video-js.zencoder.com/oceans-clip.png">
<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.webm" type='video/webm'>
</video>
</td>
<td colspan="2">
<video id="vid2" class="video-js vjs-default-skin" controls preload="none" width="480" height="198"
<video id="vid2" class="video-js vjs-default-skin" controls preload="auto" width="480" height="198"
poster="http://video-js.zencoder.com/oceans-clip.png">
<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'> -->

View File

@ -1,7 +1,7 @@
$(function(){
var tech, i,
techList = ["html5","h5swf"],
props = "error,currentSrc,networkState,buffered,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoWidth,videoHeight,textTracks,preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,controls,volume,muted,defaultMuted".split(","),
props = "error,currentSrc,networkState,buffered,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoWidth,videoHeight,textTracks,preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,controls,volume,muted,defaultMuted,poster".split(","),
methods = "play,pause,src,load,canPlayType,addTextTrack",
notUsed = "mediaGroup,controller,videoTracks,audioTracks,defaultPlaybackRate";
@ -16,8 +16,6 @@ $(function(){
var eventsId = "#"+this+"_events",
type = evt.type,
prev = $(eventsId+" div").first();
if (type == 'error') _V_.log(evt);
if (prev && prev.html() && prev.html().indexOf(type + " ") === 0) {
var countSpan = prev.children(".count");
@ -47,7 +45,6 @@ $(function(){
result = (result.length > 0) ? "s:"+result.start(0)+" e:"+result.end(0) : "-";
}
} catch(e) {
_V_.log(e);
result = "<span class='na'>N/A</span>";
}
$("#"+this.currentTechName+prop).html(result);

View File

@ -19,6 +19,8 @@
<script src="src/log.js"></script>
<script src="src/ui.js"></script>
<script src="src/api.js"></script>
<script src="src/events.js"></script>
@ -47,7 +49,7 @@
</head>
<body>
<video id="vid1" class="video-js vjs-default-skin" autoplay preload="auto" width="640" height="264"
<video id="vid1" class="video-js vjs-default-skin" controls preload="none" width="640" height="264"
poster="http://video-js.zencoder.com/oceans-clip.png"
data-setup='{"techOrder":["html5","h5swf","youtube"]}'>
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4'>

Binary file not shown.

View File

@ -117,7 +117,7 @@ VideoJS.fn.extend({
// Turn on fullscreen (or window) mode
enterFullScreen: function(){
if (this.supportsFullScreen()) {
this.api("enterFullScreen");
this.apiCall("enterFullScreen");
} else {
this.enterFullWindow();
}
@ -142,10 +142,7 @@ VideoJS.fn.extend({
this.docOrigOverflow = document.documentElement.style.overflow;
// Add listener for esc key to exit fullscreen
_V_.addEvent(document, "keydown", _V_.proxy(this, this.fullscreenOnEscKey));
// Add listener for a window resize
_V_.addEvent(window, "resize", _V_.proxy(this, this.fullscreenOnWindowResize));
_V_.addEvent(document, "keydown", _V_.proxy(this, this.fullWindowOnEscKey));
// Hide any scroll bars
document.documentElement.style.overflow = 'hidden';
@ -156,11 +153,16 @@ VideoJS.fn.extend({
this.triggerEvent("enterFullWindow");
},
fullWindowOnEscKey: function(event){
if (event.keyCode == 27) {
this.exitFullScreen();
}
},
exitFullWindow: function(){
this.videoIsFullScreen = false;
_V_.removeEvent(document, "keydown", this.fullscreenOnEscKey);
_V_.removeEvent(window, "resize", this.fullscreenOnWindowResize);
_V_.removeEvent(document, "keydown", this.fullWindowOnEscKey);
// Unhide scroll bars.
document.documentElement.style.overflow = this.docOrigOverflow;
@ -272,6 +274,7 @@ VideoJS.fn.extend({
controls: function(){ return this.options.controls; },
textTracks: function(){ return this.options.tracks; },
poster: function(){ return this.apiCall("poster"); },
error: function(){ return this.apiCall("error"); },
networkState: function(){ return this.apiCall("networkState"); },

View File

@ -96,10 +96,10 @@ VideoJS.fn.newBehavior("seekBar",
},
updateSeekBars: function(){
// If scrubbing, use the cached currentTime value for speed
var progress = /* (this.scrubbing) ? this.scrubTime / this.duration() : */ this.currentTime() / this.duration();
var progress = /* (this.scrubbing) ? this.values.currentTime / this.duration() : */ this.currentTime() / this.duration();
// Protect against no duration and other division issues
if (isNaN(progress)) { progress = 0; }
this.each(this.bels.seekBars, function(bar){
var barData = _V_.getData(bar),
barX = _V_.findPosX(bar),
@ -165,33 +165,36 @@ VideoJS.fn.newBehavior("seekHandle",
{}
);
/* Play Progress Bar Behaviors
/*
CHANGED TO SEEK BAR
Play Progress Bar Behaviors
================================================================================ */
VideoJS.fn.newBehavior("playProgressBar",
function(element){
if (!this.bels.playProgressBars) {
this.bels.playProgressBars = [];
this.addEvent("timeupdate", this.updatePlayProgressBars);
}
this.bels.playProgressBars.push(element);
},
function(){
// Remove
},
{
// Ajust the play progress bar's width based on the current play time
updatePlayProgressBars: function(){
// If scrubbing, use the cached currentTime value for speed
var progress = (this.scrubbing) ? this.values.currentTime / this.duration() : this.currentTime() / this.duration();
// Protect against no duration and other division issues
if (isNaN(progress)) { progress = 0; }
// Update bar length
this.each(this.bels.playProgressBars, function(bar){
if (bar.style) { bar.style.width = _V_.round(progress * 100, 2) + "%"; }
});
}
}
);
// VideoJS.fn.newBehavior("playProgressBar",
// function(element){
// if (!this.bels.playProgressBars) {
// this.bels.playProgressBars = [];
// this.addEvent("timeupdate", this.updatePlayProgressBars);
// }
// this.bels.playProgressBars.push(element);
// },
// function(){
// // Remove
// },
// {
// // Ajust the play progress bar's width based on the current play time
// updatePlayProgressBars: function(){
// // If scrubbing, use the cached currentTime value for speed
// var progress = (this.scrubbing) ? this.values.currentTime / this.duration() : this.currentTime() / this.duration();
// _V_.log("PROG", progress)
// // Protect against no duration and other division issues
// if (isNaN(progress)) { progress = 0; }
// // Update bar length
// this.each(this.bels.playProgressBars, function(bar){
// if (bar.style) { bar.style.width = _V_.round(progress * 100, 2) + "%"; }
// });
// }
// }
// );
/* Load Progress Bar Behaviors
================================================================================ */

View File

@ -104,6 +104,9 @@ var VideoJS = _V_ = function(id, addOptions, ready){
// this.cels.mainControls.playButton = playButtonDiv;
this.cels = {};
// New holder for UI objects
this.ui = {};
// Cache for video property values.
this.values = {};
@ -117,8 +120,12 @@ var VideoJS = _V_ = function(id, addOptions, ready){
if (this.options.controls) {
this.addEvent("techready", function(){
this.each(this.options.controlSets, function(set){
_V_.controlSets[set].add.call(this);
this.appendUI(set);
});
// this.each(this.options.controlSets, function(set){
// _V_.controlSets[set].add.call(this);
// });
});
}
@ -133,7 +140,8 @@ var VideoJS = _V_ = function(id, addOptions, ready){
VideoJS.options = {
techOrder: ["html5","h5swf","flowplayer"],
controlSets: ["bigPlayButton", "bar", "subtitlesBox"/*, "replay"*/],
// controlSets: ["bigPlayButton", "bar", "subtitlesBox"/*, "replay"*/],
controlSets: ["bigPlayButton", "controlBar"/*, "bar", "subtitlesBox", "replay"*/],
controlSetOptions: {
bigPlayButton: {},
bar: {},
@ -286,6 +294,29 @@ VideoJS.fn = VideoJS.prototype = {
if (typeof element == "string") { element = _V_.el(element); }
this.behaviors[behavior].remove.call(this, element);
},
appendUI: function(nameORobj){
var name, uiClass, options, ui;
if (typeof set == "string") {
name = nameORobj;
// Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)
uiClass = _V_.capitalize(nameORobj);
// Can also pass in object to define a different class than the name and add other options
} else {
name = nameORobj.name;
uiClass = nameORobj.uiClass;
options = nameORobj.options;
}
// Create a new object & element for this controls set
ui = this.ui[name] = new _V_[uiClass](this);
// Add the UI object's element to the container div (box)
this.box.appendChild(ui.el);
},
/* Fallbacks for unsupported event types
================================================================================ */
@ -380,9 +411,9 @@ VideoJS.fn = VideoJS.prototype = {
this.currentTime(0);
this.play();
} else {
this.pause();
this.currentTime(0);
this.pause();
// this.pause();
// this.currentTime(0);
// this.pause();
}
},

View File

@ -119,6 +119,10 @@ _V_.extend({
return h + m + s;
},
capitalize: function(string){
return string.charAt(0).toUpperCase() + string.slice(1);
},
// Return the relative horizonal position of an event as a value from 0-1
getRelativePosition: function(x, relativeElement){
return Math.max(0, Math.min(1, (x - _V_.findPosX(relativeElement)) / relativeElement.offsetWidth));

View File

@ -38,7 +38,8 @@ VideoJS.tech.h5swf = {
autoplay: this.options.autoplay,
preload: this.options.preload,
loop: this.options.loop,
muted: this.options.muted
muted: this.options.muted,
poster: this.options.poster,
},
params = {
@ -105,6 +106,7 @@ VideoJS.tech.h5swf = {
pause: function(){ this.tels.h5swf.vjs_pause(); },
src: function(src){ this.tels.h5swf.vjs_src(src); },
load: function(){ this.tels.h5swf.vjs_load(); },
poster: function(){ this.tels.h5swf.vjs_getProperty("poster"); },
buffered: function(){
return _V_.createTimeRange(0, this.tels.h5swf.vjs_getProperty("buffered"));

262
dev/src/ui.js Normal file
View File

@ -0,0 +1,262 @@
(function(){var initializing=false, fnTest=/xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; _V_.Class = function(){}; _V_.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;};})();
// bar.playToggle = new _V_.PlayToggle(player, options);
/* UI Component- Base class for all UI objects
================================================================================ */
_V_.UIComponent = _V_.Class.extend({
init: function(player, options){
this.player = player;
// Array of sub-components
this.components = [];
},
createElement: function(){},
destroy: function(){},
// Add child components to this component.
// 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.
addComponent: function(nameORobject){
var name, uiClass, options, component;
if (typeof set == "string") {
name = nameORobj;
// Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)
uiClass = _V_.capitalize(nameORobj);
// Can also pass in object to define a different class than the name and add other options
} else {
name = nameORobj.name;
uiClass = nameORobj.uiClass;
options = nameORobj.options;
}
// Create a new object & element for this controls set
component = this.ui[name] = new _V_[uiClass](this);
// Add the UI object's element to the container div (box)
this.el.appendChild(component.el);
},
show: function(){
this.el.style.display = "block";
},
hide: function(){
this.el.style.display = "none";
}
});
/* Button - Base class for all buttons
================================================================================ */
_V_.Button = _V_.UIComponent.extend({
init: function(player, options){
this.player = player;
this.el = this.createElement();
_V_.addEvent(this.el, "click", _V_.proxy(this, this.onClick));
_V_.addEvent(this.el, "focus", _V_.proxy(this, this.onFocus));
_V_.addEvent(this.el, "blur", _V_.proxy(this, this.onBlur));
this._super(player, options);
},
createElement: function(type, options){
_V_.merge({
role: "button",
tabIndex: 0
}, options || {})
return _V_.createElement(type || "div", options);
},
// Click - Override with specific functionality for button
onClick: function(){},
// Focus - Add keyboard functionality to element
onFocus: function(){
_V_.addEvent(document, "keyup", _V_.proxy(this, this.onKeyPress));
},
// KeyPress (document level) - Trigger click when keys are pressed
onKeyPress: function(event){
// Check for space bar (32) or enter (13) keys
if (event.which == 32 || event.which == 13) {
event.preventDefault();
this.onClick();
}
},
// Blur - Remove keyboard triggers
onBlur: function(){
_V_.removeEvent(document, "keyup", _V_.proxy(this, this.onKeyPress));
}
});
/* Play Button
================================================================================ */
_V_.PlayButton = _V_.Button.extend({
createElement: function(){
return this._super("div", {
className: "vjs-play-button vjs-control",
innerHTML: '<div><span class="vjs-control-text">Play</span></div>'
});
},
onClick: function(){
this.player.play();
}
});
/* Pause Button
================================================================================ */
_V_.PauseButton = _V_.Button.extend({
createElement: function(){
return this._super("div", {
className: "vjs-pause-button vjs-control",
innerHTML: '<div><span class="vjs-control-text">Pause</span></div>'
});
},
onClick: function(){
this.player.pause();
}
});
/* Play Toggle - Play or Pause Media
================================================================================ */
_V_.PlayToggle = _V_.Button.extend({
init: function(player, options){
player.addEvent("play", _V_.proxy(this, this.onPlay));
player.addEvent("pause", _V_.proxy(this, this.onPause));
return this._super(player, options);
},
createElement: function(){
return this._super("div", {
className: "vjs-play-control vjs-control",
innerHTML: '<div><span class="vjs-control-text">Play</span></div>'
});
},
// OnClick - Toggle between play and pause
onClick: function(){
if (this.player.paused()) {
this.player.play();
} else {
this.player.pause();
}
},
// OnPlay - Add the vjs-playing class to the element so it can change appearance
onPlay: function(){
_V_.removeClass(this.el, "vjs-paused");
_V_.addClass(this.el, "vjs-playing");
},
// OnPause - Add the vjs-paused class to the element so it can change appearance
onPause: function(){
_V_.removeClass(this.el, "vjs-playing");
_V_.addClass(this.el, "vjs-paused");
}
});
/* Fullscreen Toggle Behaviors
================================================================================ */
_V_.FullscreenToggle = _V_.Button.extend({
createElement: function(){
return this._super("div", {
className: "vjs-fullscreen-control vjs-control",
innerHTML: '<div><span class="vjs-control-text">Fullscreen</span></div>'
});
},
onClick: function(){
if (!this.player.videoIsFullScreen) {
this.player.enterFullScreen();
} else {
this.player.exitFullScreen();
}
}
});
/* Big Play Button
================================================================================ */
_V_.BigPlayButton = _V_.Button.extend({
init: function(player){
player.addEvent("play", _V_.proxy(this, this.hide));
player.addEvent("ended", _V_.proxy(this, this.show));
return this._super(player);
},
createElement: function(){
return this._super("div", {
className: "vjs-big-play-button",
innerHTML: "<span></span>"
});
},
onClick: function(){
this.player.play();
}
});
/* Control Bar
================================================================================ */
_V_.ControlBar = _V_.UIComponent.extend({
init: function(player, options){
this.player = player;
this.el = this.createElement();
this.children = [];
player.addEvent("mouseover", _V_.proxy(this, this.show));
player.addEvent("mouseout", _V_.proxy(this, this.hide));
_V_.each(options.children, function(child){
this.appendUI(child)
});
var pt = this.children["playToggle"] = new _V_.PlayToggle(player);
this.el.appendChild(pt.el);
var ft = this.children["fullscreenToggle"] = new _V_.FullscreenToggle(player);
this.el.appendChild(ft.el);
},
createElement: function(){
return _V_.createElement("div", {
className: "vjs-controls"
});
},
appendUI: function(name){
var component = this.children[name] = new _V_.PlayToggle(player);
this.el.appendChild(pt.el);
},
show: function(){
// Used for transitions (fading out)
this.el.style.opacity = 1;
// bar.style.display = "block";
},
hide: function(){
this.el.style.opacity = 0;
// bar.style.display = "none";
}
});