main
HuangHai 2 months ago
parent 110da5b52b
commit 146fb07209

@ -0,0 +1,260 @@
package com.dsideal.aiSupport.Util.Suno;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dsideal.aiSupport.Plugin.YamlProp;
import com.dsideal.aiSupport.Util.Midjourney.Kit.MjCommon;
import com.jfinal.kit.Prop;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static com.dsideal.aiSupport.AiSupportApplication.getEnvPrefix;
public class SunoMusicGenerator {
private static final String GENERATE_URL = "https://goapi.gptnb.ai/suno/v2/generate";
private static final String FEED_URL = "https://goapi.gptnb.ai/suno/v2/feed";
private static final int MAX_RETRIES = 30; // 最大重试次数
private static final int RETRY_INTERVAL = 5000; // 重试间隔(毫秒)
private static final Logger log = LoggerFactory.getLogger(SunoMusicGenerator.class);
// 获取项目根目录路径
protected static String projectRoot = System.getProperty("user.dir").replace("\\","/")+"/dsAiSupport";
// 拼接相对路径
protected static String basePath = projectRoot + "/src/main/java/com/dsideal/aiSupport/Util/Suno/Example/";
protected static String ak; // 填写access key
public static Prop PropKit; // 配置文件工具
protected static final String BASE_URL = "https://goapi.gptnb.ai";
static {
//加载配置文件
String configFile = "application_{?}.yaml".replace("{?}", getEnvPrefix());
PropKit = new YamlProp(configFile);
ak = PropKit.get("GPTNB.sk");
}
public static void main(String[] args) throws IOException, InterruptedException {
// 创建OkHttpClient
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
// 1. 生成音乐
String musicDescription = "an anthemic dancepop song about dancing all night long";
System.out.println("开始生成音乐: " + musicDescription);
// 构建JSON请求体
JSONObject requestJson = new JSONObject();
requestJson.put("gpt_description_prompt", musicDescription);
requestJson.put("mv", "chirp-v3-5");
requestJson.put("prompt", "");
requestJson.put("make_instrumental", true);
// 创建请求
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, requestJson.toJSONString());
Request generateRequest = new Request.Builder()
.url(GENERATE_URL)
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer " + ak)
.build();
// 执行生成请求
Response generateResponse = client.newCall(generateRequest).execute();
// 处理生成响应
if (!generateResponse.isSuccessful()) {
System.out.println("音乐生成请求失败,状态码: " + generateResponse.code());
System.out.println("错误信息: " + generateResponse.message());
return;
}
String generateResponseBody = generateResponse.body().string();
System.out.println("音乐生成响应: " + generateResponseBody);
// 从响应中提取任务ID
JSONObject generateJson = JSON.parseObject(generateResponseBody);
String taskId = null;
// 根据响应格式提取任务ID
// 注意:这里需要根据实际的响应格式进行调整
if (generateJson.containsKey("id")) {
taskId = generateJson.getString("id");
} else if (generateJson.containsKey("task_id")) {
taskId = generateJson.getString("task_id");
} else if (generateJson.containsKey("clip_id")) {
taskId = generateJson.getString("clip_id");
}
if (taskId == null) {
System.out.println("无法从响应中提取任务ID无法继续查询");
return;
}
System.out.println("音乐生成任务已提交任务ID: " + taskId);
System.out.println("开始查询任务状态...");
// 存储任务ID列表
List<String> taskIds = new ArrayList<>();
taskIds.add(taskId);
// 2. 查询任务状态
boolean isComplete = false;
int retryCount = 0;
String audioUrl = null;
while (!isComplete && retryCount < MAX_RETRIES) {
// 等待一段时间再查询
Thread.sleep(RETRY_INTERVAL);
// 构建查询URL添加ids参数
HttpUrl.Builder urlBuilder = HttpUrl.parse(FEED_URL).newBuilder();
// 添加ids参数用逗号分隔多个ID
if (!taskIds.isEmpty()) {
// 注意这里我们查询的是clips的ID而不是生成任务的ID
// 从生成响应中获取clips的ID
List<String> clipIds = new ArrayList<>();
if (generateJson.containsKey("clips")) {
JSONArray clipsArray = generateJson.getJSONArray("clips");
for (int i = 0; i < clipsArray.size(); i++) {
JSONObject clip = clipsArray.getJSONObject(i);
if (clip.containsKey("id")) {
clipIds.add(clip.getString("id"));
}
}
}
// 如果找到了clips的ID则使用这些ID进行查询
if (!clipIds.isEmpty()) {
String idsParam = String.join(",", clipIds);
urlBuilder.addQueryParameter("ids", idsParam);
log.info("使用clips ID查询: {}", idsParam);
} else {
// 否则使用任务ID
String idsParam = String.join(",", taskIds);
urlBuilder.addQueryParameter("ids", idsParam);
log.info("使用任务ID查询: {}", idsParam);
}
}
// 创建查询请求
Request feedRequest = new Request.Builder()
.url(urlBuilder.build())
.method("GET", null)
.addHeader("Authorization", "Bearer " + ak)
.addHeader("Accept", "application/json") // 添加Accept头
.build();
log.info("查询URL: {}", urlBuilder.build());
// 执行查询请求
Response feedResponse = client.newCall(feedRequest).execute();
// 处理查询响应
if (!feedResponse.isSuccessful()) {
System.out.println("查询任务状态失败,状态码: " + feedResponse.code());
System.out.println("错误信息: " + feedResponse.message());
retryCount++;
continue;
}
String feedResponseBody = feedResponse.body().string();
JSONObject jsonResponse = JSON.parseObject(feedResponseBody);
JSONArray clips = jsonResponse.getJSONArray("clips");
if (clips != null && !clips.isEmpty()) {
// 遍历所有返回的音乐片段
for (int i = 0; i < clips.size(); i++) {
JSONObject clip = clips.getJSONObject(i);
String clipId = clip.getString("id");
String status = clip.getString("status");
String title = clip.getString("title");
System.out.println("\n查询结果 (第" + (retryCount + 1) + "次):");
System.out.println("ID: " + clipId);
System.out.println("标题: " + title);
System.out.println("状态: " + status);
// 检查是否是我们要查询的任务
if (taskIds.contains(clipId)) {
// 检查是否完成
if ("complete".equals(status)) {
audioUrl = clip.getString("audio_url");
System.out.println("音乐生成已完成!");
System.out.println("音频URL: " + audioUrl);
isComplete = true;
break; // 找到了我们要查询的任务,并且已完成
} else if ("streaming".equals(status)) {
System.out.println("音乐生成中,继续等待...");
} else if ("failed".equals(status)) {
System.out.println("音乐生成失败!");
isComplete = true; // 任务失败,不再继续查询
break;
}
}
}
} else {
System.out.println("未找到音乐片段,继续等待...");
}
retryCount++;
}
// 3. 下载音频文件(如果生成成功)
if (isComplete && audioUrl != null) {
String fileName = "suno_music_" + System.currentTimeMillis() + ".mp3";
String savePath = "./downloads/" + fileName;
downloadAudio(client, audioUrl, savePath);
} else if (retryCount >= MAX_RETRIES) {
System.out.println("达到最大重试次数,任务可能仍在处理中");
System.out.println("请稍后手动查询任务ID: " + taskId);
}
}
/**
*
* @param client OkHttpClient
* @param audioUrl URL
* @param savePath
*/
public static void downloadAudio(OkHttpClient client, String audioUrl, String savePath) throws IOException {
System.out.println("开始下载音频文件...");
Request request = new Request.Builder()
.url(audioUrl)
.method("GET", null)
.build();
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
// 确保目录存在
java.io.File file = new java.io.File(savePath);
java.io.File parentDir = file.getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs();
}
// 保存文件
try (java.io.InputStream inputStream = response.body().byteStream();
java.io.FileOutputStream outputStream = new java.io.FileOutputStream(savePath)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
}
System.out.println("音频下载成功,保存路径: " + savePath);
} else {
System.out.println("下载音频失败,状态码: " + response.code());
}
}
}
Loading…
Cancel
Save