UNPKG

ps-tcplayer

Version:

Tencent Cloud Player component with Vue2/Vue3 compatibility

190 lines (158 loc) 5.13 kB
import { createApp, h } from 'vue-demi' import tcplayer from './tcplayer.vue' import TcPlayerComponent from './tccomponents' import { version, isVue2, isVue3 } from 'vue-demi' interface InstanceData { app: any vm: any mountEl: HTMLElement container: Element config: any playerReady: boolean readyCallbacks: Function[] playerInstance: any } class TcPlayerSDK { static version = version static TcPlayerComponent = TcPlayerComponent static isVue2 = isVue2 static isVue3 = isVue3 private static instances: Record<string, InstanceData> = {} static init(selector: string, config: any = {}) { if (!selector) { console.error('TcPlayerSDK: 必须提供有效的DOM选择器') return null } const container = document.querySelector(selector) if (!container) { console.error(`TcPlayerSDK: 无法找到指定的DOM元素: ${selector}`) return null } const instanceId = `tcplayer-${Date.now()}-${Math.floor(Math.random() * 1000)}` const mountEl = document.createElement('div') mountEl.style.width = '100%' mountEl.style.height = '100%' container.appendChild(mountEl) // 添加播放器就绪状态追踪 const instanceData: InstanceData = { app: null, vm: null, mountEl, container, config, playerReady: false, readyCallbacks: [], playerInstance: null } const app = createApp({ render() { return h(tcplayer, { config: { ...config, onready: (player: any) => { // 播放器准备就绪时执行 console.log('播放器准备就绪,更新实例状态') instanceData.playerReady = true instanceData.playerInstance = player // 执行所有等待的回调 instanceData.readyCallbacks.forEach(callback => { try { callback(player) } catch (error) { console.error('播放器就绪回调执行失败:', error) } }) instanceData.readyCallbacks = [] // 调用用户原始的onready回调 if (config.onready) { config.onready(player) } } } }) } }) const vm = app.mount(mountEl) instanceData.app = app instanceData.vm = vm this.instances[instanceId] = instanceData return instanceId } static destroy(instanceId: string) { const instance = this.instances[instanceId] if (!instance) { console.warn(`TcPlayerSDK: 找不到ID为 ${instanceId} 的实例`) return false } instance.app.unmount() if (instance.mountEl && instance.mountEl.parentNode) { instance.mountEl.parentNode.removeChild(instance.mountEl) } delete this.instances[instanceId] return true } static getInstance(instanceId: string) { return this.instances[instanceId] || null } static getAllInstances() { return Object.keys(this.instances) } // 获取播放器实例(可能为空) static getPlayer(instanceId: string): any { const instance = this.instances[instanceId] if (!instance) { return null } // 如果播放器已经准备就绪,直接返回 if (instance.playerReady && instance.playerInstance) { return instance.playerInstance } // 尝试从Vue组件实例中获取 try { if (instance.vm && instance.vm.$player) { return instance.vm.$player } // Vue 3 Composition API方式 if (instance.vm && instance.vm._ && instance.vm._.$player) { return instance.vm._.$player } } catch (error) { console.warn('无法从Vue实例获取播放器:', error) } return null } // 等待播放器就绪(返回Promise) static waitForPlayerReady(instanceId: string): Promise<any> { return new Promise((resolve, reject) => { const instance = this.instances[instanceId] if (!instance) { reject(new Error(`找不到ID为 ${instanceId} 的实例`)) return } // 如果播放器已经准备就绪,立即返回 if (instance.playerReady && instance.playerInstance) { resolve(instance.playerInstance) return } // 添加到等待队列 instance.readyCallbacks.push(resolve) // 设置超时 setTimeout(() => { const index = instance.readyCallbacks.indexOf(resolve) if (index > -1) { instance.readyCallbacks.splice(index, 1) reject(new Error('等待播放器就绪超时')) } }, 10000) // 10秒超时 }) } // 检查播放器是否就绪 static isPlayerReady(instanceId: string): boolean { const instance = this.instances[instanceId] return instance ? instance.playerReady : false } } if (typeof window !== 'undefined') { (window as any).PsTcPlayer = TcPlayerSDK } export default TcPlayerSDK