Page updated Jan 16, 2024

Example application

Sample React app

A sample React application with all of the Predictions features is provided below. It shows how to use all scenarios above by calling the appropriate convert, identify, and interpret API calls in the Amplify library.

This example uses the package microphone-stream, which you will need to install along with the necessary polyfills if you would like to use the sample directly.

1npm install microphone-stream

If you are using Vite, this package provides straightforward instructions on installing the necessary polyfills.

The components in the app code below are rendered according to the scenarios above like so:

1return (
2 <div>
3 <TextTranslation />
4 <TextToSpeech />
5 <SpeechToText />
6 <TextIdentification />
7 <EntityIdentification />
8 <PredictionsUpload />
9 <LabelsIdentification />
10 <TextInterpretation />
11 </div>
12);

React app code

1import { Predictions } from '@aws-amplify/predictions';
2import { Amplify } from 'aws-amplify';
3import mic from 'microphone-stream';
4import { useState } from 'react';
5import './App.css';
6import amplifyconfig from './amplifyconfiguration.json';
7
8Amplify.configure(amplifyconfig);
9
10function TextIdentification() {
11 const [response, setResponse] = useState('You can add a photo by uploading directly from the app');
12
13 const identifyFromFile = async (event) => {
14 setResponse('identifying text...');
15 const { target: { files } } = event;
16 const [file,] = files || [];
17
18 if (!file) {
19 return;
20 }
21 try {
22 const { text } = await Predictions.identify({
23 text: {
24 source: {
25 file,
26 },
27 format: 'PLAIN', // Available options 'PLAIN', 'FORM', 'TABLE', 'ALL'
28 }
29 })
30 setResponse(text.fullText);
31 } catch (err) {
32 setResponse(JSON.stringify(err, null, 2));
33 }
34 }
35
36 return (
37 <div>
38 <div>
39 <h3>Text identification</h3>
40 <input type="file" onChange={identifyFromFile}></input>
41 <p>{response}</p>
42 </div>
43 </div>
44 );
45}
46
47function EntityIdentification() {
48 const [response, setResponse] = useState('Click upload for test');
49
50 const identifyFromFile = async (event) => {
51 setResponse('searching...');
52
53 const { target: { files } } = event;
54 const [file,] = files || [];
55
56 if (!file) {
57 return;
58 }
59 try {
60 const result = await Predictions.identify({
61 entities: {
62 source: {
63 file,
64 },
65 /*
66 * For using the Identify Entities advanced features, enable collection:true and comment out celebrityDetection
67 * Then after you upload an image to your S3 bucket (protected/predictions/index-faces/) you'll be able to run this again
68 * and it will tell you if the photo you're testing is in that Collection or not
69 */
70 // collection: true
71 celebrityDetection: true
72 }
73 });
74 setResponse(JSON.stringify(result, null, 2))
75 } catch (err) {
76 setResponse(JSON.stringify(err, null, 2));
77 }
78 }
79
80 return (
81 <div>
82 <div>
83 <h3>Entity identification</h3>
84 <input type="file" onChange={identifyFromFile}></input>
85 <p>{response}</p>
86 </div>
87 </div>
88 );
89}
90
91function LabelsIdentification() {
92 const [response, setResponse] = useState('Click upload for test')
93
94 const identifyFromFile = async (event) => {
95 const { target: { files } } = event;
96 const [file,] = files || [];
97
98 if (!file) {
99 return;
100 }
101 try {
102 const result = Predictions.identify({
103 labels: {
104 source: {
105 file,
106 },
107 type: 'ALL' // 'LABELS' will detect objects , 'UNSAFE' will detect if content is not safe, 'ALL' will do both default on amplifyconfiguration.json
108 }
109 });
110 console.log(result);
111 setResponse(JSON.stringify(result, null, 2));
112 } catch (err) {
113 setResponse(JSON.stringify(err, null, 2));
114 }
115 }
116
117 return (
118 <div>
119 <div>
120 <h3>Labels identification</h3>
121 <input type="file" onChange={identifyFromFile}></input>
122 <p>{response}</p>
123 </div>
124 </div>
125 );
126}
127
128function SpeechToText() {
129 const [response, setResponse] = useState('Record audio to generate a transcription.')
130
131 function AudioRecorder({ finishRecording }) {
132 const [recording, setRecording] = useState(false);
133 const [micStream, setMicStream] = useState<any>();
134 const [audioBuffer] = useState(
135 (function() {
136 let buffer = [];
137 function add(raw) {
138 buffer = buffer.concat(...raw);
139 return buffer;
140 }
141 function newBuffer() {
142 console.log('resetting buffer');
143 buffer = [];
144 }
145
146 return {
147 reset: function() {
148 newBuffer();
149 },
150 addData: function(raw) {
151 add(raw);
152 },
153 getData: function() {
154 return buffer;
155 }
156 };
157 })()
158 );
159
160 const startRecording = async () => {
161 console.log('start recording');
162 audioBuffer.reset();
163
164 const startMic = new mic();
165 startMic.setStream(await window.navigator.mediaDevices.getUserMedia({ video: false, audio: true }));
166
167 startMic.on('data', (chunk) => {
168 var raw = mic.toRaw(chunk);
169 if (raw == null) {
170 return;
171 }
172 audioBuffer.addData(raw);
173
174 });
175
176 setRecording(true);
177 setMicStream(startMic);
178 }
179
180 async function stopRecording() {
181 console.log('stop recording');
182
183 micStream.stop();
184 setMicStream(null);
185 setRecording(false);
186
187 const resultBuffer = audioBuffer.getData();
188 finishRecording(resultBuffer);
189 }
190
191 return (
192 <div>
193 <div>
194 {recording && <button onClick={stopRecording}>Stop recording</button>}
195 {!recording && <button onClick={startRecording}>Start recording</button>}
196 </div>
197 </div>
198 );
199 }
200
201 const convertFromBuffer = async (bytes) => {
202 setResponse('Converting text...');
203
204 try {
205 const { transcription } = await Predictions.convert({
206 transcription: {
207 source: {
208 bytes
209 },
210 language: 'en-US', // other options include 'en-GB', 'fr-FR', 'fr-CA', 'es-US'
211 },
212 });
213 setResponse(transcription.fullText);
214 } catch (err) {
215 setResponse(JSON.stringify(err, null, 2));
216 }
217 }
218
219 return (
220 <div>
221 <div>
222 <h3>Speech to text</h3>
223 <AudioRecorder finishRecording={convertFromBuffer} />
224 <p>{response}</p>
225 </div>
226 </div>
227 );
228}
229
230function TextToSpeech() {
231 const [response, setResponse] = useState('...')
232 const [textToGenerateSpeech, setTextToGenerateSpeech] = useState('write to generate audio');
233
234 const generateTextToSpeech = async () => {
235 setResponse('Generating audio...');
236
237 try {
238 const result = await Predictions.convert({
239 textToSpeech: {
240 source: {
241 text: textToGenerateSpeech,
242 },
243 voiceId: 'Amy' // default configured on amplifyconfiguration.json
244 // list of different options are here https://docs.aws.amazon.com/polly/latest/dg/voicelist.html
245 }
246 });
247
248 let AudioContext = window.AudioContext || window.webkitAudioContext;
249 const audioCtx = new AudioContext();
250 const source = audioCtx.createBufferSource();
251 audioCtx.decodeAudioData(result.audioStream, (buffer) => {
252 source.buffer = buffer;
253 source.connect(audioCtx.destination);
254 source.start(0);
255 }, (err) => console.log({ err }));
256
257 setResponse('Generation completed');
258 } catch(err: unknown) {
259 setResponse(JSON.stringify(err, null, 2));
260 }
261 }
262
263 const setText = (event) => {
264 setTextToGenerateSpeech(event.target.value);
265 }
266
267 return (
268 <div>
269 <div>
270 <h3>Text To Speech</h3>
271 <input type="text" value={textToGenerateSpeech} onChange={setText}></input>
272 <button onClick={generateTextToSpeech}>Text to Speech</button>
273 <h3>{response}</h3>
274 </div>
275 </div>
276 );
277}
278
279function TextTranslation() {
280 const [response, setResponse] = useState('Input some text and click enter to test');
281 const [textToTranslate, setTextToTranslate] = useState('write to translate');
282
283 const translate = async () => {
284 try {
285 const result = Predictions.convert({
286 translateText: {
287 source: {
288 text: textToTranslate,
289 // language : "es" // defaults configured on amplifyconfiguration.json
290 // supported languages https://docs.aws.amazon.com/translate/latest/dg/what-is-languages.html
291 },
292 // targetLanguage: "en"
293 }
294 })
295 setResponse(JSON.stringify(result, null, 2));
296 } catch(err: unknown) {
297 setResponse(JSON.stringify(err, null, 2));
298 }
299 }
300
301 function setText(event) {
302 setTextToTranslate(event.target.value);
303 }
304
305 return (
306 <div>
307 <div>
308 <h3>Text Translation</h3>
309 <input type="text" value={textToTranslate} onChange={setText}></input>
310 <button onClick={translate}>Translate</button>
311 <p>{response}</p>
312 </div>
313 </div>
314 );
315}
316
317function TextInterpretation() {
318 const [response, setResponse] = useState('Input some text and click enter to test');
319 const [textToInterpret, setTextToInterpret] = useState('write some text here to interpret');
320
321 const interpretFromPredictions = async () => {
322 try {
323 const result = Predictions.interpret({
324 text: {
325 source: {
326 text: textToInterpret,
327 },
328 type: 'all'
329 }
330 })
331 setResponse(JSON.stringify(result, null, 2));
332 } catch (err) {
333 setResponse(JSON.stringify(err, null, 2));
334 }
335 }
336
337 function setText(event) {
338 setTextToInterpret(event.target.value);
339 }
340
341 return (
342 <div>
343 <div>
344 <h3>Text interpretation</h3>
345 <input value={textToInterpret} onChange={setText}></input>
346 <button onClick={interpretFromPredictions}>test</button>
347 <p>{response}</p>
348 </div>
349 </div>
350 );
351}
352
353function App() {
354 return (
355 <div>
356 <TextTranslation />
357 <br/>
358 <TextToSpeech />
359 <br/>
360 <SpeechToText />
361 <br/>
362 <TextIdentification />
363 <br/>
364 <EntityIdentification />
365 <br/>
366 <LabelsIdentification />
367 <br/>
368 <TextInterpretation />
369 </div>
370 );
371}
372
373export default App;

Now run npm start and press the buttons to demo the app.