aboutsummaryrefslogtreecommitdiffstats
path: root/librevideojs/js
diff options
context:
space:
mode:
Diffstat (limited to 'librevideojs/js')
-rw-r--r--librevideojs/js/cliplibrejs.dev.js514
1 files changed, 511 insertions, 3 deletions
diff --git a/librevideojs/js/cliplibrejs.dev.js b/librevideojs/js/cliplibrejs.dev.js
index d779226..1361b40 100644
--- a/librevideojs/js/cliplibrejs.dev.js
+++ b/librevideojs/js/cliplibrejs.dev.js
@@ -6,7 +6,7 @@
* @licstart The following is the entire license notice for the
* JavaScript code in this page.
*
- * Copyleft 2016 Jesús Eduardo
+ * Copyleft 2016 Jesus Eduardo
*
* The JavaScript code in this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
@@ -66,7 +66,6 @@ var librevjs = function(id, options, ready){
if (ready) {
librevjs.players[id].ready(ready);
}
-
return librevjs.players[id];
// Otherwise get element for ID
@@ -6305,5 +6304,514 @@ if (document.readyState === 'complete') {
// You have to wait at least once in case this script is loaded after your video in the DOM (weird behavior only with minified version)
librevjs.autoSetupTimeout(1);
librevjs.plugin = function(name, init){
- librevjs.Player.prototype[name] = init;
+librevjs.Player.prototype[name] = init;
};
+/* Selector Quality
+@base: https://github.com/dominic-p/videojs-resolution-selector
+================================================================================ */
+(function(_V_) {
+ /***********************************************************************************
+ * Define some helper functions
+ ***********************************************************************************/
+ var methods = {
+ /**
+ * Utility function for merging 2 objects recursively. It treats
+ * arrays like plain objects and it relies on a for...in loop which will
+ * break if the Object prototype is messed with.
+ *
+ * @param (object) destination The object to modify and return
+ * @param (object) source The object to use to overwrite the first
+ * object
+ *
+ * @returns (object) The modified first object is returned
+ */
+ extend : function(destination, source){
+ for (var prop in source){
+ // Sanity check
+ if (!source.hasOwnProperty(prop)){continue;}
+
+ // Enable recursive (deep) object extension
+ if (typeof source[prop] == 'object' && null !== source[prop]) {
+ destination[prop] = methods.extend( destination[prop] || {}, source[prop] );
+ } else {
+ destination[prop] = source[prop];
+ }
+ }
+ return destination;
+ },
+
+ /**
+ * In a future version, this can be made more intelligent,
+ * but for now, we'll just add a "p" at the end if we are passed
+ * numbers.
+ *
+ * @param (string) res The resolution to make a label for
+ *
+ * @returns (string) The label text string
+ */
+ res_label : function(res){
+ return (/^\d+$/.test(res)) ? res + 'p' : res;
+ },
+ matchResolution: function(resStack, res){
+ },
+
+ /**
+ * returns a dummy object that implements the basic get/set
+ * functionality of the Cookies library. Used in the case where
+ * the Cookies library is not present
+ */
+ buildCookiesDummy: function(){
+ return{
+ get: function(key){
+ return "";
+ },
+ set: function(key, val){
+ return false;
+ }
+ };
+ }
+ };
+
+ /***********************************************************************************
+ * Setup our resolution menu items
+ ***********************************************************************************/
+ _V_.ResolutionMenuItem = _V_.MenuItem.extend({
+
+ /** @constructor */
+ init : function(player, options){
+
+ // Modify options for parent MenuItem class's init.
+ options.label = methods.res_label(options.res);
+ options.selected = (options.res.toString() === player.getCurrentRes().toString());
+
+ // Call the parent constructor
+ _V_.MenuItem.call(this, player, options);
+
+ // Store the resolution as a call property
+ this.resolution = options.res;
+
+ // Register our click handler
+ this.on('click', this.onClick);
+
+ // Toggle the selected class whenever the resolution changes
+ player.on('changeRes', _V_.bind(this, function(){
+ if (this.resolution == player.getCurrentRes()){
+ this.selected(true);
+ } else {
+ this.selected(false);
+ }
+ }));
+ }
+ });
+
+ // Handle clicks on the menu items
+ _V_.ResolutionMenuItem.prototype.onClick = function(){
+ var player = this.player(),
+ video_el = player.el().firstChild,
+ current_time = player.currentTime(),
+ is_paused = player.paused(),
+ button_nodes = player.controlBar.resolutionSelector.el().firstChild.children,
+ button_node_count = button_nodes.length;
+
+ // Do nothing if we aren't changing resolutions
+ if (player.getCurrentRes() == this.resolution){return;}
+
+ // Make sure the loadedmetadata event will fire
+ if ('none' == video_el.preload) {video_el.preload = 'metadata';}
+
+ // Change the source and make sure we don't start the video over
+ player.src( player.availableRes[this.resolution]).one('loadedmetadata', function() {
+ player.currentTime(current_time);
+ if (!is_paused) {player.play();}
+ });
+
+ // Save the newly selected resolution in our player options property
+ player.currentRes = this.resolution;
+
+ // Update the button text
+ while (button_node_count > 0){
+ button_node_count--;
+ if ('librevjs-current-res' == button_nodes[button_node_count].className){
+ button_nodes[button_node_count].innerHTML = methods.res_label(this.resolution);
+ break;
+ }
+ }
+
+ // Update the classes to reflect the currently selected resolution
+ player.trigger('changeRes');
+ };
+
+ /***********************************************************************************
+ * Setup our resolution menu title item
+ ***********************************************************************************/
+ _V_.ResolutionTitleMenuItem = _V_.MenuItem.extend({
+
+ init : function(player, options){
+
+ // Call the parent constructor
+ _V_.MenuItem.call(this, player, options);
+
+ // No click handler for the menu title
+ this.off('click');
+ }
+ });
+
+ /***********************************************************************************
+ * Define our resolution selector button
+ ***********************************************************************************/
+ _V_.ResolutionSelector = _V_.MenuButton.extend({
+
+ /** @constructor */
+ init : function(player, options) {
+
+ // Add our list of available resolutions to the player object
+ player.availableRes = options.available_res;
+
+ // Call the parent constructor
+ _V_.MenuButton.call(this, player, options);
+ }
+ });
+
+ // Create a menu item for each available resolution
+ _V_.ResolutionSelector.prototype.createItems = function(){
+
+ var player = this.player(),
+ items = [],
+ current_res;
+
+ // Add the menu title item
+ items.push( new _V_.ResolutionTitleMenuItem(player,{
+ el : _V_.Component.prototype.createEl('li',{
+ className : 'librevjs-menu-title librevjs-res-menu-title',
+ innerHTML : 'Calidad'
+ })
+ }));
+
+ // Add an item for each available resolution
+ for (current_res in player.availableRes){
+ // Don't add an item for the length attribute
+ if ('length' == current_res) {continue;}
+ items.push( new _V_.ResolutionMenuItem(player,{
+ res : current_res
+ }));
+ }
+
+ // Sort the available resolutions in descending order
+ items.sort(function(a,b){
+ if (typeof a.resolution == 'undefined'){
+ return -1;
+ } else {
+ return parseInt(b.resolution) - parseInt(a.resolution);
+ }
+ });
+ return items;
+ };
+
+ /***********************************************************************************
+ * Register the plugin with cliplibrejs, main plugin function
+ ***********************************************************************************/
+ _V_.plugin('resolutionSelector', function(options){
+
+ // Only enable the plugin on HTML5 videos
+ if (!this.el().firstChild.canPlayType){return;}
+
+ var player = this,
+ sources = player.options().sources,
+ i = sources.length,
+ j,
+ found_type,
+
+ // Override default options with those provided
+ settings = methods.extend({
+
+ default_res : '', // (string) The resolution that should be selected by default ( '480' or '480,1080,240' )
+ force_types : false // (array) List of media types. If passed, we need to have source for each type in each resolution or that resolution will not be an option
+
+ }, options || {}),
+
+ available_res = {length : 0},
+ current_res,
+ resolutionSelector,
+
+ // Split default resolutions if set and valid, otherwise default to an empty array
+ default_resolutions = (settings.default_res && typeof settings.default_res == 'string') ? settings.default_res.split( ',' ) : [],
+ cookieNamespace = 'cliplibrejs.resolutionSelector',
+ resCookieName = cookieNamespace + '.res',
+ cookieRef = (typeof(Cookies) === "function") ? Cookies : methods.buildCookiesDummy();
+
+ // Get all of the available resoloutions
+ while (i > 0){
+
+ i--;
+
+ // Skip sources that don't have data-res attributes
+ if (!sources[i]['data-res']){continue;}
+ current_res = sources[i]['data-res'];
+ if (typeof available_res[current_res] !== 'object'){
+ available_res[current_res] = [];
+ available_res.length++;
+ }
+ available_res[current_res].push( sources[i] );
+ }
+
+ // Check for forced types
+ if (settings.force_types){
+ // Loop through all available resoultions
+ for (current_res in available_res){
+ // Don't count the length property as a resolution
+ if ('length' == current_res){continue;}
+ i = settings.force_types.length;
+ // For each resolution loop through the required types
+ while (i > 0){
+
+ i--;
+
+ j = available_res[current_res].length;
+ found_types = 0;
+
+ // For each required type loop through the available sources to check if its there
+ while (j > 0){
+
+ j--;
+
+ if (settings.force_types[i] === available_res[current_res][j].type){
+ found_types++;
+ }
+ } // End loop through current resolution sources
+
+ if (found_types < settings.force_types.length){
+ delete available_res[current_res];
+ available_res.length--;
+ break;
+ }
+ } // End loop through required types
+ } // End loop through resolutions
+ }
+
+ // Make sure we have at least 2 available resolutions before we add the button
+ if (available_res.length < 2) {return;}
+
+ var resCookie = cookieRef.get(resCookieName)
+ if (resCookie) {
+ // rebuild the default_resolutions stack with the cookie's resolution on top
+ default_resolutions = [resCookie].concat(default_resolutions);
+ }
+
+ // Loop through the choosen default resolutions if there were any
+ for (i = 0; i < default_resolutions.length; i++){
+ // Set the video to start out with the first available default res
+ if (available_res[default_resolutions[i]]){
+ player.src(available_res[default_resolutions[i]]);
+ player.currentRes = default_resolutions[i];
+ break;
+ }
+ }
+
+ // Helper function to get the current resolution
+ player.getCurrentRes = function(){
+ if (typeof player.currentRes !== 'undefined'){
+ return player.currentRes;
+ } else {
+ try {
+ return res = player.options().sources[0]['data-res'];
+ } catch(e) {
+ return '';
+ }
+ }
+ };
+
+ // Get the started resolution
+ current_res = player.getCurrentRes();
+
+ if (current_res) {current_res = methods.res_label(current_res);}
+
+ // Add the resolution selector button
+ resolutionSelector = new _V_.ResolutionSelector(player,{
+ el : _V_.Component.prototype.createEl( null,{
+ className : 'librevjs-res-button librevjs-menu-button librevjs-control',
+ innerHTML : '<div class="librevjs-control-content"><span class="librevjs-current-res">' + (current_res || 'Quality') + '</span></div>',
+ role : 'button',
+ 'aria-live' : 'polite', // let the screen reader user know that the text of the button may change
+ tabIndex : 0
+ }),
+ available_res : available_res
+ });
+
+ // Attach an event to remember previous res selection via cookie
+ this.on('changeRes', function(){
+ cookieRef.set(resCookieName, player.getCurrentRes());
+ });
+
+ // Attach an event to update player.src once on loadedmetadata
+ // if a resolution was previously set
+ this.one('loadedmetadata', function(){
+ var resCookie = cookieRef.get(resCookieName);
+
+ if (resCookie) {
+ player.src(player.availableRes[resCookie]);
+ player.currentRes = resCookie;
+ player.trigger( 'changeRes' );
+ }
+ });
+
+ // Add the button to the control bar object and the DOM
+ player.controlBar.resolutionSelector = player.controlBar.addChild( resolutionSelector );
+ });
+})(cliplibrejs);
+
+/* Hotkeys for LibreVideoJS
+@base: https://github.com/ctd1500/videojs-hotkeys
+================================================================================ */
+(function(window, cliplibrejs){
+ 'use strict';
+
+ window['cliplibrejs_hotkeys'] = {version: "0.2.4"};
+ var hotkeys = function(options){
+ var player = this;
+ var def_options = {
+ volumeStep: 0.1,
+ seekStep: 5,
+ enableMute: true,
+ enableFullscreen: true,
+ enableNumbers: true,
+ };
+ options = options || {};
+
+ // Set default player tabindex to handle keydown and doubleclick events
+ if (!player.el().hasAttribute('tabIndex')){
+ player.el().setAttribute('tabIndex', '-1');
+ }
+
+ player.on('play', function(){
+ // Fix allowing the YouTube plugin to have hotkey support.
+ var ifblocker = player.el().querySelector('.iframeblocker');
+ if (ifblocker &&
+ ifblocker.style.display == ""){
+ ifblocker.style.display = "block";
+ ifblocker.style.bottom = "39px";
+ }
+ });
+
+ var keyDown = function keyDown(event){
+ var ewhich = event.which;
+ var volumeStep = options.volumeStep || def_options.volumeStep;
+ var seekStep = options.seekStep || def_options.seekStep;
+ var enableMute = options.enableMute || def_options.enableMute;
+ var enableFull = options.enableFullscreen || def_options.enableFullscreen;
+ var enableNumbers = options.enableNumbers || def_options.enableNumbers;
+
+ // When controls are disabled, hotkeys will be disabled as well
+ if (player.controls()){
+
+ // Don't catch keys if any control buttons are focused
+ var activeEl = document.activeElement;
+ if (activeEl == player.el() ||
+ activeEl == player.el().querySelector('.librevjs-tech') ||
+ activeEl == player.el().querySelector('.librevjs-control-bar') ||
+ activeEl == player.el().querySelector('.iframeblocker')){
+
+ // Spacebar toggles play/pause
+ if (ewhich === 32){
+ event.preventDefault();
+ if (this.player_.paused()){
+ this.player_.play();
+ } else {
+ this.player_.pause();
+ }
+ }
+
+ // Seeking with the left/right arrow keys
+ else if (ewhich === 37){ // Left Arrow
+ event.preventDefault();
+ var curTime = player.currentTime() - seekStep;
+
+ // The flash player tech will allow you to seek into negative
+ // numbers and break the seekbar, so try to prevent that.
+ if (player.currentTime() <= seekStep){
+ curTime = 0;
+ }
+ player.currentTime(curTime);
+ } else if (ewhich === 39){ // Right Arrow
+ event.preventDefault();
+ player.currentTime(player.currentTime() + seekStep);
+ }
+
+ // Volume control with the up/down arrow keys
+ else if (ewhich === 40){ // Down Arrow
+ event.preventDefault();
+ player.volume(player.volume() - volumeStep);
+ } else if (ewhich === 38){ // Up Arrow
+ event.preventDefault();
+ player.volume(player.volume() + volumeStep);
+ }
+
+ // Toggle Mute with the M key
+ else if (ewhich === 77){
+ if (enableMute) {
+ if (player.muted()){
+ player.muted(false);
+ } else {
+ player.muted(true);
+ }
+ }
+ }
+
+ // Toggle Fullscreen with the F key
+ else if (ewhich === 70){
+ if (enableFull){
+ if (this.player_.isFullScreen){
+ this.player_.cancelFullScreen();
+ } else{
+ this.player_.requestFullScreen();
+ }
+ }
+ }
+
+ // Number keys from 0-9 skip to a percentage of the video. 0 is 0% and 9 is 90%
+ else if ((ewhich > 47 && ewhich < 59) || (ewhich > 95 && ewhich < 106)){
+ if (enableNumbers){
+ var sub = 48;
+ if (ewhich > 95){
+ sub = 96;
+ }
+ var number = ewhich - sub;
+ event.preventDefault();
+ player.currentTime(player.duration() * number * 0.1);
+ }
+ }
+ }
+ }
+ };
+
+ var doubleClick = function doubleClick(event){
+ var enableFull = options.enableFullscreen || def_options.enableFullscreen;
+
+ // When controls are disabled, hotkeys will be disabled as well
+ if (player.controls()){
+
+ // Don't catch clicks if any control buttons are focused
+ var activeEl = event.relatedTarget || event.toElement || document.activeElement;
+ if (activeEl == player.el() ||
+ activeEl == player.el().querySelector('.librevjs-tech') ||
+ activeEl == player.el().querySelector('.iframeblocker')){
+
+ if (enableFull){
+ if (this.player_.isFullScreen){
+ this.player_.cancelFullScreen();
+ } else{
+ this.player_.requestFullScreen();
+ }
+ }
+ }
+ }
+ };
+
+ player.on('keydown', keyDown);
+ player.on('dblclick', doubleClick);
+
+ return this;
+ };
+
+ cliplibrejs.plugin('hotkeys', hotkeys);
+
+})(window, window.cliplibrejs);