mirror of
https://github.com/videojs/video.js.git
synced 2025-01-08 07:00:10 +02:00
Upgrading to latest version.
This commit is contained in:
parent
5149064a98
commit
625a4bcf40
@ -1,9 +1,11 @@
|
|||||||
VideoJS
|
VideoJS - [HTML5 Video Player](http://videojs.com)
|
||||||
--------
|
------------------------------------------------
|
||||||
[HTML5 Video Player](http://videojs.com)
|
|
||||||
|
|
||||||
View [VideoJS.com](http://videojs.com) for a demo and overview.
|
View [VideoJS.com](http://videojs.com) for a demo and overview.
|
||||||
|
|
||||||
|
VideoJS is an HTML5 video player that uses the HTML5 video tag built into modern browsers, and javascript to add custom controls and functionality.
|
||||||
|
|
||||||
|
The base of VideoJS is Kroc Camen's [Video for Everybody](http://camendesign.com/code/video_for_everybody), which is a video embed code that falls back to a Flash video player or download links for browsers and devices that don't support HTML5 video.
|
||||||
|
|
||||||
View demo.html for an example of how to use it.
|
View demo.html for an example of how to use it.
|
||||||
|
|
||||||
Based on the tutorial at http://blog.steveheffernan.com/2010/04/how-to-build-an-html5-video-player/
|
Based on the tutorial at http://blog.steveheffernan.com/2010/04/how-to-build-an-html5-video-player/
|
13
video-js/demo-subtitles.srt
Executable file
13
video-js/demo-subtitles.srt
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
1
|
||||||
|
00:00:02,400 --> 00:00:05,200
|
||||||
|
[Background Music Playing]
|
||||||
|
|
||||||
|
2
|
||||||
|
00:00:15,712 --> 00:00:17,399
|
||||||
|
Heay!!
|
||||||
|
|
||||||
|
3
|
||||||
|
00:00:25,712 --> 00:00:30,399
|
||||||
|
[Bird noises]
|
||||||
|
|
||||||
|
|
@ -8,22 +8,39 @@
|
|||||||
<script src="video.js" type="text/javascript" charset="utf-8"></script>
|
<script src="video.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
<script type="text/javascript" charset="utf-8">
|
||||||
// Run the script on page load.
|
// Must come after the video.js library
|
||||||
|
|
||||||
// If using jQuery
|
// Add VideoJS to all video tags on the page
|
||||||
// $(function(){
|
|
||||||
// VideoJS.setup();
|
|
||||||
// })
|
|
||||||
|
|
||||||
// If using Prototype
|
|
||||||
// document.observe("dom:loaded", function() {
|
|
||||||
// VideoJS.setup();
|
|
||||||
// });
|
|
||||||
|
|
||||||
// If not using a JS library
|
|
||||||
window.onload = function(){
|
|
||||||
VideoJS.setup();
|
VideoJS.setup();
|
||||||
}
|
|
||||||
|
/* ========== OR ========== */
|
||||||
|
|
||||||
|
// Setup and store a reference to a video.
|
||||||
|
// Must happen after the DOM is loaded
|
||||||
|
/*
|
||||||
|
VideoJS.DOMReady(function(){
|
||||||
|
var myPlayer = new VideoJS("example_video_1");
|
||||||
|
|
||||||
|
// Then you can...(example)
|
||||||
|
myPlayer.play();
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
// If you are already using a DOM Loaded function from another lib (jQuery, Prototype, etc.)
|
||||||
|
// you can use that instead of VideoJS.DOMReady
|
||||||
|
|
||||||
|
/* ========== OR ========== */
|
||||||
|
|
||||||
|
// Set options when setting up the videos
|
||||||
|
// The defaults are shown here
|
||||||
|
/*
|
||||||
|
VideoJS.setup({
|
||||||
|
controlsBelow: false, // Display control bar below video instead of in front of
|
||||||
|
controlsHiding: true, // Hide controls when mouse is not over the video
|
||||||
|
defaultVolume: 0.85, // Will be overridden by user's last volume if available
|
||||||
|
flashVersion: 9, // Required flash version for fallback
|
||||||
|
linksHiding: true // Hide download links when video is supported
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<!-- Include the VideoJS Stylesheet -->
|
<!-- Include the VideoJS Stylesheet -->
|
||||||
@ -34,7 +51,7 @@
|
|||||||
<!-- Begin VideoJS -->
|
<!-- Begin VideoJS -->
|
||||||
<div class="video-js-box">
|
<div class="video-js-box">
|
||||||
<!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody -->
|
<!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody -->
|
||||||
<video class="video-js" width="640" height="264" poster="http://video-js.zencoder.com/oceans-clip.png" controls preload>
|
<video id="example_video_1" class="video-js" width="640" height="264" poster="http://video-js.zencoder.com/oceans-clip.png" controls preload>
|
||||||
<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.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.webm" type='video/webm; codecs="vp8, vorbis"'>
|
||||||
<source src="http://video-js.zencoder.com/oceans-clip.ogg" type='video/ogg; codecs="theora, vorbis"'>
|
<source src="http://video-js.zencoder.com/oceans-clip.ogg" type='video/ogg; codecs="theora, vorbis"'>
|
||||||
@ -43,8 +60,8 @@
|
|||||||
data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
|
data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
|
||||||
<param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
|
<param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
|
||||||
<param name="allowfullscreen" value="true" />
|
<param name="allowfullscreen" value="true" />
|
||||||
<param name="flashvars" value='config={"clip":{"url":"http://video-js.zencoder.com/oceans-clip.mp4","autoPlay":false,"autoBuffering":true}}' />
|
<param name="flashvars" value='config={"playlist":["http://video-js.zencoder.com/oceans-clip.png", {"url": "http://video-js.zencoder.com/oceans-clip.mp4","autoPlay":false,"autoBuffering":true}]}' />
|
||||||
<!-- Image Fallback -->
|
<!-- Image Fallback. Typically the same as the poster image. -->
|
||||||
<img src="http://video-js.zencoder.com/oceans-clip.png" width="640" height="264" alt="Poster Image"
|
<img src="http://video-js.zencoder.com/oceans-clip.png" width="640" height="264" alt="Poster Image"
|
||||||
title="No video playback capabilities." />
|
title="No video playback capabilities." />
|
||||||
</object>
|
</object>
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
================================================================================ */
|
================================================================================ */
|
||||||
|
|
||||||
/* Box containing video, controls, and download links.
|
/* Box containing video, controls, and download links.
|
||||||
If you want to add some kind of frame, use another containing element, not this one. */
|
If you want to add some kind of frame or special positioning, use another containing element, not video-js-box. */
|
||||||
.video-js-box { text-align: left; position: relative; } /* Will be set to the width of the video element */
|
.video-js-box { text-align: left; position: relative; vertical-align: bottom; } /* Will be set to the width of the video element */
|
||||||
|
|
||||||
/* Video Element */
|
/* Video Element */
|
||||||
video.video-js { background-color: #000; position: relative; }
|
video.video-js { background-color: #000; position: relative; }
|
||||||
@ -13,8 +13,10 @@ video.video-js { background-color: #000; position: relative; }
|
|||||||
.video-js-box.vjs-fullscreen video.video-js { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1001; }
|
.video-js-box.vjs-fullscreen video.video-js { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1001; }
|
||||||
.video-js-box.vjs-fullscreen .vjs-controls { z-index: 1002; }
|
.video-js-box.vjs-fullscreen .vjs-controls { z-index: 1002; }
|
||||||
|
|
||||||
/* Poster styles */
|
/* Poster Style */
|
||||||
.vjs-poster { display: block; position: absolute; left: 0; top: 0; width: 100%; height: 100%; }
|
.vjs-poster { display: block; position: absolute; left: 0; top: 0; width: 100%; height: 100%; }
|
||||||
|
/* Subtiles Style */
|
||||||
|
.vjs-subtitles { color:#fff; font-size: 20px; text-align: center; bottom: 20px; left: 0; right: 0; position: absolute; z-index: 1002; }
|
||||||
|
|
||||||
|
|
||||||
/* DEFAULT SKIN (override in another file)
|
/* DEFAULT SKIN (override in another file)
|
||||||
|
@ -19,17 +19,22 @@ along with VideoJS. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
var videoJSPlayers = new Array();
|
var videoJSPlayers = new Array();
|
||||||
|
|
||||||
// Using jresig's Class implementation http://ejohn.org/blog/simple-javascript-inheritance/
|
// Using jresig's Class implementation http://ejohn.org/blog/simple-javascript-inheritance/
|
||||||
(function(){var initializing=false, fnTest=/xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; this.Class = function(){}; Class.extend = function(prop) { var _super = this.prototype; initializing = true; var prototype = new this(); initializing = false; for (var name in prop) { prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn){ return function() { var tmp = this._super; this._super = _super[name]; var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } function Class() { if ( !initializing && this.init ) this.init.apply(this, arguments); } Class.prototype = prototype; Class.constructor = Class; Class.extend = arguments.callee; return Class;};})();
|
(function(){var initializing=false, fnTest=/xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; this.JRClass = function(){}; JRClass.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 JRClass() { if ( !initializing && this.init ) this.init.apply(this, arguments); } JRClass.prototype = prototype; JRClass.constructor = JRClass; JRClass.extend = arguments.callee; return JRClass;};})();
|
||||||
|
|
||||||
// Video JS Player Class
|
// Video JS Player Class
|
||||||
var VideoJS = Class.extend({
|
var VideoJS = JRClass.extend({
|
||||||
|
|
||||||
// Initialize the player for the supplied video tag element
|
// Initialize the player for the supplied video tag element
|
||||||
// element: video tag
|
// element: video tag
|
||||||
// num: the current player's position in the videoJSPlayers array
|
// num: the current player's position in the videoJSPlayers array
|
||||||
init: function(element, setOptions){
|
init: function(element, setOptions){
|
||||||
|
|
||||||
|
// Allow an ID string or an element
|
||||||
|
if (typeof element == 'string') {
|
||||||
|
this.video = document.getElementById(element);
|
||||||
|
} else {
|
||||||
this.video = element;
|
this.video = element;
|
||||||
|
}
|
||||||
|
|
||||||
// Hide default controls
|
// Hide default controls
|
||||||
this.video.controls = false;
|
this.video.controls = false;
|
||||||
@ -37,13 +42,17 @@ var VideoJS = Class.extend({
|
|||||||
// Default Options
|
// Default Options
|
||||||
this.options = {
|
this.options = {
|
||||||
num: 0, // Optional tracking of videoJSPLayers position
|
num: 0, // Optional tracking of videoJSPLayers position
|
||||||
controlsBelow: false, // Display control bar below video vs. on top
|
controlsBelow: false, // Display control bar below video vs. in front of
|
||||||
controlsHiding: true, // Hide controls when not over the video
|
controlsHiding: true, // Hide controls when not over the video
|
||||||
defaultVolume: 0.85, // Will be overridden by localStorage volume if available
|
defaultVolume: 0.85, // Will be overridden by localStorage volume if available
|
||||||
flashVersion: 9, // Required flash version for fallback
|
flashVersion: 9, // Required flash version for fallback
|
||||||
linksHiding: true // Hide download links when video is supported
|
linksHiding: true // Hide download links when video is supported
|
||||||
};
|
};
|
||||||
// Override default options with set options
|
|
||||||
|
// Override default options with global options
|
||||||
|
if (typeof VideoJS.options == "object") _V_.merge(this.options, VideoJS.options);
|
||||||
|
|
||||||
|
// Override global options with options specific to this video
|
||||||
if (typeof setOptions == "object") _V_.merge(this.options, setOptions);
|
if (typeof setOptions == "object") _V_.merge(this.options, setOptions);
|
||||||
|
|
||||||
this.box = this.video.parentNode;
|
this.box = this.video.parentNode;
|
||||||
@ -103,6 +112,8 @@ var VideoJS = Class.extend({
|
|||||||
this.video.addEventListener('progress', this.onProgress.context(this), false);
|
this.video.addEventListener('progress', this.onProgress.context(this), false);
|
||||||
// Set interval for load progress using buffer watching method
|
// Set interval for load progress using buffer watching method
|
||||||
this.watchBuffer = setInterval(this.updateBufferedTotal.context(this), 33);
|
this.watchBuffer = setInterval(this.updateBufferedTotal.context(this), 33);
|
||||||
|
// Listen for Video time update
|
||||||
|
this.video.addEventListener('timeupdate', this.onTimeUpdate.context(this), false);
|
||||||
|
|
||||||
// Listen for clicks on the play/pause button
|
// Listen for clicks on the play/pause button
|
||||||
this.playControl.addEventListener("click", this.onPlayControlClick.context(this), false);
|
this.playControl.addEventListener("click", this.onPlayControlClick.context(this), false);
|
||||||
@ -156,7 +167,15 @@ var VideoJS = Class.extend({
|
|||||||
}.context(this);
|
}.context(this);
|
||||||
|
|
||||||
// Support older browsers that used autobuffer
|
// Support older browsers that used autobuffer
|
||||||
this.fixPreloading()
|
this.fixPreloading();
|
||||||
|
|
||||||
|
// Load subtitles. Based on http://matroska.org/technical/specs/subtitles/srt.html
|
||||||
|
this.subtitlesSource = this.video.getAttribute("data-subtitles");
|
||||||
|
if (this.subtitlesSource != null) {
|
||||||
|
this.loadSubtitles();
|
||||||
|
this.buildSubtitles();
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Support older browsers that used "autobuffer"
|
// Support older browsers that used "autobuffer"
|
||||||
@ -166,6 +185,10 @@ var VideoJS = Class.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Translate functionality
|
||||||
|
play: function(){ this.video.play(); },
|
||||||
|
pause: function(){ this.video.pause(); },
|
||||||
|
|
||||||
buildController: function(){
|
buildController: function(){
|
||||||
|
|
||||||
/* Creating this HTML
|
/* Creating this HTML
|
||||||
@ -291,6 +314,24 @@ var VideoJS = Class.extend({
|
|||||||
// Make sure the controls are visible
|
// Make sure the controls are visible
|
||||||
if (this.controls.style.display == 'none') return;
|
if (this.controls.style.display == 'none') return;
|
||||||
|
|
||||||
|
// Sometimes the CSS styles haven't been applied to the controls yet
|
||||||
|
// when we're trying to calculate the height and position them correctly.
|
||||||
|
// This causes a flicker where the controls are out of place.
|
||||||
|
// Best way I can think of to test this is to check if the width of all the controls are the same.
|
||||||
|
// If so, hide the controller and delay positioning them briefly.
|
||||||
|
if (this.playControl.offsetWidth == this.progressControl.offsetWidth
|
||||||
|
&& this.playControl.offsetWidth == this.timeControl.offsetWidth
|
||||||
|
&& this.playControl.offsetWidth == this.volumeControl.offsetWidth) {
|
||||||
|
// Don't want to create an endless loop either.
|
||||||
|
if (!this.positionRetries) this.positionRetries = 1;
|
||||||
|
if (this.positionRetries++ < 100) {
|
||||||
|
this.controls.style.display = "none";
|
||||||
|
setTimeout(this.showController.context(this),0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set width based on fullscreen or not.
|
||||||
if (this.videoIsFullScreen) {
|
if (this.videoIsFullScreen) {
|
||||||
this.box.style.width = "";
|
this.box.style.width = "";
|
||||||
} else {
|
} else {
|
||||||
@ -483,6 +524,13 @@ var VideoJS = Class.extend({
|
|||||||
// Backup for when the user only clicks and doesn't drag
|
// Backup for when the user only clicks and doesn't drag
|
||||||
onProgressHolderMouseUp: function(event){
|
onProgressHolderMouseUp: function(event){
|
||||||
this.setPlayProgressWithEvent(event);
|
this.setPlayProgressWithEvent(event);
|
||||||
|
|
||||||
|
// Fixe for an apparent play button state issue.
|
||||||
|
if (this.video.paused) {
|
||||||
|
this.onPause();
|
||||||
|
} else {
|
||||||
|
this.onPlay();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Adjust the volume when the user drags on the volume control
|
// Adjust the volume when the user drags on the volume control
|
||||||
@ -532,16 +580,6 @@ var VideoJS = Class.extend({
|
|||||||
|
|
||||||
// Adjust the width of the progress bar to fill the controls width
|
// Adjust the width of the progress bar to fill the controls width
|
||||||
sizeProgressBar: function(){
|
sizeProgressBar: function(){
|
||||||
// this.progressControl.style.width =
|
|
||||||
// this.controls.offsetWidth
|
|
||||||
// - this.playControl.offsetWidth
|
|
||||||
// - this.volumeControl.offsetWidth
|
|
||||||
// - this.timeControl.offsetWidth
|
|
||||||
// - this.fullscreenControl.offsetWidth
|
|
||||||
// - (this.getControlsPadding() * 6)
|
|
||||||
// - this.getControlBorderAdjustment()
|
|
||||||
// + "px";
|
|
||||||
// this.progressHolder.style.width = (this.progressControl.offsetWidth - (this.timeControl.offsetWidth + 20)) + "px";
|
|
||||||
this.updatePlayProgress();
|
this.updatePlayProgress();
|
||||||
this.updateLoadProgress();
|
this.updateLoadProgress();
|
||||||
},
|
},
|
||||||
@ -560,6 +598,7 @@ var VideoJS = Class.extend({
|
|||||||
|
|
||||||
// Track & display the current play progress
|
// Track & display the current play progress
|
||||||
trackPlayProgress: function(){
|
trackPlayProgress: function(){
|
||||||
|
if(this.playProgressInterval) clearInterval(this.playProgressInterval);
|
||||||
this.playProgressInterval = setInterval(function(){ this.updatePlayProgress(); }.context(this), 33);
|
this.playProgressInterval = setInterval(function(){ this.updatePlayProgress(); }.context(this), 33);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -580,6 +619,8 @@ var VideoJS = Class.extend({
|
|||||||
this.video.currentTime = newProgress * this.video.duration;
|
this.video.currentTime = newProgress * this.video.duration;
|
||||||
this.playProgress.style.width = newProgress * (_V_.getComputedStyleValue(this.progressHolder, "width").replace("px", "")) + "px";
|
this.playProgress.style.width = newProgress * (_V_.getComputedStyleValue(this.progressHolder, "width").replace("px", "")) + "px";
|
||||||
this.updateTimeDisplay();
|
this.updateTimeDisplay();
|
||||||
|
// currentTime changed, reset subtitles
|
||||||
|
if (this.subtitles != null) { this.currentSubtitlePosition = 0; }
|
||||||
},
|
},
|
||||||
|
|
||||||
setPlayProgressWithEvent: function(event){
|
setPlayProgressWithEvent: function(event){
|
||||||
@ -617,6 +658,13 @@ var VideoJS = Class.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Check if browser can use this flash player
|
||||||
|
flashVersionSupported: function(){
|
||||||
|
return VideoJS.getFlashVersion() >= this.options.flashVersion;
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Fullscreen / Full-window
|
||||||
|
================================================================================ */
|
||||||
// Turn on fullscreen (window) mode
|
// Turn on fullscreen (window) mode
|
||||||
// Real fullscreen isn't available in browsers quite yet.
|
// Real fullscreen isn't available in browsers quite yet.
|
||||||
fullscreenOn: function(){
|
fullscreenOn: function(){
|
||||||
@ -672,16 +720,122 @@ var VideoJS = Class.extend({
|
|||||||
this.positionPoster();
|
this.positionPoster();
|
||||||
},
|
},
|
||||||
|
|
||||||
flashVersionSupported: function(){
|
/* Subtitles
|
||||||
return VideoJS.getFlashVersion() >= this.options.flashVersion;
|
================================================================================ */
|
||||||
|
loadSubtitles: function() {
|
||||||
|
if (typeof XMLHttpRequest == "undefined") {
|
||||||
|
XMLHttpRequest = function () {
|
||||||
|
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
|
||||||
|
catch (e) {}
|
||||||
|
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
|
||||||
|
catch (e) {}
|
||||||
|
try { return new ActiveXObject("Msxml2.XMLHTTP"); }
|
||||||
|
catch (e) {}
|
||||||
|
//Microsoft.XMLHTTP points to Msxml2.XMLHTTP.3.0 and is redundant
|
||||||
|
throw new Error("This browser does not support XMLHttpRequest.");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
request.open("GET",this.subtitlesSource);
|
||||||
|
request.onreadystatechange = function() {
|
||||||
|
if (request.readyState == 4 && request.status == 200) {
|
||||||
|
this.parseSubtitles(request.responseText);
|
||||||
|
}
|
||||||
|
}.context(this);
|
||||||
|
request.send();
|
||||||
|
},
|
||||||
|
|
||||||
|
parseSubtitles: function(text) {
|
||||||
|
var lines = text.replace("\r",'').split("\n");
|
||||||
|
this.subtitles = new Array();
|
||||||
|
this.currentSubtitlePosition = 0;
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
while(i<lines.length) {
|
||||||
|
// define the current subtitle object
|
||||||
|
var subtitle = {};
|
||||||
|
// get the number
|
||||||
|
subtitle.id = lines[i++];
|
||||||
|
if (subtitle.id=="") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get time
|
||||||
|
var time = lines[i++].split(" --> ");
|
||||||
|
subtitle.startTime = this.parseSubtitleTime(time[0]);
|
||||||
|
subtitle.endTime = this.parseSubtitleTime(time[1]);
|
||||||
|
|
||||||
|
// get subtitle text
|
||||||
|
var text = new Array();
|
||||||
|
while(lines[i].length>0 && lines[i]!="\r") {
|
||||||
|
text.push(lines[i++]);
|
||||||
|
}
|
||||||
|
subtitle.text = text.join('<br/>');
|
||||||
|
|
||||||
|
// add this subtitle
|
||||||
|
this.subtitles.push(subtitle);
|
||||||
|
|
||||||
|
// ignore the blank line
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
parseSubtitleTime: function(timeText) {
|
||||||
|
var parts = timeText.split(':');
|
||||||
|
var time = 0;
|
||||||
|
// hours => seconds
|
||||||
|
time += parseInt(parts[0])*60*60;
|
||||||
|
// minutes => seconds
|
||||||
|
time += parseInt(parts[1])*60;
|
||||||
|
// get seconds
|
||||||
|
var seconds = parts[2].split(',');
|
||||||
|
time += parseInt(seconds[0]);
|
||||||
|
// add miliseconds
|
||||||
|
time = time + parseInt(seconds[1])/1000;
|
||||||
|
return time;
|
||||||
|
},
|
||||||
|
|
||||||
|
buildSubtitles: function(){
|
||||||
|
/* Creating this HTML
|
||||||
|
<div class="vjs-subtitles">
|
||||||
|
</div>
|
||||||
|
*/
|
||||||
|
this.subtitlesDiv = _V_.createElement("div", { className: 'vjs-subtitles' });
|
||||||
|
this.video.parentNode.appendChild(this.subtitlesDiv);
|
||||||
|
},
|
||||||
|
|
||||||
|
onTimeUpdate: function(){
|
||||||
|
// show the subtitles
|
||||||
|
if (this.subtitles != null) {
|
||||||
|
var x = this.currentSubtitlePosition;
|
||||||
|
|
||||||
|
while (x<this.subtitles.length && this.video.currentTime>this.subtitles[x].endTime) {
|
||||||
|
if (this.subtitles[x].showing) {
|
||||||
|
this.subtitles[x].showing = false;
|
||||||
|
this.subtitlesDiv.innerHTML = "";
|
||||||
|
}
|
||||||
|
this.currentSubtitlePosition++;
|
||||||
|
x = this.currentSubtitlePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currentSubtitlePosition>=this.subtitles.length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this.video.currentTime>=this.subtitles[x].startTime && this.video.currentTime<=this.subtitles[x].endTime) {
|
||||||
|
this.subtitlesDiv.innerHTML = this.subtitles[x].text;
|
||||||
|
this.subtitles[x].showing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Convenience Functions (mini library)
|
// Convenience Functions (mini library)
|
||||||
// Functions not specific to video or VideoJS and could be replaced with a library like jQuery
|
// Functions not specific to video or VideoJS and could be replaced with a library like jQuery
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
var _V_ = {
|
var _V_ = {
|
||||||
addClass: function(element, classToAdd){
|
addClass: function(element, classToAdd){
|
||||||
if (element.className.split(/\s+/).lastIndexOf(classToAdd) == -1) element.className = element.className == "" ? classToAdd : element.className + " " + classToAdd;
|
if (element.className.split(/\s+/).lastIndexOf(classToAdd) == -1) { element.className = element.className == "" ? classToAdd : element.className + " " + classToAdd; }
|
||||||
},
|
},
|
||||||
|
|
||||||
removeClass: function(element, classToRemove){
|
removeClass: function(element, classToRemove){
|
||||||
@ -736,23 +890,102 @@ var _V_ = {
|
|||||||
|
|
||||||
getComputedStyleValue: function(element, style){
|
getComputedStyleValue: function(element, style){
|
||||||
return window.getComputedStyle(element, null).getPropertyValue(style);
|
return window.getComputedStyle(element, null).getPropertyValue(style);
|
||||||
|
},
|
||||||
|
|
||||||
|
// DOM Ready functionality adapted from jQuery. http://jquery.com/
|
||||||
|
bindDOMReady: function(){
|
||||||
|
if (document.readyState === "complete") {
|
||||||
|
return _V_.DOMReady();
|
||||||
}
|
}
|
||||||
|
if (document.addEventListener) {
|
||||||
|
document.addEventListener("DOMContentLoaded", _V_.DOMContentLoaded, false);
|
||||||
|
window.addEventListener("load", _V_.DOMReady, false);
|
||||||
|
} else if (document.attachEvent) {
|
||||||
|
document.attachEvent("onreadystatechange", _V_.DOMContentLoaded);
|
||||||
|
window.attachEvent("onload", _V_.DOMReady);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DOMContentLoaded: function(){
|
||||||
|
if (document.addEventListener) {
|
||||||
|
document.removeEventListener( "DOMContentLoaded", _V_.DOMContentLoaded, false);
|
||||||
|
_V_.DOMReady();
|
||||||
|
} else if ( document.attachEvent ) {
|
||||||
|
if ( document.readyState === "complete" ) {
|
||||||
|
document.detachEvent("onreadystatechange", _V_.DOMContentLoaded);
|
||||||
|
_V_.DOMReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Functions to be run once the DOM is loaded
|
||||||
|
DOMReadyList: [],
|
||||||
|
addToDOMReady: function(fn){
|
||||||
|
if (_V_.DOMIsReady) {
|
||||||
|
fn.call(document)
|
||||||
|
} else {
|
||||||
|
_V_.DOMReadyList.push(fn);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DOMIsReady: false,
|
||||||
|
DOMReady: function(){
|
||||||
|
if (_V_.DOMIsReady) return;
|
||||||
|
if (!document.body) { return setTimeout(_V_.DOMReady, 13); }
|
||||||
|
_V_.DOMIsReady = true;
|
||||||
|
if (_V_.DOMReadyList) {
|
||||||
|
for (var i=0; i<_V_.DOMReadyList.length; i++) {
|
||||||
|
|
||||||
|
_V_.DOMReadyList[i].call(document)
|
||||||
|
}
|
||||||
|
_V_.DOMReadyList = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
_V_.bindDOMReady();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Class Methods
|
||||||
|
// Functions that don't apply to individual videos.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Add video-js to any video tag with the class on page load
|
||||||
|
VideoJS.setup = function(options){
|
||||||
|
VideoJS.options = options;
|
||||||
|
_V_.addToDOMReady(VideoJS.setupAllWhenReady)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Class Methods
|
VideoJS.setupAllWhenReady = function(){
|
||||||
|
|
||||||
// Add video-js to any video tag with the class
|
|
||||||
VideoJS.setup = function(options){
|
|
||||||
var elements = document.getElementsByTagName("video");
|
var elements = document.getElementsByTagName("video");
|
||||||
for (var i=0,j=elements.length; i<j; i++) {
|
for (var i=0,j=elements.length; i<j; i++) {
|
||||||
videoTag = elements[i];
|
videoTag = elements[i];
|
||||||
if (videoTag.className.indexOf("video-js") != -1) {
|
if (videoTag.className.indexOf("video-js") != -1) {
|
||||||
options = (options) ? _V_.merge(options, { num: i }) : options;
|
videoJSPlayers[i] = new VideoJS(videoTag, { num: i });
|
||||||
videoJSPlayers[i] = new VideoJS(videoTag, options);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VideoJS.DOMReady = function(fn){
|
||||||
|
_V_.addToDOMReady(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add video-js to the video tag or array of video tags (or IDs) passed in.
|
||||||
|
// Typically used when videos are being added to a page dynamically.
|
||||||
|
VideoJS.addVideos = function(videos, options) {
|
||||||
|
videos = videos instanceof Array ? videos : [videos];
|
||||||
|
var videoTag;
|
||||||
|
for (var i=0; i<videos.length; i++) {
|
||||||
|
if (typeof videos[i] == 'string') {
|
||||||
|
videoTag = document.getElementById(videos[i]);
|
||||||
|
} else { // assume DOM object
|
||||||
|
videoTag = videos[i];
|
||||||
|
}
|
||||||
|
options = (options) ? _V_.merge(options, { num: videoJSPlayers.length }) : options;
|
||||||
|
videoJSPlayers.push(new VideoJS(videoTag, options));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the browser supports video.
|
// Check if the browser supports video.
|
||||||
VideoJS.browserSupportsVideo = function() {
|
VideoJS.browserSupportsVideo = function() {
|
||||||
if (typeof VideoJS.videoSupport != "undefined") return VideoJS.videoSupport;
|
if (typeof VideoJS.videoSupport != "undefined") return VideoJS.videoSupport;
|
||||||
|
Loading…
Reference in New Issue
Block a user