"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;