mirror of
https://github.com/vastxie/99AI.git
synced 2025-09-17 09:16:38 +08:00
248 lines
12 KiB
JavaScript
248 lines
12 KiB
JavaScript
"use strict";
|
||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||
};
|
||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||
};
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
exports.SunoService = void 0;
|
||
const common_1 = require("@nestjs/common");
|
||
const axios_1 = require("axios");
|
||
const chatLog_service_1 = require("../chatLog/chatLog.service");
|
||
let SunoService = class SunoService {
|
||
constructor(chatLogService) {
|
||
this.chatLogService = chatLogService;
|
||
}
|
||
async suno(inputs) {
|
||
var _a, _b, _c;
|
||
const { apiKey, proxyUrl, action, prompt, timeout, assistantLogId, taskData, extraParam, } = inputs;
|
||
let result = {
|
||
text: '',
|
||
fileInfo: '',
|
||
taskId: '',
|
||
taskData: '',
|
||
status: 2,
|
||
};
|
||
common_1.Logger.log('开始生成音乐', 'SunoService');
|
||
let response = null;
|
||
let url = '';
|
||
let payloadJson = {};
|
||
const headers = { Authorization: `Bearer ${apiKey}` };
|
||
if (action === 'LYRICS') {
|
||
url = `${proxyUrl}/task/suno/v1/submit/lyrics`;
|
||
payloadJson = { prompt: prompt };
|
||
}
|
||
if (action === 'MUSIC') {
|
||
url = `${proxyUrl}/task/suno/v1/submit/music`;
|
||
try {
|
||
payloadJson = JSON.parse(taskData);
|
||
}
|
||
catch (error) {
|
||
common_1.Logger.error(`解析taskData失败: ${error.message}`, 'SunoService');
|
||
throw new Error('taskData格式错误');
|
||
}
|
||
}
|
||
common_1.Logger.log(`正在准备发送请求到 ${url},payload: ${JSON.stringify(payloadJson)}, headers: ${JSON.stringify(headers)}`);
|
||
try {
|
||
response = await axios_1.default.post(url, payloadJson, { headers });
|
||
}
|
||
catch (error) {
|
||
common_1.Logger.error(`任务提交失败: ${error.message}`, 'SunoService');
|
||
throw new Error('任务提交失败');
|
||
}
|
||
if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.data) {
|
||
result.taskId = (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.data;
|
||
common_1.Logger.log(`任务提交成功, 任务ID: ${(_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.data}`, 'SunoService');
|
||
}
|
||
else {
|
||
throw new Error('未能获取结果数据, 即将重试');
|
||
}
|
||
try {
|
||
await this.pollSunoMusicResult({
|
||
proxyUrl,
|
||
apiKey,
|
||
taskId: response.data.data,
|
||
timeout,
|
||
prompt,
|
||
action,
|
||
onSuccess: async (data) => {
|
||
try {
|
||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||
videoUrl: data === null || data === void 0 ? void 0 : data.videoUrl,
|
||
audioUrl: data === null || data === void 0 ? void 0 : data.audioUrl,
|
||
fileInfo: data === null || data === void 0 ? void 0 : data.fileInfo,
|
||
answer: (data === null || data === void 0 ? void 0 : data.answer) || prompt,
|
||
progress: '100%',
|
||
status: 3,
|
||
taskId: data === null || data === void 0 ? void 0 : data.taskId,
|
||
taskData: data === null || data === void 0 ? void 0 : data.taskData,
|
||
});
|
||
common_1.Logger.log('音乐任务已完成', 'SunoService');
|
||
}
|
||
catch (error) {
|
||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'SunoService');
|
||
}
|
||
},
|
||
onAudioSuccess: async (data) => {
|
||
try {
|
||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||
videoUrl: data === null || data === void 0 ? void 0 : data.videoUrl,
|
||
audioUrl: data === null || data === void 0 ? void 0 : data.audioUrl,
|
||
fileInfo: data === null || data === void 0 ? void 0 : data.fileInfo,
|
||
answer: (data === null || data === void 0 ? void 0 : data.answer) || prompt,
|
||
progress: data === null || data === void 0 ? void 0 : data.progress,
|
||
status: data.status,
|
||
taskId: data === null || data === void 0 ? void 0 : data.taskId,
|
||
taskData: data === null || data === void 0 ? void 0 : data.taskData,
|
||
});
|
||
common_1.Logger.log('音频生成成功,等待视频生成...', 'SunoService');
|
||
}
|
||
catch (error) {
|
||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'SunoService');
|
||
}
|
||
},
|
||
onGenerating: async (data) => {
|
||
try {
|
||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||
videoUrl: data === null || data === void 0 ? void 0 : data.videoUrl,
|
||
audioUrl: data === null || data === void 0 ? void 0 : data.audioUrl,
|
||
fileInfo: data === null || data === void 0 ? void 0 : data.fileInfo,
|
||
answer: (data === null || data === void 0 ? void 0 : data.answer) || '音乐生成中...',
|
||
progress: data === null || data === void 0 ? void 0 : data.progress,
|
||
status: data.status,
|
||
});
|
||
common_1.Logger.log('音乐生成中...', 'SunoService');
|
||
}
|
||
catch (error) {
|
||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'SunoService');
|
||
}
|
||
},
|
||
onFailure: async (data) => {
|
||
try {
|
||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||
answer: '音乐生成失败',
|
||
status: data.status,
|
||
});
|
||
common_1.Logger.log('生成失败', 'SunoService');
|
||
}
|
||
catch (error) {
|
||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'SunoService');
|
||
}
|
||
},
|
||
});
|
||
}
|
||
catch (error) {
|
||
common_1.Logger.error('查询生成结果时发生错误:', error.message, 'SunoService');
|
||
throw new Error('查询生成结果时发生错误');
|
||
}
|
||
return result;
|
||
}
|
||
async pollSunoMusicResult(inputs) {
|
||
const { proxyUrl, apiKey, taskId, timeout, onSuccess, onAudioSuccess, onFailure, onGenerating, action, } = inputs;
|
||
let result = {
|
||
videoUrl: '',
|
||
audioUrl: '',
|
||
fileInfo: '',
|
||
drawId: '',
|
||
taskData: '',
|
||
status: 2,
|
||
progress: 0,
|
||
answer: '',
|
||
};
|
||
const headers = { Authorization: `Bearer ${apiKey}` };
|
||
const url = `${proxyUrl}/task/suno/v1/fetch/${taskId}`;
|
||
const startTime = Date.now();
|
||
const POLL_INTERVAL = 5000;
|
||
let retryCount = 0;
|
||
try {
|
||
while (Date.now() - startTime < timeout) {
|
||
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
|
||
try {
|
||
const res = await axios_1.default.get(url, { headers });
|
||
const responses = res.data.data;
|
||
if (action === 'LYRICS') {
|
||
if (responses.status === 'SUCCESS') {
|
||
result.taskId = responses.data.id;
|
||
result.taskData = JSON.stringify(responses.data);
|
||
result.answer = responses.data.text;
|
||
onSuccess(result);
|
||
return;
|
||
}
|
||
result.progress = responses === null || responses === void 0 ? void 0 : responses.progress;
|
||
result.answer = `歌词生成中`;
|
||
if (result.progress) {
|
||
onGenerating(result);
|
||
}
|
||
}
|
||
if (action === 'MUSIC') {
|
||
const data = responses.data;
|
||
if (responses.data) {
|
||
const data = responses.data;
|
||
result.taskData = JSON.stringify(data);
|
||
if (Array.isArray(data)) {
|
||
const validAudioUrls = data
|
||
.map((item) => item.audio_url)
|
||
.filter((url) => url);
|
||
const validVideoUrls = data
|
||
.map((item) => item.video_url)
|
||
.filter((url) => url);
|
||
const validImageUrls = data
|
||
.map((item) => item.image_url)
|
||
.filter((url) => url);
|
||
const titles = data.map((item) => item.title);
|
||
const firstTitle = titles.length > 0 ? titles[0] : '音乐已生成';
|
||
const audioUrls = validAudioUrls.join(',');
|
||
const videoUrls = validVideoUrls.join(',');
|
||
const imageUrls = validImageUrls.join(',');
|
||
result.audioUrl = audioUrls;
|
||
result.videoUrl = videoUrls;
|
||
result.fileInfo = imageUrls;
|
||
if (validAudioUrls.length === 2) {
|
||
result.status = 3;
|
||
result.answer = firstTitle;
|
||
}
|
||
else {
|
||
result.status = 2;
|
||
result.progress = responses === null || responses === void 0 ? void 0 : responses.progress;
|
||
result.answer = `当前生成进度 ${responses === null || responses === void 0 ? void 0 : responses.progress}`;
|
||
}
|
||
onAudioSuccess(result);
|
||
}
|
||
}
|
||
if (responses.status === 'SUCCESS') {
|
||
common_1.Logger.debug(`音乐生成成功: ${JSON.stringify(data)}`, 'SunoService');
|
||
onSuccess(result);
|
||
return;
|
||
}
|
||
if (result.progress && result.status === 2) {
|
||
onGenerating(result);
|
||
}
|
||
}
|
||
}
|
||
catch (error) {
|
||
retryCount++;
|
||
common_1.Logger.error(`轮询失败,重试次数: ${retryCount}`, 'SunoService');
|
||
}
|
||
}
|
||
common_1.Logger.error('轮询超时,请稍后再试!', 'SunoService');
|
||
result.status = 4;
|
||
onFailure(result);
|
||
throw new Error('查询超时,请稍后再试!');
|
||
}
|
||
catch (error) {
|
||
common_1.Logger.error(`轮询过程中发生错误: ${error}`, 'SunoService');
|
||
result.status = 5;
|
||
onFailure(result);
|
||
}
|
||
}
|
||
};
|
||
SunoService = __decorate([
|
||
(0, common_1.Injectable)(),
|
||
__metadata("design:paramtypes", [chatLog_service_1.ChatLogService])
|
||
], SunoService);
|
||
exports.SunoService = SunoService;
|