polyv-live-cli
Version:
CLI tool for managing PolyV live streaming services.
367 lines (366 loc) • 16.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadAuthAndServiceConfig = loadAuthAndServiceConfig;
exports.validateOutputFormat = validateOutputFormat;
exports.parsePositiveInteger = parsePositiveInteger;
exports.parseNonNegativeInteger = parseNonNegativeInteger;
exports.registerAiCommands = registerAiCommands;
const ai_digital_human_handler_1 = require("../handlers/ai-digital-human.handler");
const ai_video_produce_handler_1 = require("../handlers/ai-video-produce.handler");
const auth_adapter_1 = require("../config/auth-adapter");
const manager_1 = require("../config/manager");
const errors_1 = require("../utils/errors");
const DEFAULT_TIMEOUT_MS = 30000;
async function loadAuthAndServiceConfig(parentOptions) {
const authResult = auth_adapter_1.authAdapter.tryGetAuthConfig(parentOptions);
if (!authResult) {
throw new Error(auth_adapter_1.authAdapter.getStatusMessage(parentOptions));
}
let configResult;
try {
configResult = await manager_1.configManager.load({
cliOptions: parentOptions,
});
}
catch (error) {
if (error instanceof Error && error.message.includes('Auth configuration is incomplete')) {
configResult = {
config: {
baseUrl: 'https://api.polyv.net',
timeout: DEFAULT_TIMEOUT_MS,
debug: false,
},
};
}
else {
throw error;
}
}
const serviceConfig = {
baseUrl: configResult.config.baseUrl,
timeout: configResult.config.timeout,
debug: configResult.config.debug,
};
const isVerbose = !!parentOptions['verbose'];
if (isVerbose) {
console.log('Using authentication from:', authResult.source);
}
return { authConfig: authResult.config, serviceConfig, isVerbose };
}
function validateOutputFormat(format) {
if (format !== 'table' && format !== 'json') {
throw new Error('Invalid output format. Must be table or json');
}
return format;
}
function parsePositiveInteger(value) {
const parsed = Number.parseInt(value, 10);
if (!Number.isInteger(parsed) || parsed < 1) {
throw new Error(`${value} is not a positive integer`);
}
return parsed;
}
function parseNonNegativeInteger(value) {
const parsed = Number.parseInt(value, 10);
if (!Number.isInteger(parsed) || parsed < 0) {
throw new Error(`${value} is not a non-negative integer`);
}
return parsed;
}
function validatePptConvertType(value) {
if (value !== 'common' && value !== 'animate') {
throw new Error('PPT convert type must be common or animate');
}
return value;
}
async function createDigitalHumanHandler(program, commandOptions) {
const { authConfig, serviceConfig } = await loadAuthAndServiceConfig({
...program.opts(),
...commandOptions,
});
return new ai_digital_human_handler_1.AIDigitalHumanHandler(authConfig, serviceConfig);
}
async function createVideoProduceHandler(program, commandOptions) {
const { authConfig, serviceConfig } = await loadAuthAndServiceConfig({
...program.opts(),
...commandOptions,
});
return new ai_video_produce_handler_1.AIVideoProduceHandler(authConfig, serviceConfig);
}
function registerAiCommands(program) {
const aiCmd = program
.command('ai')
.description('Manage AI features for live streaming (管理AI功能)');
const digitalHumanCmd = aiCmd
.command('digital-human')
.description('Manage AI Digital Humans (管理AI数字人)');
digitalHumanCmd
.command('list')
.description('List AI Digital Humans (列出AI数字人)')
.option('--page <number>', 'Page number (default: 1)', parseInt)
.option('--size <number>', 'Page size (default: 10, max: 1000)', parseInt)
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createDigitalHumanHandler(program, options);
await handler.listDigitalHumans({
page: options.page,
size: options.size,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
digitalHumanCmd
.command('list-org')
.description('List organization associations for AI Digital Humans (查询AI数字人关联的组织)')
.requiredOption('--ids <ids>', 'AI Digital Human IDs, comma-separated (数字人ID,逗号分隔)')
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createDigitalHumanHandler(program, options);
await handler.listOrganizations({
ids: options.ids,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
digitalHumanCmd
.command('set-org')
.description(`Set organization associations for AI Digital Humans (设置AI数字人关联的组织)
Tip: discover organization IDs with \`user org list\`, and digital-human IDs with \`ai digital-human list\`.`)
.option('--config-json <json>', 'JSON array config, e.g. \'[{"aiDigitalHumanId":1,"organizationIds":[2,3],"includeChildren":true}]\'')
.option('--aiDigitalHumanId <id>', 'AI Digital Human ID (数字人ID)')
.option('--organizationIds <ids>', 'Organization IDs, comma-separated (组织ID,逗号分隔)')
.option('--includeChildren', 'Include child organizations (包含子组织)', true)
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createDigitalHumanHandler(program, options);
await handler.setOrganizations({
configJson: options.configJson,
aiDigitalHumanId: options.aiDigitalHumanId,
organizationIds: options.organizationIds,
includeChildren: options.includeChildren,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
const videoProduceCmd = aiCmd
.command('video-produce')
.description('Manage AI video production tasks, PPT files, and TTS voices (管理AI视频制作)');
const ttsVoiceCmd = videoProduceCmd
.command('tts-voice')
.description('Manage TTS voices for AI video production (管理视频制作声音)');
ttsVoiceCmd
.command('list')
.description('List TTS voices for AI video production (列出可用声音)')
.option('--page <number>', 'Page number (default: 1)', parsePositiveInteger, 1)
.option('--size <number>', 'Page size (default: 10, max: 1000)', parsePositiveInteger, 10)
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createVideoProduceHandler(program, options);
await handler.listTtsVoices({
page: options.page,
size: options.size,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
videoProduceCmd
.command('list')
.description('List AI video production tasks (列出AI视频制作任务)')
.option('--page <number>', 'Page number (default: 1)', parsePositiveInteger, 1)
.option('--size <number>', 'Page size (default: 10, max: 1000)', parsePositiveInteger, 10)
.option('--video-name <name>', 'Filter by video name')
.option('--status <number>', 'Filter by task status', parsePositiveInteger)
.option('--create-time-start <timestamp>', 'Creation start timestamp in milliseconds', parseNonNegativeInteger)
.option('--create-time-end <timestamp>', 'Creation end timestamp in milliseconds', parseNonNegativeInteger)
.option('--tags <tags>', 'Comma-separated tags')
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createVideoProduceHandler(program, options);
await handler.listVideoProduces({
page: options.page,
size: options.size,
videoName: options.videoName,
status: options.status,
createTimeStart: options.createTimeStart,
createTimeEnd: options.createTimeEnd,
tags: options.tags,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
videoProduceCmd
.command('get')
.description('Get an AI video production task (查询AI视频制作任务)')
.requiredOption('--id <id>', 'AI video production task ID', parsePositiveInteger)
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createVideoProduceHandler(program, options);
await handler.getVideoProduce({
id: options.id,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
videoProduceCmd
.command('create')
.description('Create AI video production tasks in batch (批量创建AI视频制作任务)')
.requiredOption('--tasks <json>', 'JSON array of task payloads, max 20')
.option('--force', 'Create without confirmation')
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createVideoProduceHandler(program, options);
await handler.createVideoProduces({
tasks: options.tasks,
force: options.force || false,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
videoProduceCmd
.command('delete')
.description('Delete an AI video production task (删除AI视频制作任务)')
.requiredOption('--id <id>', 'AI video production task ID', parsePositiveInteger)
.option('--force', 'Delete without confirmation')
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createVideoProduceHandler(program, options);
await handler.deleteVideoProduce({
id: options.id,
force: options.force || false,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
const pptCmd = videoProduceCmd
.command('ppt')
.description('Manage PPT files for AI video production (管理视频制作PPT)');
pptCmd
.command('list')
.description('List PPT files for AI video production (列出视频制作PPT)')
.option('--page <number>', 'Page number (default: 1)', parsePositiveInteger, 1)
.option('--size <number>', 'Page size (default: 10, max: 1000)', parsePositiveInteger, 10)
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createVideoProduceHandler(program, options);
await handler.listVideoProducePpts({
page: options.page,
size: options.size,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
pptCmd
.command('get')
.description('Get a PPT file for AI video production (查询视频制作PPT)')
.requiredOption('--file-id <fileId>', 'PPT file ID')
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createVideoProduceHandler(program, options);
await handler.getVideoProducePpt({
fileId: options.fileId,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
pptCmd
.command('upload')
.description('Upload a PPT by URL for AI video production (上传视频制作PPT)')
.requiredOption('--url <url>', 'PPT file URL')
.option('--doc-name <name>', 'Custom PPT file name')
.option('--force', 'Upload without confirmation')
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createVideoProduceHandler(program, options);
await handler.uploadVideoProducePpt({
url: options.url,
docName: options.docName,
force: options.force || false,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
pptCmd
.command('async-upload')
.description('Start async PPT upload by URL for AI video production (异步上传视频制作PPT)')
.requiredOption('--url <url>', 'PPT file URL')
.option('--doc-name <name>', 'Custom PPT file name')
.option('--type <type>', 'PPT conversion type (common|animate)', validatePptConvertType)
.option('--callback-url <url>', 'Callback URL for upload/convert status')
.option('--child-user-id <id>', 'Child account user ID for PPT isolation')
.option('--force', 'Start async upload without confirmation')
.option('-o, --output <format>', 'Output format (table|json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const handler = await createVideoProduceHandler(program, options);
await handler.asyncUploadVideoProducePpt({
url: options.url,
docName: options.docName,
type: options.type,
callbackUrl: options.callbackUrl,
childUserId: options.childUserId,
force: options.force || false,
output: options.output,
});
}
catch (error) {
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
}
//# sourceMappingURL=ai.commands.js.map