From 447526a6d9c31cce93a27da4176a345f881baf6f Mon Sep 17 00:00:00 2001 From: xiaoxin <718949661@qq.com> Date: Mon, 27 May 2024 15:44:55 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91AI=EF=BC=9A?= =?UTF-8?q?suno?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/ai/core/model/suno/SunoApi.java | 175 ++++++++++++++++++ .../yudao/framework/ai/suno/SunoTests.java | 24 +++ 2 files changed, 199 insertions(+) create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/suno/SunoApi.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/suno/SunoTests.java diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/suno/SunoApi.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/suno/SunoApi.java new file mode 100644 index 000000000..0198197f1 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/suno/SunoApi.java @@ -0,0 +1,175 @@ +package cn.iocoder.yudao.framework.ai.core.model.suno; + + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.Data; +import lombok.experimental.Accessors; +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @Author xiaoxin + * @Date 2024/5/27 + */ +@Slf4j +public class SunoApi { + + public static final String APPLICATION_JSON = "application/json"; + public static final String TOKEN_PREFIX = "Bearer "; + public static final String API_URL = "https://api.acedata.cloud/suno/audios"; + public static final String TEST_TOKEN = "13f13540dd3f4ae9885f63ac9f5d0b9f"; + private static final int READ_TIMEOUT = 160; // 连接超时时间(秒),音乐生成时间较长,设置为 160s,后续可做callback + private final OkHttpClient client; + private final ObjectMapper objectMapper; + + public SunoApi() { + this.client = new OkHttpClient().newBuilder().readTimeout(READ_TIMEOUT, TimeUnit.SECONDS).build(); + this.objectMapper = new ObjectMapper(); + } + + public SunoResponse generateMusic(SunoRequest sunoRequest) throws IOException { + Request request = new Request.Builder() + .url(API_URL) + .header("Authorization", TOKEN_PREFIX + TEST_TOKEN) + .post(RequestBody.create(MediaType.parse(APPLICATION_JSON), objectMapper.writeValueAsString(sunoRequest))) + .build(); + + try (Response response = client.newCall(request).execute()) { + if (!response.isSuccessful()) { + log.error("suno调用失败! response: {}", response); + throw new IllegalStateException("suno调用失败!" + response); + } + return objectMapper.readValue(response.body().string(), SunoResponse.class); + } + } + + + /** + * 请求数据对象,用于生成音乐音频 + */ + @Data + @Accessors(chain = true) + @JsonInclude(value = JsonInclude.Include.NON_NULL) + public static class SunoRequest { + /** + * 用于生成音乐音频的提示 + */ + private String prompt; + + /** + * 用于生成音乐音频的歌词 + */ + private String lyric; + + /** + * 指示音乐音频是否为定制,如果为 true,则从歌词生成,否则从提示生成 + */ + private boolean custom; + + /** + * 音乐音频的标题 + */ + private String title; + + /** + * 音乐音频的风格 + */ + private String style; + + /** + * 音乐音频生成后回调的 URL + */ + private String callbackUrl; + } + + + /** + * API 响应的数据 + */ + @Data + public static class SunoResponse { + /** + * 表示请求是否成功 + */ + private boolean success; + + /** + * 任务 ID + */ + @JsonProperty("task_id") + private String taskId; + + /** + * 音乐数据列表 + */ + private List data; + + /** + * 表示单个音乐数据的类 + */ + @Data + static class MusicData { + /** + * 音乐数据的 ID + */ + private String id; + + /** + * 音乐音频的标题 + */ + private String title; + + /** + * 音乐音频的图片 URL + */ + @JsonProperty("image_url") + private String imageUrl; + + /** + * 音乐音频的歌词 + */ + private String lyric; + + /** + * 音乐音频的 URL + */ + @JsonProperty("audio_url") + private String audioUrl; + + /** + * 音乐视频的 URL + */ + @JsonProperty("video_url") + private String videoUrl; + + /** + * 音乐音频的创建时间 + */ + @JsonProperty("created_at") + private String createdAt; + + /** + * 使用的模型名称 + */ + private String model; + + /** + * 生成音乐音频的提示 + */ + private String prompt; + + /** + * 音乐音频的风格 + */ + private String style; + } + } + + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/suno/SunoTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/suno/SunoTests.java new file mode 100644 index 000000000..30883a6e1 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/suno/SunoTests.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.framework.ai.suno; + +import cn.iocoder.yudao.framework.ai.core.model.suno.SunoApi; +import org.junit.Test; + +import java.io.IOException; + +/** + * @Author xiaoxin + * @Date 2024/5/27 + */ +public class SunoTests { + + + @Test + public void generateMusic() throws IOException { + SunoApi sunoApi = new SunoApi(); + SunoApi.SunoRequest sunoRequest = new SunoApi + .SunoRequest() + .setPrompt("创作一首带有轻松吉他旋律的流行歌曲,[verse] 描述夏日海滩的宁静,[chorus] 节奏加快,表达对自由的向往。"); + SunoApi.SunoResponse sunoResponse = sunoApi.generateMusic(sunoRequest); + System.out.println(sunoResponse); + } +}