feat: support standalone video

This commit is contained in:
陈泳瑾 2025-02-14 18:04:54 +08:00 committed by gemstone
parent bb0a991f0e
commit 4daf5162e1
3 changed files with 18 additions and 12 deletions

View File

@ -20,6 +20,7 @@ import { getLang } from './utils/util'
* @typedef { {
* id?: string,
* el?: HTMLElement,
* mediaEl?: HTMLMediaElement | (mediaConfig: { [propName: string]: any }) => HTMLMediaElement,
* url?: IUrl,
* domEventType?: 'default' | 'touch' | 'mouse',
* nullUrlStart?: boolean,
@ -99,6 +100,7 @@ import { getLang } from './utils/util'
* sliderBtnStyle?: { [propName: string]: any },
* volumeColor?: string
* },
* remainMediaAfterDestroy? boolean,
* [propName: string]: any;
* } } IPlayerOptions
*/

View File

@ -26,6 +26,9 @@ import { URL_CHANGE, WAITING, VIDEO_EVENTS, SOURCE_ERROR, SOURCE_SUCCESS } from
* pause: Function,
* } } IMediaProxy
*/
/**
* @typedef { import ('./defaultConfig').IPlayerOptions } IPlayerOptions
*/
function emitVideoEvent (eventKey, e) {
if (!this || !this.emit) {
@ -103,6 +106,9 @@ function getVideoEventHandler (eventKey, player) {
* @extends { EventEmitter }
*/
class MediaProxy extends EventEmitter {
/**
* @param { IPlayerOptions } options
*/
constructor (options) {
super(options)
/**
@ -185,7 +191,12 @@ class MediaProxy extends EventEmitter {
/**
* @type { HTMLVideoElement | HTMLAudioElement | HTMLElement | IMediaProxy | null }
*/
this.media = Util.createDom(this.mediaConfig.mediaType, '', this.mediaConfig, '')
this.media =
options.mediaEl instanceof HTMLMediaElement
? options.mediaEl
: typeof options.mediaEl === 'function'
? options.mediaEl(this.mediaConfig)
: Util.createDom(this.mediaConfig.mediaType, '', this.mediaConfig, '')
if (options.defaultPlaybackRate) {
this.media.defaultPlaybackRate = this.media.playbackRate = options.defaultPlaybackRate

View File

@ -450,20 +450,12 @@ class Player extends MediaProxy {
ret.destroy()
}
this.root.setAttribute(PLATER_ID, this.playerId)
this.media.setAttribute(PLATER_ID, this.playerId)
instManager?.add(this)
pluginsManager.init(this)
this._initBaseDoms()
// 允许自定义video对象的构造
const XgVideoProxy = this.constructor.XgVideoProxy
if (XgVideoProxy && this.mediaConfig.mediaType === XgVideoProxy.mediaType) {
const el = this.innerContainer || this.root
this.detachVideoEvents(this.media)
const _nVideo = new XgVideoProxy(el, this.config, this.mediaConfig)
this.attachVideoEvents(_nVideo)
this.media = _nVideo
}
this.media.setAttribute(PLATER_ID, this.playerId)
if (this.config.controls) {
const _root = this.config.controls.root || null
const controls = pluginsManager.register(this, Controls, { root: _root })
@ -1321,6 +1313,7 @@ class Player extends MediaProxy {
this.hasStart = false
this._useAutoplay = false
root.removeAttribute(PLATER_ID)
media.removeAttribute(PLATER_ID)
this.updateAcc('destroy')
this._unbindEvents()
this._detachSourceEvents(this.media)
@ -1343,7 +1336,7 @@ class Player extends MediaProxy {
}
!innerContainer &&
media instanceof window.Node &&
root.contains(media) &&
root.contains(media) && !this.config.remainMediaAfterDestroy &&
root.removeChild(media);
['topBar', 'leftBar', 'rightBar', 'innerContainer'].map((item) => {
this[item] && root.removeChild(this[item])