package com.vetti.common.ai; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import com.google.gson.Gson; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; /** * 文本转换为语音 */ public class ElevenLabsClient { private static final String BASE_URL = "https://api.elevenlabs.io/v1"; private final String apiKey; private final CloseableHttpClient httpClient; private final Gson gson; public ElevenLabsClient(String apiKey) { this.apiKey = apiKey; this.httpClient = HttpClients.createDefault(); this.gson = new Gson(); } /** * 将文本转换为语音并保存到文件 * * @param text 要转换的文本 * @param voiceId 语音ID (可从ElevenLabs网站获取) * @param outputFilePath 输出文件路径 * @throws IOException 网络请求或文件操作异常 */ public void textToSpeech(String text, String voiceId, String outputFilePath) throws IOException { HttpPost httpPost = new HttpPost(BASE_URL + "/text-to-speech/" + voiceId); httpPost.setHeader("xi-api-key", apiKey); httpPost.setHeader("Content-Type", "application/json"); Map payload = new HashMap<>(); payload.put("text", text); payload.put("model_id", "eleven_monolingual_v1"); payload.put("voice_settings", new VoiceSettings(0.7, 0.5)); StringEntity entity = new StringEntity(gson.toJson(payload), ContentType.APPLICATION_JSON); httpPost.setEntity(entity); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { try (InputStream inputStream = responseEntity.getContent(); FileOutputStream outputStream = new FileOutputStream(outputFilePath)) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } } } } } /** * 获取可用的语音列表 * * @return 语音列表响应 * @throws IOException 网络请求异常 */ public VoicesResponse getVoices() throws IOException { HttpGet httpGet = new HttpGet(BASE_URL + "/voices"); httpGet.setHeader("xi-api-key", apiKey); try (CloseableHttpResponse response = httpClient.execute(httpGet)) { HttpEntity responseEntity = response.getEntity(); String responseBody = EntityUtils.toString(responseEntity); return gson.fromJson(responseBody, VoicesResponse.class); } } // 关闭HTTP客户端 public void close() throws IOException { httpClient.close(); } // 语音设置内部类 private static class VoiceSettings { private double stability; private double similarity_boost; public VoiceSettings(double stability, double similarity_boost) { this.stability = stability; this.similarity_boost = similarity_boost; } // getter方法 public double getStability() { return stability; } public double getSimilarity_boost() { return similarity_boost; } } // 语音列表响应模型 public static class VoicesResponse { private Voice[] voices; public Voice[] getVoices() { return voices; } public void setVoices(Voice[] voices) { this.voices = voices; } public static class Voice { private String voice_id; private String name; private String category; private FineTuning fine_tuning; public String getVoice_id() { return voice_id; } public void setVoice_id(String voice_id) { this.voice_id = voice_id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } public FineTuning getFine_tuning() { return fine_tuning; } public void setFine_tuning(FineTuning fine_tuning) { this.fine_tuning = fine_tuning; } } } // 使用示例 public static void main(String[] args) { String apiKey = "sk_5240d8f56cb1eb5225fffcf903f62479884d1af5b3de6812"; ElevenLabsClient client = new ElevenLabsClient(apiKey); try { // 获取可用语音 VoicesResponse voicesResponse = client.getVoices(); if (voicesResponse != null && voicesResponse.getVoices() != null && voicesResponse.getVoices().length > 0) { System.out.println("Available voices:"); for (VoicesResponse.Voice voice : voicesResponse.getVoices()) { System.out.println(voice.getName() + " (ID: " + voice.getVoice_id() + ")"); } // 使用第一个可用语音进行文本转语音 String firstVoiceId = voicesResponse.getVoices()[0].getVoice_id(); String text = "Come on, Baby,Come on, Baby,Come on, Baby,Come on, Baby"; String outputFile = "output.mp3"; client.textToSpeech(text, firstVoiceId, outputFile); System.out.println("Audio saved to: " + outputFile); } } catch (IOException e) { e.printStackTrace(); } finally { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } } }