mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	【代码评审】AI:音乐接入
This commit is contained in:
		| @@ -118,8 +118,9 @@ public class YudaoAiProperties { | ||||
|     public static class SunoProperties { | ||||
|  | ||||
|         private boolean enable = false; | ||||
|  | ||||
|         /** | ||||
|          * suno-api 服务的基本地址 | ||||
|          * API 服务的基本地址 | ||||
|          */ | ||||
|         private String baseUrl; | ||||
|  | ||||
|   | ||||
| @@ -4,16 +4,20 @@ import lombok.AllArgsConstructor; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
|  | ||||
| // TODO @xin:不需要这个类哈,直接 SunoApi 传入 baseUrl 参数即可 | ||||
| /** | ||||
|  * @Author xiaoxin | ||||
|  * @Date 2024/5/29 | ||||
|  * Suno 配置类 | ||||
|  * | ||||
|  * @author  xiaoxin | ||||
|  */ | ||||
| @Data | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| public class SunoConfig { | ||||
|  | ||||
|     /** | ||||
|      * suno-api服务的基本路径 | ||||
|      */ | ||||
|     private String baseUrl; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -27,14 +27,15 @@ import java.util.function.Predicate; | ||||
| public class SunoApi { | ||||
|  | ||||
|     private final WebClient webClient; | ||||
|  | ||||
|     private final Predicate<HttpStatusCode> STATUS_PREDICATE = status -> !status.is2xxSuccessful(); | ||||
|     private final Function<ClientResponse, Mono<? extends Throwable>> EXCEPTION_FUNCTION = response -> response.bodyToMono(String.class) | ||||
|             .handle((respBody, sink) -> { | ||||
|                 // TODO @xin:最好是 request、response 都有哈 | ||||
|                 log.error("【suno-api】调用失败!resp: 【{}】", respBody); | ||||
|                 sink.error(new IllegalStateException("【suno-api】调用失败!")); | ||||
|             }); | ||||
|  | ||||
|  | ||||
|     public SunoApi(SunoConfig config) { | ||||
|         this.webClient = WebClient.builder() | ||||
|                 .baseUrl(config.getBaseUrl()) | ||||
| @@ -42,50 +43,49 @@ public class SunoApi { | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
|     public List<MusicData> generate(SunoApi.SunoReq sunReq) { | ||||
|     public List<MusicData> generate(SunoRequest request) { | ||||
|         return this.webClient.post() | ||||
|                 .uri("/api/generate") | ||||
|                 .body(Mono.just(sunReq), SunoApi.SunoReq.class) | ||||
|                 .body(Mono.just(request), SunoRequest.class) | ||||
|                 .retrieve() | ||||
|                 .onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION) | ||||
|                 .bodyToMono(new ParameterizedTypeReference<List<MusicData>>() { | ||||
|                 }) | ||||
|                 .bodyToMono(new ParameterizedTypeReference<List<MusicData>>() { }) | ||||
|                 .block(); | ||||
|     } | ||||
|  | ||||
|     public List<MusicData> customGenerate(SunoApi.SunoReq sunReq) { | ||||
|     public List<MusicData> customGenerate(SunoRequest request) { | ||||
|         return this.webClient.post() | ||||
|                 .uri("/api/custom_generate") | ||||
|                 .body(Mono.just(sunReq), SunoApi.SunoReq.class) | ||||
|                 .body(Mono.just(request), SunoRequest.class) | ||||
|                 .retrieve() | ||||
|                 .onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION) | ||||
|                 .bodyToMono(new ParameterizedTypeReference<List<MusicData>>() { | ||||
|                 }) | ||||
|                 .bodyToMono(new ParameterizedTypeReference<List<MusicData>>() { }) | ||||
|                 .block(); | ||||
|     } | ||||
|  | ||||
|     // TODO @xin: 是不是叫 chatCompletion | ||||
|     public List<MusicData> doChatCompletion(String prompt) { | ||||
|         return this.webClient.post() | ||||
|                 .uri("/v1/chat/completions") | ||||
|                 .body(Mono.just(new SunoReq(prompt)), SunoApi.SunoReq.class) | ||||
|                 .body(Mono.just(new SunoRequest(prompt)), SunoRequest.class) | ||||
|                 .retrieve() | ||||
|                 .onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION) | ||||
|                 .bodyToMono(new ParameterizedTypeReference<List<MusicData>>() { | ||||
|                 }) | ||||
|                 .bodyToMono(new ParameterizedTypeReference<List<MusicData>>() { }) | ||||
|                 .block(); | ||||
|     } | ||||
|  | ||||
|     public LyricsData generateLyrics(String prompt) { | ||||
|         return this.webClient.post() | ||||
|                 .uri("/api/generate_lyrics") | ||||
|                 .body(Mono.just(new SunoReq(prompt)), SunoApi.SunoReq.class) | ||||
|                 .body(Mono.just(new SunoRequest(prompt)), SunoRequest.class) | ||||
|                 .retrieve() | ||||
|                 .onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION) | ||||
|                 .bodyToMono(LyricsData.class) | ||||
|                 .block(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     // TODO @xin:应该传入 List<String> ids | ||||
|     // TODO @xin:方法名,建议使用 getMusicList | ||||
|     public List<MusicData> selectById(String ids) { | ||||
|         return this.webClient.get() | ||||
|                 .uri(uriBuilder -> uriBuilder | ||||
| @@ -94,12 +94,11 @@ public class SunoApi { | ||||
|                         .build()) | ||||
|                 .retrieve() | ||||
|                 .onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION) | ||||
|                 .bodyToMono(new ParameterizedTypeReference<List<MusicData>>() { | ||||
|                 }) | ||||
|                 .bodyToMono(new ParameterizedTypeReference<List<MusicData>>() { }) | ||||
|                 .block(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     // TODO @xin:方法名,建议使用 getLimitUsage | ||||
|     public LimitData selectLimit() { | ||||
|         return this.webClient.get() | ||||
|                 .uri("/api/get_limit") | ||||
| @@ -109,7 +108,7 @@ public class SunoApi { | ||||
|                 .block(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     // TODO @xin:可以改成 MusicGenerateRequest | ||||
|     /** | ||||
|      * 根据提示生成音频 | ||||
|      * | ||||
| @@ -117,12 +116,12 @@ public class SunoApi { | ||||
|      * @param tags             音乐风格 | ||||
|      * @param title            音乐名称 | ||||
|      * @param mv               模型 | ||||
|      * @param waitAudio        false表示后台模式,仅返回音频任务信息,需要调用get API获取详细的音频信息。 | ||||
|      *                         true表示同步模式,API最多等待100s,音频生成完毕后直接返回音频链接等信息,建议在GPT等agent中使用。 | ||||
|      * @param waitAudio        false 表示后台模式,仅返回音频任务信息,需要调用 get API 获取详细的音频信息。 | ||||
|      *                         true 表示同步模式,API 最多等待 100s,音频生成完毕后直接返回音频链接等信息,建议在 GPT 等 agent 中使用。 | ||||
|      * @param makeInstrumental 指示音乐音频是否为定制,如果为 true,则从歌词生成,否则从提示生成 | ||||
|      */ | ||||
|     @JsonInclude(value = JsonInclude.Include.NON_NULL) | ||||
|     public record SunoReq( | ||||
|     public record SunoRequest( | ||||
|             String prompt, | ||||
|             String tags, | ||||
|             String title, | ||||
| @@ -130,23 +129,23 @@ public class SunoApi { | ||||
|             @JsonProperty("wait_audio") boolean waitAudio, | ||||
|             @JsonProperty("make_instrumental") boolean makeInstrumental | ||||
|     ) { | ||||
|         public SunoReq(String prompt) { | ||||
|  | ||||
|         public SunoRequest(String prompt) { | ||||
|             this(prompt, null, null, null, false, false); | ||||
|         } | ||||
|  | ||||
|         public SunoReq(String prompt, String mv, boolean makeInstrumental) { | ||||
|         public SunoRequest(String prompt, String mv, boolean makeInstrumental) { | ||||
|             this(prompt, null, null, mv, false, makeInstrumental); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public SunoReq(String prompt, String mv, String tags, String title) { | ||||
|         public SunoRequest(String prompt, String mv, String tags, String title) { | ||||
|             this(prompt, tags, title, mv, false, false); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * SunoAPI 响应的音频数据。 | ||||
|      * Suno API 响应的音频数据 | ||||
|      * | ||||
|      * @param id                   音乐数据的 ID | ||||
|      * @param title                音乐音频的标题 | ||||
| @@ -179,9 +178,8 @@ public class SunoApi { | ||||
|     ) { | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * SunoAPI 响应的歌词数据。 | ||||
|      * Suno API 响应的歌词数据。 | ||||
|      * | ||||
|      * @param text   歌词 | ||||
|      * @param title  标题 | ||||
| @@ -194,9 +192,8 @@ public class SunoApi { | ||||
|     ) { | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * SunoAPI 响应的限额数据,目前每日免费50 | ||||
|      * Suno API 响应的限额数据,目前每日免费50 | ||||
|      */ | ||||
|     public record LimitData( | ||||
|             @JsonProperty("credits_left") Long creditsLeft, | ||||
| @@ -206,5 +203,4 @@ public class SunoApi { | ||||
|     ) { | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -29,7 +29,7 @@ public class SunoTests { | ||||
|  | ||||
|     @Test | ||||
|     public void generate() { | ||||
|         List<SunoApi.MusicData> generate = sunoApi.generate(new SunoApi.SunoReq("创作一首带有轻松吉他旋律的流行歌曲,[verse] 描述夏日海滩的宁静,[chorus] 节奏加快,表达对自由的向往。")); | ||||
|         List<SunoApi.MusicData> generate = sunoApi.generate(new SunoApi.SunoRequest("创作一首带有轻松吉他旋律的流行歌曲,[verse] 描述夏日海滩的宁静,[chorus] 节奏加快,表达对自由的向往。")); | ||||
|         System.out.println(generate); | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV