From e773e2c44f41b635ec20db5b6831d821b4ac584b Mon Sep 17 00:00:00 2001 From: Harvey Zack Date: Fri, 30 May 2025 10:45:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20VAST=20=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E5=92=8C=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=8F=8F=E8=BF=B0=E5=92=8C=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=EF=BC=8C=E5=A2=9E=E5=BC=BA=E5=B9=BF=E5=91=8A?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E5=99=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/artplayer-plugin-vast/README.md | 2 +- packages/artplayer-plugin-vast/package.json | 4 +- packages/artplayer-plugin-vast/src/index.js | 100 ++++++++++++++---- .../types/artplayer-plugin-vast.d.ts | 36 +++++-- 4 files changed, 106 insertions(+), 36 deletions(-) diff --git a/packages/artplayer-plugin-vast/README.md b/packages/artplayer-plugin-vast/README.md index 785687886..9dc39247d 100644 --- a/packages/artplayer-plugin-vast/README.md +++ b/packages/artplayer-plugin-vast/README.md @@ -1,6 +1,6 @@ # artplayer-plugin-vast -vast plugin for ArtPlayer +VAST plugin for ArtPlayer ## Demo diff --git a/packages/artplayer-plugin-vast/package.json b/packages/artplayer-plugin-vast/package.json index f1a76306a..94efc95db 100644 --- a/packages/artplayer-plugin-vast/package.json +++ b/packages/artplayer-plugin-vast/package.json @@ -1,8 +1,8 @@ { "license": "MIT", - "version": "1.0.0", + "version": "1.0.1", "name": "artplayer-plugin-vast", - "description": "vast plugin for ArtPlayer", + "description": "VAST plugin for ArtPlayer", "main": "dist/artplayer-plugin-vast.js", "legacy": "dist/artplayer-plugin-vast.legacy.js", "module": "dist/artplayer-plugin-vast.esm.js", diff --git a/packages/artplayer-plugin-vast/src/index.js b/packages/artplayer-plugin-vast/src/index.js index 612e7e284..50dade9da 100644 --- a/packages/artplayer-plugin-vast/src/index.js +++ b/packages/artplayer-plugin-vast/src/index.js @@ -3,7 +3,7 @@ import { Player, PlayerOptions, loadImaSdk } from '@glomex/vast-ima-player'; export default function artplayerPluginVast(callback) { return async (art) => { const { template, constructor } = art; - const { createElement, setStyles, append } = constructor.utils; + const { createElement, setStyles } = constructor.utils; const { $video, $player } = template; await loadImaSdk(); @@ -11,45 +11,101 @@ export default function artplayerPluginVast(callback) { const ima = google.ima; const adsRenderingSettings = new ima.AdsRenderingSettings(); + adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; + adsRenderingSettings.enablePreloading = true; + const playerOptions = new PlayerOptions(); + let isAdPlaying = false; + let imaPlayer = null; + let $container = null; - const id = `art-${Date.now()}`; - const $container = createElement('div'); - append($player, $container); - $container.id = id; - setStyles($container, { - position: 'absolute', - inset: '0', - width: '100%', - height: '100%', - zIndex: '150', - display: 'none', - }); + function createContainer() { + const container = createElement('div'); + const id = `art-vast-${Date.now()}`; + container.id = id; + setStyles(container, { + position: 'absolute', + inset: '0', + width: '100%', + height: '100%', + zIndex: '150', + backgroundColor: 'black', + display: 'none', + pointerEvents: 'auto', + }); + return container; + } - const imaPlayer = new Player(ima, $video, $container, adsRenderingSettings, playerOptions); + function initPlayer() { + $container = createContainer(); + $player.appendChild($container); + imaPlayer = new Player(ima, $video, $container, adsRenderingSettings, playerOptions); + + // ✅ 事件绑定 + imaPlayer.onAdStarted = () => { + isAdPlaying = true; + $container.style.display = 'block'; + art.pause(); + }; + + imaPlayer.onAdEnd = () => { + isAdPlaying = false; + $container.style.display = 'none'; + art.play(); + }; + + imaPlayer.onAdError = (error) => { + console.error('VAST Ad Error:', error); + isAdPlaying = false; + $container.style.display = 'none'; + art.play(); + }; + } + + function destroyPlayer() { + if ($container && $container.parentNode) { + $container.parentNode.removeChild($container); + } + $container = null; + imaPlayer = null; + } function playUrl(url) { - const playAdsRequest = new ima.AdsRequest(); - playAdsRequest.adTagUrl = url; - imaPlayer.playAds(playAdsRequest); + if (isAdPlaying) return; + if (!imaPlayer) initPlayer(); + const request = new ima.AdsRequest(); + request.adTagUrl = url; + imaPlayer.playAds(request); } function playRes(res) { - const playAdsRequest = new ima.AdsRequest(); - playAdsRequest.adsResponse = res; - imaPlayer.playAds(playAdsRequest); + if (isAdPlaying) return; + if (!imaPlayer) initPlayer(); + const request = new ima.AdsRequest(); + request.adsResponse = res; + imaPlayer.playAds(request); } if (typeof callback === 'function') { - await callback({ art, id, ima, imaPlayer, $container, playUrl, playRes }); + await callback({ + art, + playUrl, + playRes, + ima, + imaPlayer, + get container() { + return $container; + }, + }); } return { name: 'artplayerPluginVast', + destroy: destroyPlayer, }; }; } if (typeof window !== 'undefined') { - window['artplayerPluginVast'] = artplayerPluginVast; + window.artplayerPluginVast = artplayerPluginVast; } diff --git a/packages/artplayer-plugin-vast/types/artplayer-plugin-vast.d.ts b/packages/artplayer-plugin-vast/types/artplayer-plugin-vast.d.ts index 82c2445a8..f2b27c916 100644 --- a/packages/artplayer-plugin-vast/types/artplayer-plugin-vast.d.ts +++ b/packages/artplayer-plugin-vast/types/artplayer-plugin-vast.d.ts @@ -1,20 +1,34 @@ import type Artplayer from 'artplayer'; +import { Player } from '@glomex/vast-ima-player'; export = artplayerPluginVast; export as namespace artplayerPluginVast; -type Option = (params: { +declare global { + interface Window { + artplayerPluginVast?: typeof artplayerPluginVast; + } +} + +type PlayUrlFn = (url: string) => void; +type PlayResFn = (res: string) => void; + +interface VastPluginContext { art: Artplayer; - id: string; - ima: any; - imaPlayer: any; - $container: HTMLDivElement; - playUrl: (url: string) => void; - playRes: (res: string) => void; -}) => void; + ima: typeof google.ima; + imaPlayer: Player; + playUrl: PlayUrlFn; + playRes: PlayResFn; + container: HTMLDivElement | null; +} -type Result = { +export type ArtplayerPluginVastOption = (params: VastPluginContext) => void | Promise; + +export interface ArtplayerPluginVastInstance { name: 'artplayerPluginVast'; -}; + destroy?: () => void; +} -declare const artplayerPluginVast: (option: Option) => (art: Artplayer) => Result; +declare function artplayerPluginVast( + option: ArtplayerPluginVastOption, +): (art: Artplayer) => ArtplayerPluginVastInstance;