Files
WebControlCenter/src/services/Channel.service.ts
2025-09-04 20:25:15 -04:00

249 lines
6.7 KiB
TypeScript

/**
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
*/
import { Channel, Channels } from '@techniker-me/pcast-api';
import PCastApiService from './PCastApi.service';
import LoggerFactory from './logger/LoggerFactory';
const logger = LoggerFactory.getLogger('services/channel.service');
export interface CreateChannelParams {
name: string;
description?: string;
options?: string[];
}
export interface UpdateChannelParams {
channelId: string;
name?: string;
alias?: string;
description?: string;
tags?: string[];
capabilities?: string[];
}
export interface ForkChannelParams {
sourceChannelId: string;
destinationChannelId: string;
streamCapabilities?: string[];
streamTags?: string[];
options?: string[];
}
export interface DeleteChannelParams {
channelId: string;
alias: string;
}
export interface KillChannelParams {
channelId: string;
reason?: string;
options?: string[];
enteredAlias?: string;
}
/**
* Channel Service providing CRUD operations for channels
*/
class ChannelService {
private phenixChannelService: PhenixChannelService | null = null;
public async initializeWithPCastApi(channels: Channels) {
try {
// Wait for PCastApiService to be initialized
this.phenixChannelService = channels;
} catch (error) {
logger.error('Failed to initialize ChannelService', error);
}
}
/**
* Get all channels
*/
async listChannels(): Promise<Channel[]> {
try {
logger.debug('Fetching channel list');
if (!this.phenixChannelService) {
return PCastApiService.channels.list();
}
return await this.phenixChannelService.list();
} catch (error) {
logger.error('Failed to list channels', error);
throw error;
}
}
/**
* Create a new channel
*/
async createChannel(params: CreateChannelParams): Promise<Channel> {
try {
logger.debug('Creating channel', params);
const channelData = {
name: params.name,
alias: params.alias,
description: params.description || '',
tags: params.tags || [],
capabilities: params.capabilities || []
};
if (!this.phenixChannelService) {
return PCastApiService.channels.create(name, description, options);
}
return await this.phenixChannelService.create(channelData);
} catch (error) {
logger.error('Failed to create channel', error);
throw error;
}
}
/**
* Update an existing channel
*/
async updateChannel(params: UpdateChannelParams): Promise<Channel> {
try {
logger.debug('Updating channel', params);
const updateData = {
...params.name && { name: params.name },
...params.alias && { alias: params.alias },
...params.description && { description: params.description },
...params.tags && { tags: params.tags },
...params.capabilities && { capabilities: params.capabilities }
};
if (!this.phenixChannelService) {
return PCastApiService.channels.update(params.channelId, updateData);
}
return await this.phenixChannelService.update(params.channelId, updateData);
} catch (error) {
logger.error('Failed to update channel', error);
throw error;
}
}
/**
* Delete a channel
*/
async deleteChannel(params: DeleteChannelParams): Promise<void> {
try {
logger.debug('Deleting channel', params);
if (!this.phenixChannelService) {
return PCastApiService.channels.delete(params.channelId);
}
await this.phenixChannelService.delete(params.channelId);
} catch (error) {
logger.error('Failed to delete channel', error);
throw error;
}
}
/**
* Fork a channel
*/
async forkChannel(params: ForkChannelParams): Promise<void> {
try {
logger.debug('Forking channel', params);
const forkData = {
destinationChannelId: params.destinationChannelId,
streamCapabilities: params.streamCapabilities || [],
streamTags: params.streamTags || [],
options: params.options || []
};
// Phenix SDK fork method
if (!this.phenixChannelService) {
return PCastApiService.channels.fork(params.sourceChannelId, forkData);
}
await this.phenixChannelService.fork(params.sourceChannelId, forkData);
} catch (error) {
logger.error('Failed to fork channel', error);
throw error;
}
}
/**
* Kill a channel
*/
async killChannel(params: KillChannelParams): Promise<void> {
try {
logger.debug('Killing channel', params);
const killData = {
reason: params.reason || 'portal:killed',
options: params.options || []
};
if (!this.phenixChannelService) {
return PCastApiService.channels.kill(params.channelId, killData);
}
await this.phenixChannelService.kill(params.channelId, killData);
} catch (error) {
logger.error('Failed to kill channel', error);
throw error;
}
}
/**
* Get channel by ID
*/
async getChannel(channelId: string): Promise<Channel | null> {
try {
logger.debug('Getting channel', { channelId });
if (!this.phenixChannelService) {
return PCastApiService.channels.get(channelId);
}
return await this.phenixChannelService.get(channelId);
} catch (error) {
logger.error('Failed to get channel', error);
throw error;
}
}
/**
* Get publisher count for a channel
*/
async getPublisherCount(channelId: string): Promise<number> {
try {
logger.debug('Getting publisher count', { channelId });
if (!this.phenixChannelService) {
return PCastApiService.channels.getPublisherCount(channelId);
}
return await this.phenixChannelService.getPublisherCount(channelId);
} catch (error) {
logger.error('Failed to get publisher count', error);
return 0;
}
}
}
// Export singleton instance
const channelService = new ChannelService();
// Named exports for individual operations
export const listChannels = channelService.listChannels.bind(channelService);
export const createChannel = channelService.createChannel.bind(channelService);
export const updateChannel = channelService.updateChannel.bind(channelService);
export const deleteChannel = channelService.deleteChannel.bind(channelService);
export const forkChannel = channelService.forkChannel.bind(channelService);
export const killChannel = channelService.killChannel.bind(channelService);
export const getChannel = channelService.getChannel.bind(channelService);
export const getPublisherCount = channelService.getPublisherCount.bind(channelService);
export default channelService;