diff --git a/core/src/main/java/ai/z/openapi/api/audio/AudioApi.java b/core/src/main/java/ai/z/openapi/api/audio/AudioApi.java index 5839161..26d5d01 100644 --- a/core/src/main/java/ai/z/openapi/api/audio/AudioApi.java +++ b/core/src/main/java/ai/z/openapi/api/audio/AudioApi.java @@ -39,6 +39,20 @@ public interface AudioApi { @POST("audio/speech") Single audioSpeech(@Body AudioSpeechRequest request); + /** + * Text-to-Speech (TTS) conversion using GLM-4-Voice Converts text input into + * natural-sounding speech audio with emotion and tone control Supports multiple + * voices, languages, speed adjustment, and various audio formats Features advanced + * voice synthesis with customizable emotional expressions and dialects + * @param request TTS parameters including text, voice selection, emotion, speed, + * tone, and output format + * @return Generated high-quality audio streaming in specified format with natural + * prosody + */ + @Streaming + @POST("audio/speech") + Call audioSpeechStreaming(@Body AudioSpeechRequest request); + /** * Voice cloning and customization using advanced neural models Creates custom voice * models from provided audio samples with high fidelity Enables personalized speech diff --git a/core/src/main/java/ai/z/openapi/service/audio/AudioService.java b/core/src/main/java/ai/z/openapi/service/audio/AudioService.java index 2aa0bf5..e44b11f 100644 --- a/core/src/main/java/ai/z/openapi/service/audio/AudioService.java +++ b/core/src/main/java/ai/z/openapi/service/audio/AudioService.java @@ -12,6 +12,13 @@ public interface AudioService { */ AudioSpeechResponse createSpeech(AudioSpeechRequest request); + /** + * Creates speech from text using text-to-speech. + * @param request the speech generation request + * @return AudioSpeechStreamingResponse containing the generated speech streaming + */ + AudioSpeechStreamingResponse createStreamingSpeechStreaming(AudioSpeechRequest request); + /** * Creates customized speech with specific voice characteristics. * @param request the speech customization request diff --git a/core/src/main/java/ai/z/openapi/service/audio/AudioServiceImpl.java b/core/src/main/java/ai/z/openapi/service/audio/AudioServiceImpl.java index 9c128e4..3c5eb26 100644 --- a/core/src/main/java/ai/z/openapi/service/audio/AudioServiceImpl.java +++ b/core/src/main/java/ai/z/openapi/service/audio/AudioServiceImpl.java @@ -6,6 +6,7 @@ import ai.z.openapi.service.deserialize.MessageDeserializeFactory; import ai.z.openapi.utils.FlowableRequestSupplier; import ai.z.openapi.utils.RequestSupplier; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import io.reactivex.rxjava3.core.Single; import lombok.extern.slf4j.Slf4j; import okhttp3.MediaType; @@ -57,6 +58,13 @@ public class AudioServiceImpl implements AudioService { return this.zAiClient.executeRequest(request, supplier, AudioSpeechResponse.class); } + @Override + public AudioSpeechStreamingResponse createStreamingSpeechStreaming(AudioSpeechRequest request) { + validateSpeechParams(request); + FlowableRequestSupplier> supplier = audioApi::audioSpeechStreaming; + return this.zAiClient.streamRequest(request, supplier, AudioSpeechStreamingResponse.class, ObjectNode.class); + } + @Override public AudioCustomizationResponse createCustomSpeech(AudioCustomizationRequest request) { validateCustomSpeechParams(request); diff --git a/core/src/main/java/ai/z/openapi/service/audio/AudioSpeechStreamingResponse.java b/core/src/main/java/ai/z/openapi/service/audio/AudioSpeechStreamingResponse.java new file mode 100644 index 0000000..7f5770b --- /dev/null +++ b/core/src/main/java/ai/z/openapi/service/audio/AudioSpeechStreamingResponse.java @@ -0,0 +1,27 @@ +package ai.z.openapi.service.audio; + +import ai.z.openapi.core.model.ClientResponse; +import ai.z.openapi.core.model.FlowableClientResponse; +import ai.z.openapi.service.model.ChatError; +import java.io.File; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.reactivex.rxjava3.core.Flowable; +import lombok.Data; + +@Data +public class AudioSpeechStreamingResponse implements FlowableClientResponse { + + private int code; + + private String msg; + + private boolean success; + + private ObjectNode data; + + private ChatError error; + + private Flowable flowable; + +} diff --git a/core/src/test/java/ai/z/openapi/service/audio/AudioServiceTest.java b/core/src/test/java/ai/z/openapi/service/audio/AudioServiceTest.java index 3e1b0c9..e7675ac 100644 --- a/core/src/test/java/ai/z/openapi/service/audio/AudioServiceTest.java +++ b/core/src/test/java/ai/z/openapi/service/audio/AudioServiceTest.java @@ -82,6 +82,29 @@ public class AudioServiceTest { logger.info("Text-to-speech response: {}", mapper.writeValueAsString(response)); } + @Test + @DisplayName("Should generate speech streaming from text successfully") + @EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$") + void testAudioSpeechStreaming() { + String requestId = String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis()); + AudioSpeechRequest audioSpeechRequest = AudioSpeechRequest.builder() + .model(Constants.ModelTTS) + .encodeFormat("base64") + .input("Hello, this is a test for text-to-speech functionality.") + .voice("female") + .speed(1.0f) + .volume(1.0f) + .stream(Boolean.TRUE) + .responseFormat("wav") + .requestId(requestId) + .build(); + AudioSpeechStreamingResponse audioSpeechStreamingApiResponse = audioService + .createStreamingSpeechStreaming(audioSpeechRequest); + audioSpeechStreamingApiResponse.getFlowable() + .doOnNext(speechPro -> logger.info("speechPro: {}", speechPro.toString())) + .blockingSubscribe(); + } + @Test @DisplayName("Should generate custom speech with voice cloning successfully") @EnabledIfEnvironmentVariable(named = "ZAI_API_KEY", matches = "^[^.]+\\.[^.]+$")