mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-21 21:01:20 -08:00
refactor(ads): [PKG-ADS-04] reconcile public types and historical imports
This commit is contained in:
1 parent
39e2d4cdfb
commit
fb1cfa701d
41 files changed
+1208
-149
No files matched your search
@@ -1,9 +1,9 @@
|
||||
# Ads implementation and maintenance
|
||||
|
||||
Ads is a single preroll attached by `artplayerPluginAds(option)(art)`. The factory and
|
||||
returned `{ name, skip, pause, play }` are synchronous. Package public declarations are
|
||||
still scheduled for PKG-ADS-04; do not infer that their current source/type fields are
|
||||
implemented runtime aliases. Runtime input remains html/video/url plus timing, mute and i18n.
|
||||
returned `{ name, skip, pause, play }` are synchronous. Runtime input remains html/video/url
|
||||
plus timing, mute and i18n. Historical source/type fields are accepted by the compatibility
|
||||
declaration but are not implemented runtime aliases.
|
||||
|
||||
## Module boundaries
|
||||
|
||||
@@ -11,7 +11,7 @@ implemented runtime aliases. Runtime input remains html/video/url plus timing, m
|
||||
| --- | --- |
|
||||
| src/index.ts | Public factory, checked legacy constructor capabilities, import-time style injection |
|
||||
| src/options.ts | Per-attachment defaults and the existing shallow validator schema |
|
||||
| src/types.ts | Internal options, result and narrow core/DOM dependencies; public types remain separate for now |
|
||||
| src/types.ts | Normalized options and narrow core/DOM dependencies, reusing public input/result shapes |
|
||||
| src/countdown.ts | One owned timeout, whole-second counting, pause/resume and terminal cancellation; no core or DOM dependency |
|
||||
| src/view.ts | Existing HTML/CSS hooks, labels, ad element, mute and fullscreen icon rendering |
|
||||
| src/resources.ts | Instance-owned core/DOM subscriptions, guarded callbacks and disposal that continues after cleanup failures |
|
||||
@@ -22,6 +22,33 @@ only a parent, icons, options, three DOM utilities and callbacks, rather than th
|
||||
Style remains in src/style.less. There are no runtime imports from the ArtPlayer core package;
|
||||
all imports of its declarations are erased. Old cores do not need new lifecycle helpers.
|
||||
|
||||
## Public declarations and imports
|
||||
|
||||
`types/artplayer-plugin-ads.d.ts` owns the callable namespace and public shapes. CommonJS
|
||||
bridges use `.d.cts`; ESM bridges use `.d.mts`. Root and `/legacy` accept historical inputs.
|
||||
The new `/runtime` entry resolves to the same JS implementation and restricts options to
|
||||
implemented fields. `Option` is accurate, `LegacyOption` preserves the published string
|
||||
duration declaration error, and `WorkspaceOption` represents the unpublished source/type
|
||||
declaration. `CompatOption` accepts both families. No runtime duration coercion was added.
|
||||
The existing validator rejects string durations before the single localized normalization
|
||||
assertion in options.ts. Translation objects still replace all four fields together.
|
||||
|
||||
The factory has a self-referencing `.default`, supporting both callable require and the
|
||||
published `require(package).default` access. This does not emulate the old noncallable
|
||||
CommonJS namespace object's identity or key set. The returned plugin and its lifecycle
|
||||
remain unchanged. Root and `/runtime` resolve to the same module for each module system.
|
||||
|
||||
The editor generator in scripts/plugin-editor-types.mjs accepts this type-only namespace
|
||||
shape explicitly and rejects unknown imports/exports. Generate docs globals with
|
||||
`yarn build:ts`; test their semantics and actual Monaco emit/run, not only parseability.
|
||||
|
||||
ADS-TYPE-01 is accepted with scope by the maintainer on 2026-09-12: `Parameters<typeof factory>[0]` accepts both old option
|
||||
objects, but reading totalDuration yields `number | string | undefined`; the published
|
||||
declaration yielded `string | undefined`. Workspace source/type fields also become optional.
|
||||
Frozen consumers reproduce these differences. This approval covers only these historical
|
||||
inference corrections, not general API changes. Preserve the diagnostic cases and migration
|
||||
examples in the README; do not claim every historical TS program compiles unchanged.
|
||||
|
||||
## State and ordering
|
||||
|
||||
`waiting -> active -> ended`, with any state able to become `destroyed`. Ready arms the two
|
||||
@@ -78,6 +105,9 @@ generates main/legacy/ESM through the repository build. Do not hand-edit dist or
|
||||
|
||||
Tests distinguish actual media decoding from injected errors/controlled clocks. Baseline and
|
||||
open release gates live in [Ads validation](../../refactor/ads-validation.md). Public declaration
|
||||
reconciliation, old CommonJS default compatibility, isolated package consumption and demo
|
||||
validation remain PKG-ADS-04/06. Real hidden-page/device behavior and complete media-resource
|
||||
reconciliation is recorded in PKG-ADS-04; complete historical distribution and demo validation
|
||||
remain PKG-ADS-06. `yarn test:ads-types-package` packs and installs outside the workspace,
|
||||
checks all installed bytes, frozen offline install, five compiler modes and Node exports.
|
||||
`yarn test:browser test/browser/ads-editor-types.spec.js` verifies actual Monaco integration.
|
||||
Real hidden-page/device behavior and complete media-resource
|
||||
acceptance remain PKG-ADS-05. No claim of compatibility with every historical 4.x core is made.
|
||||
@@ -5,6 +5,57 @@ Ads plugin for ArtPlayer
|
||||
Implementation, resource ownership and regression commands:
|
||||
[maintenance guide](ARCHITECTURE.md).
|
||||
|
||||
## Usage and TypeScript
|
||||
|
||||
```ts
|
||||
import Artplayer from 'artplayer'
|
||||
import ads from 'artplayer-plugin-ads'
|
||||
|
||||
new Artplayer({
|
||||
container: '#player',
|
||||
url: '/content.mp4',
|
||||
plugins: [ads({ video: '/advertisement.mp4', url: '/details', playDuration: 5, totalDuration: 10 })],
|
||||
})
|
||||
```
|
||||
|
||||
Use `html` for HTML or an image element string. When both are present, `video` takes
|
||||
precedence. `playDuration` controls when closing is allowed; `totalDuration` controls
|
||||
the countdown. Durations are numeric seconds. Plugin `play()` and `pause()` control
|
||||
only the countdown; `skip()` completes the advertisement once. All three return void.
|
||||
|
||||
For accurate options without historical declaration mistakes, import the same runtime
|
||||
from `artplayer-plugin-ads/runtime`. Root and `/legacy` retain old input acceptance:
|
||||
the old `totalDuration: string` declaration compiles but strings still fail runtime
|
||||
validation; old workspace `source/type` fields are ignored. Use `video` or `html`.
|
||||
An `i18n` object must supply `close`, `countdown`, `detail` and `canBeClosed` together.
|
||||
|
||||
CommonJS supports both `require('artplayer-plugin-ads')(options)` and
|
||||
`require('artplayer-plugin-ads').default(options)`. ESM uses the default export.
|
||||
## Migrating inferred option types
|
||||
|
||||
The maintainer approved correcting conflicting historical inference on 2026-09-12.
|
||||
Existing option calls remain accepted, but `Parameters<typeof ads>[0].totalDuration`
|
||||
now reads as `number | string | undefined`; historical workspace `source/type` are
|
||||
optional. Code that assumed only one old declaration's field types may need adjustment.
|
||||
This does not make string durations or source/type runtime aliases valid.
|
||||
|
||||
Prefer accurate options for new or migrated code:
|
||||
|
||||
```ts
|
||||
import type { Option } from 'artplayer-plugin-ads'
|
||||
import ads from 'artplayer-plugin-ads/runtime'
|
||||
|
||||
const option: Option = { video: '/advertisement.mp4', totalDuration: 10 }
|
||||
const duration: number | undefined = option.totalDuration
|
||||
const plugin = ads(option)
|
||||
```
|
||||
|
||||
For a generic wrapper receiving historical input, narrow `totalDuration` before numeric
|
||||
operations and check `source/type` before reading them as required fields. Do not use a
|
||||
cast to hide string durations: the runtime validator rejects them. `LegacyOption` and
|
||||
`WorkspaceOption` remain available for code explicitly representing those historical
|
||||
declarations; `Option` describes the implemented configuration.
|
||||
|
||||
## Demo
|
||||
|
||||
[https://artplayer.org](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-ads/index.js&example=ads)
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
* (c) 2017-2026 Harvey Zhao
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
!function(e,n){"object"===typeof exports&&"undefined"!==typeof module?module.exports=n():"function"==typeof define&&define.amd?(e.artplayerPluginAds=n(),define(function(){return e.artplayerPluginAds})):(e="undefined"!==typeof globalThis?globalThis:e||self).artplayerPluginAds=n()}(this,function(){"use strict";function e(e){console.warn("Artplayer Ads:",e)}function n(n){const t=[];let i=!1;function l(e,n){if(!i){t.push(n);try{e()}finally{i&&n()}}}return{on(e,t){const a=()=>{i||t()};l(()=>{n.on(e,a)},()=>{n.off(e,a)})},dom(e,n,t){const a=()=>{i||t()};l(()=>e.addEventListener(n,a),()=>e.removeEventListener(n,a))},dispose(){if(!i){i=!0;for(const i of t.splice(0).reverse())try{i()}catch(n){e(n)}}}}}const t=(e,n)=>n.replace("%s",String(e));function i(i,l,a,o){const r=n(i),s=n(i),d=i.template;let u,p,c="waiting",y=!1,f=!1,g=!1;const v=function(e,n,t){let i,l=0,a=!1,o=!1,r=!1;function s(){a&&o&&!r&&void 0===i&&(i=setTimeout(()=>{i=void 0,!r&&o&&(l+=1,n(l),r||(l>=e()?t():s()))},1e3))}function d(){o=!1,void 0!==i&&clearTimeout(i),i=void 0}return{start(){a||r||(a=!0,o=!0,s())},play(){a&&!r&&(o=!0,s())},pause:d,stop(){r=!0,d()}}}(()=>l.totalDuration,e=>p?.render(e),b),m=()=>"active"===c&&!i.isDestroy,h=()=>"destroyed"===c||i.isDestroy;function x(n){try{n?.pause()}catch(t){e(t)}}function w(n,t,i){try{Promise.resolve(n()).then(()=>{m()||i?.()},t).catch(e)}catch(l){t(l)}}function b(){if("ended"!==c&&"destroyed"!==c&&!i.isDestroy){if(c="ended",v.stop(),r.dispose(),y){if(w(()=>i.play(),n=>{"destroyed"!==c&&e(n)}),h())return;if(x(p?.video),h())return;p?.hide()}h()||i.emit("artplayerPluginAds:skip",l)}}function D(){const n=p?.video;if(x(n),n)try{n.removeAttribute("src"),n.load()}catch(t){e(t)}try{u?.remove()}catch(t){e(t)}finally{d.$ads===u&&delete d.$ads}}function k(){"destroyed"!==c&&(c="destroyed",v.stop(),r.dispose(),s.dispose(),D())}function A(){if("waiting"===c&&!i.isDestroy){c="active",y=!0;try{if(p=function(e,n,i,l,a){const{append:o,query:r,setStyle:s}=l,d=o(e,'<div class="artplayer-plugin-ads"></div>');a(d);const u=o(d,i.video?'<video class="artplayer-plugin-ads-video" loop playsInline></video>':`<div class="artplayer-plugin-ads-html">${i.html}</div>`),p=i.video?u:null,c=o(d,'<div class="artplayer-plugin-ads-loading"></div>');o(c,n.loading);const y=o(d,'<div class="artplayer-plugin-ads-timer">\n <div class="artplayer-plugin-ads-close"></div>\n <div class="artplayer-plugin-ads-countdown"></div>\n </div>'),f=r(".artplayer-plugin-ads-close",y),g=r(".artplayer-plugin-ads-countdown",y),v=o(d,`<div class="artplayer-plugin-ads-control">\n <div class="artplayer-plugin-ads-detail">${i.i18n.detail}</div>\n <div class="artplayer-plugin-ads-muted"></div>\n <div class="artplayer-plugin-ads-fullscreen"></div>\n </div>`),m=r(".artplayer-plugin-ads-detail",v),h=r(".artplayer-plugin-ads-muted",v),x=r(".artplayer-plugin-ads-fullscreen",v);let w=i.playDuration<=0;function b(){s(n.volume,"display",p?.muted?"none":"inline-flex"),s(n.volumeClose,"display",p?.muted?"inline-flex":"none")}function D(e){const n=i.playDuration-e;w=0===e?i.playDuration<=0:n<1||Number.isNaN(n),f.innerHTML=w?i.i18n.close:t(n,i.i18n.canBeClosed),g.innerHTML=t(i.totalDuration-e,i.i18n.countdown)}return i.playDuration>=i.totalDuration&&s(f,"display","none"),i.url||s(m,"display","none"),p?(o(h,n.volume),o(h,n.volumeClose),p.muted=Boolean(i.muted),b()):s(h,"display","none"),o(x,n.fullscreenOn),o(x,n.fullscreenOff),D(0),{root:d,video:p,render:D,ready(){s(y,"display","flex"),s(v,"display","flex"),s(c,"display","none")},hide(){s(d,"display","none")},fullscreen(e){s(n.fullscreenOn,"display",e?"none":"inline-flex"),s(n.fullscreenOff,"display",e?"inline-flex":"none")},bind(e,n){e.dom(f,"click",()=>{w&&n.skip()}),e.dom(u,"click",n.click),i.url&&e.dom(m,"click",n.click),p&&e.dom(h,"click",()=>{p.muted=!p.muted,b()}),e.dom(x,"click",n.fullscreen)}}}(d.$player,a,l,o,e=>{u=e,d.$ads=e}),!m())return void D();if(i.pause(),!m())return;const n=p,s=u.ownerDocument;n.fullscreen(i.fullscreen),n.bind(r,{skip:b,click(){l.url&&(s.defaultView||window).open(l.url),m()&&i.emit("artplayerPluginAds:click",l)},fullscreen(){i.fullscreen=!i.fullscreen,m()&&n.fullscreen(i.fullscreen)}}),r.on("fullscreen",()=>n.fullscreen(i.fullscreen));const c=()=>s.hidden?v.pause():v.play();r.dom(s,"visibilitychange",c),r.on("document:visibilitychange",c);const y=()=>{if(m()&&!g){if(g=!0,v.start(),s.hidden&&v.pause(),n.video){const t=n.video;w(()=>t.play(),n=>{m()&&(e(n),b())},()=>x(t))}m()&&n.ready()}};n.video?(r.dom(n.video,"error",b),r.dom(n.video,"loadedmetadata",y),n.video.src=l.video):y()}catch(n){throw k(),n}}}try{s.on("destroy",k),r.on("ready",()=>{f||"waiting"!==c||(f=!0,r.on("play",A),r.on("video:playing",A))}),i.isDestroy&&k()}catch(C){throw k(),C}return{name:"artplayerPluginAds",skip:b,pause:v.pause,play:v.play}}if("undefined"!==typeof document&&!document.getElementById("artplayer-plugin-ads")){const e=document.createElement("style");e.id="artplayer-plugin-ads",e.textContent=".artplayeLine truncated
|
||||
!function(e,n){"object"===typeof exports&&"undefined"!==typeof module?module.exports=n():"function"==typeof define&&define.amd?(e.artplayerPluginAds=n(),define(function(){return e.artplayerPluginAds})):(e="undefined"!==typeof globalThis?globalThis:e||self).artplayerPluginAds=n()}(this,function(){"use strict";function e(e){console.warn("Artplayer Ads:",e)}function n(n){const t=[];let i=!1;function l(e,n){if(!i){t.push(n);try{e()}finally{i&&n()}}}return{on(e,t){const a=()=>{i||t()};l(()=>{n.on(e,a)},()=>{n.off(e,a)})},dom(e,n,t){const a=()=>{i||t()};l(()=>e.addEventListener(n,a),()=>e.removeEventListener(n,a))},dispose(){if(!i){i=!0;for(const i of t.splice(0).reverse())try{i()}catch(n){e(n)}}}}}const t=(e,n)=>n.replace("%s",String(e));function i(i,l,a,o){const r=n(i),s=n(i),d=i.template;let u,p,c="waiting",y=!1,f=!1,g=!1;const v=function(e,n,t){let i,l=0,a=!1,o=!1,r=!1;function s(){a&&o&&!r&&void 0===i&&(i=setTimeout(()=>{i=void 0,!r&&o&&(l+=1,n(l),r||(l>=e()?t():s()))},1e3))}function d(){o=!1,void 0!==i&&clearTimeout(i),i=void 0}return{start(){a||r||(a=!0,o=!0,s())},play(){a&&!r&&(o=!0,s())},pause:d,stop(){r=!0,d()}}}(()=>l.totalDuration,e=>p?.render(e),w),m=()=>"active"===c&&!i.isDestroy,h=()=>"destroyed"===c||i.isDestroy;function x(n){try{n?.pause()}catch(t){e(t)}}function b(n,t,i){try{Promise.resolve(n()).then(()=>{m()||i?.()},t).catch(e)}catch(l){t(l)}}function w(){if("ended"!==c&&"destroyed"!==c&&!i.isDestroy){if(c="ended",v.stop(),r.dispose(),y){if(b(()=>i.play(),n=>{"destroyed"!==c&&e(n)}),h())return;if(x(p?.video),h())return;p?.hide()}h()||i.emit("artplayerPluginAds:skip",l)}}function D(){const n=p?.video;if(x(n),n)try{n.removeAttribute("src"),n.load()}catch(t){e(t)}try{u?.remove()}catch(t){e(t)}finally{d.$ads===u&&delete d.$ads}}function k(){"destroyed"!==c&&(c="destroyed",v.stop(),r.dispose(),s.dispose(),D())}function O(){if("waiting"===c&&!i.isDestroy){c="active",y=!0;try{if(p=function(e,n,i,l,a){const{append:o,query:r,setStyle:s}=l,d=o(e,'<div class="artplayer-plugin-ads"></div>');a(d);const u=o(d,i.video?'<video class="artplayer-plugin-ads-video" loop playsInline></video>':`<div class="artplayer-plugin-ads-html">${i.html}</div>`),p=i.video?u:null,c=o(d,'<div class="artplayer-plugin-ads-loading"></div>');o(c,n.loading);const y=o(d,'<div class="artplayer-plugin-ads-timer">\n <div class="artplayer-plugin-ads-close"></div>\n <div class="artplayer-plugin-ads-countdown"></div>\n </div>'),f=r(".artplayer-plugin-ads-close",y),g=r(".artplayer-plugin-ads-countdown",y),v=o(d,`<div class="artplayer-plugin-ads-control">\n <div class="artplayer-plugin-ads-detail">${i.i18n.detail}</div>\n <div class="artplayer-plugin-ads-muted"></div>\n <div class="artplayer-plugin-ads-fullscreen"></div>\n </div>`),m=r(".artplayer-plugin-ads-detail",v),h=r(".artplayer-plugin-ads-muted",v),x=r(".artplayer-plugin-ads-fullscreen",v);let b=i.playDuration<=0;function w(){s(n.volume,"display",p?.muted?"none":"inline-flex"),s(n.volumeClose,"display",p?.muted?"inline-flex":"none")}function D(e){const n=i.playDuration-e;b=0===e?i.playDuration<=0:n<1||Number.isNaN(n),f.innerHTML=b?i.i18n.close:t(n,i.i18n.canBeClosed),g.innerHTML=t(i.totalDuration-e,i.i18n.countdown)}return i.playDuration>=i.totalDuration&&s(f,"display","none"),i.url||s(m,"display","none"),p?(o(h,n.volume),o(h,n.volumeClose),p.muted=Boolean(i.muted),w()):s(h,"display","none"),o(x,n.fullscreenOn),o(x,n.fullscreenOff),D(0),{root:d,video:p,render:D,ready(){s(y,"display","flex"),s(v,"display","flex"),s(c,"display","none")},hide(){s(d,"display","none")},fullscreen(e){s(n.fullscreenOn,"display",e?"none":"inline-flex"),s(n.fullscreenOff,"display",e?"inline-flex":"none")},bind(e,n){e.dom(f,"click",()=>{b&&n.skip()}),e.dom(u,"click",n.click),i.url&&e.dom(m,"click",n.click),p&&e.dom(h,"click",()=>{p.muted=!p.muted,w()}),e.dom(x,"click",n.fullscreen)}}}(d.$player,a,l,o,e=>{u=e,d.$ads=e}),!m())return void D();if(i.pause(),!m())return;const n=p,s=u.ownerDocument;n.fullscreen(i.fullscreen),n.bind(r,{skip:w,click(){l.url&&(s.defaultView||window).open(l.url),m()&&i.emit("artplayerPluginAds:click",l)},fullscreen(){i.fullscreen=!i.fullscreen,m()&&n.fullscreen(i.fullscreen)}}),r.on("fullscreen",()=>n.fullscreen(i.fullscreen));const c=()=>s.hidden?v.pause():v.play();r.dom(s,"visibilitychange",c),r.on("document:visibilitychange",c);const y=()=>{if(m()&&!g){if(g=!0,v.start(),s.hidden&&v.pause(),n.video){const t=n.video;b(()=>t.play(),n=>{m()&&(e(n),w())},()=>x(t))}m()&&n.ready()}};n.video?(r.dom(n.video,"error",w),r.dom(n.video,"loadedmetadata",y),n.video.src=l.video):y()}catch(n){throw k(),n}}}try{s.on("destroy",k),r.on("ready",()=>{f||"waiting"!==c||(f=!0,r.on("play",O),r.on("video:playing",O))}),i.isDestroy&&k()}catch(A){throw k(),A}return{name:"artplayerPluginAds",skip:w,pause:v.pause,play:v.play}}function l(e){return n=>{const t=n.constructor;if("function"!==typeof t.validator||!["append","query","setStyle"].every(e=>"function"===typeof Reflect.get(t.utils||{},e)))throwLine truncated
|
||||
@@ -4,4 +4,4 @@
|
||||
* (c) 2017-2026 Harvey Zhao
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
!function(e,n){"object"===typeof exports&&"undefined"!==typeof module?module.exports=n():"function"==typeof define&&define.amd?(e.artplayerPluginAds=n(),define(function(){return e.artplayerPluginAds})):(e="undefined"!==typeof globalThis?globalThis:e||self).artplayerPluginAds=n()}(this,function(){"use strict";var e=Object.defineProperty,n=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,t=Object.prototype.propertyIsEnumerable,i=(n,l,t)=>l in n?e(n,l,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[l]=t;function r(e,r){return r(((e,r)=>{for(var o in r||(r={}))l.call(r,o)&&i(e,o,r[o]);if(n)for(var o of n(r))t.call(r,o)&&i(e,o,r[o]);return e})({html:"",video:"",url:"",playDuration:5,totalDuration:10,muted:!1,i18n:{close:"\u5173\u95ed\u5e7f\u544a",countdown:"%s\u79d2",detail:"\u67e5\u770b\u8be6\u60c5",canBeClosed:"%s\u79d2\u540e\u53ef\u5173\u95ed\u5e7f\u544a"}},e),{html:"?string",video:"?string",url:"?string",playDuration:"number",totalDuration:"number",muted:"?boolean",i18n:{close:"string",countdown:"string",detail:"string",canBeClosed:"string"}})}function o(e){console.warn("Artplayer Ads:",e)}function a(e){const n=[];let l=!1;function t(e,t){if(!l){n.push(t);try{e()}finally{l&&t()}}}return{on(n,i){const r=()=>{l||i()};t(()=>{e.on(n,r)},()=>{e.off(n,r)})},dom(e,n,i){const r=()=>{l||i()};t(()=>e.addEventListener(n,r),()=>e.removeEventListener(n,r))},dispose(){if(!l){l=!0;for(const l of n.splice(0).reverse())try{l()}catch(e){o(e)}}}}}const s=(e,n)=>n.replace("%s",String(e));function d(e,n,l,t){const i=a(e),r=a(e),d=e.template;let u,p,c="waiting",y=!1,f=!1,g=!1;const v=function(e,n,l){let t,i=0,r=!1,o=!1,a=!1;function s(){r&&o&&!a&&void 0===t&&(t=setTimeout(()=>{t=void 0,!a&&o&&(i+=1,n(i),a||(i>=e()?l():s()))},1e3))}function d(){o=!1,void 0!==t&&clearTimeout(t),t=void 0}return{start(){r||a||(r=!0,o=!0,s())},play(){r&&!a&&(o=!0,s())},pause:d,stop(){a=!0,d()}}}(()=>n.totalDuration,e=>null==p?void 0:p.render(e),w),m=()=>"active"===c&&!e.isDestroy,h=()=>"destroyed"===c||e.isDestroy;function b(e){try{null==e||e.pause()}catch(n){o(n)}}function x(e,n,l){try{Promise.resolve(e()).then(()=>{m()||null==l||l()},n).catch(o)}catch(t){n(t)}}function w(){if("ended"!==c&&"destroyed"!==c&&!e.isDestroy){if(c="ended",v.stop(),i.dispose(),y){if(x(()=>e.play(),e=>{"destroyed"!==c&&o(e)}),h())return;if(b(null==p?void 0:p.video),h())return;null==p||p.hide()}h()||e.emit("artplayerPluginAds:skip",n)}}function D(){const e=null==p?void 0:p.video;if(b(e),e)try{e.removeAttribute("src"),e.load()}catch(n){o(n)}try{null==u||u.remove()}catch(n){o(n)}finally{d.$ads===u&&delete d.$ads}}function k(){"destroyed"!==c&&(c="destroyed",v.stop(),i.dispose(),r.dispose(),D())}function O(){if("waiting"===c&&!e.isDestroy){c="active",y=!0;try{if(p=function(e,n,l,t,i){const{append:r,query:o,setStyle:a}=t,d=r(e,'<div class="artplayer-plugin-ads"></div>');i(d);const u=r(d,l.video?'<video class="artplayer-plugin-ads-video" loop playsInline></video>':`<div class="artplayer-plugin-ads-html">${l.html}</div>`),p=l.video?u:null,c=r(d,'<div class="artplayer-plugin-ads-loading"></div>');r(c,n.loading);const y=r(d,'<div class="artplayer-plugin-ads-timer">\n <div class="artplayer-plugin-ads-close"></div>\n <div class="artplayer-plugin-ads-countdown"></div>\n </div>'),f=o(".artplayer-plugin-ads-close",y),g=o(".artplayer-plugin-ads-countdown",y),v=r(d,`<div class="artplayer-plugin-ads-control">\n <div class="artplayer-plugin-ads-detail">${l.i18n.detail}</div>\n <div class="artplayer-plugin-ads-muted"></div>\n <div class="artplayer-plugin-ads-fullscreen"></div>\n </div>`),m=o(".artplayer-plugin-ads-detail",v),h=o(".artplayer-plugin-ads-muted",v),b=o(".artplayer-plugin-ads-fullscreen",v);let x=l.playDuration<=0;function w(){a(n.volume,"display",(null==p?void 0:p.muted)?"none":"inline-flex"),a(n.volumeClose,"display",(null==p?void 0:p.muted)?"inline-flex":"none")}function D(e){const n=l.playDuration-e;x=0===e?l.playDuration<=0:n<1||Number.isNaN(n),f.innerHTML=x?l.i18n.close:s(n,l.i18n.canBeClosed),g.innerHTML=s(l.totalDuration-e,l.i18n.countdown)}return l.playDuration>=l.totalDuration&&a(f,"display","none"),l.url||a(m,"display","none"),p?(r(h,n.volume),r(h,n.volumeClose),p.muted=Boolean(l.muted),w()):a(h,"display","none"),r(b,n.fullscreenOn),r(b,n.fullscreenOff),D(0),{root:d,video:p,render:D,ready(){a(y,"display","flex"),a(v,"display","flex"),a(c,"display","none")},hide(){a(d,"display","none")},fullscreen(e){a(n.fullscreenOn,"display",e?"none":"inline-flex"),a(n.fullscreenOff,"display",e?"inline-flex":"none")},bind(e,n){e.dom(f,"click",()=>{x&&n.skip()}),e.dom(u,"click",n.click),l.url&&e.dom(m,"click",n.click),p&&e.dom(h,"click",()=>{p.muted=!p.muted,w()}),e.dom(b,"click",n.fullscreen)}}}(d.$player,l,n,t,e=>{u=e,d.$ads=e}),!m())return void D();if(e.pause(),!m())return;const r=p,a=u.ownerDocument;r.fullscreen(e.fullscreen),r.bind(i,{skip:w,click(){n.url&&(a.defaultView||window).open(n.url),m()&&e.emit("artplayerPluginAds:click",n)},fullscreenLine truncated
|
||||
!function(e,n){"object"===typeof exports&&"undefined"!==typeof module?module.exports=n():"function"==typeof define&&define.amd?(e.artplayerPluginAds=n(),define(function(){return e.artplayerPluginAds})):(e="undefined"!==typeof globalThis?globalThis:e||self).artplayerPluginAds=n()}(this,function(){"use strict";var e=Object.defineProperty,n=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,i=(n,t,l)=>t in n?e(n,t,{enumerable:!0,configurable:!0,writable:!0,value:l}):n[t]=l;function r(e,r){return r(((e,r)=>{for(var o in r||(r={}))t.call(r,o)&&i(e,o,r[o]);if(n)for(var o of n(r))l.call(r,o)&&i(e,o,r[o]);return e})({html:"",video:"",url:"",playDuration:5,totalDuration:10,muted:!1,i18n:{close:"\u5173\u95ed\u5e7f\u544a",countdown:"%s\u79d2",detail:"\u67e5\u770b\u8be6\u60c5",canBeClosed:"%s\u79d2\u540e\u53ef\u5173\u95ed\u5e7f\u544a"}},e),{html:"?string",video:"?string",url:"?string",playDuration:"number",totalDuration:"number",muted:"?boolean",i18n:{close:"string",countdown:"string",detail:"string",canBeClosed:"string"}})}function o(e){console.warn("Artplayer Ads:",e)}function a(e){const n=[];let t=!1;function l(e,l){if(!t){n.push(l);try{e()}finally{t&&l()}}}return{on(n,i){const r=()=>{t||i()};l(()=>{e.on(n,r)},()=>{e.off(n,r)})},dom(e,n,i){const r=()=>{t||i()};l(()=>e.addEventListener(n,r),()=>e.removeEventListener(n,r))},dispose(){if(!t){t=!0;for(const t of n.splice(0).reverse())try{t()}catch(e){o(e)}}}}}const s=(e,n)=>n.replace("%s",String(e));function d(e,n,t,l){const i=a(e),r=a(e),d=e.template;let u,p,c="waiting",y=!1,f=!1,g=!1;const v=function(e,n,t){let l,i=0,r=!1,o=!1,a=!1;function s(){r&&o&&!a&&void 0===l&&(l=setTimeout(()=>{l=void 0,!a&&o&&(i+=1,n(i),a||(i>=e()?t():s()))},1e3))}function d(){o=!1,void 0!==l&&clearTimeout(l),l=void 0}return{start(){r||a||(r=!0,o=!0,s())},play(){r&&!a&&(o=!0,s())},pause:d,stop(){a=!0,d()}}}(()=>n.totalDuration,e=>null==p?void 0:p.render(e),w),m=()=>"active"===c&&!e.isDestroy,h=()=>"destroyed"===c||e.isDestroy;function b(e){try{null==e||e.pause()}catch(n){o(n)}}function x(e,n,t){try{Promise.resolve(e()).then(()=>{m()||null==t||t()},n).catch(o)}catch(l){n(l)}}function w(){if("ended"!==c&&"destroyed"!==c&&!e.isDestroy){if(c="ended",v.stop(),i.dispose(),y){if(x(()=>e.play(),e=>{"destroyed"!==c&&o(e)}),h())return;if(b(null==p?void 0:p.video),h())return;null==p||p.hide()}h()||e.emit("artplayerPluginAds:skip",n)}}function D(){const e=null==p?void 0:p.video;if(b(e),e)try{e.removeAttribute("src"),e.load()}catch(n){o(n)}try{null==u||u.remove()}catch(n){o(n)}finally{d.$ads===u&&delete d.$ads}}function k(){"destroyed"!==c&&(c="destroyed",v.stop(),i.dispose(),r.dispose(),D())}function O(){if("waiting"===c&&!e.isDestroy){c="active",y=!0;try{if(p=function(e,n,t,l,i){const{append:r,query:o,setStyle:a}=l,d=r(e,'<div class="artplayer-plugin-ads"></div>');i(d);const u=r(d,t.video?'<video class="artplayer-plugin-ads-video" loop playsInline></video>':`<div class="artplayer-plugin-ads-html">${t.html}</div>`),p=t.video?u:null,c=r(d,'<div class="artplayer-plugin-ads-loading"></div>');r(c,n.loading);const y=r(d,'<div class="artplayer-plugin-ads-timer">\n <div class="artplayer-plugin-ads-close"></div>\n <div class="artplayer-plugin-ads-countdown"></div>\n </div>'),f=o(".artplayer-plugin-ads-close",y),g=o(".artplayer-plugin-ads-countdown",y),v=r(d,`<div class="artplayer-plugin-ads-control">\n <div class="artplayer-plugin-ads-detail">${t.i18n.detail}</div>\n <div class="artplayer-plugin-ads-muted"></div>\n <div class="artplayer-plugin-ads-fullscreen"></div>\n </div>`),m=o(".artplayer-plugin-ads-detail",v),h=o(".artplayer-plugin-ads-muted",v),b=o(".artplayer-plugin-ads-fullscreen",v);let x=t.playDuration<=0;function w(){a(n.volume,"display",(null==p?void 0:p.muted)?"none":"inline-flex"),a(n.volumeClose,"display",(null==p?void 0:p.muted)?"inline-flex":"none")}function D(e){const n=t.playDuration-e;x=0===e?t.playDuration<=0:n<1||Number.isNaN(n),f.innerHTML=x?t.i18n.close:s(n,t.i18n.canBeClosed),g.innerHTML=s(t.totalDuration-e,t.i18n.countdown)}return t.playDuration>=t.totalDuration&&a(f,"display","none"),t.url||a(m,"display","none"),p?(r(h,n.volume),r(h,n.volumeClose),p.muted=Boolean(t.muted),w()):a(h,"display","none"),r(b,n.fullscreenOn),r(b,n.fullscreenOff),D(0),{root:d,video:p,render:D,ready(){a(y,"display","flex"),a(v,"display","flex"),a(c,"display","none")},hide(){a(d,"display","none")},fullscreen(e){a(n.fullscreenOn,"display",e?"none":"inline-flex"),a(n.fullscreenOff,"display",e?"inline-flex":"none")},bind(e,n){e.dom(f,"click",()=>{x&&n.skip()}),e.dom(u,"click",n.click),t.url&&e.dom(m,"click",n.click),p&&e.dom(h,"click",()=>{p.muted=!p.muted,w()}),e.dom(b,"click",n.fullscreen)}}}(d.$player,t,n,l,e=>{u=e,d.$ads=e}),!m())return void D();if(e.pause(),!m())return;const r=p,a=u.ownerDocument;r.fullscreen(e.fullscreen),r.bind(i,{skip:w,click(){n.url&&(a.defaultView||window).open(n.url),m()&&e.emit("artplayerPluginAds:click",n)},fullscreenLine truncated
|
||||
@@ -390,6 +390,7 @@ function artplayerPluginAds(input) {
|
||||
return createSession(art, option, { volume, volumeClose, fullscreenOn, fullscreenOff, loading }, constructor.utils);
|
||||
};
|
||||
}
|
||||
const index = Object.assign(artplayerPluginAds, { default: artplayerPluginAds });
|
||||
if (typeof document !== "undefined" && !document.getElementById("artplayer-plugin-ads")) {
|
||||
const element = document.createElement("style");
|
||||
element.id = "artplayer-plugin-ads";
|
||||
@@ -397,5 +398,5 @@ if (typeof document !== "undefined" && !document.getElementById("artplayer-plugi
|
||||
document.head.appendChild(element);
|
||||
}
|
||||
export {
|
||||
artplayerPluginAds as default
|
||||
index as default
|
||||
};
|
||||
@@ -19,19 +19,49 @@
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/artplayer-plugin-ads.d.ts",
|
||||
"import": "./dist/artplayer-plugin-ads.mjs",
|
||||
"require": "./dist/artplayer-plugin-ads.js"
|
||||
"import": {
|
||||
"types": "./types/artplayer-plugin-ads.d.mts",
|
||||
"default": "./dist/artplayer-plugin-ads.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./types/artplayer-plugin-ads.d.cts",
|
||||
"default": "./dist/artplayer-plugin-ads.js"
|
||||
}
|
||||
},
|
||||
"./legacy": {
|
||||
"types": "./types/artplayer-plugin-ads.d.ts",
|
||||
"import": "./dist/artplayer-plugin-ads.legacy.js",
|
||||
"require": "./dist/artplayer-plugin-ads.legacy.js"
|
||||
"import": {
|
||||
"types": "./types/artplayer-plugin-ads.d.cts",
|
||||
"default": "./dist/artplayer-plugin-ads.legacy.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./types/artplayer-plugin-ads.d.cts",
|
||||
"default": "./dist/artplayer-plugin-ads.legacy.js"
|
||||
}
|
||||
},
|
||||
"./runtime": {
|
||||
"import": {
|
||||
"types": "./types/runtime/index.d.mts",
|
||||
"default": "./dist/artplayer-plugin-ads.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./types/runtime/index.d.cts",
|
||||
"default": "./dist/artplayer-plugin-ads.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"main": "./dist/artplayer-plugin-ads.js",
|
||||
"module": "./dist/artplayer-plugin-ads.mjs",
|
||||
"types": "./types/artplayer-plugin-ads.d.ts",
|
||||
"legacy": "./dist/artplayer-plugin-ads.legacy.js",
|
||||
"browserslist": "last 1 Chrome version"
|
||||
"browserslist": "last 1 Chrome version",
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"legacy": [
|
||||
"types/artplayer-plugin-ads.d.ts"
|
||||
],
|
||||
"runtime": [
|
||||
"types/runtime/index.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { normalizeOptions } from './options'
|
||||
import { createSession } from './session'
|
||||
import style from './style.less?inline'
|
||||
|
||||
export default function artplayerPluginAds(input?: Input) {
|
||||
function artplayerPluginAds(input?: Input) {
|
||||
return (art: Artplayer): Result => {
|
||||
// Legacy core declarations type instance.constructor as Function. Check the
|
||||
// actual capabilities before using its existing static validator/utilities.
|
||||
@@ -17,6 +17,8 @@ export default function artplayerPluginAds(input?: Input) {
|
||||
}
|
||||
}
|
||||
|
||||
export default Object.assign(artplayerPluginAds, { default: artplayerPluginAds })
|
||||
|
||||
if (typeof document !== 'undefined' && !document.getElementById('artplayer-plugin-ads')) {
|
||||
const element = document.createElement('style')
|
||||
element.id = 'artplayer-plugin-ads'
|
||||
|
||||
@@ -2,6 +2,8 @@ import type Artplayer from 'artplayer'
|
||||
import type { Input, Options } from './types'
|
||||
|
||||
export function normalizeOptions(input: Input | undefined, validate: typeof Artplayer.validator): Options {
|
||||
// The legacy declaration accepts strings, but this unchanged validator proves
|
||||
// numeric runtime durations before the result crosses the declaration boundary.
|
||||
return validate({
|
||||
html: '',
|
||||
video: '',
|
||||
@@ -24,5 +26,5 @@ export function normalizeOptions(input: Input | undefined, validate: typeof Artp
|
||||
totalDuration: 'number',
|
||||
muted: '?boolean',
|
||||
i18n: { close: 'string', countdown: 'string', detail: 'string', canBeClosed: 'string' },
|
||||
})
|
||||
}) as Options
|
||||
}
|
||||
@@ -1,31 +1,18 @@
|
||||
import type Artplayer from 'artplayer'
|
||||
import type { CompatOption, Option, Result as PublicResult, Translations as PublicTranslations } from '../types/artplayer-plugin-ads'
|
||||
|
||||
export interface Translations {
|
||||
close: string
|
||||
countdown: string
|
||||
detail: string
|
||||
canBeClosed: string
|
||||
}
|
||||
export type Translations = PublicTranslations
|
||||
|
||||
export interface Options {
|
||||
html?: string
|
||||
video?: string
|
||||
url?: string
|
||||
export interface Options extends Option {
|
||||
playDuration: number
|
||||
totalDuration: number
|
||||
muted?: boolean
|
||||
i18n: Translations
|
||||
}
|
||||
|
||||
export type Input = Partial<Options>
|
||||
export type Input = CompatOption
|
||||
export type Host = Pick<Artplayer, 'on' | 'off' | 'emit' | 'play' | 'pause' | 'template' | 'icons' | 'fullscreen' | 'isDestroy'>
|
||||
export type Utilities = Pick<typeof Artplayer.utils, 'append' | 'query' | 'setStyle'>
|
||||
export type Icons = Pick<Artplayer['icons'], 'volume' | 'volumeClose' | 'fullscreenOn' | 'fullscreenOff' | 'loading'>
|
||||
export type Cleanup = () => void
|
||||
|
||||
export interface Result {
|
||||
name: 'artplayerPluginAds'
|
||||
skip: Cleanup
|
||||
pause: Cleanup
|
||||
play: Cleanup
|
||||
}
|
||||
export type Result = PublicResult
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": { "allowJs": false },
|
||||
"include": ["src/**/*.ts", "types/**/*.d.ts", "../../types/assets.d.ts"]
|
||||
"include": ["src/**/*.ts", "types/**/*.d.ts", "types/**/*.d.mts", "types/**/*.d.cts", "../../types/assets.d.ts"]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// eslint-disable-next-line ts/no-require-imports -- Preserve the CommonJS export-assignment namespace.
|
||||
import artplayerPluginAds = require('./artplayer-plugin-ads.js')
|
||||
|
||||
export = artplayerPluginAds
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default } from './artplayer-plugin-ads.js'
|
||||
export type { Callable, CompatOption, Factory, LegacyOption, Option, Result, RuntimeCallable, RuntimeFactory, Translations, WorkspaceOption } from './artplayer-plugin-ads.js'
|
||||
+81
-43
@@ -1,51 +1,89 @@
|
||||
/* eslint-disable ts/no-redeclare -- The callable export and public type namespace intentionally merge. */
|
||||
import type Artplayer from 'artplayer'
|
||||
|
||||
interface Option {
|
||||
/**
|
||||
* 广告源文本,支持视频链接、图片链接、HTML文本
|
||||
*/
|
||||
source: string
|
||||
declare namespace artplayerPluginAds {
|
||||
interface Translations {
|
||||
close: string
|
||||
countdown: string
|
||||
detail: string
|
||||
canBeClosed: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 知名广告的类型:'video' | 'image' | 'html'
|
||||
*/
|
||||
type: 'video' | 'image' | 'html'
|
||||
/** Implemented options. Video takes precedence over HTML. */
|
||||
interface Option {
|
||||
html?: string
|
||||
video?: string
|
||||
url?: string
|
||||
/** Seconds before the close button becomes available. @default 5 */
|
||||
playDuration?: number
|
||||
/** Total advertisement duration in seconds. @default 10 */
|
||||
totalDuration?: number
|
||||
/** Initial ad-video mute state. @default false */
|
||||
muted?: boolean
|
||||
/** All four fields replace the default translation object together. */
|
||||
i18n?: Translations
|
||||
}
|
||||
|
||||
/**
|
||||
* 广告必看的时长,单位为秒
|
||||
*/
|
||||
playDuration?: number
|
||||
/** Historical published declaration. String durations still fail runtime validation. */
|
||||
interface LegacyOption extends Omit<Option, 'totalDuration'> {
|
||||
/** @deprecated Incorrect in the old declaration; use a numeric duration. */
|
||||
totalDuration?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 广告总的时长,单位为秒
|
||||
*/
|
||||
totalDuration?: number
|
||||
/** Historical unpublished workspace declaration; these fields are not runtime aliases. */
|
||||
interface WorkspaceOption extends Option {
|
||||
/** @deprecated Ignored by the runtime. Use html or video instead. */
|
||||
source: string
|
||||
/** @deprecated Ignored by the runtime. Images are supplied through html. */
|
||||
type: 'video' | 'image' | 'html'
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频广告是否默认静音
|
||||
*/
|
||||
muted?: boolean
|
||||
/** Input acceptance for both historical declaration families. */
|
||||
interface CompatOption extends Omit<Option, 'totalDuration'> {
|
||||
/** @deprecated The string branch exists for old types only and is rejected at runtime. */
|
||||
totalDuration?: number | string
|
||||
/** @deprecated Ignored by the runtime. Use html or video instead. */
|
||||
source?: string
|
||||
/** @deprecated Ignored by the runtime. Images are supplied through html. */
|
||||
type?: 'video' | 'image' | 'html'
|
||||
}
|
||||
|
||||
interface Result {
|
||||
name: 'artplayerPluginAds'
|
||||
/** Complete once; before initialization this cancels the pending preroll. */
|
||||
skip: () => void
|
||||
/** Pause only the countdown, leaving ad video playback unchanged. */
|
||||
pause: () => void
|
||||
/** Resume only the countdown without adding extra timers. */
|
||||
play: () => void
|
||||
}
|
||||
|
||||
interface Callable {
|
||||
(option?: Option): (art: Artplayer) => Result
|
||||
/** @deprecated Compatibility with erroneous old string-duration declarations only. */
|
||||
(option: LegacyOption): (art: Artplayer) => Result
|
||||
(option: WorkspaceOption): (art: Artplayer) => Result
|
||||
(option?: CompatOption): (art: Artplayer) => Result
|
||||
/** Required final signature keeps Parameters extraction free of top-level undefined. */
|
||||
(option: CompatOption): (art: Artplayer) => Result
|
||||
}
|
||||
|
||||
interface Factory extends Callable {
|
||||
/** Same function; supports historical require(package).default calls. */
|
||||
readonly default: Callable
|
||||
}
|
||||
|
||||
interface RuntimeCallable {
|
||||
(option?: Option): (art: Artplayer) => Result
|
||||
(option: Option): (art: Artplayer) => Result
|
||||
}
|
||||
|
||||
/** Accurate typing for the identical implementation at /runtime. */
|
||||
interface RuntimeFactory extends RuntimeCallable {
|
||||
readonly default: RuntimeCallable
|
||||
}
|
||||
}
|
||||
|
||||
interface Ads {
|
||||
name: 'artplayerPluginAds'
|
||||
|
||||
/**
|
||||
* 跳过广告
|
||||
*/
|
||||
skip: () => void
|
||||
|
||||
/**
|
||||
* 暂停广告
|
||||
*/
|
||||
pause: () => void
|
||||
|
||||
/**
|
||||
* 播放广告
|
||||
*/
|
||||
play: () => void
|
||||
}
|
||||
|
||||
declare const artplayerPluginAds: (option: Option) => (art: Artplayer) => Ads
|
||||
|
||||
export default artplayerPluginAds
|
||||
declare const artplayerPluginAds: artplayerPluginAds.Factory
|
||||
export = artplayerPluginAds
|
||||
export as namespace artplayerPluginAds
|
||||
@@ -0,0 +1,4 @@
|
||||
// eslint-disable-next-line ts/no-require-imports -- Preserve the CommonJS export-assignment namespace.
|
||||
import artplayerPluginAds = require('./index.js')
|
||||
|
||||
export = artplayerPluginAds
|
||||
@@ -0,0 +1,2 @@
|
||||
export type { Option, Result, RuntimeFactory, Translations } from '../artplayer-plugin-ads.js'
|
||||
export { default } from './index.js'
|
||||
@@ -0,0 +1,11 @@
|
||||
/* eslint-disable ts/no-redeclare -- The callable export and public type namespace intentionally merge. */
|
||||
import type * as Definition from '../artplayer-plugin-ads'
|
||||
|
||||
declare const artplayerPluginAds: Definition.RuntimeFactory
|
||||
declare namespace artplayerPluginAds {
|
||||
type Option = Definition.Option
|
||||
type Result = Definition.Result
|
||||
type RuntimeFactory = Definition.RuntimeFactory
|
||||
type Translations = Definition.Translations
|
||||
}
|
||||
export = artplayerPluginAds
|
||||
Reference in new issue
Block a user