ps-tcplayer
Version:
Tencent Cloud Player component with Vue2/Vue3 compatibility
274 lines (243 loc) • 8.08 kB
JavaScript
/**
* TCPlayer插件管理器
* 负责组件的注册、初始化和生命周期管理
*/
// 添加到播放器的兼容层,确保组件需要的属性/方法存在
function addPlayerCompatLayer(player) {
if (!player) return;
if (!player.lang) {
player.lang = function(key) {
// 提供默认中文文案映射
const langMap = {
"Play": "播放",
"Pause": "暂停",
"Mute": "静音",
"Unmute": "取消静音",
"Fullscreen": "全屏",
"Exit Fullscreen": "退出全屏",
"Settings": "设置",
"Speed": "速度",
"Normal": "正常",
"Quality": "质量",
"Auto": "自动",
"HD": "高清",
"SD": "标清"
};
return langMap[key] || key;
};
}
// 确保options_存在
if (!player.options_) {
player.options_ = player.options_ || {};
}
// 确保语言相关设置存在
if (player.options_ && !player.options_.languages) {
player.options_.languages = {
'zh-CN': {
"Play": "播放",
"Pause": "暂停",
"Mute": "静音",
"Unmute": "取消静音",
"Fullscreen": "全屏",
"Exit Fullscreen": "退出全屏",
"Settings": "设置",
"Speed": "速度",
"Normal": "正常",
"Quality": "质量",
"Auto": "自动",
"HD": "高清",
"SD": "标清"
}
};
// 设置当前语言
player.options_.language = 'zh-CN';
}
}
function bindComponentEvents(player, component, componentName) {
if (!player || !component) return;
//"loadstart","suspend","abort","error","emptied","stalled","loadedmetadata","loadeddata","canplay","canplaythrough","playing","waiting","seeking","seeked","ended","durationchange","timeupdate","progress","play","pause","ratechange","resize","volumechange"
const eventMappings = {
'play': 'play',
'playing': 'playing',
'pause': 'pause',
'timeupdate': 'timeupdate',
'ended': 'ended',
'waiting': 'waiting',
'error': 'error',
'seeking': 'seeking',
'seeked': 'seeked',
'loadstart': 'loadstart',
'canplay': 'canplay',
'canplaythrough': 'canplaythrough',
'durationchange': 'durationchange',
'volumechange': 'volumechange',
'ratechange': 'ratechange',
'resize': 'resize',
'fullscreenchange': 'fullscreenchange'
};
if (!component._eventListeners) {
component._eventListeners = [];
}
Object.entries(eventMappings).forEach(([playerEvent, componentMethod]) => {
if (typeof component[componentMethod] === 'function') {
const listener = (e) => {
try {
component[componentMethod](e);
} catch (err) {
console.error(`组件 ${componentName} 的 ${componentMethod} 方法执行失败:`, err);
}
};
// 监听播放器事件
player.on(playerEvent, listener);
// 记录监听器用于清理
component._eventListeners.push({
event: playerEvent,
listener: listener
});
}
});
}
/**
* 清理组件事件监听器
* @param {Object} player - 播放器实例
* @param {Object} component - 组件实例
*/
function unbindComponentEvents(player, component) {
if (!player || !component || !component._eventListeners) return;
component._eventListeners.forEach(({ event, listener }) => {
try {
player.off(event, listener);
} catch (err) {
console.error('清理组件事件监听器失败:', err);
}
});
component._eventListeners = [];
}
/**
* 注册组件到播放器实例
* @param {Object} player - 播放器实例
* @param {Array} plugins - 插件配置数组
* @returns {Array} - 注册的组件实例数组
*/
function registerComponents(player, plugins) {
if (!player) return [];
const registeredComponents = [];
try {
if (!plugins || !Array.isArray(plugins)) return registeredComponents;
plugins.forEach(plugin => {
try {
if (plugin.type && typeof plugin.type === 'function') {
// 检查player对象是否有效
if (!player || !player.el_) {
console.warn('播放器实例不完整,跳过组件注册', plugin.name);
return;
}
// 创建组件实例,注意捕获错误
let componentInstance;
try {
componentInstance = new plugin.type(player, ...(plugin.args || []));
} catch (initErr) {
console.error(`组件 ${plugin.name} 初始化失败:`, initErr);
return;
}
// 存储组件到播放器实例
if (plugin.name) {
if (!player._components) {
player._components = {};
}
player._components[plugin.name] = componentInstance;
registeredComponents.push(componentInstance);
// 添加getComponent方法
if (!player.getComponent) {
player.getComponent = function(name) {
return this._components && this._components[name];
};
}
// 绑定播放器事件到组件方法
bindComponentEvents(player, componentInstance, plugin.name);
// 如果组件有createEl方法,则调用
if (componentInstance.createEl && typeof componentInstance.createEl === 'function') {
try {
// 确保播放器元素存在
if (player.el_ && player.el_.nodeType === 1) {
componentInstance.createEl(player.el_);
} else {
console.warn(`组件 ${plugin.name} 跳过DOM创建,播放器元素不存在`);
}
} catch (elErr) {
console.error(`组件 ${plugin.name} 创建DOM元素失败:`, elErr);
console.log('组件:', componentInstance);
console.log('错误详情:', elErr);
}
}
// 如果组件有created方法,则调用
if (componentInstance.created && typeof componentInstance.created === 'function') {
try {
componentInstance.created(player);
} catch (createdErr) {
console.error(`组件 ${plugin.name} created方法执行失败:`, createdErr);
}
}
}
}
} catch (pluginErr) {
console.error(`处理插件时发生错误:`, pluginErr);
}
});
} catch (err) {
console.error('注册组件错误:', err);
}
return registeredComponents;
}
/**
* 初始化组件的ready方法
* @param {Object} player - 播放器实例
*/
function initComponentsReadyState(player) {
if (!player || !player._components) return;
try {
Object.values(player._components).forEach(component => {
try {
if (component.ready && typeof component.ready === 'function') {
component.ready();
}
} catch (err) {
console.error('组件ready方法执行失败:', err);
}
});
} catch (err) {
console.error('初始化组件ready状态失败:', err);
}
}
/**
* 销毁所有组件
* @param {Object} player - 播放器实例
*/
function destroyComponents(player) {
if (!player || !player._components) return;
try {
Object.values(player._components).forEach(component => {
try {
// 清理事件监听器
unbindComponentEvents(player, component);
// 调用组件的destroy方法
if (component.destroy && typeof component.destroy === 'function') {
component.destroy();
}
} catch (err) {
console.error('组件destroy方法执行失败:', err);
}
});
// 清空组件列表
player._components = {};
} catch (err) {
console.error('销毁组件失败:', err);
}
}
// 导出插件管理器API
export default {
addPlayerCompatLayer,
registerComponents,
initComponentsReadyState,
destroyComponents
};