import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import javax.sound.sampled.*; public class MozillaTTSClient { private final String voiceId = "en_US/vctk_low"; // Free voice model private final String apiUrl = "https://api-inference.huggingface.co/models/mozilla/tts"; public MozillaTTSClient() { // No API key needed for basic usage } public void speakText(String text) throws IOException { String inputJson = "{\n" + " \"inputs\": \"" + text.replace("\"", "\\\"") + "\",\n" + " \"parameters\": {\n" + " \"voice_preset\": \"" + voiceId + "\"\n" + " }\n" + "}"; URL url = new URL(apiUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json"); conn.setDoOutput(true); try (OutputStream os = conn.getOutputStream()) { os.write(inputJson.getBytes("utf-8")); } int status = conn.getResponseCode(); if (status == 200) { try (InputStream is = conn.getInputStream()) { // Save the audio to a temporary file File tempFile = File.createTempFile("speech", ".wav"); try (FileOutputStream fos = new FileOutputStream(tempFile)) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = is.read(buffer)) != -1) { fos.write(buffer, 0, bytesRead); } } // Play the audio try (AudioInputStream audioIn = AudioSystem.getAudioInputStream(tempFile)) { Clip clip = AudioSystem.getClip(); clip.open(audioIn); clip.start(); clip.drain(); clip.close(); } catch (UnsupportedAudioFileException | LineUnavailableException e) { throw new IOException("Error playing audio: " + e.getMessage()); } // Clean up the temporary file tempFile.delete(); } } else { throw new IOException("Error: " + status); } } }