/**
* @file video.js
* @module videojs
*/
import {version} de '../../package.json' ;
import window from 'global/window' ;
import {
crochets_,
crochets,
crochet,
hookOnce,
Retirer le crochet
} from './utils/hooks' ;
import * as setup from './setup' ;
import * as stylesheet from './utils/stylesheet.js' ;
import Component from './component' ;
import EventTarget from './event-target' ;
import * as Events from './utils/events.js' ;
import Player from './player' ;
import Plugin from './plugin' ;
import mergeOptions from './utils/merge-options.js' ;
import * as Fn from './utils/fn.js' ;
import TextTrack de './tracks/text-track.js' ;
import AudioTrack from './tracks/audio-track.js' ;
import VideoTrack from './tracks/video-track.js' ;
import { createTimeRanges } from './utils/time-ranges.js' ;
import formatTime, { setFormatTime, resetFormatTime } from './utils/format-time.js' ;
import log, { createLogger } from './utils/log.js' ;
import * as Dom from './utils/dom.js' ;
import * as browser from './utils/browser.js' ;
import * as Url from './utils/url.js' ;
import {isObject} de './utils/obj' ;
import computedStyle de './utils/computed-style.js' ;
import extend from './extend.js' ;
import xhr de '@videojs/xhr' ;
// Inclure les techniciens intégrés
import Tech from './tech/tech.js' ;
import { use as middlewareUse, TERMINATOR } from './tech/middleware.js' ;
import defineLazyProperty de './utils/define-lazy-property.js' ;
/**
* Normaliser une valeur `id` en enlevant le `#` de tête
*
* @private
* @param {string} id
* Une chaîne de caractères, éventuellement précédée d'un `#`.
*
* @return {string}
* La chaîne de caractères, sans `#` en tête.
*/
const normalizeId = (id) => id.indexOf('#') === 0 ? id.slice(1) : id ;
/**
* La fonction `videojs()` est également la fonction principale permettant aux utilisateurs de créer une vidéo
* {@link Player} ainsi que l'espace de noms de la bibliothèque principale.
*
* Il peut également être utilisé comme un getter pour une instance {@link Player} préexistante.
* Cependant, nous recommandons fortement d'utiliser `videojs.getPlayer()` pour cela
* car elle permet d'éviter tout risque d'initialisation involontaire.
*
* En raison de [limitations] (https://github.com/jsdoc3/jsdoc/issues/955#issuecomment-313829149)
* de notre modèle JSDoc, nous ne pouvons pas documenter correctement cette fonction comme étant à la fois une fonction
* et un espace de noms, de sorte que la signature de sa fonction est documentée ici.
*
* #### Arguments
* ##### id
* chaîne|élément, **obligatoire**
*
* Élément vidéo ou ID de l'élément vidéo.
*
* ##### options
* Objet, optionnel
*
* Objet d'options permettant de définir des paramètres.
* Voir : [Guide des options] (https://docs.videojs.com/tutorial-options.html).
*
* ##### prêt
* {@link Component~ReadyCallback}, optionnel
*
* Une fonction à appeler lorsque le {@link Player} et le {@link Tech} sont prêts.
*
* #### Valeur de retour
*
* La fonction `videojs()` renvoie une instance {@link Player}.
*
* @namespace
*
* @borrows AudioTrack as AudioTrack
* @borrows Component.getComponent as getComponent
* @borrows module:computed-style~computedStyle as computedStyle
* @borrows module:events.on as on
* @borrows module:events.one as one
* @borrows module:events.off as off
* @borrows module:events.trigger as trigger
* @borrows EventTarget as EventTarget
* @borrows module:extend~extend as extend
* @borrows module:fn.bind as bind
* @borrows module:format-time.formatTime as formatTime
* @borrows module:format-time.resetFormatTime as resetFormatTime
* @borrows module:format-time.setFormatTime as setFormatTime
* @borrows module:merge-options.mergeOptions as mergeOptions
* @borrows module:middleware.use comme use
* @borrows Player.players as players
* @borrows Plugin.registerPlugin as registerPlugin
* @borrows Plugin.deregisterPlugin as deregisterPlugin
* @borrows Plugin.getPlugins as getPlugins
* @borrows Plugin.getPlugin as getPlugin
* @borrows Plugin.getPluginVersion as getPluginVersion
* @borrows Tech.getTech as getTech
* @borrows Tech.registerTech as registerTech
* @borrows TextTrack as TextTrack
* @borrows module:time-ranges.createTimeRanges as createTimeRange
* @borrows module:time-ranges.createTimeRanges as createTimeRanges
* @borrows module:url.isCrossOrigin as isCrossOrigin
* @borrows module:url.parseUrl as parseUrl
* @borrows VideoTrack as VideoTrack
*
* @param {string|Element} id
* Élément vidéo ou ID de l'élément vidéo.
*
* @param {Objet} [options]
* Objet d'options permettant de définir des paramètres.
* Voir : [Guide des options] (https://docs.videojs.com/tutorial-options.html).
*
* @param {Component~ReadyCallback} [ready]
* Une fonction à appeler lorsque les {@link Player} et {@link Tech} sont
* prêt.
*
* @return {Player}
* La fonction `videojs()` renvoie une instance {@link Player|Player}.
*/
function videojs(id, options, ready) {
let player = videojs.getPlayer(id) ;
if (player) {
if (options) {
log.warn(`Le joueur "${id}" est déjà initialisé. Les options ne seront pas appliquées.`) ;
}
if (ready) {
player.ready(ready) ;
}
joueur de retour ;
}
const el = (typeof id === 'string') ? Dom.$('#' + normalizeId(id)) : id ;
if (!Dom.isEl(el)) {
throw new TypeError('L'élément ou l'ID fourni n'est pas valide. (videojs)') ;
}
// document.body.contains(el) ne vérifiera que si el est contenu dans ce seul document.
// Cela pose des problèmes pour les éléments dans les iframes.
// Au lieu de cela, utilisez le document propriétaire de l'élément au lieu du document global.
// Cela permet de s'assurer que l'élément se trouve bien dans le dom de ce document.
// En outre, vérifiez que le document en question dispose d'une vue par défaut.
// Si le document n'est plus attaché au dom, la vue par défaut du document sera nulle.
if (!el.ownerDocument.defaultView || !el.ownerDocument.body.contains(el)) {
log.warn('L'élément fourni n'est pas inclus dans le DOM') ;
}
options = options || {} ;
// Stocker une copie de l'el avant modification, s'il doit être restauré dans destroy()
// En cas d'ingestion de div, stocker le div parent
if (options.restoreEl === true) {
options.restoreEl = (el.parentNode && el.parentNode.hasAttribute('data-vjs-player') ? el.parentNode : el).cloneNode(true) ;
}
hooks('beforesetup').forEach((hookFunction) => {
const opts = hookFunction(el, mergeOptions(options)) ;
if (!isObject(opts) || Array.isArray(opts)) {
log.error('please return an object in beforesetup hooks') ;
retour ;
}
options = mergeOptions(options, opts) ;
}) ;
// Nous obtenons ici le composant "Player" actuel au cas où une intégration aurait eu lieu
// l'a remplacé par un lecteur personnalisé.
const PlayerComponent = Component.getComponent('Player') ;
player = new PlayerComponent(el, options, ready) ;
hooks('setup').forEach((hookFunction) => hookFunction(player)) ;
joueur de retour ;
}
videojs.hooks_ = hooks_ ;
videojs.hooks = hooks ;
videojs.hook = hook ;
videojs.hookOnce = hookOnce ;
videojs.removeHook = removeHook ;
// Ajouter les styles par défaut
if (window.VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) {
let style = Dom.$('.vjs-styles-defaults') ;
if (!style) {
style = stylesheet.createStyleElement('vjs-styles-defaults') ;
const head = Dom.$('head') ;
if (head) {
head.insertBefore(style, head.firstChild) ;
}
feuille de style.setTextContent(style, `
.video-js {
width: 300px ;
height: 150px ;
}
.vjs-fluid:not(.vjs-audio-only-mode) {
padding-top : 56,25%
}
`) ;
}
}
// Lancer le chargement automatique des joueurs
// Vous devez attendre au moins une fois au cas où ce script serait chargé après votre
// vidéo dans le DOM (comportement bizarre uniquement avec la version minifiée)
setup.autoSetupTimeout(1, videojs) ;
/**
* Version actuelle de Video.js. Suit [version sémantique] (https://semver.org/).
*
* @type {string}
*/
videojs.VERSION = version ;
/**
* L'objet des options globales. Voici les paramètres qui s'appliquent
* si aucune dérogation n'est spécifiée lors de la création du lecteur.
*
* @type {Objet}
*/
videojs.options = Player.prototype.options_ ;
/**
* Obtention d'un objet contenant les joueurs actuellement créés, avec pour clé l'identifiant du joueur
*
* @return {Object}
* Les acteurs créés
*/
videojs.getPlayers = () => Player.players ;
/**
* Obtenir un lecteur unique sur la base d'un ID ou d'un élément DOM.
*
* Cette fonction est utile si vous souhaitez vérifier si un élément ou un ID est associé à un
* Video.js, mais n'en crée pas si ce n'est pas le cas.
*
* @param {string|Element} id
* Un élément HTML - `<video>`, `<audio>`, ou `<video-js>` -
* ou une chaîne de caractères correspondant à l'`id` d'un tel élément.
*
* @return {Player|undefined}
* Une instance de joueur ou `undefined` s'il n'y a pas d'instance de joueur
* correspondant à l'argument.
*/
videojs.getPlayer = (id) => {
const players = Player.players ;
let tag ;
if (typeof id === 'string') {
const nId = normalizeId(id) ;
const player = players[nId] ;
if (player) {
joueur de retour ;
}
tag = Dom.$('#' + nId) ;
} else {
tag = id ;
}
if (Dom.isEl(tag)) {
const {player, playerId} = tag ;
// L'élément peut avoir une propriété `player` faisant référence à un élément déjà créé
// instance de joueur. Si c'est le cas, renvoyez-le.
if (player || players[playerId]) {
return player || players[playerId] ;
}
}
};
/**
* Renvoie un tableau de tous les joueurs actuels.
*
* @return {Array}
* Un tableau de tous les joueurs. Le tableau sera présenté dans l'ordre suivant
* `Object.keys`, qui peut potentiellement varier entre
* Moteurs JavaScript.
*
*/
videojs.getAllPlayers = () =>
// Les joueurs éliminés laissent une clé avec une valeur `null`, nous devons donc nous assurer que
// nous les filtrons.
Object.keys(Player.players).map(k => Player.players[k]).filter(Boolean) ;
videojs.players = Player.players ;
videojs.getComponent = Component.getComponent ;
/**
* Enregistrer un composant pour qu'il puisse être référencé par son nom. Utilisé lors de l'ajout à d'autres
* soit par addChild `component.addChild('myComponent')` soit par addChild
* options par défaut pour les enfants `{ children : ['myComponent'] }`.
*
* > NOTE : Vous pouvez également initialiser le composant avant de l'ajouter.
* `component.addChild(new MyComponent());`
*
* @param {string} name
* Le nom de la classe du composant
*
* @param {Composant} comp
* La classe de composants
*
* @return {Component}
* Le composant nouvellement enregistré
*/
videojs.registerComponent = (name, comp) => {
if (Tech.isTech(comp)) {
log.warn(`La technologie ${nom} a été enregistrée en tant que composant. Il doit être enregistré à l'aide de videojs.registerTech(name, tech)`) ;
}
Component.registerComponent.call(Component, name, comp) ;
};
videojs.getTech = Tech.getTech ;
videojs.registerTech = Tech.registerTech ;
videojs.use = middlewareUse ;
/**
* Un objet qui peut être renvoyé par un intergiciel pour signifier
* que l'intergiciel est en train de se terminer.
*
* @type {objet}
* @property {objet} middleware.TERMINATOR
*/
Object.defineProperty(videojs, 'middleware', {
valeur : {},
accessible à l'écriture : false,
énumérable : true
}) ;
Object.defineProperty(videojs.middleware, 'TERMINATOR', {
valeur : TERMINATOR,
accessible à l'écriture : false,
énumérable : true
}) ;
/**
* Une référence au {@link module:browser|module utilitaire du navigateur} en tant qu'objet.
*
* @type {Objet}
* @see {@link module:browser|browser}
*/
videojs.browser = browser ;
/**
* Utilisez plutôt {@link module:browser.TOUCH_ENABLED|browser.TOUCH_ENABLED} ; seulement
* inclus pour la compatibilité ascendante avec la version 4.x.
*
* @deprecated Depuis la version 5.0, utilisez {@link module:browser.TOUCH_ENABLED|browser.TOUCH_ENABLED à la place.
* @type {boolean}
*/
videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED ;
videojs.extend = extend ;
videojs.mergeOptions = mergeOptions ;
videojs.bind = Fn.bind ;
videojs.registerPlugin = Plugin.registerPlugin ;
videojs.deregisterPlugin = Plugin.deregisterPlugin ;
/**
* Méthode obsolète pour enregistrer un plugin avec Video.js
*
* @deprecated videojs.plugin() est obsolète ; utilisez videojs.registerPlugin() à la place
*
* @param {string} name
* Le nom du plugin
*
* @param {Plugin|Function} plugin
* La sous-classe ou la fonction du plugin
*/
videojs.plugin = (name, plugin) => {
log.warn('videojs.plugin() is deprecated ; use videojs.registerPlugin() instead') ;
return Plugin.registerPlugin(name, plugin) ;
};
videojs.getPlugins = Plugin.getPlugins ;
videojs.getPlugin = Plugin.getPlugin ;
videojs.getPluginVersion = Plugin.getPluginVersion ;
/**
* Ajout de langues pour qu'elles soient disponibles pour tous les joueurs.
* Exemple : `videojs.addLanguage('es', { 'Hello' : 'Hola' });`
*
* @param {string} code
* Le code de la langue ou la propriété du dictionnaire
*
* @param {Object} data
* Les valeurs de données à traduire
*
* @return {Object}
* L'objet dictionnaire de langue résultant
*/
videojs.addLanguage = function(code, data) {
code = ('' + code).toLowerCase() ;
videojs.options.languages = mergeOptions(
videojs.options.languages,
{[code] : données}
) ;
return videojs.options.languages[code] ;
};
/**
* Une référence au {@link module:log|module utilitaire log} en tant qu'objet.
*
* @type {Fonction}
* @see {@link module:log|log}
*/
videojs.log = log ;
videojs.createLogger = createLogger ;
videojs.createTimeRange = videojs.createTimeRanges = createTimeRanges ;
videojs.formatTime = formatTime ;
videojs.setFormatTime = setFormatTime ;
videojs.resetFormatTime = resetFormatTime ;
videojs.parseUrl = Url.parseUrl ;
videojs.isCrossOrigin = Url.isCrossOrigin ;
videojs.EventTarget = EventTarget ;
videojs.on = Events.on ;
videojs.one = Events.one ;
videojs.off = Events.off ;
videojs.trigger = Events.trigger ;
/**
* Un wrapper XMLHttpRequest pour tous les navigateurs.
*
* @fonction
* @param {Objet} options
* Paramètres de la demande.
*
* @return {XMLHttpRequest|XDomainRequest}
* L'objet de la demande.
*
* voir https://github.com/Raynos/xhr
*/
videojs.xhr = xhr ;
videojs.TextTrack = TextTrack ;
videojs.AudioTrack = AudioTrack ;
videojs.VideoTrack = VideoTrack ;
[
'isEl',
'isTextNode',
'createEl',
'hasClass',
'addClass',
'removeClass',
'toggleClass',
'setAttributes',
'getAttributes',
emptyEl",
'appendContent',
insérerContenu
].forEach(k => {
videojs[k] = function() {
log.warn(`videojs.${k}() is deprecated ; use videojs.dom.${k}() instead`) ;
return Dom[k].apply(null, arguments) ;
};
}) ;
videojs.computedStyle = computedStyle ;
/**
* Une référence au {@link module:dom|DOM utility module} en tant qu'objet.
*
* @type {Objet}
* @see {@link module:dom|dom}
*/
videojs.dom = Dom ;
/**
* Une référence au module utilitaire {@link module:url|URL} en tant qu'objet.
*
* @type {Objet}
* @see {@link module:url|url}
*/
videojs.url = Url ;
videojs.defineLazyProperty = defineLazyProperty ;
// Ajout d'un texte moins ambigu pour le bouton fullscreen.
// Dans une mise à jour majeure, cela pourrait devenir le texte et la clé par défaut.
videojs.addLanguage('en', {'Non-Fullscreen' : 'Exit Fullscreen'}) ;
export default videojs ;