|
16 | 16 |
|
17 | 17 | package com.example.dialogflow; |
18 | 18 |
|
19 | | - |
| 19 | +// [START dialogflow_detect_intent_streaming] |
20 | 20 | // Imports the Google Cloud client library |
21 | | - |
22 | | -import com.google.api.gax.rpc.ApiStreamObserver; |
| 21 | +import com.google.api.gax.rpc.BidiStream; |
23 | 22 | import com.google.cloud.dialogflow.v2.AudioEncoding; |
24 | 23 | import com.google.cloud.dialogflow.v2.InputAudioConfig; |
25 | 24 | import com.google.cloud.dialogflow.v2.QueryInput; |
|
29 | 28 | import com.google.cloud.dialogflow.v2.StreamingDetectIntentRequest; |
30 | 29 | import com.google.cloud.dialogflow.v2.StreamingDetectIntentResponse; |
31 | 30 | import com.google.protobuf.ByteString; |
32 | | - |
33 | 31 | import java.io.FileInputStream; |
34 | | -import java.util.ArrayList; |
35 | | -import java.util.List; |
36 | | -import java.util.concurrent.CountDownLatch; |
| 32 | +import java.io.IOException; |
37 | 33 |
|
38 | 34 | /** |
39 | 35 | * DialogFlow API Detect Intent sample with audio files processes as an audio stream. |
40 | 36 | */ |
41 | | -public class DetectIntentStream { |
42 | | - // [START dialogflow_detect_intent_streaming] |
| 37 | +class DetectIntentStream { |
43 | 38 |
|
44 | | - /** |
45 | | - * Returns the result of detect intent with streaming audio as input. |
46 | | - * |
47 | | - * Using the same `session_id` between requests allows continuation of the conversation. |
48 | | - * |
49 | | - * @param projectId Project/Agent Id. |
50 | | - * @param audioFilePath The audio file to be processed. |
51 | | - * @param sessionId Identifier of the DetectIntent session. |
52 | | - * @param languageCode Language code of the query. |
53 | | - * @return The List of StreamingDetectIntentResponses to the input audio inputs. |
54 | | - */ |
55 | | - public static List<StreamingDetectIntentResponse> detectIntentStream( |
56 | | - String projectId, |
57 | | - String audioFilePath, |
58 | | - String sessionId, |
59 | | - String languageCode) throws Throwable { |
60 | | - // Start bi-directional StreamingDetectIntent stream. |
61 | | - final CountDownLatch notification = new CountDownLatch(1); |
62 | | - final List<Throwable> responseThrowables = new ArrayList<>(); |
63 | | - final List<StreamingDetectIntentResponse> responses = new ArrayList<>(); |
| 39 | + static void detectIntentStream(String projectId, String audioFilePath, String sessionId) { |
| 40 | + // String projectId = "YOUR_PROJECT_ID"; |
| 41 | + // String audioFilePath = "path_to_your_audio_file"; |
| 42 | + // Using the same `sessionId` between requests allows continuation of the conversation. |
| 43 | + // String sessionId = "Identifier of the DetectIntent session"; |
64 | 44 |
|
65 | 45 | // Instantiates a client |
66 | 46 | try (SessionsClient sessionsClient = SessionsClient.create()) { |
67 | 47 | // Set the session name using the sessionId (UUID) and projectID (my-project-id) |
68 | 48 | SessionName session = SessionName.of(projectId, sessionId); |
69 | | - System.out.println("Session Path: " + session.toString()); |
70 | 49 |
|
| 50 | + // Instructs the speech recognizer how to process the audio content. |
71 | 51 | // Note: hard coding audioEncoding and sampleRateHertz for simplicity. |
72 | 52 | // Audio encoding of the audio content sent in the query request. |
73 | | - AudioEncoding audioEncoding = AudioEncoding.AUDIO_ENCODING_LINEAR_16; |
74 | | - int sampleRateHertz = 16000; |
75 | | - |
76 | | - // Instructs the speech recognizer how to process the audio content. |
77 | 53 | InputAudioConfig inputAudioConfig = InputAudioConfig.newBuilder() |
78 | | - .setAudioEncoding(audioEncoding) // audioEncoding = AudioEncoding.AUDIO_ENCODING_LINEAR_16 |
79 | | - .setLanguageCode(languageCode) // languageCode = "en-US" |
80 | | - .setSampleRateHertz(sampleRateHertz) // sampleRateHertz = 16000 |
| 54 | + .setAudioEncoding(AudioEncoding.AUDIO_ENCODING_LINEAR_16) |
| 55 | + .setLanguageCode("en-US") // languageCode = "en-US" |
| 56 | + .setSampleRateHertz(16000) // sampleRateHertz = 16000 |
81 | 57 | .build(); |
82 | 58 |
|
83 | | - ApiStreamObserver<StreamingDetectIntentResponse> responseObserver = |
84 | | - new ApiStreamObserver<StreamingDetectIntentResponse>() { |
85 | | - @Override |
86 | | - public void onNext(StreamingDetectIntentResponse response) { |
87 | | - // Do something when receive a response |
88 | | - responses.add(response); |
89 | | - } |
90 | | - |
91 | | - @Override |
92 | | - public void onError(Throwable t) { |
93 | | - // Add error-handling |
94 | | - responseThrowables.add(t); |
95 | | - } |
96 | | - |
97 | | - @Override |
98 | | - public void onCompleted() { |
99 | | - // Do something when complete. |
100 | | - notification.countDown(); |
101 | | - } |
102 | | - }; |
103 | | - |
104 | | - // Performs the streaming detect intent callable request |
105 | | - ApiStreamObserver<StreamingDetectIntentRequest> requestObserver = |
106 | | - sessionsClient.streamingDetectIntentCallable().bidiStreamingCall(responseObserver); |
107 | | - |
108 | 59 | // Build the query with the InputAudioConfig |
109 | 60 | QueryInput queryInput = QueryInput.newBuilder().setAudioConfig(inputAudioConfig).build(); |
110 | 61 |
|
111 | | - try (FileInputStream audioStream = new FileInputStream(audioFilePath)) { |
112 | | - // The first request contains the configuration |
113 | | - StreamingDetectIntentRequest request = StreamingDetectIntentRequest.newBuilder() |
114 | | - .setSession(session.toString()) |
115 | | - .setQueryInput(queryInput) |
116 | | - .build(); |
| 62 | + // Create the Bidirectional stream |
| 63 | + BidiStream<StreamingDetectIntentRequest, StreamingDetectIntentResponse> bidiStream = |
| 64 | + sessionsClient.streamingDetectIntentCallable().call(); |
117 | 65 |
|
118 | | - // Make the first request |
119 | | - requestObserver.onNext(request); |
| 66 | + // The first request must **only** contain the audio configuration: |
| 67 | + bidiStream.send(StreamingDetectIntentRequest.newBuilder() |
| 68 | + .setSession(session.toString()) |
| 69 | + .setQueryInput(queryInput) |
| 70 | + .build()); |
120 | 71 |
|
| 72 | + try (FileInputStream audioStream = new FileInputStream(audioFilePath)) { |
| 73 | + // Subsequent requests must **only** contain the audio data. |
121 | 74 | // Following messages: audio chunks. We just read the file in fixed-size chunks. In reality |
122 | 75 | // you would split the user input by time. |
123 | 76 | byte[] buffer = new byte[4096]; |
124 | 77 | int bytes; |
125 | 78 | while ((bytes = audioStream.read(buffer)) != -1) { |
126 | | - requestObserver.onNext( |
| 79 | + bidiStream.send( |
127 | 80 | StreamingDetectIntentRequest.newBuilder() |
128 | 81 | .setInputAudio(ByteString.copyFrom(buffer, 0, bytes)) |
129 | 82 | .build()); |
130 | 83 | } |
131 | | - } catch (RuntimeException e) { |
132 | | - // Cancel stream. |
133 | | - requestObserver.onError(e); |
134 | | - } |
135 | | - // Half-close the stream. |
136 | | - requestObserver.onCompleted(); |
137 | | - // Wait for the final response (without explicit timeout). |
138 | | - notification.await(); |
139 | | - // Process errors/responses. |
140 | | - if (!responseThrowables.isEmpty()) { |
141 | | - throw responseThrowables.get(0); |
142 | | - } |
143 | | - if (responses.isEmpty()) { |
144 | | - throw new RuntimeException("No response from Dialogflow."); |
145 | 84 | } |
146 | 85 |
|
147 | | - for (StreamingDetectIntentResponse response : responses) { |
148 | | - if (response.hasRecognitionResult()) { |
149 | | - System.out.format( |
150 | | - "Intermediate transcript: '%s'\n", response.getRecognitionResult().getTranscript()); |
151 | | - } |
152 | | - } |
| 86 | + // Tell the service you are done sending data |
| 87 | + bidiStream.closeSend(); |
153 | 88 |
|
154 | | - // Display the last query result |
155 | | - QueryResult queryResult = responses.get(responses.size() - 1).getQueryResult(); |
156 | | - System.out.println("===================="); |
157 | | - System.out.format("Query Text: '%s'\n", queryResult.getQueryText()); |
158 | | - System.out.format("Detected Intent: %s (confidence: %f)\n", |
159 | | - queryResult.getIntent().getDisplayName(), queryResult.getIntentDetectionConfidence()); |
160 | | - System.out.format("Fulfillment Text: '%s'\n", queryResult.getFulfillmentText()); |
| 89 | + for (StreamingDetectIntentResponse response : bidiStream) { |
| 90 | + QueryResult queryResult = response.getQueryResult(); |
| 91 | + System.out.println("===================="); |
| 92 | + System.out.format("Intent Display Name: %s\n", queryResult.getIntent().getDisplayName()); |
| 93 | + System.out.format("Query Text: '%s'\n", queryResult.getQueryText()); |
| 94 | + System.out.format("Detected Intent: %s (confidence: %f)\n", |
| 95 | + queryResult.getIntent().getDisplayName(), queryResult.getIntentDetectionConfidence()); |
| 96 | + System.out.format("Fulfillment Text: '%s'\n", queryResult.getFulfillmentText()); |
161 | 97 |
|
162 | | - return responses; |
| 98 | + } |
| 99 | + } catch (IOException e) { |
| 100 | + e.printStackTrace(); |
163 | 101 | } |
164 | 102 | } |
165 | | - // [END dialogflow_detect_intent_streaming] |
166 | 103 | } |
| 104 | +// [END dialogflow_detect_intent_streaming] |
0 commit comments