mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-13 11:53:48 +00:00
init v1.0.0
This commit is contained in:
@@ -12,15 +12,17 @@ public class OpenAIConst {
|
||||
|
||||
public final static int SUCCEED_CODE = 200;
|
||||
|
||||
public final static double GPT3_COST = 0.03;
|
||||
public final static double GPT3_COST = 0.05;
|
||||
|
||||
public final static double GPT4_COST = 0.3;
|
||||
|
||||
public final static double GPT4_ALL_COST = 0.3;
|
||||
|
||||
/** 绘图费用 */
|
||||
public final static double DALL3_COST = 0.3;
|
||||
public final static double DALL3_COST = 0.4;
|
||||
|
||||
/** 绘图费用-高清 */
|
||||
public final static double DALL3_HD_COST = 0.6;
|
||||
public final static double DALL3_HD_COST = 0.8;
|
||||
|
||||
/** mdjourney绘图费用 */
|
||||
public final static double MJ_COST = 0.3;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.xmzs.common.chat.domain.request;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* mj任务请求实体类
|
||||
*
|
||||
* @author WangLe
|
||||
*/
|
||||
@Data
|
||||
public class MjTaskRequest {
|
||||
|
||||
private String prompt;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.xmzs.common.chat.entity.Tts;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.*;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TextToSpeech {
|
||||
|
||||
@Builder.Default
|
||||
private String model = Model.TTS_1.getName();
|
||||
/**
|
||||
* 音频声音源
|
||||
*
|
||||
* @see TtsVoice
|
||||
*/
|
||||
private String voice;
|
||||
/**
|
||||
* 输入内容
|
||||
*/
|
||||
private String input;
|
||||
/**
|
||||
* 输出音频文件格式
|
||||
*
|
||||
* @see TtsFormat
|
||||
*/
|
||||
@JsonProperty("response_format")
|
||||
private String responseFormat;
|
||||
/**
|
||||
* 速度调节,默认是1,取值范围0.25——4.0
|
||||
*/
|
||||
private Double speed;
|
||||
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum Model {
|
||||
TTS_1("tts-1"),
|
||||
TTS_1_HD("tts-1-hd"),
|
||||
;
|
||||
private final String name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.xmzs.common.chat.entity.Tts;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum TtsFormat {
|
||||
MP3("mp3"),
|
||||
OPUS("opus"),
|
||||
AAC("aac"),
|
||||
FLAC("flac"),
|
||||
;
|
||||
private final String name;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.xmzs.common.chat.entity.Tts;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 生成不同声音的音频
|
||||
* <p>具体语音效果参考:https://platform.openai.com/docs/guides/text-to-speech</p>
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum TtsVoice {
|
||||
|
||||
ALLOY("alloy"),
|
||||
ECHO("echo"),
|
||||
FABLE("fable"),
|
||||
ONYX("onyx"),
|
||||
NOVA("nova"),
|
||||
SHIMMER("shimmer"),
|
||||
;
|
||||
|
||||
private final String name;
|
||||
}
|
||||
@@ -174,6 +174,10 @@ public class BaseChatCompletion implements Serializable {
|
||||
* gpt-3.5-turbo-16k-0613 超长上下文 支持函数
|
||||
*/
|
||||
GPT_3_5_TURBO_16K_0613("gpt-3.5-turbo-16k-0613"),
|
||||
/**
|
||||
* gpt-3.5-turbo-0125 超长上下文 支持函数
|
||||
*/
|
||||
GPT_3_5_TURBO_0125("gpt-3.5-turbo-0125"),
|
||||
/**
|
||||
* GPT4.0
|
||||
*/
|
||||
@@ -209,6 +213,10 @@ public class BaseChatCompletion implements Serializable {
|
||||
* 支持图片
|
||||
*/
|
||||
GPT_4_VISION_PREVIEW("gpt-4-vision-preview"),
|
||||
/**
|
||||
* gpt-4-0613,支持函数
|
||||
*/
|
||||
GPT_4_0125_PREVIEW("gpt-4-0125-preview"),
|
||||
;
|
||||
private final String name;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.xmzs.common.chat.openai;
|
||||
|
||||
import com.xmzs.common.chat.entity.Tts.TextToSpeech;
|
||||
import com.xmzs.common.chat.entity.chat.ChatCompletionWithPicture;
|
||||
import io.reactivex.Single;
|
||||
import okhttp3.MultipartBody;
|
||||
@@ -33,6 +34,7 @@ import com.xmzs.common.chat.entity.models.ModelResponse;
|
||||
import com.xmzs.common.chat.entity.moderations.Moderation;
|
||||
import com.xmzs.common.chat.entity.moderations.ModerationResponse;
|
||||
import com.xmzs.common.chat.entity.whisper.WhisperResponse;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
@@ -340,4 +342,15 @@ public interface OpenAiApi {
|
||||
*/
|
||||
@POST("v1/chat/completions")
|
||||
Single<ChatCompletionResponse> chatCompletionWithPicture(@Body ChatCompletionWithPicture chatCompletion);
|
||||
|
||||
/**
|
||||
* 文本转语音
|
||||
*
|
||||
* @param textToSpeech 参数
|
||||
* @return ResponseBody body
|
||||
* @since 1.1.2
|
||||
*/
|
||||
@POST("v1/audio/speech")
|
||||
@Streaming
|
||||
Call<ResponseBody> textToSpeech(@Body TextToSpeech textToSpeech);
|
||||
}
|
||||
|
||||
@@ -668,7 +668,6 @@ public class OpenAiClient {
|
||||
return this.chatCompletion(chatCompletion);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 语音翻译:目前仅支持翻译为英文
|
||||
*
|
||||
|
||||
@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.xmzs.common.chat.config.LocalCache;
|
||||
import com.xmzs.common.chat.entity.Tts.TextToSpeech;
|
||||
import com.xmzs.common.chat.entity.billing.BillingUsage;
|
||||
import com.xmzs.common.chat.entity.billing.KeyInfo;
|
||||
import com.xmzs.common.chat.entity.billing.Subscription;
|
||||
@@ -37,10 +38,12 @@ import com.xmzs.common.chat.entity.chat.ChatCompletion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
||||
import retrofit2.converter.jackson.JacksonConverterFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
@@ -344,6 +347,67 @@ public class OpenAiStreamClient {
|
||||
Transcriptions transcriptions = Transcriptions.builder().build();
|
||||
return this.speechToTextTranscriptions(file, transcriptions);
|
||||
}
|
||||
/**
|
||||
* 文本转语音(异步)
|
||||
*
|
||||
* @param textToSpeech 参数
|
||||
* @param callback 返回值接收
|
||||
* @since 1.1.2
|
||||
*/
|
||||
public void textToSpeech(TextToSpeech textToSpeech, retrofit2.Callback callback) {
|
||||
retrofit2.Call<ResponseBody> responseBody = this.openAiApi.textToSpeech(textToSpeech);
|
||||
responseBody.enqueue(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本转语音(同步)
|
||||
*
|
||||
* @param textToSpeech 参数
|
||||
* @since 1.1.3
|
||||
*/
|
||||
public ResponseBody textToSpeech(TextToSpeech textToSpeech){
|
||||
Call<ResponseBody> responseBody = this.openAiApi.textToSpeech(textToSpeech);
|
||||
try {
|
||||
return responseBody.execute().body();
|
||||
} catch (IOException e) {
|
||||
throw new BaseException("文本转语音(同步)失败: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本转语音(克隆)
|
||||
*
|
||||
* @param textToSpeech
|
||||
* @return
|
||||
*/
|
||||
public ResponseBody textToSpeechClone(TextToSpeech textToSpeech) {
|
||||
String baseUrl = "http://localhost:8081";
|
||||
String spk = "三月七";
|
||||
String text = textToSpeech.getInput();
|
||||
String lang = "zh";
|
||||
|
||||
// 创建OkHttpClient实例
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
|
||||
// 构建请求URL
|
||||
HttpUrl.Builder urlBuilder = HttpUrl.parse(baseUrl).newBuilder();
|
||||
urlBuilder.addQueryParameter("spk", spk);
|
||||
urlBuilder.addQueryParameter("text", text);
|
||||
urlBuilder.addQueryParameter("lang", lang);
|
||||
String url = urlBuilder.build().toString();
|
||||
|
||||
// 创建请求对象
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
// 发送请求并处理响应
|
||||
try {
|
||||
return client.newCall(request).execute().body();
|
||||
} catch (IOException e) {
|
||||
throw new BaseException("语音克隆失败!{}",e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.knuddels.jtokkit.api.Encoding;
|
||||
import com.knuddels.jtokkit.api.EncodingRegistry;
|
||||
import com.knuddels.jtokkit.api.EncodingType;
|
||||
import com.knuddels.jtokkit.api.ModelType;
|
||||
import com.xmzs.common.chat.entity.chat.BaseChatCompletion;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import com.xmzs.common.chat.entity.chat.ChatCompletion;
|
||||
@@ -39,11 +40,13 @@ public class TikTokensUtil {
|
||||
modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_0613.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
|
||||
modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_16K.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
|
||||
modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
|
||||
modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_0125.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
|
||||
modelMap.put(ChatCompletion.Model.GPT_4_32K.getName(), registry.getEncodingForModel(ModelType.GPT_4));
|
||||
modelMap.put(ChatCompletion.Model.GPT_4_0613.getName(), registry.getEncodingForModel(ModelType.GPT_4));
|
||||
modelMap.put(ChatCompletion.Model.GPT_4_32K_0613.getName(), registry.getEncodingForModel(ModelType.GPT_4));
|
||||
modelMap.put(ChatCompletion.Model.GPT_4_1106_PREVIEW.getName(), registry.getEncodingForModel(ModelType.GPT_4));
|
||||
modelMap.put(ChatCompletion.Model.GPT_4_VISION_PREVIEW.getName(), registry.getEncodingForModel(ModelType.GPT_4));
|
||||
modelMap.put(ChatCompletion.Model.GPT_4_0125_PREVIEW.getName(), registry.getEncodingForModel(ModelType.GPT_4));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user