diff --git a/docs/assets/js/common.js b/docs/assets/js/common.js index cd1efd93c..b6f0bf963 100644 --- a/docs/assets/js/common.js +++ b/docs/assets/js/common.js @@ -1,13 +1,8 @@ (function () { Artplayer.DEBUG = true; - var userAgent = window.navigator.userAgent; - var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent); - var isIE = /MSIE|Trident/.test(userAgent); - - if (isMobile || isIE) { + if (Artplayer.utils.isMobile) { window.location.href = './mobile.html' + location.search; - return; } var $codeMirror = document.querySelector('.codeMirrorWrap'); @@ -15,57 +10,65 @@ var $run = document.querySelector('.run'); var $popups = document.querySelector('.popups'); var $console = document.querySelector('.console'); - var loaddLib = []; - - window.consoleLog($console); - var $typeScript = document.querySelector('#typeScript'); + + var loadedLibs = []; + window['consoleLog']($console); $typeScript.checked = localStorage.getItem('typeScript') === 'true'; var editor = null; require.config({ paths: { vs: './assets/js/vs' } }); - require(['vs/editor/editor.main'], function () { - var libUri = './assets/ts/artplayer.d.ts'; - fetch(libUri) - .then((res) => res.text()) - .then((libSource) => { - monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({ - noSemanticValidation: true, - noSyntaxValidation: false, - }); + require(['vs/editor/editor.main'], async function () { + monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({ + noSemanticValidation: true, + noSyntaxValidation: false, + }); - monaco.languages.typescript.javascriptDefaults.setCompilerOptions({ - target: monaco.languages.typescript.ScriptTarget.ES6, - allowNonTsExtensions: true, - }); + monaco.languages.typescript.javascriptDefaults.setCompilerOptions({ + target: monaco.languages.typescript.ScriptTarget.ES6, + allowNonTsExtensions: true, + }); - monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource, libUri); - monaco.editor.createModel(libSource, 'typescript', monaco.Uri.parse(libUri)); + var libUris = [ + './assets/ts/artplayer.d.ts', + './assets/ts/artplayer-plugin-ads.d.ts', + './assets/ts/artplayer-plugin-control.d.ts', + './assets/ts/artplayer-plugin-danmuku.d.ts', + './assets/ts/artplayer-plugin-dash-quality.d.ts', + './assets/ts/artplayer-plugin-hls-quality.d.ts', + './assets/ts/artplayer-plugin-iframe.d.ts', + ]; + + for (let index = 0; index < libUris.length; index++) { + var libUri = libUris[index]; + var libSource = await (await fetch(libUri)).text(); + monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource, libUri); + monaco.editor.createModel(libSource, 'typescript', monaco.Uri.parse(libUri)); + } - var disposable = monaco.editor.onDidCreateEditor(function () { - disposable.dispose(); - setTimeout(initApp, 1000); - }); + var disposable = monaco.editor.onDidCreateEditor(function () { + disposable.dispose(); + setTimeout(initApp, 1000); + }); - editor = monaco.editor.create($codeMirror, { - theme: 'vs-dark', - automaticLayout: true, - quickSuggestions: { - other: true, - comments: true, - strings: true, - }, - model: monaco.editor.createModel( - [ - 'var art = new Artplayer({', - "\tcontainer: '.artplayer-app',", - "\turl: '/assets/sample/video.mp4',", - '});', - ].join('\n'), - $typeScript.checked ? 'typescript' : 'javascript', - ), - }); - }); + editor = monaco.editor.create($codeMirror, { + theme: 'vs-dark', + automaticLayout: true, + quickSuggestions: { + other: true, + comments: true, + strings: true, + }, + model: monaco.editor.createModel( + [ + 'var art = new Artplayer({', + "\tcontainer: '.artplayer-app',", + "\turl: '/assets/sample/video.mp4',", + '});', + ].join('\n'), + $typeScript.checked ? 'typescript' : 'javascript', + ), + }); }); function getURLParameters(url) { @@ -125,7 +128,7 @@ libsDecode .split(/\r?\n/) .filter(function (url) { - return !loaddLib.includes(url); + return !loadedLibs.includes(url); }) .forEach(function (url) { var ext = getExt(url); @@ -180,7 +183,7 @@ loadLib(libs) .then(function (result) { - loaddLib = loaddLib.concat(result); + loadedLibs = loadedLibs.concat(result); loadCode(code, example); }) .catch(function (err) { diff --git a/docs/assets/ts/artplayer-plugin-ads.d.ts b/docs/assets/ts/artplayer-plugin-ads.d.ts new file mode 100644 index 000000000..70b0c4752 --- /dev/null +++ b/docs/assets/ts/artplayer-plugin-ads.d.ts @@ -0,0 +1,52 @@ +import type Artplayer from 'artplayer'; + +export = artplayerPluginAds; +export as namespace artplayerPluginAds; + +type Option = { + /** + * 广告源文本,支持视频链接、图片链接、HTML文本 + */ + source: string; + + /** + * 知名广告的类型:'video' | 'image' | 'html' + */ + type: 'video' | 'image' | 'html'; + + /** + * 广告必看的时长,单位为秒 + */ + playDuration?: number; + + /** + * 广告总的时长,单位为秒 + */ + totalDuration?: number; + + /** + * 视频广告是否默认静音 + */ + muted?: boolean; +}; + +type Ads = { + name: 'artplayerPluginAds'; + + /** + * 跳过广告 + */ + skip: () => void; + + /** + * 暂停广告 + */ + pause: () => void; + + /** + * 播放广告 + */ + play: () => void; +}; + +declare const artplayerPluginAds: (option: Option) => (art: Artplayer) => Ads; diff --git a/docs/assets/ts/artplayer-plugin-control.d.ts b/docs/assets/ts/artplayer-plugin-control.d.ts new file mode 100644 index 000000000..46176c215 --- /dev/null +++ b/docs/assets/ts/artplayer-plugin-control.d.ts @@ -0,0 +1,13 @@ +import type Artplayer from 'artplayer'; + +export = artplayerPluginControl; +export as namespace artplayerPluginControl; + +type Option = {}; + +type Control = { + name: 'artplayerPluginControl'; + enable: Boolean; +}; + +declare const artplayerPluginControl: (option?: Option) => (art: Artplayer) => Control; diff --git a/docs/assets/ts/artplayer-plugin-danmuku.d.ts b/docs/assets/ts/artplayer-plugin-danmuku.d.ts new file mode 100644 index 000000000..dd3451021 --- /dev/null +++ b/docs/assets/ts/artplayer-plugin-danmuku.d.ts @@ -0,0 +1,182 @@ +import type Artplayer from 'artplayer'; + +export = artplayerPluginDanmuku; +export as namespace artplayerPluginDanmuku; + +type Danmu = { + /** + * 弹幕文本 + */ + text: string; + + /** + * 弹幕发送模式,0为滚动,1为静止 + */ + mode?: 0 | 1; + + /** + * 弹幕颜色 + */ + color?: string; + + /** + * 弹幕出现的时间,单位为秒 + */ + time?: number; + + /** + * 弹幕是否有描边 + */ + border?: boolean; +}; + +type Option = { + /** + * 弹幕源,可以是弹幕数组,xml 地址或者一个返回 Promise 的函数 + */ + danmuku: Danmu[] | string | (() => Promise) | Promise; + + /** + * 弹幕持续时间,单位秒,范围在[1 ~ 10] + */ + speed?: number; + + /** + * 弹幕上下边距,支持数字和高度的百分比 + */ + margin?: [number | `${number}%`, number | `${number}%`]; + + /** + * 弹幕透明度,范围在[0 ~ 1] + */ + opacity?: number; + + /** + * 默认字体颜色 + */ + color?: string; + + /** + * 默认弹幕发送模式,0为滚动,1为静止 + */ + mode?: 0 | 1; + + /** + * 字体大小,支持数字和高度的百分比 + */ + fontSize?: number | `${number}%`; + + /** + * 弹幕过滤函数,返回 true 则可以发送 + */ + filter?: (danmu: Danmu) => boolean; + + /** + * 是否防重叠 + */ + antiOverlap?: boolean; + + /** + * 是否使用 web worker + */ + useWorker?: boolean; + + /** + * 是否同步到播放速度 + */ + synchronousPlayback?: boolean; + + /** + * 输入框锁定时间,单位秒,范围在[1 ~ 60] + */ + lockTime?: number; + + /** + * 输入框最大可输入的字数,范围在[0 ~ 500] + */ + maxLength?: number; + + /** + * 输入框最小宽度,范围在[0 ~ 500],填 0 则为无限制 + */ + minWidth?: number; + + /** + * 输入框最大宽度,范围在[0 ~ Infinity],填 0 则为 100% 宽度 + */ + maxWidth?: number; + + /** + * 通过 mount 选项可以自定义输入框挂载的位置,默认挂载于播放器底部,仅在当宽度小于最小值时生效 + */ + mount?: Element; + + /** + * 输入框自定义挂载时的主题色,默认为 dark,可以选填亮色 light + */ + theme?: 'dark' | 'light'; + + /** + * 是否开启弹幕热度图 + */ + heatmap?: + | boolean + | { + xMin?: number; + xMax?: number; + yMin?: number; + yMax?: number; + scale?: number; + opacity?: number; + minHeight?: number; + sampling?: number; + smoothing?: number; + flattening?: number; + }; + + /** + * 发送弹幕前的自定义校验,返回 true 则可以发送 + */ + beforeEmit?: (danmu: Danmu) => boolean; +}; + +type Danmuku = { + name: 'artplayerPluginDanmuku'; + + /** + * 发送一条实时弹幕 + */ + emit: (danmu: Danmu) => Danmuku; + + /** + * 重载弹幕源,或者切换新弹幕 + */ + load: () => Promise; + + /** + * 实时改变弹幕配置 + */ + config: (option: Option) => Danmuku; + + /** + * 隐藏弹幕层 + */ + hide: () => Danmuku; + + /** + * 显示弹幕层 + */ + show: () => Danmuku; + + /** + * 是否隐藏弹幕层 + */ + isHide: boolean; + + /** + * 是否弹幕层停止状态 + */ + isStop: boolean; +}; + +declare const artplayerPluginDanmuku: (option: Option) => (art: Artplayer) => Danmuku; diff --git a/docs/assets/ts/artplayer-plugin-dash-quality.d.ts b/docs/assets/ts/artplayer-plugin-dash-quality.d.ts new file mode 100644 index 000000000..6a897b74b --- /dev/null +++ b/docs/assets/ts/artplayer-plugin-dash-quality.d.ts @@ -0,0 +1,14 @@ +import type Artplayer from 'artplayer'; + +export = artplayerPluginDashQuality; +export as namespace artplayerPluginDashQuality; + +declare const artplayerPluginDashQuality: (option: { + control?: boolean; + setting?: boolean; + title?: string; + auto?: string; + getResolution?(level: any): String; +}) => (art: Artplayer) => { + name: 'artplayerPluginDashQuality'; +}; diff --git a/docs/assets/ts/artplayer-plugin-hls-quality.d.ts b/docs/assets/ts/artplayer-plugin-hls-quality.d.ts new file mode 100644 index 000000000..9b7c66f9b --- /dev/null +++ b/docs/assets/ts/artplayer-plugin-hls-quality.d.ts @@ -0,0 +1,14 @@ +import type Artplayer from 'artplayer'; + +export = artplayerPluginHlsQuality; +export as namespace artplayerPluginHlsQuality; + +declare const artplayerPluginHlsQuality: (option: { + control?: boolean; + setting?: boolean; + title?: string; + auto?: string; + getResolution?(level: any): String; +}) => (art: Artplayer) => { + name: 'artplayerPluginHlsQuality'; +}; diff --git a/docs/assets/ts/artplayer-plugin-iframe.d.ts b/docs/assets/ts/artplayer-plugin-iframe.d.ts new file mode 100644 index 000000000..a7c7ce9f6 --- /dev/null +++ b/docs/assets/ts/artplayer-plugin-iframe.d.ts @@ -0,0 +1,30 @@ +export = ArtplayerPluginIframe; +export as namespace ArtplayerPluginIframe; + +type Message = { + type: string; + data: any; + id?: number; +}; + +declare class ArtplayerPluginIframe { + constructor(option: { iframe: HTMLIFrameElement; url: string }); + + static iframe: boolean; + static postMessage(message: Message): void; + static onMessage(event: MessageEvent & { data: Message }): void; + static inject(): void; + + readonly promises: Record; + readonly injected: boolean; + readonly destroyed: boolean; + readonly $iframe: HTMLIFrameElement; + readonly url: string; + readonly messageCallback: (...args: any[]) => any; + + onMessage(event: MessageEvent & { data: Message }): void; + postMessage(message: Message): Promise; + commit any>(callback: T): Promise>; + message(callback: (...args: any[]) => any): void; + destroy(): void; +} diff --git a/docs/uncompiled/artplayer/index.js b/docs/uncompiled/artplayer/index.js index 1f7729fcf..7b422a225 100644 --- a/docs/uncompiled/artplayer/index.js +++ b/docs/uncompiled/artplayer/index.js @@ -242,7 +242,7 @@ class Artplayer extends (0, _emitterDefault.default) { return "development"; } static get build() { - return "2023-05-03 09:55:39"; + return "2023-05-03 10:21:04"; } static get config() { return 0, _configDefault.default; diff --git a/scripts/build-ts.js b/scripts/build-ts.js index 3d531a759..7595520b1 100644 --- a/scripts/build-ts.js +++ b/scripts/build-ts.js @@ -1,16 +1,26 @@ import fs from 'fs'; +import cpy from 'cpy'; import path from 'path'; import { glob } from 'glob'; const reg = /^import.*;$/gim; -const types = glob.sync('packages/artplayer/types/*'); -const output = path.join('docs/assets/ts/artplayer.d.ts'); +const artplayerTS = glob.sync('packages/artplayer/types/*.d.ts'); +const artplayerTSoutput = path.join('docs/assets/ts/artplayer.d.ts'); let code = ''; -for (let index = 0; index < types.length; index++) { - const type = types[index]; +for (let index = 0; index < artplayerTS.length; index++) { + const type = artplayerTS[index]; code += String(fs.readFileSync(type)).replace(reg, '') + '\n'; } -fs.writeFileSync(output, code.trim()); -console.log(`✨ Built artplayer.d.ts`); +fs.writeFileSync(artplayerTSoutput, code.trim()); +console.log(`✨ Built ${artplayerTSoutput}`); + +(async function () { + const pluginsTS = glob.sync('packages/artplayer-plugin-*/types/*.d.ts'); + for (let index = 0; index < pluginsTS.length; index++) { + const type = pluginsTS[index]; + await cpy(type, 'docs/assets/ts/', { flat: true }); + console.log(`✨ Copy ${type}`); + } +})();