mirror of
https://github.com/videojs/video.js.git
synced 2024-12-25 02:42:10 +02:00
Organized API and files.
Abstracted player API from video API. Started on Control fading through CSS transitions.
This commit is contained in:
parent
54308bb616
commit
98a3d991a0
@ -133,6 +133,9 @@ Changelog
|
||||
---------
|
||||
2.0.3
|
||||
|
||||
- Feature: Made returning to the start at the end of the movie an option ("returnToStart").
|
||||
- Feature: Added loop option to loop movie ("loop").
|
||||
- Feature: Reorganized player API and listeners.
|
||||
- Feature: Setup method now has a callback, so you can more easily work with the player after setup
|
||||
- Changes: setupAllWhenReady is now just setupAll (backward compatible)
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
cat src/_begin.js > combined.js
|
||||
|
||||
cat src/main.js >> combined.js
|
||||
cat src/api.js >> combined.js
|
||||
cat src/html5.js >> combined.js
|
||||
cat src/flash.js >> combined.js
|
||||
cat src/behaviors.js >> combined.js
|
||||
|
@ -5,10 +5,13 @@
|
||||
<title>HTML5 Video Player: flowplayer</title>
|
||||
|
||||
<!-- Include the VideoJS Library -->
|
||||
<script src="../src/video.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../src/main.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../src/api.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../src/html5.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../src/flash.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../src/behaviors.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../src/lib.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../src/video-js.jquery.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- <script type="text/javascript" src="flowplayer-3.2.4.min.js"></script> -->
|
||||
<script type="text/javascript" src="video-js.flowplayer.js"></script>
|
||||
|
@ -20,80 +20,43 @@ VideoJS.flashPlayers.flowplayer = {
|
||||
},
|
||||
|
||||
api: {
|
||||
play: function(){ this.flowplayer.play(); return this; },
|
||||
onPlay: function(fn){
|
||||
this.flowplayer.onStart(fn.context(this));
|
||||
this.flowplayer.onResume(fn.context(this));
|
||||
return this;
|
||||
|
||||
setupTriggers: function(){
|
||||
this.flowplayer.onStart(function(e){ this.triggerListeners("play", e); }.context(this));
|
||||
this.flowplayer.onResume(function(e){ this.triggerListeners("play", e); }.context(this));
|
||||
this.flowplayer.onPause(function(e){ this.triggerListeners("pause", e); }.context(this));
|
||||
this.flowplayer.onVolume(function(e){ this.triggerListeners("volumechange", e); }.context(this));
|
||||
this.flowplayer.onError(function(e){ this.triggerListeners("error", e); }.context(this));
|
||||
},
|
||||
|
||||
pause: function(){ this.flowplayer.pause(); return this; },
|
||||
onPause: function(fn){
|
||||
this.flowplayer.onPause(fn.context(this));
|
||||
return this;
|
||||
},
|
||||
play: function(){ this.flowplayer.play(); },
|
||||
pause: function(){ this.flowplayer.pause(); },
|
||||
paused: function(){
|
||||
return !this.flowplayer.isPlaying(); // More accurate than isPaused
|
||||
},
|
||||
|
||||
currentTime: function(seconds){
|
||||
if (seconds !== undefined) {
|
||||
this.flowplayer.seek(seconds);
|
||||
return this;
|
||||
}
|
||||
return this.flowplayer.getTime();
|
||||
},
|
||||
currentTime: function(){ return this.flowplayer.getTime(); },
|
||||
setCurrentTime: function(seconds){ this.flowplayer.seek(seconds); },
|
||||
|
||||
duration: function(){
|
||||
var clip = this.flowplayer.getClip();
|
||||
if (clip) { return clip.duration; }
|
||||
return (clip) ? clip.duration : 0;
|
||||
},
|
||||
|
||||
buffered: function(){
|
||||
var status = this.flowplayer.getStatus();
|
||||
return [status.bufferStart, status.bufferEnd]
|
||||
return this.createTimeRange(status.bufferStart, status.bufferEnd);
|
||||
},
|
||||
|
||||
volume: function(percentAsDecimal){
|
||||
if (percentAsDecimal !== undefined) {
|
||||
this.values.volume = parseFloat(percentAsDecimal);
|
||||
this.flowplayer.setVolume(parseInt(percentAsDecimal * 100));
|
||||
this.setLocalStorage("volume", this.values.volume);
|
||||
return this;
|
||||
}
|
||||
return this.flowplayer.getVolume() / 100;
|
||||
},
|
||||
onVolumeChange: function(fn){ this.flowplayer.onVolume(fn.context(this)); return this; },
|
||||
|
||||
width: function(width){
|
||||
if (width !== undefined) {
|
||||
this.flashElement.width = width;
|
||||
this.box.style.width = width+"px";
|
||||
this.triggerResizeListeners();
|
||||
return this;
|
||||
}
|
||||
return parseInt(this.flashElement.getAttribute("width"));
|
||||
},
|
||||
height: function(height){
|
||||
if (height !== undefined) {
|
||||
this.flashElement.height = height;
|
||||
this.box.style.height = height+"px";
|
||||
this.triggerResizeListeners();
|
||||
return this;
|
||||
}
|
||||
return parseInt(this.flashElement.getAttribute("height"));
|
||||
},
|
||||
volume: function(){ return this.flowplayer.getVolume() / 100; },
|
||||
setVolume: function(percentAsDecimal){ this.flowplayer.setVolume(parseInt(percentAsDecimal * 100)); },
|
||||
|
||||
supportsFullScreen: function(){
|
||||
return false; // Flash does not allow fullscreen through javascript
|
||||
// Maybe at click listener, and say "click screen".
|
||||
},
|
||||
enterFullScreen: function(){
|
||||
this.flowplayer.toggleFullscreen();
|
||||
return this;
|
||||
},
|
||||
enterFullScreen: function(){ this.flowplayer.toggleFullscreen(); },
|
||||
|
||||
onError: function(fn){ this.flowplayer.onError(fn); return this; },
|
||||
readError: function(eventArguments){
|
||||
var errorCode = arguments[0],
|
||||
errorMessage = arguments[1];
|
||||
|
150
dev/src/api.js
Normal file
150
dev/src/api.js
Normal file
@ -0,0 +1,150 @@
|
||||
/* Player API
|
||||
================================================================================ */
|
||||
VideoJS.fn.extend({
|
||||
|
||||
/* Listener types: play, pause, timeupdate, bufferedupdate, ended, volumechange, error */
|
||||
addListener: function(type, fn){
|
||||
if (!this.listeners[type]) { this.listeners[type] = []; }
|
||||
this.listeners[type].push(fn);
|
||||
},
|
||||
|
||||
triggerListeners: function(type, e){
|
||||
this.each(this.listeners[type], function(listener){
|
||||
listener.call(this, e);
|
||||
});
|
||||
},
|
||||
|
||||
removeListener: function(type, fn){
|
||||
var listeners = this.listeners[type];
|
||||
if (!listeners) { return; }
|
||||
for (var i=0; i<listeners.length; i++) {
|
||||
if (listeners[i] == fn) {
|
||||
listeners.splice(i--, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
play: function(){ this.api.play.apply(this); return this; },
|
||||
pause: function(){ this.api.pause.apply(this); return this; },
|
||||
paused: function(){ return this.api.paused.apply(this); },
|
||||
|
||||
currentTime: function(seconds){
|
||||
if (seconds !== undefined) {
|
||||
this.values.currentTime = seconds; // Cache the last set value for smoother scrubbing.
|
||||
this.api.setCurrentTime.call(this, seconds);
|
||||
return this;
|
||||
}
|
||||
return this.api.currentTime.apply(this);
|
||||
},
|
||||
|
||||
duration: function(){ return this.api.duration.apply(this); },
|
||||
|
||||
buffered: function(){
|
||||
var buffered = this.api.buffered.apply(this),
|
||||
start = 0, end = this.values.bufferEnd = this.values.bufferEnd || 0,
|
||||
timeRange;
|
||||
|
||||
if (buffered && buffered.length > 0 && buffered.end(0) > end) {
|
||||
end = buffered.end(0);
|
||||
// Storing values allows them be overridden by setBufferedFromProgress
|
||||
this.values.bufferEnd = end;
|
||||
}
|
||||
|
||||
return this.createTimeRange(start, end);
|
||||
},
|
||||
// Mimic HTML5 TimeRange Spec.
|
||||
createTimeRange: function(start, end){
|
||||
return {
|
||||
length: 1,
|
||||
start: function() { return start; },
|
||||
end: function() { return end; }
|
||||
};
|
||||
},
|
||||
// Calculates amount of buffer is full
|
||||
bufferedPercent: function(){ return (this.duration()) ? this.buffered().end(0) / this.duration() : 0; },
|
||||
|
||||
volume: function(percentAsDecimal){
|
||||
if (percentAsDecimal !== undefined) {
|
||||
var vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1
|
||||
this.values.volume = vol;
|
||||
this.api.setVolume.call(this, vol);
|
||||
this.setLocalStorage("volume", vol);
|
||||
return this;
|
||||
}
|
||||
// if (this.values.volume) { return this.values.volume; }
|
||||
return this.api.volume.call(this);
|
||||
},
|
||||
|
||||
width: function(width, skipListeners){
|
||||
if (width !== undefined) {
|
||||
this.element.width = width; // Not using style so it can be overridden on fullscreen.
|
||||
this.box.style.width = width+"px";
|
||||
if (!skipListeners) { this.triggerListeners("resize"); }
|
||||
return this;
|
||||
}
|
||||
return parseInt(this.element.getAttribute("width"));
|
||||
// return this.element.offsetWidth;
|
||||
},
|
||||
height: function(height){
|
||||
if (height !== undefined) {
|
||||
this.element.height = height;
|
||||
this.box.style.height = height+"px";
|
||||
this.triggerListeners("resize");
|
||||
return this;
|
||||
}
|
||||
return parseInt(this.element.getAttribute("height"));
|
||||
// return this.element.offsetHeight;
|
||||
},
|
||||
size: function(width, height){
|
||||
// Skip resize listeners on width for optimization
|
||||
return this.width(width, true).height(height);
|
||||
},
|
||||
|
||||
supportsFullScreen: function(){ return this.api.supportsFullScreen.call(this); },
|
||||
|
||||
// Turn on fullscreen (or window) mode
|
||||
enterFullScreen: function(){
|
||||
if (this.supportsFullScreen()) {
|
||||
this.api.enterFullScreen.call(this);
|
||||
} else {
|
||||
this.enterFullWindow();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
exitFullScreen: function(){
|
||||
if (!this.supportsFullScreen()) {
|
||||
this.exitFullWindow();
|
||||
}
|
||||
// Otherwise Shouldn't be called since native fullscreen uses own controls.
|
||||
return this;
|
||||
},
|
||||
|
||||
enterFullWindow: function(){
|
||||
this.videoIsFullScreen = true;
|
||||
// Storing original doc overflow value to return to when fullscreen is off
|
||||
this.docOrigOverflow = document.documentElement.style.overflow;
|
||||
// Add listener for esc key to exit fullscreen
|
||||
_V_.addListener(document, "keydown", this.fullscreenOnEscKey.rEvtContext(this));
|
||||
// Add listener for a window resize
|
||||
_V_.addListener(window, "resize", this.fullscreenOnWindowResize.rEvtContext(this));
|
||||
// Hide any scroll bars
|
||||
document.documentElement.style.overflow = 'hidden';
|
||||
// Apply fullscreen styles
|
||||
_V_.addClass(this.box, "vjs-fullscreen");
|
||||
// Resize the box, controller, and poster
|
||||
this.positionAll();
|
||||
},
|
||||
|
||||
exitFullWindow: function(){
|
||||
this.videoIsFullScreen = false;
|
||||
document.removeEventListener("keydown", this.fullscreenOnEscKey, false);
|
||||
window.removeEventListener("resize", this.fullscreenOnWindowResize, false);
|
||||
// Unhide scroll bars.
|
||||
document.documentElement.style.overflow = this.docOrigOverflow;
|
||||
// Remove fullscreen styles
|
||||
_V_.removeClass(this.box, "vjs-fullscreen");
|
||||
// Resize the box, controller, and poster to original sizes
|
||||
this.positionAll();
|
||||
}
|
||||
});
|
@ -6,82 +6,61 @@
|
||||
/* Player Behaviors - How VideoJS reacts to what the video is doing.
|
||||
================================================================================ */
|
||||
VideoJS.fn.newBehavior("player", function(player){
|
||||
this.onError(this.playerOnVideoError);
|
||||
// Listen for when the video is played
|
||||
this.onPlay(this.playerOnVideoPlay);
|
||||
this.onPlay(this.trackCurrentTime);
|
||||
// Listen for when the video is paused
|
||||
this.onPause(this.playerOnVideoPause);
|
||||
this.onPause(this.stopTrackingCurrentTime);
|
||||
// Listen for when the video ends
|
||||
this.onEnded(this.playerOnVideoEnded);
|
||||
// Set interval for load progress using buffer watching method
|
||||
// this.trackCurrentTime();
|
||||
this.addListener("error", this.playerOnVideoError);
|
||||
this.addListener("play", this.playerOnVideoPlay);
|
||||
this.addListener("play", this.trackCurrentTime);
|
||||
this.addListener("pause", this.stopTrackingCurrentTime);
|
||||
this.addListener("ended", this.playerOnVideoEnded);
|
||||
this.trackBuffered();
|
||||
// Buffer Full
|
||||
this.onBufferedUpdate(this.isBufferFull);
|
||||
this.addListener("bufferedupdate", this.bufferFull);
|
||||
},{
|
||||
playerOnVideoError: function(event){
|
||||
this.log(event);
|
||||
this.log(this.video.error);
|
||||
},
|
||||
playerOnVideoPlay: function(event){ this.hasPlayed = true; },
|
||||
playerOnVideoPause: function(event){},
|
||||
playerOnVideoEnded: function(event){
|
||||
this.currentTime(0);
|
||||
this.pause();
|
||||
if (this.options.loop) {
|
||||
this.currentTime(0);
|
||||
this.play();
|
||||
} else if (this.options.returnToStart) {
|
||||
this.currentTime(0);
|
||||
this.pause();
|
||||
}
|
||||
},
|
||||
|
||||
/* Load Tracking -------------------------------------------------------------- */
|
||||
// Buffer watching method for load progress.
|
||||
// Used for browsers that don't support the progress event
|
||||
trackBuffered: function(){
|
||||
this.bufferedInterval = setInterval(this.triggerBufferedListeners.context(this), 500);
|
||||
this.bufferedInterval = setInterval(function(){
|
||||
// Don't trigger unless
|
||||
if (this.values.bufferEnd < this.buffered().end(0)) {
|
||||
this.triggerListeners("bufferedupdate");
|
||||
}
|
||||
}.context(this), 500);
|
||||
},
|
||||
stopTrackingBuffered: function(){ clearInterval(this.bufferedInterval); },
|
||||
bufferedListeners: [],
|
||||
onBufferedUpdate: function(fn){
|
||||
this.bufferedListeners.push(fn);
|
||||
},
|
||||
triggerBufferedListeners: function(){
|
||||
this.isBufferFull();
|
||||
this.each(this.bufferedListeners, function(listener){
|
||||
(listener.context(this))();
|
||||
});
|
||||
},
|
||||
isBufferFull: function(){
|
||||
if (this.bufferedPercent() == 1) { this.stopTrackingBuffered(); }
|
||||
bufferFull: function(){
|
||||
if (this.bufferedPercent() == 1) {
|
||||
this.stopTrackingBuffered();
|
||||
}
|
||||
},
|
||||
|
||||
/* Time Tracking -------------------------------------------------------------- */
|
||||
trackCurrentTime: function(){
|
||||
if (this.currentTimeInterval) { clearInterval(this.currentTimeInterval); }
|
||||
this.currentTimeInterval = setInterval(this.triggerCurrentTimeListeners.context(this), 100); // 42 = 24 fps
|
||||
|
||||
this.currentTimeInterval = setInterval(function(){
|
||||
this.triggerListeners("timeupdate");
|
||||
}.context(this), 100); // 42 = 24 fps
|
||||
|
||||
this.trackingCurrentTime = true;
|
||||
},
|
||||
// Turn off play progress tracking (when paused or dragging)
|
||||
stopTrackingCurrentTime: function(){
|
||||
clearInterval(this.currentTimeInterval);
|
||||
this.trackingCurrentTime = false;
|
||||
},
|
||||
currentTimeListeners: [],
|
||||
// onCurrentTimeUpdate is in API section now
|
||||
triggerCurrentTimeListeners: function(late, newTime){ // FF passes milliseconds late as the first argument
|
||||
this.each(this.currentTimeListeners, function(listener){
|
||||
(listener.context(this))(newTime || this.currentTime());
|
||||
});
|
||||
},
|
||||
|
||||
/* Resize Tracking -------------------------------------------------------------- */
|
||||
resizeListeners: [],
|
||||
onResize: function(fn){
|
||||
this.resizeListeners.push(fn);
|
||||
},
|
||||
// Trigger anywhere the video/box size is changed.
|
||||
triggerResizeListeners: function(){
|
||||
this.each(this.resizeListeners, function(listener){
|
||||
(listener.context(this))();
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -116,8 +95,8 @@ VideoJS.fn.newBehavior("box", function(element){
|
||||
this.positionBox();
|
||||
_V_.addClass(element, "vjs-paused");
|
||||
this.activateElement(element, "mouseOverVideoReporter");
|
||||
this.onPlay(this.boxOnVideoPlay);
|
||||
this.onPause(this.boxOnVideoPause);
|
||||
this.addListener("play", this.boxOnVideoPlay);
|
||||
this.addListener("pause", this.boxOnVideoPause);
|
||||
},{
|
||||
boxOnVideoPlay: function(){
|
||||
_V_.removeClass(this.box, "vjs-paused");
|
||||
@ -134,9 +113,9 @@ VideoJS.fn.newBehavior("box", function(element){
|
||||
VideoJS.fn.newBehavior("poster", function(element){
|
||||
this.activateElement(element, "mouseOverVideoReporter");
|
||||
this.activateElement(element, "playButton");
|
||||
this.onPlay(this.hidePoster);
|
||||
this.onEnded(this.showPoster);
|
||||
this.onResize(this.positionPoster);
|
||||
this.addListener("play", this.hidePoster);
|
||||
this.addListener("ended", this.showPoster);
|
||||
this.addListener("resize", this.positionPoster);
|
||||
},{
|
||||
showPoster: function(){
|
||||
if (!this.poster) { return; }
|
||||
@ -168,7 +147,7 @@ VideoJS.fn.newBehavior("poster", function(element){
|
||||
VideoJS.fn.newBehavior("controlBar", function(element){
|
||||
if (!this.controlBars) {
|
||||
this.controlBars = [];
|
||||
this.onResize(this.positionControlBars);
|
||||
this.addListener("resize", this.positionControlBars);
|
||||
}
|
||||
this.controlBars.push(element);
|
||||
_V_.addListener(element, "mousemove", this.onControlBarsMouseMove.context(this));
|
||||
@ -177,6 +156,7 @@ VideoJS.fn.newBehavior("controlBar", function(element){
|
||||
showControlBars: function(){
|
||||
if (!this.options.controlsAtStart && !this.hasPlayed) { return; }
|
||||
this.each(this.controlBars, function(bar){
|
||||
// bar.style.opacity = 1;
|
||||
bar.style.display = "block";
|
||||
});
|
||||
},
|
||||
@ -188,6 +168,7 @@ VideoJS.fn.newBehavior("controlBar", function(element){
|
||||
hideControlBars: function(){
|
||||
if (this.options.controlsHiding && !this.mouseIsOverControls) {
|
||||
this.each(this.controlBars, function(bar){
|
||||
// bar.style.opacity = 0;
|
||||
bar.style.display = "none";
|
||||
});
|
||||
}
|
||||
@ -205,8 +186,8 @@ VideoJS.fn.newBehavior("controlBar", function(element){
|
||||
VideoJS.fn.newBehavior("playToggle", function(element){
|
||||
if (!this.elements.playToggles) {
|
||||
this.elements.playToggles = [];
|
||||
this.onPlay(this.playTogglesOnPlay);
|
||||
this.onPause(this.playTogglesOnPause);
|
||||
this.addListener("play", this.playTogglesOnPlay);
|
||||
this.addListener("pause", this.playTogglesOnPause);
|
||||
}
|
||||
this.elements.playToggles.push(element);
|
||||
_V_.addListener(element, "click", this.onPlayToggleClick.context(this));
|
||||
@ -249,17 +230,17 @@ VideoJS.fn.newBehavior("pauseButton", function(element){
|
||||
/* Play Progress Bar Behaviors
|
||||
================================================================================ */
|
||||
VideoJS.fn.newBehavior("playProgressBar", function(element){
|
||||
if (!this.playProgressBars) {
|
||||
this.playProgressBars = [];
|
||||
this.onCurrentTimeUpdate(this.updatePlayProgressBars);
|
||||
if (!this.elements.playProgressBars) {
|
||||
this.elements.playProgressBars = [];
|
||||
this.addListener("timeupdate", this.updatePlayProgressBars);
|
||||
}
|
||||
this.playProgressBars.push(element);
|
||||
this.elements.playProgressBars.push(element);
|
||||
},{
|
||||
// Ajust the play progress bar's width based on the current play time
|
||||
updatePlayProgressBars: function(newTime){
|
||||
var progress = (newTime !== undefined) ? newTime / this.duration() : this.currentTime() / this.duration();
|
||||
var progress = (this.scrubbing) ? this.values.currentTime / this.duration() : this.currentTime() / this.duration();
|
||||
if (isNaN(progress)) { progress = 0; }
|
||||
this.each(this.playProgressBars, function(bar){
|
||||
this.each(this.elements.playProgressBars, function(bar){
|
||||
if (bar.style) { bar.style.width = _V_.round(progress * 100, 2) + "%"; }
|
||||
});
|
||||
}
|
||||
@ -268,12 +249,12 @@ VideoJS.fn.newBehavior("playProgressBar", function(element){
|
||||
/* Load Progress Bar Behaviors
|
||||
================================================================================ */
|
||||
VideoJS.fn.newBehavior("loadProgressBar", function(element){
|
||||
if (!this.loadProgressBars) { this.loadProgressBars = []; }
|
||||
this.loadProgressBars.push(element);
|
||||
this.onBufferedUpdate(this.updateLoadProgressBars);
|
||||
if (!this.elements.loadProgressBars) { this.elements.loadProgressBars = []; }
|
||||
this.elements.loadProgressBars.push(element);
|
||||
this.addListener("bufferedupdate", this.updateLoadProgressBars);
|
||||
},{
|
||||
updateLoadProgressBars: function(){
|
||||
this.each(this.loadProgressBars, function(bar){
|
||||
this.each(this.elements.loadProgressBars, function(bar){
|
||||
if (bar.style) { bar.style.width = _V_.round(this.bufferedPercent() * 100, 2) + "%"; }
|
||||
});
|
||||
}
|
||||
@ -283,18 +264,17 @@ VideoJS.fn.newBehavior("loadProgressBar", function(element){
|
||||
/* Current Time Display Behaviors
|
||||
================================================================================ */
|
||||
VideoJS.fn.newBehavior("currentTimeDisplay", function(element){
|
||||
if (!this.currentTimeDisplays) {
|
||||
this.currentTimeDisplays = [];
|
||||
this.onCurrentTimeUpdate(this.updateCurrentTimeDisplays);
|
||||
if (!this.elements.currentTimeDisplays) {
|
||||
this.elements.currentTimeDisplays = [];
|
||||
this.addListener("timeupdate", this.updateCurrentTimeDisplays);
|
||||
}
|
||||
this.currentTimeDisplays.push(element);
|
||||
this.elements.currentTimeDisplays.push(element);
|
||||
},{
|
||||
// Update the displayed time (00:00)
|
||||
updateCurrentTimeDisplays: function(newTime){
|
||||
if (!this.currentTimeDisplays) { return; }
|
||||
// Allows for smooth scrubbing, when player can't keep up.
|
||||
var time = (newTime) ? newTime : this.currentTime();
|
||||
this.each(this.currentTimeDisplays, function(dis){
|
||||
var time = (this.scrubbing) ? this.values.currentTime : this.currentTime();
|
||||
this.each(this.elements.currentTimeDisplays, function(dis){
|
||||
dis.innerHTML = _V_.formatTime(time);
|
||||
});
|
||||
}
|
||||
@ -304,15 +284,14 @@ VideoJS.fn.newBehavior("currentTimeDisplay", function(element){
|
||||
/* Duration Display Behaviors
|
||||
================================================================================ */
|
||||
VideoJS.fn.newBehavior("durationDisplay", function(element){
|
||||
if (!this.durationDisplays) {
|
||||
this.durationDisplays = [];
|
||||
this.onCurrentTimeUpdate(this.updateDurationDisplays);
|
||||
if (!this.elements.durationDisplays) {
|
||||
this.elements.durationDisplays = [];
|
||||
this.addListener("timeupdate", this.updateDurationDisplays);
|
||||
}
|
||||
this.durationDisplays.push(element);
|
||||
this.elements.durationDisplays.push(element);
|
||||
},{
|
||||
updateDurationDisplays: function(){
|
||||
if (!this.durationDisplays) { return; }
|
||||
this.each(this.durationDisplays, function(dis){
|
||||
this.each(this.elements.durationDisplays, function(dis){
|
||||
if (this.duration()) { dis.innerHTML = _V_.formatTime(this.duration()); }
|
||||
});
|
||||
}
|
||||
@ -330,6 +309,7 @@ VideoJS.fn.newBehavior("currentTimeScrubber", function(element){
|
||||
this.currentScrubber = scrubber;
|
||||
|
||||
this.stopTrackingCurrentTime(); // Allows for smooth scrubbing
|
||||
this.scrubbing = true;
|
||||
|
||||
this.videoWasPlaying = !this.paused();
|
||||
this.pause();
|
||||
@ -346,6 +326,7 @@ VideoJS.fn.newBehavior("currentTimeScrubber", function(element){
|
||||
_V_.unblockTextSelection();
|
||||
document.removeEventListener("mousemove", this.onCurrentTimeScrubberMouseMove, false);
|
||||
document.removeEventListener("mouseup", this.onCurrentTimeScrubberMouseUp, false);
|
||||
this.scrubbing = false;
|
||||
if (this.videoWasPlaying) {
|
||||
this.play();
|
||||
this.trackCurrentTime();
|
||||
@ -354,28 +335,28 @@ VideoJS.fn.newBehavior("currentTimeScrubber", function(element){
|
||||
setCurrentTimeWithScrubber: function(event){
|
||||
var newProgress = _V_.getRelativePosition(event.pageX, this.currentScrubber);
|
||||
var newTime = newProgress * this.duration();
|
||||
this.triggerCurrentTimeListeners(0, newTime); // Allows for smooth scrubbing
|
||||
// Don't let video end while scrubbing.
|
||||
if (newTime == this.duration()) { newTime = newTime - 0.1; }
|
||||
this.currentTime(newTime);
|
||||
this.triggerListeners("timeupdate");
|
||||
}
|
||||
}
|
||||
);
|
||||
/* Volume Display Behaviors
|
||||
================================================================================ */
|
||||
VideoJS.fn.newBehavior("volumeDisplay", function(element){
|
||||
if (!this.volumeDisplays) {
|
||||
this.volumeDisplays = [];
|
||||
this.onVolumeChange(this.updateVolumeDisplays);
|
||||
if (!this.elements.volumeDisplays) {
|
||||
this.elements.volumeDisplays = [];
|
||||
this.addListener("volumechange", this.updateVolumeDisplays);
|
||||
}
|
||||
this.volumeDisplays.push(element);
|
||||
this.elements.volumeDisplays.push(element);
|
||||
this.updateVolumeDisplay(element); // Set the display to the initial volume
|
||||
},{
|
||||
// Update the volume control display
|
||||
// Unique to these default controls. Uses borders to create the look of bars.
|
||||
updateVolumeDisplays: function(){
|
||||
if (!this.volumeDisplays) { return; }
|
||||
this.each(this.volumeDisplays, function(dis){
|
||||
if (!this.elements.volumeDisplays) { return; }
|
||||
this.each(this.elements.volumeDisplays, function(dis){
|
||||
this.updateVolumeDisplay(dis);
|
||||
});
|
||||
},
|
||||
@ -450,14 +431,12 @@ VideoJS.fn.newBehavior("fullscreenToggle", function(element){
|
||||
VideoJS.fn.newBehavior("bigPlayButton", function(element){
|
||||
if (!this.elements.bigPlayButtons) {
|
||||
this.elements.bigPlayButtons = [];
|
||||
this.onPlay(this.bigPlayButtonsOnPlay);
|
||||
this.onEnded(this.bigPlayButtonsOnEnded);
|
||||
this.addListener("play", this.hideBigPlayButtons);
|
||||
this.addListener("ended", this.showBigPlayButtons);
|
||||
}
|
||||
this.elements.bigPlayButtons.push(element);
|
||||
this.activateElement(element, "playButton");
|
||||
},{
|
||||
bigPlayButtonsOnPlay: function(event){ this.hideBigPlayButtons(); },
|
||||
bigPlayButtonsOnEnded: function(event){ this.showBigPlayButtons(); },
|
||||
showBigPlayButtons: function(){
|
||||
this.each(this.elements.bigPlayButtons, function(element){
|
||||
element.style.display = "block";
|
||||
@ -475,6 +454,7 @@ VideoJS.fn.newBehavior("bigPlayButton", function(element){
|
||||
VideoJS.fn.newBehavior("spinner", function(element){
|
||||
if (!this.spinners) {
|
||||
this.spinners = [];
|
||||
this.spinnersRotated = 0;
|
||||
_V_.addListener(this.video, "loadeddata", this.spinnersOnVideoLoadedData.context(this));
|
||||
_V_.addListener(this.video, "loadstart", this.spinnersOnVideoLoadStart.context(this));
|
||||
_V_.addListener(this.video, "seeking", this.spinnersOnVideoSeeking.context(this));
|
||||
@ -502,7 +482,6 @@ VideoJS.fn.newBehavior("spinner", function(element){
|
||||
});
|
||||
clearInterval(this.spinnerInterval);
|
||||
},
|
||||
spinnersRotated: 0,
|
||||
rotateSpinners: function(){
|
||||
this.each(this.spinners, function(spinner){
|
||||
// spinner.style.transform = 'scale(0.5) rotate('+this.spinnersRotated+'deg)';
|
||||
@ -520,7 +499,7 @@ VideoJS.fn.newBehavior("spinner", function(element){
|
||||
spinnersOnVideoCanPlayThrough: function(event){ this.hideSpinners(); },
|
||||
spinnersOnVideoWaiting: function(event){
|
||||
// Safari sometimes triggers waiting inappropriately
|
||||
// Like after video has played, any you play again.
|
||||
// Like after video has played, and you play again.
|
||||
this.showSpinners();
|
||||
},
|
||||
spinnersOnVideoStalled: function(event){},
|
||||
@ -535,16 +514,17 @@ VideoJS.fn.newBehavior("spinner", function(element){
|
||||
/* Subtitles
|
||||
================================================================================ */
|
||||
VideoJS.fn.newBehavior("subtitlesDisplay", function(element){
|
||||
if (!this.subtitleDisplays) {
|
||||
this.subtitleDisplays = [];
|
||||
this.onCurrentTimeUpdate(this.subtitleDisplaysOnVideoTimeUpdate);
|
||||
this.onEnded(function() { this.lastSubtitleIndex = 0; }.context(this));
|
||||
if (!this.elements.subtitleDisplays) {
|
||||
this.elements.subtitleDisplays = [];
|
||||
this.addListener("timeupdate", this.subtitleDisplaysOnVideoTimeUpdate);
|
||||
this.addListener("ended", function() { this.lastSubtitleIndex = 0; }.context(this));
|
||||
}
|
||||
this.subtitleDisplays.push(element);
|
||||
this.elements.subtitleDisplays.push(element);
|
||||
},{
|
||||
subtitleDisplaysOnVideoTimeUpdate: function(time){
|
||||
subtitleDisplaysOnVideoTimeUpdate: function(){
|
||||
// Assuming all subtitles are in order by time, and do not overlap
|
||||
if (this.subtitles) {
|
||||
var time = this.currentTime();
|
||||
// If current subtitle should stay showing, don't do anything. Otherwise, find new subtitle.
|
||||
if (!this.currentSubtitle || this.currentSubtitle.start >= time || this.currentSubtitle.end < time) {
|
||||
var newSubIndex = false,
|
||||
@ -588,7 +568,7 @@ VideoJS.fn.newBehavior("subtitlesDisplay", function(element){
|
||||
}
|
||||
},
|
||||
updateSubtitleDisplays: function(val){
|
||||
this.each(this.subtitleDisplays, function(disp){
|
||||
this.each(this.elements.subtitleDisplays, function(disp){
|
||||
disp.innerHTML = val;
|
||||
});
|
||||
}
|
||||
|
@ -12,9 +12,10 @@ VideoJS.fn.extend({
|
||||
this.replaceWithFlash();
|
||||
this.element = this.flashElement;
|
||||
this.video.src = ""; // Stop video from downloading if HTML5 is still supported
|
||||
var flashPlayerType = VideoJS.flashPlayers[this.options.flashPlayer];
|
||||
this.extend(flashPlayerType.api);
|
||||
(flashPlayerType.init.context(this))();
|
||||
var flashPlayer = VideoJS.flashPlayers[this.options.flashPlayer];
|
||||
flashPlayer.init.call(this);
|
||||
this.api = flashPlayer.api;
|
||||
this.api.setupTriggers.call(this);
|
||||
},
|
||||
|
||||
// Get Flash Fallback object element from Embed Code
|
||||
@ -43,32 +44,12 @@ VideoJS.fn.extend({
|
||||
}
|
||||
});
|
||||
|
||||
/* Flash Object Fallback (Flash Player Type)
|
||||
/* Flash Object Fallback (Flash Player)
|
||||
================================================================================ */
|
||||
VideoJS.flashPlayers = {};
|
||||
VideoJS.flashPlayers.htmlObject = {
|
||||
flashPlayerVersion: 9,
|
||||
init: function() { return true; },
|
||||
api: { // No video API available with HTML Object embed method
|
||||
|
||||
width: function(width){
|
||||
if (width !== undefined) {
|
||||
this.element.width = width;
|
||||
this.box.style.width = width+"px";
|
||||
this.triggerResizeListeners();
|
||||
return this;
|
||||
}
|
||||
return this.element.width;
|
||||
},
|
||||
|
||||
height: function(height){
|
||||
if (height !== undefined) {
|
||||
this.element.height = height;
|
||||
this.box.style.height = height+"px";
|
||||
this.triggerResizeListeners();
|
||||
return this;
|
||||
}
|
||||
return this.element.height;
|
||||
}
|
||||
}
|
||||
api: {} // No video API available with HTML Object embed method
|
||||
};
|
||||
|
||||
|
195
dev/src/html5.js
195
dev/src/html5.js
@ -12,6 +12,8 @@ VideoJS.fn.extend({
|
||||
|
||||
html5Init: function(){
|
||||
this.element = this.video;
|
||||
this.api = this.html5API;
|
||||
this.api.setupTriggers.call(this);
|
||||
|
||||
this.fixPreloading(); // Support old browsers that used autobuffer
|
||||
this.supportProgressEvents(); // Support browsers that don't use 'buffered'
|
||||
@ -104,15 +106,18 @@ VideoJS.fn.extend({
|
||||
// Listen for Video Load Progress (currently does not if html file is local)
|
||||
// Buffered does't work in all browsers, so watching progress as well
|
||||
supportProgressEvents: function(e){
|
||||
_V_.addListener(this.video, 'progress', this.playerOnVideoProgress.context(this));
|
||||
},
|
||||
playerOnVideoProgress: function(event){
|
||||
this.setBufferedFromProgress(event);
|
||||
_V_.addListener(this.video, 'progress', this.setBufferedFromProgress.context(this));
|
||||
},
|
||||
// playerOnVideoProgress: function(event){
|
||||
// this.setBufferedFromProgress(event);
|
||||
// },
|
||||
setBufferedFromProgress: function(event){ // HTML5 Only
|
||||
if(event.total > 0) {
|
||||
if(event.total > 0 && this.duration()) {
|
||||
var newBufferEnd = (event.loaded / event.total) * this.duration();
|
||||
if (newBufferEnd > this.values.bufferEnd) { this.values.bufferEnd = newBufferEnd; }
|
||||
if (newBufferEnd > this.values.bufferEnd) {
|
||||
this.values.bufferEnd = newBufferEnd;
|
||||
this.triggerListeners("bufferedupdate");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -411,153 +416,55 @@ VideoJS.fn.extend({
|
||||
|
||||
/* Player API - Translate functionality from player to video
|
||||
================================================================================ */
|
||||
html5AddVideoListener: function(type, fn){ _V_.addListener(this.video, type, fn.rEvtContext(this)); },
|
||||
html5API: {
|
||||
setupTriggers: function(){
|
||||
// Make video events trigger player events
|
||||
// May seem verbose here, but makes other APIs possible.
|
||||
var types = ["play", "pause", "ended", "volumechange", "error"],
|
||||
player = this, i, type;
|
||||
for (i = 0; i<types.length; i++) {
|
||||
type = types[i];
|
||||
_V_.addListener(this.video, type, function(e){
|
||||
player.triggerListeners(this, e);
|
||||
}.context(type));
|
||||
}
|
||||
},
|
||||
|
||||
play: function(){
|
||||
this.video.play();
|
||||
return this;
|
||||
},
|
||||
onPlay: function(fn){ this.html5AddVideoListener("play", fn); return this; },
|
||||
play: function(){ this.video.play(); },
|
||||
pause: function(){ this.video.pause(); },
|
||||
paused: function(){ return this.video.paused; },
|
||||
|
||||
pause: function(){
|
||||
this.video.pause();
|
||||
return this;
|
||||
},
|
||||
onPause: function(fn){ this.html5AddVideoListener("pause", fn); return this; },
|
||||
paused: function() { return this.video.paused; },
|
||||
|
||||
currentTime: function(seconds){
|
||||
if (seconds !== undefined) {
|
||||
currentTime: function(){ return this.video.currentTime; },
|
||||
setCurrentTime: function(seconds){
|
||||
try { this.video.currentTime = seconds; }
|
||||
catch(e) { this.warning(VideoJS.warnings.videoNotReady); }
|
||||
this.values.currentTime = seconds;
|
||||
return this;
|
||||
}
|
||||
return this.video.currentTime;
|
||||
},
|
||||
onCurrentTimeUpdate: function(fn){
|
||||
this.currentTimeListeners.push(fn);
|
||||
},
|
||||
},
|
||||
|
||||
onEnded: function(fn){
|
||||
this.html5AddVideoListener("ended", fn); return this;
|
||||
},
|
||||
duration: function(){ return this.video.duration; },
|
||||
buffered: function(){ return this.video.buffered; },
|
||||
|
||||
duration: function(){
|
||||
return this.video.duration;
|
||||
},
|
||||
volume: function(){ return this.video.volume; },
|
||||
setVolume: function(percentAsDecimal){ this.video.volume = percentAsDecimal; },
|
||||
|
||||
buffered: function(){
|
||||
// Storing values allows them be overridden by setBufferedFromProgress
|
||||
if (this.values.bufferStart === undefined) {
|
||||
this.values.bufferStart = 0;
|
||||
this.values.bufferEnd = 0;
|
||||
}
|
||||
if (this.video.buffered && this.video.buffered.length > 0) {
|
||||
var newEnd = this.video.buffered.end(0);
|
||||
if (newEnd > this.values.bufferEnd) { this.values.bufferEnd = newEnd; }
|
||||
}
|
||||
return [this.values.bufferStart, this.values.bufferEnd];
|
||||
},
|
||||
width: function(){ return this.video.offsetWidth; },
|
||||
height: function(){ return this.video.offsetHeight; },
|
||||
|
||||
volume: function(percentAsDecimal){
|
||||
if (percentAsDecimal !== undefined) {
|
||||
// Force value to between 0 and 1
|
||||
this.values.volume = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
|
||||
this.video.volume = this.values.volume;
|
||||
this.setLocalStorage("volume", this.values.volume);
|
||||
return this;
|
||||
}
|
||||
if (this.values.volume) { return this.values.volume; }
|
||||
return this.video.volume;
|
||||
},
|
||||
onVolumeChange: function(fn){ _V_.addListener(this.video, 'volumechange', fn.rEvtContext(this)); },
|
||||
|
||||
width: function(width){
|
||||
if (width !== undefined) {
|
||||
this.video.width = width; // Not using style so it can be overridden on fullscreen.
|
||||
this.box.style.width = width+"px";
|
||||
this.triggerResizeListeners();
|
||||
return this;
|
||||
}
|
||||
return this.video.offsetWidth;
|
||||
},
|
||||
height: function(height){
|
||||
if (height !== undefined) {
|
||||
this.video.height = height;
|
||||
this.box.style.height = height+"px";
|
||||
this.triggerResizeListeners();
|
||||
return this;
|
||||
}
|
||||
return this.video.offsetHeight;
|
||||
},
|
||||
|
||||
supportsFullScreen: function(){
|
||||
if(typeof this.video.webkitEnterFullScreen == 'function') {
|
||||
// Seems to be broken in Chromium/Chrome
|
||||
if (!navigator.userAgent.match("Chrome") && !navigator.userAgent.match("Mac OS X 10.5")) {
|
||||
return true;
|
||||
supportsFullScreen: function(){
|
||||
if(typeof this.video.webkitEnterFullScreen == 'function') {
|
||||
// Seems to be broken in Chromium/Chrome && Safari in Leopard
|
||||
if (!navigator.userAgent.match("Chrome") && !navigator.userAgent.match("Mac OS X 10.5")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
enterFullScreen: function(){
|
||||
try {
|
||||
this.video.webkitEnterFullScreen();
|
||||
} catch (e) {
|
||||
if (e.code == 11) { this.warning(VideoJS.warnings.videoNotReady); }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
html5EnterNativeFullScreen: function(){
|
||||
try {
|
||||
this.video.webkitEnterFullScreen();
|
||||
} catch (e) {
|
||||
if (e.code == 11) { this.warning(VideoJS.warnings.videoNotReady); }
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// Turn on fullscreen (window) mode
|
||||
// Real fullscreen isn't available in browsers quite yet.
|
||||
enterFullScreen: function(){
|
||||
if (this.supportsFullScreen()) {
|
||||
this.html5EnterNativeFullScreen();
|
||||
} else {
|
||||
this.enterFullWindow();
|
||||
}
|
||||
},
|
||||
|
||||
exitFullScreen: function(){
|
||||
if (this.supportsFullScreen()) {
|
||||
// Shouldn't be called
|
||||
} else {
|
||||
this.exitFullWindow();
|
||||
}
|
||||
},
|
||||
|
||||
enterFullWindow: function(){
|
||||
this.videoIsFullScreen = true;
|
||||
// Storing original doc overflow value to return to when fullscreen is off
|
||||
this.docOrigOverflow = document.documentElement.style.overflow;
|
||||
// Add listener for esc key to exit fullscreen
|
||||
_V_.addListener(document, "keydown", this.fullscreenOnEscKey.rEvtContext(this));
|
||||
// Add listener for a window resize
|
||||
_V_.addListener(window, "resize", this.fullscreenOnWindowResize.rEvtContext(this));
|
||||
// Hide any scroll bars
|
||||
document.documentElement.style.overflow = 'hidden';
|
||||
// Apply fullscreen styles
|
||||
_V_.addClass(this.box, "vjs-fullscreen");
|
||||
// Resize the box, controller, and poster
|
||||
this.positionAll();
|
||||
},
|
||||
|
||||
// Turn off fullscreen (window) mode
|
||||
exitFullWindow: function(){
|
||||
this.videoIsFullScreen = false;
|
||||
document.removeEventListener("keydown", this.fullscreenOnEscKey, false);
|
||||
window.removeEventListener("resize", this.fullscreenOnWindowResize, false);
|
||||
// Unhide scroll bars.
|
||||
document.documentElement.style.overflow = this.docOrigOverflow;
|
||||
// Remove fullscreen styles
|
||||
_V_.removeClass(this.box, "vjs-fullscreen");
|
||||
// Resize the box, controller, and poster to original sizes
|
||||
this.positionAll();
|
||||
},
|
||||
|
||||
onError: function(fn){ this.html5AddVideoListener("error", fn); return this; },
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -75,6 +75,9 @@ VideoJS.extend({
|
||||
},
|
||||
|
||||
get: function(url, onSuccess){
|
||||
// if (netscape.security.PrivilegeManager.enablePrivilege) {
|
||||
// netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
|
||||
// }
|
||||
if (typeof XMLHttpRequest == "undefined") {
|
||||
XMLHttpRequest = function () {
|
||||
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) {}
|
||||
@ -91,7 +94,11 @@ VideoJS.extend({
|
||||
onSuccess(request.responseText);
|
||||
}
|
||||
}.context(this);
|
||||
request.send();
|
||||
try {
|
||||
request.send();
|
||||
} catch(e) {
|
||||
// Can't access file.
|
||||
}
|
||||
},
|
||||
|
||||
trim: function(string){ return string.toString().replace(/^\s+/, "").replace(/\s+$/, ""); },
|
||||
|
@ -14,17 +14,24 @@ var VideoJS = JRClass.extend({
|
||||
} else {
|
||||
this.video = element;
|
||||
}
|
||||
// Store reference to player on the video element.
|
||||
// So you can acess the player later: document.getElementById("video_id").player.play();
|
||||
this.video.player = this;
|
||||
|
||||
this.video.player = this; // Store reference to player on the video element.
|
||||
this.box = this.video.parentNode; // Container element for controls positioning
|
||||
this.values = {}; // Cache video values.
|
||||
this.elements = {}; // Store refs to controls elements.
|
||||
this.api = {}; // API to video functions
|
||||
this.listeners = {}; // Store video event listeners.
|
||||
this.api = {}; // Current API to video functions (changes with player type)
|
||||
|
||||
// Hide Links. Will be shown again if "links" player is used
|
||||
this.linksFallback = this.getLinksFallback();
|
||||
this.hideLinksFallback();
|
||||
|
||||
// Default Options
|
||||
this.options = {
|
||||
autoplay: false,
|
||||
preload: true,
|
||||
loop: false,
|
||||
returnToStart: true,
|
||||
useBuiltInControls: false, // Use the browser's controls (iPhone)
|
||||
controlsBelow: false, // Display control bar below video vs. in front of
|
||||
controlsAtStart: false, // Make controls visible when page loads
|
||||
@ -42,11 +49,6 @@ var VideoJS = JRClass.extend({
|
||||
if (this.getPreloadAttribute() !== undefined) { this.options.preload = this.getPreloadAttribute(); }
|
||||
if (this.getAutoplayAttribute() !== undefined) { this.options.autoplay = this.getAutoplayAttribute(); }
|
||||
|
||||
// Store reference to embed code pieces
|
||||
this.box = this.video.parentNode;
|
||||
this.linksFallback = this.getLinksFallback();
|
||||
this.hideLinksFallback(); // Will be shown again if "links" player is used
|
||||
|
||||
// Loop through the player names list in options, "html5" etc.
|
||||
// For each player name, initialize the player with that name under VideoJS.players
|
||||
// If the player successfully initializes, we're done
|
||||
@ -122,8 +124,6 @@ var VideoJS = JRClass.extend({
|
||||
return true;
|
||||
}
|
||||
},
|
||||
// Calculates amoutn of buffer is full
|
||||
bufferedPercent: function(){ return (this.duration()) ? this.buffered()[1] / this.duration() : 0; },
|
||||
// Each that maintains player as context
|
||||
// Break if true is returned
|
||||
each: function(arr, fn){
|
||||
@ -132,6 +132,7 @@ var VideoJS = JRClass.extend({
|
||||
if (fn.call(this, arr[i], i)) { break; }
|
||||
}
|
||||
},
|
||||
// Add functions to the player
|
||||
extend: function(obj){
|
||||
for (var attrname in obj) {
|
||||
if (obj.hasOwnProperty(attrname)) { this[attrname]=obj[attrname]; }
|
||||
|
@ -1,4 +1,5 @@
|
||||
// jQuery Plugin
|
||||
/* jQuery Plugin
|
||||
================================================================================ */
|
||||
if (window.jQuery) {
|
||||
(function($) {
|
||||
|
||||
|
@ -5,8 +5,10 @@
|
||||
<title>HTML5 Video Player</title>
|
||||
|
||||
<!-- Include the VideoJS Library -->
|
||||
<script src="src/video.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="src/main.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="src/api.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="src/html5.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="src/flash.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="src/behaviors.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="src/lib.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="src/video-js.jquery.js" type="text/javascript" charset="utf-8"></script>
|
||||
@ -80,11 +82,11 @@
|
||||
|
||||
<div class="video-js-box">
|
||||
<!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody -->
|
||||
<video data-subtitles="../demo-subtitles.srt" id="example_video_1" class="video-js" width="640" height="264" controls="controls" preload="none" poster="http://video-js.zencoder.com/oceans-clip.png">
|
||||
<video id="example_video_1" class="video-js" width="640" height="264" controls="controls" preload="auto" poster="http://video-js.zencoder.com/oceans-clip.png">
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm; codecs="vp8, vorbis"' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg; codecs="theora, vorbis"' />
|
||||
<track kind="subtitles" src="demo-subtitles.srt" srclang="en-US" label="English"></track>
|
||||
<track kind="subtitles" src="../demo-subtitles.srt" srclang="en-US" label="English"></track>
|
||||
<!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. -->
|
||||
<object id="flash_fallback_1" class="vjs-flash-fallback" width="640" height="264" type="application/x-shockwave-flash"
|
||||
data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
|
||||
@ -109,11 +111,10 @@
|
||||
|
||||
<div class="video-js-box">
|
||||
<!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody -->
|
||||
<video data-subtitles="../demo-subtitles.srt" id="example_video_2" class="video-js" width="640" height="264" controls="controls" preload="none" poster="http://video-js.zencoder.com/oceans-clip.png">
|
||||
<!-- <video id="example_video_2" class="video-jsnot" width="640" height="264" controls="controls" preload="none" poster="http://video-js.zencoder.com/oceans-clip.png"> -->
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm; codecs="vp8, vorbis"' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg; codecs="theora, vorbis"' />
|
||||
<track kind="subtitles" src="demo-subtitles.srt" srclang="en-US" label="English"></track>
|
||||
<!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. -->
|
||||
<object id="flash_fallback_1" class="vjs-flash-fallback" width="640" height="264" type="application/x-shockwave-flash"
|
||||
data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
|
||||
@ -124,7 +125,7 @@
|
||||
<img src="http://video-js.zencoder.com/oceans-clip.png" width="640" height="264" alt="Poster Image"
|
||||
title="No video playback capabilities." />
|
||||
</object>
|
||||
</video>
|
||||
<!-- </video> -->
|
||||
<!-- Download links provided for devices that can't play video in the browser. -->
|
||||
<p class="vjs-no-video"><strong>Download Video:</strong>
|
||||
<a href="http://video-js.zencoder.com/oceans-clip.mp4">MP4</a>,
|
||||
|
17
video-js.css
17
video-js.css
@ -51,6 +51,23 @@ so you can upgrade to newer versions easier. */
|
||||
bottom: 0px; /* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */
|
||||
height: 35px; /* Including any margin you want above or below control items */
|
||||
padding: 0; /* Controls are absolutely position, so no padding necessary */
|
||||
-webkit-transition: opacity 0.5s linear;
|
||||
-moz-transition: opacity 0.5s linear;
|
||||
-o-transition: opacity 0.5s linear;
|
||||
-ms-transition: opacity 0.5s linear;
|
||||
transition: opacity 0.5s linear;
|
||||
}
|
||||
|
||||
.vjs-hide {
|
||||
opacity: 0;
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* IE8 */
|
||||
filter: alpha(opacity=0); /* IE5-7 */
|
||||
}
|
||||
|
||||
.vjs-show {
|
||||
opacity: 1;
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; /* IE8 */
|
||||
filter: alpha(opacity=100); /* IE5-7 */
|
||||
}
|
||||
|
||||
.video-js-box .vjs-controls > div { /* Direct div children of control bar */
|
||||
|
Loading…
Reference in New Issue
Block a user