feat: 🎸 (xgplayer-ads) 广告UI独立于正片UI

This commit is contained in:
gemstone 2024-06-25 21:34:19 +08:00
parent 7a519e45ec
commit 3d3f481515
6 changed files with 107 additions and 21 deletions

View File

@ -25,8 +25,6 @@
margin-block-end: 0.4em;
}
</style>
</head>
<body class="text-base">
@ -34,15 +32,9 @@
<h3 class="text-lg font-semibold text-indigo-500">IMA 参数</h3>
<div class="flex flex-wrap">
<label id="ima-preset-url" class="mr-3 mb-2 p-1 bg-gray-200">
<a
class="underline text-blue-600 hover:text-blue-800 visited:text-purple-600"
href="https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags"
target="_blank"
>IMA sample tag url</a
>
: <input style="width: 500px" />
<select>
<option value="">请选择预设</option>
<option value="">请选择预设 IMA TagURL
</option>
<option
value="https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator="
>
@ -143,6 +135,16 @@
OM SDK Sample Pre-roll
</option>
</select>
<div class="mt-1 mb-1">
<a
class="underline text-blue-600 hover:text-blue-800 visited:text-purple-600"
href="https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags"
target="_blank"
>IMA sample tag url</a
>
: <input style="width: 500px" />
</div>
</label>
<label
@ -158,10 +160,10 @@
AdsResponse: <textarea style="width: 500px"></textarea>
</label>
<label id="autoplay" class="mr-3 mb-2 p-1 bg-gray-200">
autoplay<input type="checkbox" checked="true"/>
autoplay<input type="checkbox" checked="true" />
</label>
<label id="reset-player" class="mr-3 mb-2 p-1 bg-gray-200">
重置播放器<input type="checkbox" checked="true"/>
重置播放器<input type="checkbox" checked="true" />
</label>
</div>
<div class="flex flex-wrap">

View File

@ -3,6 +3,7 @@ import { Logger, createPublicPromise } from 'xgplayer-streaming-shared'
import * as AdEvents from './events'
import { ImaAdManager } from './imaAdManager'
import './index.scss'
import { AdUIManager } from './ui/adUIManager'
const logger = new Logger('AdsPlugin')
@ -25,6 +26,10 @@ export class AdsPlugin extends Plugin {
return __VERSION__
}
get paused () {
return !!(this.csManager?.isAdRunning && this.csManager?.paused)
}
afterCreate () {
this.csManager = undefined
}
@ -36,6 +41,10 @@ export class AdsPlugin extends Plugin {
// this._proxyPlayer()
this.initPromise = createPublicPromise()
this.uiManager = new AdUIManager(this.config, {
plugin: this,
player: this.player
})
if (this.config.adType === 'ima') {
this.initClientSideAd()
@ -125,6 +134,20 @@ export class AdsPlugin extends Plugin {
this.csManager?.playAds()
}
/**
* @public
*/
pause () {
this.csManager?.pause()
}
/**
* @public
*/
play () {
this.csManager?.play()
}
destroy () {
this.csManager?.destroy()
}

View File

@ -0,0 +1,21 @@
import { AdPlayIcon } from './plugins/adPlay'
export class AdUIManager {
constructor (config, { player, plugin }) {
this.player = player
this.config = config
this.plugin = plugin
this.init()
}
init () {
const { player } = this
const playIconPlugin = player.getPlugin('play')
if (playIconPlugin) {
player.registerPlugin(AdPlayIcon)
}
playIconPlugin.hide()
console.log('playPlugin', playIconPlugin)
}
}

View File

@ -0,0 +1,36 @@
import { PlayIcon } from 'xgplayer'
import * as AdEvents from '../../events'
export class AdPlayIcon extends PlayIcon {
static get pluginName () {
return 'adPlay'
}
getAdPlugin () {
return this.player.getPlugin('ad')
}
listenEvents () {
this.on([AdEvents.AD_PAUSE], () => {
this.animate(true)
})
this.on(AdEvents.AD_PLAY, () => {
this.animate(false)
})
}
btnClick = (e) => {
e.preventDefault()
e.stopPropagation()
const adPlugin = this.getAdPlugin()
if (adPlugin.paused) {
adPlugin.play()
this.animate(false)
} else {
adPlugin.pause()
this.animate(true)
}
return false
}
}

View File

@ -17,6 +17,9 @@ export { default as langZhHk } from './lang/zh-hk'
export { default as langJp } from './lang/jp'
export { default as langZhCn } from './lang/zh-cn'
export { default as PlayIcon } from './plugins/play'
export { default as TimeIcon } from './plugins/time'
export { default as Start } from './plugins/start'
export { default as Danmu } from './plugins/danmu'
export { DanmuIcon, DanmuPanel } from './plugins/danmu'
export { default as TextTrack } from './plugins/track'

View File

@ -20,23 +20,24 @@ class Play extends IconPlugin {
afterCreate () {
super.afterCreate()
const { player, config } = this
const { config } = this
if (config.disable) {
return
}
this.initIcons()
this.btnClick = this.btnClick.bind(this)
this.bind(['touchend', 'click'], this.btnClick)
this.on([Events.PAUSE, Events.ERROR, Events.EMPTIED], () => {
this.animate(player.isAd ? player.adPaused : player.paused)
})
this.on(Events.PLAY, () => {
this.animate(player.isAd ? player.adPaused : player.paused)
})
this.listenEvents()
this.animate(true)
}
listenEvents () {
const { player } = this
this.on([Events.PLAY, Events.PAUSE, Events.ERROR, Events.EMPTIED], () => {
this.animate(player.paused)
})
}
registerIcons () {
return {
play: { icon: PlaySvg, class: 'xg-icon-play' },
@ -44,7 +45,7 @@ class Play extends IconPlugin {
}
}
btnClick (e) {
btnClick = (e) => {
e.preventDefault()
e.stopPropagation()
const { player } = this