Files
MoonTVPlus/src/lib/emby-manager.ts
2026-01-23 16:41:49 +08:00

193 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* eslint-disable @typescript-eslint/no-explicit-any */
import { AdminConfig } from './admin.types';
import { getConfig } from './config';
import { EmbyClient } from './emby.client';
interface EmbySourceConfig {
key: string;
name: string;
enabled: boolean;
ServerURL: string;
ApiKey?: string;
Username?: string;
Password?: string;
UserId?: string;
AuthToken?: string;
Libraries?: string[];
LastSyncTime?: number;
ItemCount?: number;
isDefault?: boolean;
// 高级流媒体选项
removeEmbyPrefix?: boolean;
appendMediaSourceId?: boolean;
transcodeMp4?: boolean;
proxyPlay?: boolean; // 视频播放代理开关
}
class EmbyManager {
private static instance: EmbyManager;
private clients: Map<string, EmbyClient> = new Map();
private constructor() {}
static getInstance(): EmbyManager {
if (!EmbyManager.instance) {
EmbyManager.instance = new EmbyManager();
}
return EmbyManager.instance;
}
/**
* 从配置中获取所有Emby源支持新旧格式
*/
private async getSources(): Promise<EmbySourceConfig[]> {
const config = await getConfig();
// 如果是新格式Sources数组
if (config.EmbyConfig?.Sources && Array.isArray(config.EmbyConfig.Sources)) {
return config.EmbyConfig.Sources;
}
// 如果是旧格式(单源配置),转换为数组格式
if (config.EmbyConfig?.ServerURL) {
return [{
key: 'default',
name: 'Emby',
enabled: config.EmbyConfig.Enabled ?? false,
ServerURL: config.EmbyConfig.ServerURL,
ApiKey: config.EmbyConfig.ApiKey,
Username: config.EmbyConfig.Username,
Password: config.EmbyConfig.Password,
UserId: config.EmbyConfig.UserId,
AuthToken: config.EmbyConfig.AuthToken,
Libraries: config.EmbyConfig.Libraries,
LastSyncTime: config.EmbyConfig.LastSyncTime,
ItemCount: config.EmbyConfig.ItemCount,
isDefault: true,
}];
}
return [];
}
/**
* 获取指定key的EmbyClient
* @param key Emby源的key如果不指定则使用默认源
*/
async getClient(key?: string): Promise<EmbyClient> {
const sources = await this.getSources();
if (sources.length === 0) {
throw new Error('未配置 Emby 源');
}
// 如果没有指定key使用默认源第一个或标记为default的
if (!key) {
const defaultSource = sources.find(s => s.isDefault) || sources[0];
key = defaultSource.key;
}
// 从缓存获取或创建新实例
if (!this.clients.has(key)) {
const sourceConfig = sources.find(s => s.key === key);
if (!sourceConfig) {
throw new Error(`未找到 Emby 源: ${key}`);
}
if (!sourceConfig.enabled) {
throw new Error(`Emby 源已禁用: ${sourceConfig.name}`);
}
this.clients.set(key, new EmbyClient(sourceConfig));
}
return this.clients.get(key)!;
}
/**
* 获取所有启用的EmbyClient
*/
async getAllClients(): Promise<Map<string, { client: EmbyClient; config: EmbySourceConfig }>> {
const sources = await this.getSources();
const enabledSources = sources.filter(s => s.enabled);
const result = new Map<string, { client: EmbyClient; config: EmbySourceConfig }>();
for (const source of enabledSources) {
if (!this.clients.has(source.key)) {
this.clients.set(source.key, new EmbyClient(source));
}
result.set(source.key, {
client: this.clients.get(source.key)!,
config: source,
});
}
return result;
}
/**
* 获取所有启用的Emby源配置
*/
async getEnabledSources(): Promise<EmbySourceConfig[]> {
const sources = await this.getSources();
return sources.filter(s => s.enabled);
}
/**
* 检查是否配置了Emby
*/
async hasEmby(): Promise<boolean> {
const sources = await this.getSources();
return sources.some(s => s.enabled && s.ServerURL);
}
/**
* 清除缓存的客户端实例
*/
clearCache() {
this.clients.clear();
}
}
export const embyManager = EmbyManager.getInstance();
/**
* 配置迁移函数:将旧格式配置迁移到新格式
*/
export function migrateEmbyConfig(config: AdminConfig): AdminConfig {
// 如果已经是新格式,直接返回
if (config.EmbyConfig?.Sources) {
return config;
}
// 如果是旧格式,迁移到新格式
if (config.EmbyConfig && config.EmbyConfig.ServerURL) {
const oldConfig = config.EmbyConfig;
config.EmbyConfig = {
Sources: [{
key: 'default',
name: 'Emby',
enabled: oldConfig.Enabled ?? false,
ServerURL: oldConfig.ServerURL || '',
ApiKey: oldConfig.ApiKey,
Username: oldConfig.Username,
Password: oldConfig.Password,
UserId: oldConfig.UserId,
AuthToken: oldConfig.AuthToken,
Libraries: oldConfig.Libraries,
LastSyncTime: oldConfig.LastSyncTime,
ItemCount: oldConfig.ItemCount,
isDefault: true,
// 高级选项默认值
removeEmbyPrefix: false,
appendMediaSourceId: false,
transcodeMp4: false,
proxyPlay: false,
}],
};
}
return config;
}