@@ -239,7 +239,7 @@ public Flowable<SpeechSynthesisResult> streamingCallAsFlowable(Flowable<String>
239239 return duplexApi
240240 .duplexCall (
241241 StreamInputTtsParamWithStream .fromStreamInputTtsParam (
242- this .parameters , inputStream , preRequestId , false ))
242+ this .parameters , inputStream , preRequestId , false , this . canceled ))
243243 .filter (item -> item .getEvent () != WebSocketEventType .TASK_STARTED .getValue ())
244244 .map (SpeechSynthesisResult ::fromDashScopeResult )
245245 .filter (item -> !canceled .get ())
@@ -292,7 +292,8 @@ public Flowable<SpeechSynthesisResult> callAsFlowable(String text)
292292 },
293293 BackpressureStrategy .BUFFER ),
294294 preRequestId ,
295- true ))
295+ true ,
296+ this .canceled ))
296297 .filter (item -> item .getEvent () != WebSocketEventType .TASK_STARTED .getValue ())
297298 .map (SpeechSynthesisResult ::fromDashScopeResult )
298299 .doOnNext (
@@ -368,7 +369,7 @@ private void startStream(boolean enableSsml) {
368369 try {
369370 duplexApi .duplexCall (
370371 SpeechSynthesizer .StreamInputTtsParamWithStream .fromStreamInputTtsParam (
371- this .parameters , textFrames , preRequestId , enableSsml ),
372+ this .parameters , textFrames , preRequestId , enableSsml , this . canceled ),
372373 new ResultCallback <DashScopeResult >() {
373374 // private Sentence lastSentence = null;
374375
@@ -441,9 +442,6 @@ public void onEvent(DashScopeResult message) {
441442 @ Override
442443 public void onComplete () {
443444 log .debug ("[TtsV2] onComplete" );
444- if (canceled .get ()) {
445- return ;
446- }
447445 synchronized (SpeechSynthesizer .this ) {
448446 state = SpeechSynthesisState .IDLE ;
449447 }
@@ -802,11 +800,19 @@ private static class StreamInputTtsParamWithStream extends SpeechSynthesisParam
802800
803801 @ NonNull private Flowable <TextStreamItem > textStream ;
804802
803+ /**
804+ * Shared reference to the outer {@link SpeechSynthesizer}'s canceled flag. When set to true
805+ * before the finish-task message is sent, the finish-task message will carry
806+ * payload.input.directive="cancel" to notify the server to discard remaining audio.
807+ */
808+ private AtomicBoolean canceled ;
809+
805810 public static StreamInputTtsParamWithStream fromStreamInputTtsParam (
806811 SpeechSynthesisParam param ,
807812 Flowable <TextStreamItem > textStream ,
808813 String preRequestId ,
809- boolean enableSsml ) {
814+ boolean enableSsml ,
815+ AtomicBoolean canceled ) {
810816 return StreamInputTtsParamWithStream .builder ()
811817 .headers (param .getHeaders ())
812818 .parameters (param .getParameters ())
@@ -817,9 +823,15 @@ public static StreamInputTtsParamWithStream fromStreamInputTtsParam(
817823 .model (param .getModel ())
818824 .voice (param .getVoice ())
819825 .apiKey (param .getApiKey ())
826+ .canceled (canceled )
820827 .build ();
821828 }
822829
830+ @ Override
831+ public String getDirective () {
832+ return (canceled != null && canceled .get ()) ? "cancel" : null ;
833+ }
834+
823835 @ Override
824836 public Flowable <Object > getStreamingData () {
825837 return textStream
0 commit comments