This commit is contained in:
goodtube4u
2024-07-01 15:42:00 +10:00
commit b86a2cba74
23 changed files with 1184 additions and 0 deletions

6
js/sweetalert2@11.js Normal file

File diff suppressed because one or more lines are too long

40
js/video.min.js vendored Normal file

File diff suppressed because one or more lines are too long

30
js/videojs-core.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,312 @@
/*! @name videojs-hls-quality-selector @version 2.0.0 @license MIT */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('video.js')) :
typeof define === 'function' && define.amd ? define(['video.js'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.videojsHlsQualitySelector = factory(global.videojs));
}(this, (function (videojs) { 'use strict';
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var videojs__default = /*#__PURE__*/_interopDefaultLegacy(videojs);
var version = "2.0.0";
const MenuButton = videojs__default['default'].getComponent('MenuButton');
const Menu = videojs__default['default'].getComponent('Menu');
const Component = videojs__default['default'].getComponent('Component');
const Dom = videojs__default['default'].dom;
/**
* Convert string to title case.
*
* @param {string} string - the string to convert
* @return {string} the returned titlecase string
*/
function toTitleCase(string) {
if (typeof string !== 'string') {
return string;
}
return string.charAt(0).toUpperCase() + string.slice(1);
}
/**
* Extend vjs button class for quality button.
*/
class ConcreteButton extends MenuButton {
/**
* Button constructor.
*
* @param {Player} player - videojs player instance
*/
constructor(player) {
super(player, {
title: player.localize('Quality'),
name: 'QualityButton'
});
}
/**
* Creates button items.
*
* @return {Array} - Button items
*/
createItems() {
return [];
}
/**
* Create the menu and add all items to it.
*
* @return {Menu}
* The constructed menu
*/
createMenu() {
const menu = new Menu(this.player_, {
menuButton: this
});
this.hideThreshold_ = 0;
this.items = this.createItems();
if (this.items) {
// Add menu items to the menu
for (let i = 0; i < this.items.length; i++) {
menu.addItem(this.items[i]);
}
}
return menu;
}
}
// Concrete classes
const VideoJsMenuItemClass = videojs__default['default'].getComponent('MenuItem');
/**
* Extend vjs menu item class.
*/
class ConcreteMenuItem extends VideoJsMenuItemClass {
/**
* Menu item constructor.
*
* @param {Player} player - vjs player
* @param {Object} item - Item object
* @param {ConcreteButton} qualityButton - The containing button.
* @param {HlsQualitySelector} plugin - This plugin instance.
*/
constructor(player, item, qualityButton, plugin) {
super(player, {
label: item.label,
selectable: true,
selected: item.selected || false
});
this.item = item;
this.qualityButton = qualityButton;
this.plugin = plugin;
}
/**
* Click event for menu item.
*/
handleClick() {
// Reset other menu items selected status.
for (let i = 0; i < this.qualityButton.items.length; ++i) {
this.qualityButton.items[i].selected(false);
}
// Set this menu item to selected, and set quality.
this.plugin.setQuality(this.item.value);
this.selected(true);
}
}
const Plugin = videojs__default['default'].getPlugin('plugin');
// Default options for the plugin.
const defaults = {};
/**
* An advanced Video.js plugin. For more information on the API
*
* See: https://blog.videojs.com/feature-spotlight-advanced-plugins/
*/
class HlsQualitySelector extends Plugin {
/**
* Create a HlsQualitySelector plugin instance.
*
* @param {Player} player
* A Video.js Player instance.
*
* @param {Object} [options]
* An optional options object.
*
* While not a core part of the Video.js plugin architecture, a
* second argument of options is a convenient way to accept inputs
* from your plugin's caller.
*/
constructor(player, options) {
// the parent class will add player under this.player
super(player);
this.options = videojs__default['default'].obj.merge(defaults, options);
this.player.ready(() => {
// If there is quality levels plugin and the HLS tech exists then continue.
if (this.player.qualityLevels) {
this.player.addClass('vjs-hls-quality-selector');
// Create the quality button.
this.createQualityButton();
this.bindPlayerEvents();
}
});
}
/**
* Binds listener for quality level changes.
*/
bindPlayerEvents() {
this.player.qualityLevels().on('addqualitylevel', this.onAddQualityLevel.bind(this));
}
/**
* Adds the quality menu button to the player control bar.
*/
createQualityButton() {
const player = this.player;
this._qualityButton = new ConcreteButton(player);
const placementIndex = player.controlBar.children().length - 2;
const concreteButtonInstance = player.controlBar.addChild(this._qualityButton, {
componentClass: 'qualitySelector'
}, this.options.placementIndex || placementIndex);
concreteButtonInstance.addClass('vjs-quality-selector');
if (!this.options.displayCurrentQuality) {
const icon = ` ${this.options.vjsIconClass || 'vjs-icon-hd'}`;
concreteButtonInstance.menuButton_.$('.vjs-icon-placeholder').className += icon;
} else {
this.setButtonInnerText(player.localize('Auto'));
}
concreteButtonInstance.removeClass('vjs-hidden');
}
/**
*Set inner button text.
*
* @param {string} text - the text to display in the button.
*/
setButtonInnerText(text) {
this._qualityButton.menuButton_.$('.vjs-icon-placeholder').innerHTML = text;
}
/**
* Builds individual quality menu items.
*
* @param {Object} item - Individual quality menu item.
* @return {ConcreteMenuItem} - Menu item
*/
getQualityMenuItem(item) {
const player = this.player;
return new ConcreteMenuItem(player, item, this._qualityButton, this);
}
/**
* Executed when a quality level is added from HLS playlist.
*/
onAddQualityLevel() {
const player = this.player;
const qualityList = player.qualityLevels();
const levels = qualityList.levels_ || [];
const levelItems = [];
for (let i = 0; i < levels.length; ++i) {
const {
width,
height
} = levels[i];
const pixels = width > height ? height : width;
if (!pixels) {
continue;
}
if (!levelItems.filter(_existingItem => {
return _existingItem.item && _existingItem.item.value === pixels;
}).length) {
const levelItem = this.getQualityMenuItem.call(this, {
label: pixels + 'p',
value: pixels
});
levelItems.push(levelItem);
}
}
levelItems.sort((current, next) => {
if (typeof current !== 'object' || typeof next !== 'object') {
return -1;
}
if (current.item.value < next.item.value) {
return 1;
}
if (current.item.value > next.item.value) {
return -1;
}
return 0;
});
levelItems.push(this.getQualityMenuItem.call(this, {
label: this.player.localize('Auto'),
value: 'auto',
selected: true
}));
if (this._qualityButton) {
this._qualityButton.createItems = () => {
return levelItems;
};
this._qualityButton.update();
}
}
/**
* Sets quality (based on media short side)
*
* @param {number} quality - A number representing HLS playlist.
*/
setQuality(quality) {
const qualityList = this.player.qualityLevels();
// Set quality on plugin
this._currentQuality = quality;
if (this.options.displayCurrentQuality) {
this.setButtonInnerText(quality === 'auto' ? this.player.localize('Auto') : `${quality}p`);
}
for (let i = 0; i < qualityList.length; ++i) {
const {
width,
height
} = qualityList[i];
const pixels = width > height ? height : width;
qualityList[i].enabled = pixels === quality || quality === 'auto';
}
this._qualityButton.unpressButton();
// Select the correct quality menu item on screen
for (let i = 0; i < this._qualityButton.items.length; ++i) {
if (this._qualityButton.items[i]['item']['value'] == this._currentQuality) {
this._qualityButton.items[i].selected(true);
}
else {
this._qualityButton.items[i].selected(false);
}
}
}
/**
* Return the current set quality or 'auto'
*
* @return {string} the currently set quality
*/
getCurrentQuality() {
return this._currentQuality || 'auto';
}
}
// Include the version number.
HlsQualitySelector.VERSION = version;
// Register the plugin with video.js.
videojs__default['default'].registerPlugin('hlsQualitySelector', HlsQualitySelector);
return HlsQualitySelector;
})));

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,603 @@
/**
* pthumbnails
* @version 1.2.0
* @copyright 2020 Rigel Kent <sendmemail@rigelk.eu>
* @license MIT
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('video.js')) :
typeof define === 'function' && define.amd ? define(['video.js'], factory) :
(global.videojsVttThumbnails = factory(global.videojs));
}(this, (function (videojs) { 'use strict';
videojs = videojs && videojs.hasOwnProperty('default') ? videojs['default'] : videojs;
var version = "1.2.0";
var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}
function AsyncGenerator(gen) {
var front, back;
function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};
if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}
function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;
if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}
function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;
case "throw":
front.reject(value);
break;
default:
front.resolve({
value: value,
done: false
});
break;
}
front = front.next;
if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}
this._invoke = send;
if (typeof gen.return !== "function") {
this.return = undefined;
}
}
if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}
AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};
AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};
AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};
return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
// import request from 'request';
// Default options for the plugin.
var defaults = {};
// Cache for image elements
var cache = {};
// Cross-compatibility for Video.js 5 and 6.
var registerPlugin = videojs.registerPlugin || videojs.plugin;
// const dom = videojs.dom || videojs;
/**
* Function to invoke when the player is ready.
*
* This is a great place for your plugin to initialize itself. When this
* function is called, the player will have its DOM and child components
* in place.
*
* @function onPlayerReady
* @param {Player} player
* A Video.js player object.
*
* @param {Object} [options={}]
* A plain object containing options for the plugin.
*/
var onPlayerReady = function onPlayerReady(player, options) {
player.addClass('vjs-vtt-thumbnails');
player.vttThumbnails = new vttThumbnailsPlugin(player, options);
};
/**
* A video.js plugin.
*
* In the plugin function, the value of `this` is a video.js `Player`
* instance. You cannot rely on the player being in a "ready" state here,
* depending on how the plugin is invoked. This may or may not be important
* to you; if not, remove the wait for "ready"!
*
* @function vttThumbnails
* @param {Object} [options={}]
* An object of options left to the plugin author to define.
*/
var vttThumbnails = function vttThumbnails(options) {
var _this = this;
this.ready(function () {
onPlayerReady(_this, videojs.mergeOptions(defaults, options));
});
};
/**
* VTT Thumbnails class.
*
* This class performs all functions related to displaying the vtt
* thumbnails.
*/
var vttThumbnailsPlugin = function () {
/**
* Plugin class constructor, called by videojs on
* ready event.
*
* @function constructor
* @param {Player} player
* A Video.js player object.
*
* @param {Object} [options={}]
* A plain object containing options for the plugin.
* - src: path to the .vtt file
* - baseUrl (optional): host prepended to the image definitions
* - preloadStrategy (optional): preload images in the cache, for smooth scrubbing (default: none, available: 'all')
*/
function vttThumbnailsPlugin(player, options) {
classCallCheck(this, vttThumbnailsPlugin);
this.player = player;
this.options = options;
this.listenForDurationChange();
this.initializeThumbnails();
this.registeredEvents = {};
return this;
}
vttThumbnailsPlugin.prototype.src = function src(source) {
this.resetPlugin();
this.options.src = source;
this.initializeThumbnails();
};
vttThumbnailsPlugin.prototype.detach = function detach() {
this.resetPlugin();
};
vttThumbnailsPlugin.prototype.resetPlugin = function resetPlugin() {
this.thumbnailHolder && this.thumbnailHolder.parentNode.removeChild(this.thumbnailHolder);
this.progressBar && this.progressBar.removeEventListener('mouseenter', this.registeredEvents.progressBarMouseEnter);
this.progressBar && this.progressBar.removeEventListener('mouseleave', this.registeredEvents.progressBarMouseLeave);
this.progressBar && this.progressBar.removeEventListener('mousemove', this.registeredEvents.progressBarMouseMove);
delete this.registeredEvents.progressBarMouseEnter;
delete this.registeredEvents.progressBarMouseLeave;
delete this.registeredEvents.progressBarMouseMove;
delete this.progressBar;
delete this.vttData;
delete this.thumbnailHolder;
delete this.timeHolder;
delete this.lastStyle;
};
vttThumbnailsPlugin.prototype.listenForDurationChange = function listenForDurationChange() {
this.player.on('durationchange', function () {});
};
/**
* Bootstrap the plugin.
*/
vttThumbnailsPlugin.prototype.initializeThumbnails = function initializeThumbnails() {
var _this2 = this;
if (!this.options.src) {
return;
}
var baseUrl = this.getBaseUrl();
var url = this.getFullyQualifiedUrl(this.options.src, baseUrl);
this.getVttFile(url).then(function (data) {
_this2.vttData = _this2.processVtt(data);
_this2.setupThumbnailElement();
if (_this2.options.hasOwnProperty('preloadStrategy')) {
_this2.preload(_this2.vttData);
}
});
};
/**
* Builds a base URL should we require one.
*
* @returns {string}
*/
vttThumbnailsPlugin.prototype.getBaseUrl = function getBaseUrl() {
return [window.location.protocol, '//', window.location.hostname, window.location.port ? ':' + window.location.port : '', window.location.pathname].join('').split(/([^\/]*)$/gi).shift();
};
/**
* Grabs the contents of the VTT file.
*
* @param url
* @returns {Promise}
*/
vttThumbnailsPlugin.prototype.getVttFile = function getVttFile(url) {
var _this3 = this;
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.data = {
resolve: resolve
};
req.addEventListener('load', _this3.vttFileLoaded);
req.open('GET', url);
req.send();
});
};
/**
* Callback for loaded VTT file.
*/
vttThumbnailsPlugin.prototype.vttFileLoaded = function vttFileLoaded() {
this.data.resolve(this.responseText);
};
/**
* This will fill the cache and thus preload images
*/
vttThumbnailsPlugin.prototype.preload = function preload(data) {
var _this4 = this;
data.forEach(function (item) {
return _this4.setImageInCacheForItem(item);
});
};
vttThumbnailsPlugin.prototype.setupThumbnailElement = function setupThumbnailElement(data) {
var _this5 = this;
var mouseDisplay = this.player.$('.vjs-mouse-display');
this.progressBar = this.player.$('.vjs-progress-control');
// thumbnail element
var thumbHolder = document.createElement('div');
thumbHolder.setAttribute('class', 'vjs-vtt-thumbnail-display');
this.progressBar.appendChild(thumbHolder);
this.thumbnailHolder = thumbHolder;
// time element
var timeHolder = document.createElement('time');
timeHolder.setAttribute('class', 'vjs-vtt-thumbnail-time');
this.thumbnailHolder.appendChild(timeHolder);
this.timeHolder = timeHolder;
if (mouseDisplay) {
mouseDisplay.classList.add('vjs-hidden');
}
this.registeredEvents.progressBarMouseEnter = function () {
return _this5.onBarMouseenter();
};
this.registeredEvents.progressBarMouseLeave = function () {
return _this5.onBarMouseleave();
};
this.progressBar.addEventListener('mouseenter', this.registeredEvents.progressBarMouseEnter);
this.progressBar.addEventListener('mouseleave', this.registeredEvents.progressBarMouseLeave);
};
vttThumbnailsPlugin.prototype.onBarMouseenter = function onBarMouseenter() {
var _this6 = this;
this.mouseMoveCallback = function (e) {
_this6.onBarMousemove(e);
};
this.registeredEvents.progressBarMouseMove = this.mouseMoveCallback;
this.progressBar.addEventListener('mousemove', this.registeredEvents.progressBarMouseMove);
this.showThumbnailHolder();
};
vttThumbnailsPlugin.prototype.onBarMouseleave = function onBarMouseleave() {
if (this.registeredEvents.progressBarMouseMove) {
this.progressBar.removeEventListener('mousemove', this.registeredEvents.progressBarMouseMove);
}
this.hideThumbnailHolder();
};
vttThumbnailsPlugin.prototype.getXCoord = function getXCoord(bar, mouseX) {
var rect = bar.getBoundingClientRect();
var docEl = document.documentElement;
return mouseX - (rect.left + (window.pageXOffset || docEl.scrollLeft || 0));
};
vttThumbnailsPlugin.prototype.onBarMousemove = function onBarMousemove(event) {
this.updateThumbnailStyle(videojs.dom.getPointerPosition(this.progressBar, event).x, this.progressBar.offsetWidth);
};
vttThumbnailsPlugin.prototype.setImageInCacheForItem = function setImageInCacheForItem(item) {
// Cache miss
if (item.css.url && !cache[item.css.url]) {
var image = new Image();
image.src = item.css.url;
cache[item.css.url] = image;
}
};
vttThumbnailsPlugin.prototype.getStyleForTime = function getStyleForTime(time) {
for (var i = 0; i < this.vttData.length; ++i) {
var item = this.vttData[i];
if (time >= item.start && time < item.end) {
this.setImageInCacheForItem(item);
return item.css;
}
}
};
vttThumbnailsPlugin.prototype.showThumbnailHolder = function showThumbnailHolder() {
this.thumbnailHolder.style.opacity = '1';
};
vttThumbnailsPlugin.prototype.hideThumbnailHolder = function hideThumbnailHolder() {
this.thumbnailHolder.style.opacity = '0';
};
vttThumbnailsPlugin.prototype.updateThumbnailStyle = function updateThumbnailStyle(percent, width) {
var duration = this.player.duration();
var time = percent * duration;
var currentStyle = this.getStyleForTime(time);
var timestamp = new Date(Math.round(time) * 1000).toISOString().substr(11, 8);
timestamp = duration > 3599 ? timestamp : timestamp.substring(3);
this.timeHolder.innerText = timestamp;
if (!currentStyle) {
return this.hideThumbnailHolder();
}
var xPos = percent * width;
var thumbnailWidth = parseInt(this.thumbnailHolder.offsetWidth);
var halfthumbnailWidth = thumbnailWidth / 2;
var marginRight = width - (xPos + halfthumbnailWidth);
var marginLeft = xPos - halfthumbnailWidth;
if (marginLeft > 0 && marginRight > 0) {
this.thumbnailHolder.style.transform = 'translateX(' + (xPos - halfthumbnailWidth) + 'px)';
} else if (marginLeft <= 0) {
this.thumbnailHolder.style.transform = 'translateX(' + 0 + 'px)';
} else if (marginRight <= 0) {
this.thumbnailHolder.style.transform = 'translateX(' + (xPos + marginRight - halfthumbnailWidth) + 'px)';
}
if (this.lastStyle && this.lastStyle === currentStyle) {
return;
}
this.lastStyle = currentStyle;
for (var style in currentStyle) {
if (currentStyle.hasOwnProperty(style)) {
this.thumbnailHolder.style[style] = currentStyle[style];
}
}
};
vttThumbnailsPlugin.prototype.processVtt = function processVtt(data) {
var _this7 = this;
var processedVtts = [];
var vttDefinitions = data.split(/[\r\n][\r\n]/i);
vttDefinitions.forEach(function (vttDef) {
if (vttDef.match(/([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?( ?--> ?)([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?[\r\n]{1}.*/gi)) {
var vttDefSplit = vttDef.split(/[\r\n]/i);
var vttTiming = vttDefSplit[0];
var vttTimingSplit = vttTiming.split(/ ?--> ?/i);
var vttTimeStart = vttTimingSplit[0];
var vttTimeEnd = vttTimingSplit[1];
var vttImageDef = vttDefSplit[1];
var vttCssDef = _this7.getVttCss(vttImageDef);
processedVtts.push({
start: _this7.getSecondsFromTimestamp(vttTimeStart),
end: _this7.getSecondsFromTimestamp(vttTimeEnd),
css: vttCssDef
});
}
});
return processedVtts;
};
vttThumbnailsPlugin.prototype.getFullyQualifiedUrl = function getFullyQualifiedUrl(path, base) {
if (path.indexOf('//') >= 0) {
// We have a fully qualified path.
return path;
}
if (base.indexOf('//') === 0) {
// We don't have a fully qualified path, but need to
// be careful with trimming.
return [base.replace(/\/$/gi, ''), this.trim(path, '/')].join('/');
}
if (base.indexOf('//') > 0) {
// We don't have a fully qualified path, and should
// trim both sides of base and path.
return [this.trim(base, '/'), this.trim(path, '/')].join('/');
}
// If all else fails.
return path;
};
vttThumbnailsPlugin.prototype.getPropsFromDef = function getPropsFromDef(def) {
var imageDefSplit = def.split(/#xywh=/i);
var imageUrl = imageDefSplit[0];
var imageCoords = imageDefSplit[1];
var splitCoords = imageCoords.match(/[0-9]+/gi);
return {
x: splitCoords[0],
y: splitCoords[1],
w: splitCoords[2],
h: splitCoords[3],
image: imageUrl
};
};
vttThumbnailsPlugin.prototype.getVttCss = function getVttCss(vttImageDef) {
var cssObj = {};
// If there isn't a protocol, use the VTT source URL.
var baseSplit = void 0;
if (this.options.baseUrl) {
baseSplit = this.options.baseUrl;
} else if (this.options.src.indexOf('//') >= 0) {
baseSplit = this.options.src.split(/([^\/]*)$/gi).shift();
} else {
baseSplit = this.getBaseUrl() + this.options.src.split(/([^\/]*)$/gi).shift();
}
vttImageDef = this.getFullyQualifiedUrl(vttImageDef, baseSplit);
// deal with regular thumbnails
if (!vttImageDef.match(/#xywh=/i)) {
cssObj.background = 'url("' + vttImageDef + '")';
cssObj.url = vttImageDef;
return cssObj;
}
// deal with sprited thumbnails
var imageProps = this.getPropsFromDef(vttImageDef);
cssObj.background = 'url("' + imageProps.image + '") no-repeat -' + imageProps.x + 'px -' + imageProps.y + 'px';
cssObj.width = imageProps.w + 'px';
cssObj.height = imageProps.h + 'px';
cssObj.url = imageProps.image;
return cssObj;
};
vttThumbnailsPlugin.prototype.doconstructTimestamp = function doconstructTimestamp(timestamp) {
var splitStampMilliseconds = timestamp.split('.');
var timeParts = splitStampMilliseconds[0];
var timePartsSplit = timeParts.split(':');
return {
milliseconds: parseInt(splitStampMilliseconds[1]) || 0,
seconds: parseInt(timePartsSplit.pop()) || 0,
minutes: parseInt(timePartsSplit.pop()) || 0,
hours: parseInt(timePartsSplit.pop()) || 0
};
};
vttThumbnailsPlugin.prototype.getSecondsFromTimestamp = function getSecondsFromTimestamp(timestamp) {
var timestampParts = this.doconstructTimestamp(timestamp);
return parseInt(timestampParts.hours * (60 * 60) + timestampParts.minutes * 60 + timestampParts.seconds + timestampParts.milliseconds / 1000);
};
vttThumbnailsPlugin.prototype.trim = function trim(str, charlist) {
var whitespace = [' ', '\n', '\r', '\t', '\f', '\x0b', '\xa0', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200A', '\u200B', '\u2028', '\u2029', '\u3000'].join('');
var l = 0;
var i = 0;
str += '';
if (charlist) {
whitespace = (charlist + '').replace(/([[\]().?/*{}+$^:])/g, '$1');
}
l = str.length;
for (i = 0; i < l; i++) {
if (whitespace.indexOf(str.charAt(i)) === -1) {
str = str.substring(i);
break;
}
}
l = str.length;
for (i = l - 1; i >= 0; i--) {
if (whitespace.indexOf(str.charAt(i)) === -1) {
str = str.substring(0, i + 1);
break;
}
}
return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
};
return vttThumbnailsPlugin;
}();
// Register the plugin with video.js.
registerPlugin('vttThumbnails', vttThumbnails);
// Include the version number.
vttThumbnails.VERSION = version;
return vttThumbnails;
})));