refactor: Optimize code comments.
This commit is contained in:
parent
d7e879dda3
commit
c30a11744d
@ -6,23 +6,17 @@ export async function POST(req: NextRequest) {
|
|||||||
try {
|
try {
|
||||||
const body = await req.json();
|
const body = await req.json();
|
||||||
const { prompt, tags, title, make_instrumental, wait_audio } = body;
|
const { prompt, tags, title, make_instrumental, wait_audio } = body;
|
||||||
|
|
||||||
// 校验输入参数
|
|
||||||
if (!prompt || !tags || !title) {
|
if (!prompt || !tags || !title) {
|
||||||
return new NextResponse(JSON.stringify({ error: 'Prompt, tags, and title are required' }), {
|
return new NextResponse(JSON.stringify({ error: 'Prompt, tags, and title are required' }), {
|
||||||
status: 400,
|
status: 400,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用 SunoApi.custom_generate 方法生成定制音频
|
|
||||||
const audioInfo = await (await sunoApi).custom_generate(
|
const audioInfo = await (await sunoApi).custom_generate(
|
||||||
prompt, tags, title,
|
prompt, tags, title,
|
||||||
make_instrumental == true,
|
make_instrumental == true,
|
||||||
wait_audio == true
|
wait_audio == true
|
||||||
);
|
);
|
||||||
|
|
||||||
// 使用 NextResponse 构建成功响应
|
|
||||||
return new NextResponse(JSON.stringify(audioInfo), {
|
return new NextResponse(JSON.stringify(audioInfo), {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
@ -35,7 +29,6 @@ export async function POST(req: NextRequest) {
|
|||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 使用 NextResponse 构建错误响应
|
|
||||||
return new NextResponse(JSON.stringify({ error: 'Internal server error' }), {
|
return new NextResponse(JSON.stringify({ error: 'Internal server error' }), {
|
||||||
status: 500,
|
status: 500,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
|
@ -7,7 +7,6 @@ export async function POST(req: NextRequest) {
|
|||||||
const body = await req.json();
|
const body = await req.json();
|
||||||
const { prompt, make_instrumental, wait_audio } = body;
|
const { prompt, make_instrumental, wait_audio } = body;
|
||||||
|
|
||||||
// 校验输入参数
|
|
||||||
if (!prompt) {
|
if (!prompt) {
|
||||||
return new NextResponse(JSON.stringify({ error: 'Prompt is required' }), {
|
return new NextResponse(JSON.stringify({ error: 'Prompt is required' }), {
|
||||||
status: 400,
|
status: 400,
|
||||||
@ -15,10 +14,8 @@ export async function POST(req: NextRequest) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用 SunoApi.generate 方法生成音频
|
|
||||||
const audioInfo = await (await sunoApi).generate(prompt, make_instrumental == true, wait_audio == true);
|
const audioInfo = await (await sunoApi).generate(prompt, make_instrumental == true, wait_audio == true);
|
||||||
|
|
||||||
// 使用 NextResponse 构建成功响应
|
|
||||||
return new NextResponse(JSON.stringify(audioInfo), {
|
return new NextResponse(JSON.stringify(audioInfo), {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
@ -31,7 +28,6 @@ export async function POST(req: NextRequest) {
|
|||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 使用 NextResponse 构建错误响应
|
|
||||||
return new NextResponse(JSON.stringify({ error: 'Internal server error: ' + JSON.stringify(error.response.data.detail) }), {
|
return new NextResponse(JSON.stringify({ error: 'Internal server error: ' + JSON.stringify(error.response.data.detail) }), {
|
||||||
status: 500,
|
status: 500,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
|
@ -5,26 +5,23 @@ export const dynamic = "force-dynamic";
|
|||||||
export async function GET(req: NextRequest) {
|
export async function GET(req: NextRequest) {
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
try {
|
try {
|
||||||
// 修复了获取查询参数的方式
|
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const songIds = url.searchParams.get('ids');
|
const songIds = url.searchParams.get('ids');
|
||||||
let audioInfo = [];
|
let audioInfo = [];
|
||||||
if (songIds && songIds.length > 0) {
|
if (songIds && songIds.length > 0) {
|
||||||
const idsArray = songIds.split(',');
|
const idsArray = songIds.split(',');
|
||||||
// 调用 SunoApi.get 方法获取音频信息
|
|
||||||
audioInfo = await (await sunoApi).get(idsArray);
|
audioInfo = await (await sunoApi).get(idsArray);
|
||||||
} else {
|
} else {
|
||||||
audioInfo = await (await sunoApi).get();
|
audioInfo = await (await sunoApi).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用 NextResponse 构建成功响应
|
|
||||||
return new NextResponse(JSON.stringify(audioInfo), {
|
return new NextResponse(JSON.stringify(audioInfo), {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching audio:', error);
|
console.error('Error fetching audio:', error);
|
||||||
// 使用 NextResponse 构建错误响应
|
|
||||||
return new NextResponse(JSON.stringify({ error: 'Internal server error' }), {
|
return new NextResponse(JSON.stringify({ error: 'Internal server error' }), {
|
||||||
status: 500,
|
status: 500,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
|
@ -4,17 +4,17 @@ export const dynamic = "force-dynamic";
|
|||||||
export async function GET(req: NextRequest) {
|
export async function GET(req: NextRequest) {
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
try {
|
try {
|
||||||
// 调用 SunoApi.get_limit 方法获取剩余的信用额度
|
|
||||||
const limit = await (await sunoApi).get_credits();
|
const limit = await (await sunoApi).get_credits();
|
||||||
|
|
||||||
// 使用 NextResponse 构建成功响应
|
|
||||||
return new NextResponse(JSON.stringify(limit), {
|
return new NextResponse(JSON.stringify(limit), {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching limit:', error);
|
console.error('Error fetching limit:', error);
|
||||||
// 使用 NextResponse 构建错误响应
|
|
||||||
return new NextResponse(JSON.stringify({ error: 'Internal server error' }), {
|
return new NextResponse(JSON.stringify({ error: 'Internal server error' }), {
|
||||||
status: 500,
|
status: 500,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
|
@ -9,20 +9,20 @@ const logger = pino();
|
|||||||
|
|
||||||
|
|
||||||
export interface AudioInfo {
|
export interface AudioInfo {
|
||||||
id: string;
|
id: string; // Unique identifier for the audio
|
||||||
title?: string;
|
title?: string; // Title of the audio
|
||||||
image_url?: string;
|
image_url?: string; // URL of the image associated with the audio
|
||||||
lyric?: string;
|
lyric?: string; // Lyrics of the audio
|
||||||
audio_url?: string;
|
audio_url?: string; // URL of the audio file
|
||||||
video_url?: string;
|
video_url?: string; // URL of the video associated with the audio
|
||||||
created_at: string;
|
created_at: string; // Date and time when the audio was created
|
||||||
model_name: string;
|
model_name: string; // Name of the model used for audio generation
|
||||||
gpt_description_prompt?: string;
|
gpt_description_prompt?: string; // Prompt for GPT description
|
||||||
prompt?: string;
|
prompt?: string; // Prompt for audio generation
|
||||||
status: string;
|
status: string; // Status
|
||||||
type?: string;
|
type?: string;
|
||||||
tags?: string;
|
tags?: string; // Genre of music.
|
||||||
duration?: string;
|
duration?: string; // Duration of the audio
|
||||||
}
|
}
|
||||||
|
|
||||||
class SunoApi {
|
class SunoApi {
|
||||||
@ -45,7 +45,7 @@ class SunoApi {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
this.client.interceptors.request.use((config) => {
|
this.client.interceptors.request.use((config) => {
|
||||||
if (this.currentToken) { // 使用当前token的状态
|
if (this.currentToken) { // Use the current token status
|
||||||
config.headers['Authorization'] = `Bearer ${this.currentToken}`;
|
config.headers['Authorization'] = `Bearer ${this.currentToken}`;
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
@ -58,27 +58,33 @@ class SunoApi {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the session ID and save it for later use.
|
||||||
|
*/
|
||||||
private async getAuthToken() {
|
private async getAuthToken() {
|
||||||
// 获取会话ID的URL
|
// URL to get session ID
|
||||||
const getSessionUrl = `${SunoApi.CLERK_BASE_URL}/v1/client?_clerk_js_version=4.70.5`;
|
const getSessionUrl = `${SunoApi.CLERK_BASE_URL}/v1/client?_clerk_js_version=4.70.5`;
|
||||||
// 获取会话ID
|
// Get session ID
|
||||||
const sessionResponse = await this.client.get(getSessionUrl);
|
const sessionResponse = await this.client.get(getSessionUrl);
|
||||||
const sid = sessionResponse.data.response['last_active_session_id'];
|
const sid = sessionResponse.data.response['last_active_session_id'];
|
||||||
if (!sid) {
|
if (!sid) {
|
||||||
throw new Error("Failed to get session id");
|
throw new Error("Failed to get session id");
|
||||||
}
|
}
|
||||||
// 保存会话ID以备后用
|
// Save session ID for later use
|
||||||
this.sid = sid;
|
this.sid = sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep the session alive.
|
||||||
|
* @param isWait Indicates if the method should wait for the session to be fully renewed before returning.
|
||||||
|
*/
|
||||||
public async keepAlive(isWait?: boolean): Promise<void> {
|
public async keepAlive(isWait?: boolean): Promise<void> {
|
||||||
if (!this.sid) {
|
if (!this.sid) {
|
||||||
throw new Error("Session ID is not set. Cannot renew token.");
|
throw new Error("Session ID is not set. Cannot renew token.");
|
||||||
}
|
}
|
||||||
// 续订会话令牌的URL
|
// URL to renew session token
|
||||||
const renewUrl = `${SunoApi.CLERK_BASE_URL}/v1/client/sessions/${this.sid}/tokens/api?_clerk_js_version=4.70.0`;
|
const renewUrl = `${SunoApi.CLERK_BASE_URL}/v1/client/sessions/${this.sid}/tokens/api?_clerk_js_version=4.70.0`;
|
||||||
// 续订会话令牌
|
// Renew session token
|
||||||
const renewResponse = await this.client.post(renewUrl);
|
const renewResponse = await this.client.post(renewUrl);
|
||||||
logger.info("KeepAlive...\n");
|
logger.info("KeepAlive...\n");
|
||||||
if (isWait) {
|
if (isWait) {
|
||||||
@ -86,10 +92,17 @@ class SunoApi {
|
|||||||
}
|
}
|
||||||
const newToken = renewResponse.data['jwt'];
|
const newToken = renewResponse.data['jwt'];
|
||||||
console.log("newToken:===\n\n", newToken);
|
console.log("newToken:===\n\n", newToken);
|
||||||
// 更新请求头中的Authorization字段,使用新的JWT令牌
|
// Update Authorization field in request header with the new JWT token
|
||||||
this.currentToken = newToken;
|
this.currentToken = newToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a song based on the prompt.
|
||||||
|
* @param prompt The text prompt to generate audio from.
|
||||||
|
* @param make_instrumental Indicates if the generated audio should be instrumental.
|
||||||
|
* @param wait_audio Indicates if the method should wait for the audio file to be fully generated before returning.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
public async generate(
|
public async generate(
|
||||||
prompt: string,
|
prompt: string,
|
||||||
make_instrumental: boolean = false,
|
make_instrumental: boolean = false,
|
||||||
|
@ -3,9 +3,9 @@ import pino from "pino";
|
|||||||
const logger = pino();
|
const logger = pino();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 暂停指定的秒数。
|
* Pause for a specified number of seconds.
|
||||||
* @param x 最小秒数。
|
* @param x Minimum number of seconds.
|
||||||
* @param y 最大秒数(可选)。
|
* @param y Maximum number of seconds (optional).
|
||||||
*/
|
*/
|
||||||
export const sleep = (x: number, y?: number): Promise<void> => {
|
export const sleep = (x: number, y?: number): Promise<void> => {
|
||||||
let timeout = x * 1000;
|
let timeout = x * 1000;
|
||||||
|
Loading…
Reference in New Issue
Block a user