cerevox 3.11.3 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/ai.d.ts +24 -0
- package/dist/core/ai.d.ts.map +1 -1
- package/dist/core/ai.js +91 -9
- package/dist/core/ai.js.map +1 -1
- package/dist/mcp/servers/zerocut.d.ts.map +1 -1
- package/dist/mcp/servers/zerocut.js +69 -146
- package/dist/mcp/servers/zerocut.js.map +1 -1
- package/dist/utils/videokit.d.ts +10 -10
- package/package.json +1 -1
|
@@ -3463,90 +3463,43 @@ server.registerTool('media-analyzer', {
|
|
|
3463
3463
|
const currentSession = await validateSession('media-analyzer');
|
|
3464
3464
|
// 验证文件格式
|
|
3465
3465
|
const fileExtension = mediaFileName.toLowerCase().split('.').pop();
|
|
3466
|
-
const supportedFormats = ['jpeg', 'jpg', 'png', 'mp4', 'mp3'];
|
|
3466
|
+
const supportedFormats = ['jpeg', 'jpg', 'png', 'webp', 'mp4', 'mp3'];
|
|
3467
3467
|
if (!fileExtension || !supportedFormats.includes(fileExtension)) {
|
|
3468
3468
|
throw new Error(`Unsupported file format. Supported formats: ${supportedFormats.join(', ')}`);
|
|
3469
3469
|
}
|
|
3470
3470
|
// 获取媒体文件 URL
|
|
3471
3471
|
const mediaUrl = getMaterialUri(currentSession, mediaFileName);
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3472
|
+
if (fileExtension === 'mp3') {
|
|
3473
|
+
// 音频文件 - 生成字幕并进行分析
|
|
3474
|
+
// 调用AI服务生成字幕
|
|
3475
|
+
const ai = currentSession.ai;
|
|
3476
|
+
const captionsResult = await ai.voiceToCaptions({
|
|
3477
|
+
url: mediaUrl,
|
|
3478
|
+
});
|
|
3479
|
+
console.log(mediaUrl, captionsResult);
|
|
3480
|
+
if (!captionsResult || !captionsResult.utterances) {
|
|
3481
|
+
throw new Error('Failed to generate captions from audio');
|
|
3482
|
+
}
|
|
3483
|
+
const captionsFileName = `${mediaFileName}.captions.json`;
|
|
3484
|
+
// 保存字幕文件到本地材料目录
|
|
3485
|
+
const localDir = node_path_1.default.resolve(projectLocalDir, 'materials');
|
|
3486
|
+
if (!(0, node_fs_1.existsSync)(localDir)) {
|
|
3487
|
+
(0, node_fs_1.mkdirSync)(localDir, { recursive: true });
|
|
3488
|
+
}
|
|
3489
|
+
const captionsFilePath = node_path_1.default.join(localDir, captionsFileName);
|
|
3490
|
+
await (0, promises_1.writeFile)(captionsFilePath, JSON.stringify(captionsResult, null, 2), 'utf-8');
|
|
3491
|
+
// 提取字幕文本内容用于分析
|
|
3492
|
+
const captionsText = captionsResult.utterances
|
|
3493
|
+
.map((caption) => caption.text)
|
|
3494
|
+
.join(' ');
|
|
3495
|
+
const userPrompt = `请分析这个媒体文件:${prompt}
|
|
3487
3496
|
|
|
3488
3497
|
请提供详细的分析结果,包括媒体的具体内容、风格特征、技术特点等相关信息。`;
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
if (['jpeg', 'jpg', 'png'].includes(fileExtension)) {
|
|
3492
|
-
// 图片文件
|
|
3493
|
-
messageContent = [
|
|
3494
|
-
{
|
|
3495
|
-
type: 'image_url',
|
|
3496
|
-
image_url: {
|
|
3497
|
-
url: mediaUrl,
|
|
3498
|
-
},
|
|
3499
|
-
},
|
|
3498
|
+
// 构建包含字幕内容的分析提示
|
|
3499
|
+
const messageContent = [
|
|
3500
3500
|
{
|
|
3501
|
-
type: '
|
|
3502
|
-
text: userPrompt
|
|
3503
|
-
},
|
|
3504
|
-
];
|
|
3505
|
-
}
|
|
3506
|
-
else if (fileExtension === 'mp4') {
|
|
3507
|
-
// 视频文件
|
|
3508
|
-
messageContent = [
|
|
3509
|
-
{
|
|
3510
|
-
type: 'video_url',
|
|
3511
|
-
video_url: {
|
|
3512
|
-
url: mediaUrl,
|
|
3513
|
-
},
|
|
3514
|
-
},
|
|
3515
|
-
{
|
|
3516
|
-
type: 'text',
|
|
3517
|
-
text: userPrompt,
|
|
3518
|
-
},
|
|
3519
|
-
];
|
|
3520
|
-
}
|
|
3521
|
-
else if (fileExtension === 'mp3') {
|
|
3522
|
-
// 音频文件 - 生成字幕并进行分析
|
|
3523
|
-
try {
|
|
3524
|
-
// 调用AI服务生成字幕
|
|
3525
|
-
const ai = currentSession.ai;
|
|
3526
|
-
const captionsResult = await ai.voiceToCaptions({
|
|
3527
|
-
url: mediaUrl,
|
|
3528
|
-
});
|
|
3529
|
-
console.log(mediaUrl, captionsResult);
|
|
3530
|
-
if (!captionsResult || !captionsResult.utterances) {
|
|
3531
|
-
throw new Error('Failed to generate captions from audio');
|
|
3532
|
-
}
|
|
3533
|
-
const captionsFileName = `${mediaFileName}.captions.json`;
|
|
3534
|
-
// 保存字幕文件到本地材料目录
|
|
3535
|
-
const localDir = node_path_1.default.resolve(projectLocalDir, 'materials');
|
|
3536
|
-
if (!(0, node_fs_1.existsSync)(localDir)) {
|
|
3537
|
-
(0, node_fs_1.mkdirSync)(localDir, { recursive: true });
|
|
3538
|
-
}
|
|
3539
|
-
const captionsFilePath = node_path_1.default.join(localDir, captionsFileName);
|
|
3540
|
-
await (0, promises_1.writeFile)(captionsFilePath, JSON.stringify(captionsResult, null, 2), 'utf-8');
|
|
3541
|
-
// 提取字幕文本内容用于分析
|
|
3542
|
-
const captionsText = captionsResult.utterances
|
|
3543
|
-
.map((caption) => caption.text)
|
|
3544
|
-
.join(' ');
|
|
3545
|
-
// 构建包含字幕内容的分析提示
|
|
3546
|
-
messageContent = [
|
|
3547
|
-
{
|
|
3548
|
-
type: 'text',
|
|
3549
|
-
text: `${userPrompt}
|
|
3501
|
+
type: 'input_text',
|
|
3502
|
+
text: `${userPrompt}
|
|
3550
3503
|
|
|
3551
3504
|
音频文件:${mediaFileName}
|
|
3552
3505
|
字幕内容:${captionsText}
|
|
@@ -3559,84 +3512,54 @@ server.registerTool('media-analyzer', {
|
|
|
3559
3512
|
5. 创作建议和后续应用方向
|
|
3560
3513
|
|
|
3561
3514
|
字幕文件已保存为:${captionsFileName}`,
|
|
3515
|
+
},
|
|
3516
|
+
];
|
|
3517
|
+
// 在返回结果中包含字幕文件信息
|
|
3518
|
+
const analysisPayload = {
|
|
3519
|
+
model: 'Doubao-Seed-1.8',
|
|
3520
|
+
input: [
|
|
3521
|
+
{
|
|
3522
|
+
role: 'user',
|
|
3523
|
+
content: messageContent,
|
|
3562
3524
|
},
|
|
3563
|
-
]
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
content: systemPrompt,
|
|
3571
|
-
},
|
|
3572
|
-
{
|
|
3573
|
-
role: 'user',
|
|
3574
|
-
content: messageContent,
|
|
3575
|
-
},
|
|
3576
|
-
],
|
|
3577
|
-
};
|
|
3578
|
-
console.log(JSON.stringify(analysisPayload, null, 2));
|
|
3579
|
-
const completion = await ai.getCompletions(analysisPayload);
|
|
3580
|
-
const analysisResult = completion.choices[0]?.message?.content;
|
|
3581
|
-
if (!analysisResult) {
|
|
3582
|
-
throw new Error('No response from AI model');
|
|
3583
|
-
}
|
|
3584
|
-
return {
|
|
3585
|
-
content: [
|
|
3586
|
-
{
|
|
3587
|
-
type: 'text',
|
|
3588
|
-
text: JSON.stringify({
|
|
3589
|
-
success: true,
|
|
3590
|
-
mediaFileName,
|
|
3591
|
-
mediaType: fileExtension,
|
|
3592
|
-
analysisRequest,
|
|
3593
|
-
captionsFileName,
|
|
3594
|
-
captionsContent: captionsText,
|
|
3595
|
-
analysis: analysisResult,
|
|
3596
|
-
mediaUrl,
|
|
3597
|
-
timestamp: new Date().toISOString(),
|
|
3598
|
-
nextActionSuggest: '可根据字幕内容和分析结果进行后续创作,如生成相关视频、配音或其他素材。',
|
|
3599
|
-
}),
|
|
3600
|
-
},
|
|
3601
|
-
],
|
|
3602
|
-
};
|
|
3525
|
+
],
|
|
3526
|
+
};
|
|
3527
|
+
console.log(JSON.stringify(analysisPayload, null, 2));
|
|
3528
|
+
const responses = await ai.getResponses(analysisPayload);
|
|
3529
|
+
const analysisResult = responses.output?.find((item) => item.type === 'message')?.content?.[0]?.text;
|
|
3530
|
+
if (!analysisResult) {
|
|
3531
|
+
throw new Error('No response from AI model');
|
|
3603
3532
|
}
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
console.warn('Failed to generate captions:', captionError);
|
|
3607
|
-
messageContent = [
|
|
3533
|
+
return {
|
|
3534
|
+
content: [
|
|
3608
3535
|
{
|
|
3609
3536
|
type: 'text',
|
|
3610
|
-
text:
|
|
3537
|
+
text: JSON.stringify({
|
|
3538
|
+
success: true,
|
|
3539
|
+
mediaFileName,
|
|
3540
|
+
mediaType: fileExtension,
|
|
3541
|
+
analysisRequest,
|
|
3542
|
+
captionsFileName,
|
|
3543
|
+
captionsContent: captionsText,
|
|
3544
|
+
analysis: analysisResult,
|
|
3545
|
+
mediaUrl,
|
|
3546
|
+
timestamp: new Date().toISOString(),
|
|
3547
|
+
nextActionSuggest: '可根据字幕内容和分析结果进行后续创作,如生成相关视频、配音或其他素材。',
|
|
3548
|
+
}),
|
|
3611
3549
|
},
|
|
3612
|
-
]
|
|
3613
|
-
}
|
|
3614
|
-
}
|
|
3615
|
-
else {
|
|
3616
|
-
throw new Error(`Unsupported media type: ${fileExtension}`);
|
|
3550
|
+
],
|
|
3551
|
+
};
|
|
3617
3552
|
}
|
|
3618
|
-
// 调用AI模型进行媒体内容分析
|
|
3619
3553
|
const ai = currentSession.ai;
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
{
|
|
3624
|
-
role: 'system',
|
|
3625
|
-
content: systemPrompt,
|
|
3626
|
-
},
|
|
3627
|
-
{
|
|
3628
|
-
role: 'user',
|
|
3629
|
-
content: messageContent,
|
|
3630
|
-
},
|
|
3631
|
-
],
|
|
3632
|
-
};
|
|
3633
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
3634
|
-
const completion = await ai.getCompletions(payload);
|
|
3635
|
-
console.log(completion);
|
|
3636
|
-
const result = completion.choices[0]?.message?.content;
|
|
3637
|
-
if (!result) {
|
|
3638
|
-
throw new Error('No response from AI model');
|
|
3554
|
+
let type = 'video';
|
|
3555
|
+
if (['jpeg', 'jpg', 'png', 'webp'].includes(fileExtension)) {
|
|
3556
|
+
type = 'image';
|
|
3639
3557
|
}
|
|
3558
|
+
const result = await ai.analyzeMedia({
|
|
3559
|
+
mediaUrl,
|
|
3560
|
+
type,
|
|
3561
|
+
prompt: analysisRequest,
|
|
3562
|
+
});
|
|
3640
3563
|
const metadata = await ai.getMediaMetadata(mediaUrl);
|
|
3641
3564
|
return {
|
|
3642
3565
|
content: [
|