/**
* @file video.js
* @module videojs
*/
從'../../package.json'導入{version};
從“全局/窗口”導入窗口;
進口 {
鉤子_,
掛鉤,
鉤,
鉤一次,
移除鉤子
} 來自 './utils/hooks';
從“./setup”導入 * 作為設置;
import * as stylesheet from './utils/stylesheet.js';
從 './component' 導入組件;
從 './event-target' 導入 EventTarget;
import * as Events from './utils/events.js';
從'./player'導入播放器;
從'./plugin'導入插件;
從 './utils/merge-options.js' 導入 mergeOptions;
從 './utils/fn.js' 導入 * 作為 Fn;
從 './tracks/text-track.js' 導入 TextTrack;
從 './tracks/audio-track.js' 導入 AudioTrack;
從 './tracks/video-track.js' 導入 VideoTrack;
從'./utils/time-ranges.js'導入{createTimeRanges};
import formatTime, { setFormatTime, resetFormatTime } from './utils/format-time.js';
從'./utils/log.js'導入日誌,{createLogger};
import * as Dom from './utils/dom.js';
import * as browser from './utils/browser.js';
import * as Url from './utils/url.js';
從 './utils/obj' 導入 {isObject};
從 './utils/computed-style.js' 導入 computedStyle;
從 './extend.js' 導入擴展;
從“@videojs/xhr”導入 xhr;
// 包括內置技術
從 './tech/tech.js' 導入技術;
import { use as middlewareUse, TERMINATOR } from './tech/middleware.js';
從 './utils/define-lazy-property.js' 導入 defineLazyProperty;
/**
* 通過去除前導的 `#` 來規範化 `id` 值
*
* @私人的
* @param {string} id
* 一個字符串,可能以“#”開頭。
*
* @return {字符串}
* 字符串,沒有任何前導的“#”。
*/
常量正常標識 =(ID)=> ID 指數('#')=== 0?ID 切片(1):標識;
/**
* `videojs()` 函數兼作主函數,供用戶創建一個
* {@link Player} 實例以及主庫命名空間。
*
* 它也可以用作預先存在的 {@link Player} 實例的吸氣劑。
* 但是,我們_強烈_建議為此使用 `videojs.getPlayer()`
* 目的,因為它避免了任何可能的意外初始化。
*
* 由於 [限制](https://github.com/jsdoc3/jsdoc/issues/955#issuecomment-313829149)
* 我們的 JSDoc 模板,我們不能正確地將其記錄為一個函數
* 和命名空間,因此其函數簽名記錄在此處。
*
* #### 參數
* ##### ID
* 字符串|元素,**必填**
*
* 視頻元素或視頻元素 ID。
*
* ##### 選項
* 對象,可選
*
* 用於提供設置的選項對象。
* 請參閱:[選項指南](https://docs.videojs.com/tutorial-options.html)。
*
* ##### 準備好
* {@link Component~ReadyCallback},可選
*
* {@link Player} 和 {@link Tech} 準備就緒時調用的函數。
*
* #### 返回值
*
* `videojs()` 函數返回一個 {@link Player} 實例。
*
* @命名空間
*
* @borrows AudioTrack 作為 AudioTrack
* @borrows Component.getComponent 作為 getComponent
* @borrows 模組:計算樣式 ~ 計算風格作為計算樣式
* @borrows 模組:事件. 在上
* @borrows 模塊:事件。一為一
* @borrows 模塊:事件。關閉為關閉
* @borrows 模組:事件. 觸發作為觸發器
* @borrows EventTarget 作為 EventTarget
* @borrows 模塊:擴展~擴展為擴展
* @borrows 模塊:綁定作為綁定
* @borrows 模塊:format-time.formatTime as formatTime
* @borrows 模塊:格式時間。重置格式時間為重置格式時間
* @borrows 模塊:格式時間. 設置格式時間為設置格式時間
* @borrows 模塊:合併選項。合併選項作為合併選項
* @borrows 模組:中介軟體. 使用做為使用
* @borrows Player.players 作為玩家
* @borrows Plugin.registerPlugin 作為 registerPlugin
* @borrows Plugin.deregisterPlugin 作為 deregisterPlugin
* @borrows Plugin.getPlugins 作為 getPlugins
* @borrows Plugin.getPlugin 作為 getPlugin
* @borrows Plugin.getPluginVersion 作為 getPluginVersion
* @borrows Tech.getTech 作為 getTech
* @borrows Tech.registerTech 作為 registerTech
* @borrows TextTrack 作為 TextTrack
* @borrows 模組:時間範圍。將創建時間範圍創建為創建時間範圍
* @borrows 模組:時間範圍。將創建時間角創建為創建時間範圍
* @borrows 模塊:URL。交叉起源作為跨起源
* @borrows 模塊:url.parseUrl 作為 parseUrl
* @borrows VideoTrack 作為 VideoTrack
*
* @param {string|Element} id
* 視頻元素或視頻元素 ID。
*
* @param {對象} [選項]
* 用於提供設置的選項對象。
* 請參閱:[選項指南](https://docs.videojs.com/tutorial-options.html)。
*
* @param {Component~ReadyCallback} [就緒]
* {@link Player} 和 {@link Tech} 時調用的函數
* 準備好。
*
* @return {玩家}
* `videojs()` 函數返回一個 {@link Player|Player} 實例。
*/
函數 videojs(id,選項,就緒){
讓播放器 = videojs.getPlayer(id);
如果(玩家){
如果(選項){
log.warn(`Player "${id}" 已經初始化。選項將不會被應用。`);
}
如果(準備就緒){
player.ready(準備就緒);
}
回歸球員;
}
常量埃爾 =(ID === '字符串' 的類型)?點。$('#' + 正常標識(ID)):ID;
如果(!多米. 伊塞爾 (埃爾)) {
throw new TypeError('提供的元素或 ID 無效。(videojs)');
}
// document.body.contains(el) 只會檢查 el 是否包含在該文檔中。
// 這會導致 iframe 中的元素出現問題。
// 相反,使用元素的 ownerDocument 而不是全局文檔。
// 這將確保該元素確實在該文檔的 dom 中。
// 此外,檢查相關文檔是否具有默認視圖。
// 如果文檔不再附加到 dom,則文檔的 defaultView 將為 null。
如果(!所有者文檔. 默認視圖 ||!所有者文件. 身體. 包含 (el)) {
log.warn('提供的元素不包含在 DOM 中');
}
選項=選項|| {};
// 保存一份修改前的el,如果要在destroy()中恢復
// 如果 div 攝取,存儲父 div
如果(選項。restoreEl === 真){
選項還原 =(例如。父節點 && 等。父母節點 .has屬性('數據-vjs-播放器')?父節點:EL)。克隆節點(真);
}
鉤子('beforesetup').forEach((hookFunction)=> {
const opts = hookFunction(el, mergeOptions(options));
如果(!isObject(opts)|| Array.isArray(opts)){
log.error('請在 beforesetup 鉤子中返回一個對象');
返回;
}
options = mergeOptions(options, opts);
});
// 我們在這裡獲取當前的“播放器”組件,以防集成有
// 將其替換為自定義播放器。
const PlayerComponent = Component.getComponent('Player');
player = new PlayerComponent(el, options, ready);
hooks('setup').forEach((hookFunction) => hookFunction(player));
回歸球員;
}
videojs.hooks_ = hooks_;
videojs.hooks = 掛鉤;
videojs.hook = 掛鉤;
videojs.hookOnce = hookOnce;
videojs.removeHook = removeHook;
// 添加默認樣式
如果(窗口。視頻 _ 動態風格!== 真 && DOM. 真實 ()) {
let style = Dom.$('.vjs-styles-defaults');
如果(!樣式){
style = stylesheet.createStyleElement('vjs-styles-defaults');
const head = Dom.$('head');
如果(頭){
head.insertBefore(style, head.firstChild);
}
stylesheet.setTextContent(樣式,`
.video-js {
寬度:300像素;
高度:150像素;
}
. VJS-流體:不 (. VJS-音頻僅模式) {
填充頂部:56.25%
}
`);
}
}
// 運行自動加載播放器
// 你必須至少等待一次,以防這個腳本在你之後加載
// DOM 中的視頻(奇怪的行為只有縮小版)
setup.autoSetupTimeout(1, videojs);
/**
* 當前 Video.js 版本。遵循 [語義版本控制](https://semver.org/)。
*
* @type {字符串}
*/
videojs.VERSION = 版本;
/**
* 全局選項對象。這些是生效的設置
* 如果在創建播放器時沒有指定覆蓋。
*
* @type {對象}
*/
videojs.options = Player.prototype.options_;
/**
* 獲取包含當前創建的玩家的對象,以玩家 ID 為鍵
*
* @return {對象}
* 創建的玩家
*/
videojs.getPlayers = () => Player.players;
/**
* 根據 ID 或 DOM 元素獲取單個玩家。
*
* 如果你想檢查一個元素或 ID 是否有關聯,這很有用
* Video.js 播放器,但如果沒有則不創建。
*
* @param {string|Element} id
* 一個 HTML 元素 - `<video>`、`<audio>` 或 `<video-js>` -
* 或與此類元素的“id”匹配的字符串。
*
* @return {玩家|未定義}
* 一個玩家實例,如果沒有玩家實例,則為 `undefined`
* 匹配參數。
*/
videojs.getPlayer = (id) => {
const players = Player.players;
讓標籤;
如果 (typeof id === 'string') {
const nId = normalizeId(id);
const player = 玩家[nId];
如果(玩家){
回歸球員;
}
tag = Dom.$('#' + nId);
}其他{
標籤=編號;
}
如果(Dom.isEl(標籤)){
const {player, playerId} = 標籤;
// 元素可能有一個 `player` 屬性引用一個已經創建的
// 播放器實例。如果是這樣,請返回。
如果(玩家 || 玩家[playerId]){
回歸球員||玩家[玩家ID];
}
}
};
/**
* 返回所有當前玩家的數組。
*
* @return {數組}
* 所有玩家的數組。該數組將按照以下順序排列
* `Object.keys` 提供,這可能會有所不同
* JavaScript 引擎。
*
*/
videojs.getAllPlayers = () =>
// 被處置的玩家留下一個帶有 `null` 值的鍵,所以我們需要確保
// 我們過濾掉那些。
Object.keys(Player.players).map(k => Player.players[k]).filter(布爾值);
videojs.players = Player.players;
videojs.getComponent = Component.getComponent;
/**
* 註冊一個組件,以便可以通過名稱引用它。添加到其他時使用
* 組件,通過 addChild `component.addChild('myComponent')` 或通過
* 默認子項選項`{ children: ['myComponent'] }`。
*
* > 注意:您也可以在添加之前只初始化組件。
* `組件。添加子(新的我的組件());`
*
* @param {string} 名稱
* 組件的類名
*
* @param {組件} 組件
* 組件類
*
* @return {組件}
* 新註冊的組件
*/
videojs.registerComponent = (name, comp) => {
如果(Tech.isTech(comp)){
log.warn(`${name} 技術已註冊為組件。它應該使用 videojs.registerTech(name, tech)`);
}
Component.registerComponent.call(Component, name, comp);
};
videojs.getTech = Tech.getTech;
videojs.registerTech = Tech.registerTech;
videojs.use = middlewareUse;
/**
* 一個可以由中間件返回的對象來表示
* 中間件正在終止。
*
* @type {對象}
* @property {object} 中間件.TERMINATOR
*/
Object.defineProperty(videojs, '中間件', {
價值: {},
可寫:假,
可枚舉:真
});
Object.defineProperty(videojs.middleware, '終結者', {
價值:終結者,
可寫:假,
可枚舉:真
});
/**
* 將 {@link 模組:瀏覽器 | 瀏覽器公用程式模組} 做為物件的參考。
*
* @type {對象}
* @see {@link 模塊:瀏覽器|瀏覽器}
*/
videojs.browser = 瀏覽器;
/**
* 使用 {@link 模塊:瀏覽器。觸摸啟用 | 瀏覽器。觸摸啟用}; 僅
* 包括在內以向後兼容 4.x。
*
* @deprecated 自 5.0 版以來,請改用 {@link 模組:瀏覽器。觸控啟用 | 瀏覽器。
* @type {布爾}
*/
videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
videojs.extend = 擴展;
videojs.mergeOptions = mergeOptions;
videojs.bind = Fn.bind;
videojs.registerPlugin = Plugin.registerPlugin;
videojs.deregisterPlugin = Plugin.deregisterPlugin;
/**
* 不贊成使用 Video.js 註冊插件的方法
*
* @deprecated videojs.plugin() 已棄用;使用 videojs.registerPlugin() 代替
*
* @param {string} 名稱
* 插件名稱
*
* @param {Plugin|Function} 插件
* 插件子類或函數
*/
videojs.plugin =(名稱,插件)=> {
log.warn('videojs.plugin() 已棄用;請改用 videojs.registerPlugin()');
返回 Plugin.registerPlugin(名稱,插件);
};
videojs.getPlugins = Plugin.getPlugins;
videojs.getPlugin = Plugin.getPlugin;
videojs.getPluginVersion = Plugin.getPluginVersion;
/**
* 添加語言以便所有玩家都可以使用。
* 示例:`videojs.addLanguage('es', { '你好':'霍拉'}); `
*
* @param {string} 代碼
* 語言代碼或字典屬性
*
* @param {Object} 數據
* 要翻譯的數據值
*
* @return {對象}
* 生成的語言字典對象
*/
videojs.addLanguage = 函數(代碼,數據){
code = ('' + code).toLowerCase();
videojs.options.languages = mergeOptions(
videojs.options.languages,
{[代碼]:數據}
);
返回 videojs.options.languages[code];
};
/**
* 將 {@link 模組:log| 記錄公用程式模組} 做為物件的參考。
*
* @type {函數}
* @see {@link 模塊:日誌|日誌}
*/
videojs.log = 日誌;
videojs.createLogger = createLogger;
videojs.createTimeRange = videojs.createTimeRanges = createTimeRanges;
videojs.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;
/**
* 跨瀏覽器的 XMLHttpRequest 包裝器。
*
* @功能
* @param {Object} 選項
* 請求的設置。
*
* @return {XMLHttpRequest|XDomainRequest}
* 請求對象。
*
* @see https://github.com/Raynos/xhr
*/
videojs.xhr = xhr;
videojs.TextTrack = TextTrack;
videojs.AudioTrack = AudioTrack;
videojs.VideoTrack = VideoTrack;
[
'是El',
'isTextNode',
'創建El',
'有等級',
'添加類',
'刪除類',
'切換類',
'設置屬性',
'獲取屬性',
'空El',
'追加內容',
'插入內容'
].forEach(k => {
videojs[k] = function() {
log.warn(`videojs.${k}() 已棄用;請改用 videojs.dom.${k}()`);
返回 Dom[k].apply(null, arguments);
};
});
videojs.computedStyle = computedStyle;
/**
* 將 {@link 模組:DOM|DOM 公用程式模組} 做為物件的參考。
*
* @type {對象}
* @see {@link 模塊:dom|dom}
*/
videojs.dom = Dom;
/**
* 將 {@link 模組:URL|URL 公用程式模組} 做為物件的參考。
*
* @type {對象}
* @see {@link 模塊:url|url}
*/
videojs.url = 網址;
videojs.defineLazyProperty = defineLazyProperty;
// 為全屏按鈕添加更明確的文本。
// 在主要更新中,這可能成為默認文本和鍵。
videojs.addLanguage('en', {'非全屏':'退出全屏'});
導出默認videojs;