Créer une application intelligente avec les API Google Cloud Speech et Natural Language
() translation by (you can also view the original English article)
Une application qui comprend vraiment un langage naturel est une idée rêvée par les passionnés de science-fiction, les programmeurs et les chercheurs en intelligence artificielle depuis des décennies. Aujourd'hui, grâce aux progrès considérables des technologies d'apprentissage automatique, ce rêve est plus proche que jamais de devenir réalité. De plus, des services en nuage tels que Google Cloud Machine Learning ont rendu ces technologies librement accessibles à tous.
Dans ce didacticiel, vous apprendrez à utiliser deux puissantes API orientées vers le langage naturel proposées par la plateforme Google Cloud Machine Learning: les API Cloud Speech et Cloud Natural Language. En les utilisant ensemble, vous pouvez créer des applications capables de gérer la parole dans une variété de langues largement parlées.
Conditions préalables
Pour suivre, vous aurez besoin de:
- Android Studio 2.2 ou supérieur
- un compte Google Cloud Platform
- un appareil qui exécute Android 4.4 ou supérieur
1. Pourquoi utiliser ces API?
Une application capable de traiter la parole doit avoir les capacités suivantes:
- Il doit être capable d'extraire des mots individuels à partir de données audio brutes.
- Il doit être capable de faire des suppositions éclairées sur les relations grammaticales entre les mots extraits.
Les API Cloud Speech et Cloud Natural Language vous permettent d'ajouter les fonctionnalités ci-dessus à votre application Android en quelques minutes.
L'API Cloud Speech sert de système de reconnaissance vocale à la pointe de la technologie, capable de transcrire avec précision la parole dans plus de 80 langues. Il peut également gérer de manière robuste les accents régionaux et les conditions bruyantes.
Dans le même ordre d'idées, l'API Cloud Natural Language est un système de traitement de langage qui peut, avec une précision quasi humaine, déterminer le rôle que les mots jouent dans les phrases qui lui sont données. Il prend actuellement en charge dix langues et propose également une analyse des entités et des sentiments.
2. Activer les API
Avant d'utiliser les API Speech et Natural Language, vous devez les activer dans la console Google Cloud. Alors connectez-vous à la console et accédez à API Manager > Library.



Pour activer l'API Speech, cliquez sur le lien API Speech dans la section Formation de Google Cloud Machine. Dans la page qui s'ouvre ensuite, appuyez sur le bouton Activer.



Appuyez sur le bouton Retour de votre navigateur pour revenir à la page précédente.
Cette fois, activez l’API de langage naturel en cliquant sur le lien API de langage naturel, puis sur le bouton Activer de la page suivante.



Vous aurez besoin d'une clé API pour interagir avec les API. Si vous n'en avez pas déjà, ouvrez l'onglet Informations d'identification, cliquez sur le bouton Créer les informations d'identification, puis choisissez Clé API.
Vous verrez maintenant une fenêtre contextuelle affichant votre clé API. Notez-le afin que vous puissiez l'utiliser plus tard.



3. Configuration de votre projet
Les deux API sont basées sur JSON et possèdent des points de terminaison REST avec lesquels vous pouvez interagir directement à l'aide de n'importe quelle bibliothèque de réseau. Toutefois, vous pouvez gagner beaucoup de temps et écrire un code plus lisible en utilisant les bibliothèques clientes Google API disponibles. Ouvrez donc le fichier build.gradle du module d'application
de votre projet et ajoutez-lui les dépendances de compilation
suivantes:
1 |
compile 'com.google.api-client:google-api-client-android:1.22.0' |
2 |
compile 'com.google.apis:google-api-services-speech:v1beta1-rev336-1.22.0' |
3 |
compile 'com.google.apis:google-api-services-language:v1beta2-rev6-1.22.0' |
4 |
compile 'com.google.code.findbugs:jsr305:2.0.1' |
De plus, nous allons effectuer quelques opérations d’E / S sur fichiers dans ce tutoriel. Pour les simplifier, ajoutez une dépendance à la compilation
pour la bibliothèque Commons IO.
1 |
compile 'commons-io:commons-io:2.5' |
Enfin, n'oubliez pas de demander l'autorisation INTERNET
dans le fichier AndroidManifest.xml. Sans cela, votre application ne pourra pas se connecter aux serveurs de Google.
1 |
<uses-permission android:name="android.permission.INTERNET"/> |
4. Utilisation de l'API Cloud Speech
Il va sans dire que l'API Cloud Speech attend des données audio comme l'une de ses entrées. Par conséquent, nous allons maintenant créer une application Android capable de transcrire des fichiers audio.
Pour rester simple, nous ne transcrireons que les fichiers FLAC, fichiers qui utilisent le format de codage Free Lossless Audio Codec. Vous avez peut-être déjà de tels fichiers sur votre appareil. Si vous ne le faites pas, je vous suggère de télécharger quelques-uns de Wikimedia Commons.
Étape 1: créer une mise en page
La mise en page de notre application aura un widget Button
que les utilisateurs peuvent appuyer pour afficher un sélecteur de fichiers, une interface leur permettant de parcourir et de sélectionner les fichiers audio disponibles sur leurs appareils.
La mise en page aura également un widget TextView
pour afficher la transcription du fichier audio sélectionné. En conséquence, ajoutez le code suivant au fichier XML de présentation de votre activité:
1 |
<TextView
|
2 |
android:layout_width="match_parent" |
3 |
android:layout_height="wrap_content" |
4 |
android:text="" |
5 |
android:id="@+id/speech_to_text_result" |
6 |
android:textSize="18sp" |
7 |
android:layout_alignParentTop="true"/> |
8 |
|
9 |
<Button
|
10 |
android:layout_width="match_parent" |
11 |
android:layout_height="wrap_content" |
12 |
android:layout_alignParentBottom="true" |
13 |
android:id="@+id/browse_button" |
14 |
android:text="Browse"/> |
Étape 2: Créer un sélecteur de fichiers
L'interface du sélecteur de fichiers doit être affichée lorsque l'utilisateur appuie sur le bouton créé à l'étape précédente. Associez-lui donc un objet OnClickListener
. Avant de le faire, assurez-vous d’initialiser le bouton à l’aide de la méthode findViewById ()
.
1 |
Button browseButton = (Button)findViewById(R.id.browse_button); |
2 |
|
3 |
browseButton.setOnClickListener(new View.OnClickListener() { |
4 |
@Override
|
5 |
public void onClick(View view) { |
6 |
// More code here
|
7 |
}
|
8 |
});
|
Avec Storage Access Framework d'Android, disponible sur les périphériques exécutant l'API de niveau 19 ou supérieur, la création d'un sélecteur de fichiers nécessite très peu d'effort. Tout ce que vous devez faire est de créer une intention pour l'action ACTION_GET_CONTENT
et de la transmettre à la méthode startActivityForResult ()
. Vous pouvez éventuellement limiter le sélecteur de fichiers pour qu'il affiche uniquement les fichiers FLAC en transmettant le type MIME approprié à la méthode setType ()
de l'objet Intent
.
1 |
Intent filePicker = new Intent(Intent.ACTION_GET_CONTENT); |
2 |
filePicker.setType("audio/flac"); |
3 |
startActivityForResult(filePicker, 1); |
La sortie du sélecteur de fichier sera un autre objet Intent
contenant l'URI du fichier sélectionné par l'utilisateur. Pour pouvoir y accéder, vous devez remplacer la méthode onActivityResult()
de votre classe Activity
.
1 |
@Override
|
2 |
protected void onActivityResult(int requestCode, int resultCode, |
3 |
Intent data) { |
4 |
super.onActivityResult(requestCode, resultCode, data); |
5 |
if(resultCode == RESULT_OK) { |
6 |
final Uri soundUri = data.getData(); |
7 |
|
8 |
// More code here
|
9 |
|
10 |
}
|
11 |
}
|
Étape 3: Encoder le fichier
L'API Cloud Speech s'attend à ce que ses données audio se présentent sous la forme d'une chaîne Base64. Pour générer une telle chaîne, vous pouvez lire le contenu du fichier sélectionné par l'utilisateur dans un tableau d'octets
et le transmettre à la méthode utilitaire encodeBase64String ()
proposée par la bibliothèque Google API Client.
Cependant, vous n'avez actuellement que l'URI du fichier sélectionné, pas son chemin absolu. Cela signifie que, pour pouvoir lire le fichier, vous devez d'abord résoudre l'URI. Vous pouvez le faire en le transmettant à la méthode openInputStream()
du résolveur de contenu de votre activité. Une fois que vous avez accès au flux d'entrée du fichier, vous pouvez simplement le transmettre à la méthode toByteArray()
de la classe IOUtils
pour le convertir en un tableau d'octets. Le code suivant vous montre comment:
1 |
AsyncTask.execute(new Runnable() { |
2 |
@Override
|
3 |
public void run() { |
4 |
InputStream stream = getContentResolver() |
5 |
.openInputStream(soundUri); |
6 |
byte[] audioData = IOUtils.toByteArray(stream); |
7 |
stream.close(); |
8 |
|
9 |
String base64EncodedData = |
10 |
Base64.encodeBase64String(audioData); |
11 |
|
12 |
// More code here
|
13 |
}
|
14 |
}
|
Comme vous pouvez le constater dans le code ci-dessus, nous utilisons un nouveau thread pour exécuter toutes les opérations d’E / S. Cela est important pour vous assurer que l'interface utilisateur de l'application ne se fige pas.
Étape 4: jouer le fichier
À mon avis, la lecture du fichier son en cours de transcription est une bonne idée. Cela ne demande pas beaucoup d'efforts et améliore l'expérience de l'utilisateur.
Vous pouvez utiliser la classe MediaPlayer
pour lire le fichier son. Une fois que vous le dirigez vers l'URI du fichier à l'aide de sa méthode setDataSource()
, vous devez appeler sa méthode prepare()
pour préparer le lecteur de manière synchrone. Lorsque le lecteur est prêt, vous pouvez appeler sa méthode start()
pour commencer à lire le fichier.
De plus, vous devez vous rappeler de libérer les ressources du lecteur une fois la lecture du fichier terminée. Pour ce faire, affectez-lui un objet OnCompletionListener
et appelez sa méthode release()
. Le code suivant vous montre comment:
1 |
MediaPlayer player = new MediaPlayer(); |
2 |
player.setDataSource(MainActivity.this, soundUri); |
3 |
player.prepare(); |
4 |
player.start(); |
5 |
|
6 |
// Release the player
|
7 |
player.setOnCompletionListener( |
8 |
new MediaPlayer.OnCompletionListener() { |
9 |
@Override
|
10 |
public void onCompletion(MediaPlayer mediaPlayer) { |
11 |
mediaPlayer.release(); |
12 |
}
|
13 |
});
|
Étape 5: Transcrire le fichier de manière synchrone
À ce stade, nous pouvons envoyer les données audio codées en Base64 à l'API Cloud Speech pour les transcrire. Mais tout d’abord, je vous suggère de stocker la clé API que vous avez générée précédemment en tant que variable membre de votre classe d’activité
.
1 |
private final String CLOUD_API_KEY = "ABCDEF1234567890"; |
Pour pouvoir communiquer avec l'API Cloud Speech, vous devez créer un objet Speech
à l'aide d'une instance de Speech.Builder
. En tant qu'arguments, son constructeur attend un transport HTTP et une fabrique JSON. En outre, pour vous assurer que la clé d'API est incluse dans chaque demande HTTP à l'API, vous devez associer un objet SpeechRequestInitializer
au générateur et lui transmettre la clé.
Le code suivant crée un objet Speech
à l'aide de la classe AndroidJsonFactory
en tant que fabrique JSON et de la classe NetHttpTransport
en tant que transport HTTP:
1 |
Speech speechService = new Speech.Builder( |
2 |
AndroidHttp.newCompatibleTransport(), |
3 |
new AndroidJsonFactory(), |
4 |
null
|
5 |
).setSpeechRequestInitializer( |
6 |
new SpeechRequestInitializer(CLOUD_API_KEY)) |
7 |
.build(); |
L'API Cloud Speech doit être informée de la langue du fichier audio. Vous pouvez le faire en créant un objet RecognitionConfig
et en appelant sa méthode setLanguageCode()
. Voici comment vous le configurez pour ne transcrire que l'anglais américain:
1 |
RecognitionConfig recognitionConfig = new RecognitionConfig(); |
2 |
recognitionConfig.setLanguageCode("en-US"); |
En outre, la chaîne codée en Base64 doit être encapsulée dans un objet RecognitionAudio
avant de pouvoir être utilisée par l'API.
1 |
RecognitionAudio recognitionAudio = new RecognitionAudio(); |
2 |
recognitionAudio.setContent(base64EncodedData); |
Ensuite, à l'aide des objets RecognitionConfig
et RecognitionAudio
, vous devez créer un objet SyncRecognizeRequest
. Comme son nom l'indique, il vous permet de créer une requête HTTP pour transcrire de manière synchrone des données audio. Une fois que l'objet a été créé, vous pouvez le transmettre en tant qu'argument à la méthode syncrecognize()
et appeler la méthode execute () de l'objet Speech.SpeechOperations.Syncrecognize
résultante pour exécuter()
la demande HTTP.
La valeur de retour de la méthode execute()
est un objet SyncRecognizeResponse
, qui peut contenir plusieurs transcripts alternatifs. Pour le moment, nous n'utiliserons que la première alternative.
1 |
// Create request
|
2 |
SyncRecognizeRequest request = new SyncRecognizeRequest(); |
3 |
request.setConfig(recognitionConfig); |
4 |
request.setAudio(recognitionAudio); |
5 |
|
6 |
// Generate response
|
7 |
SyncRecognizeResponse response = speechService.speech() |
8 |
.syncrecognize(request) |
9 |
.execute(); |
10 |
|
11 |
// Extract transcript
|
12 |
SpeechRecognitionResult result = response.getResults().get(0); |
13 |
final String transcript = result.getAlternatives().get(0) |
14 |
.getTranscript(); |
Enfin, pour afficher la transcription à l'utilisateur, vous pouvez la transmettre au widget TextView
. Bien entendu, étant donné que les modifications de l'interface utilisateur doivent toujours se produire sur le thread d'interface utilisateur, assurez-vous de le faire après avoir appelé la méthode runOnUiThread()
de votre activité.
1 |
runOnUiThread(new Runnable() { |
2 |
@Override
|
3 |
public void run() { |
4 |
TextView speechToTextResult = |
5 |
(TextView)findViewById(R.id.speech_to_text_result); |
6 |
speechToTextResult.setText(transcript); |
7 |
}
|
8 |
});
|
Vous pouvez maintenant exécuter votre application, sélectionner un fichier FLAC contenant un discours en anglais américain et voir l'API Cloud Speech générer une transcription pour celui-ci.

Il est à noter que l'API Cloud Speech ne peut actuellement traiter que des fichiers audio à canal unique. Si vous envoyez un fichier avec plusieurs canaux, vous obtiendrez une réponse d'erreur.
5. Utilisation de l'API Cloud Natural Language
Maintenant que nous avons une transcription, nous pouvons la transmettre à l'API Cloud Natural Language pour l'analyse. Pour que ce didacticiel soit court, nous n'exécuterons l'analyse d'entité et de sentiment que sur la transcription. En d'autres termes, nous allons déterminer toutes les entités mentionnées dans la transcription, telles que les personnes, les lieux et les professions, et indiquer également si son sentiment général est négatif, neutre ou positif.
Étape 1: mettre à jour la mise en page
Pour permettre à l'utilisateur de lancer l'analyse, notre mise en page doit contenir un autre widget Button
. Par conséquent, ajoutez le code suivant au fichier XML de présentation de votre activité:
1 |
<Button |
2 |
android:layout_width="match_parent" |
3 |
android:layout_height="wrap_content" |
4 |
android:layout_above="@+id/browse_button" |
5 |
android:id="@+id/analyze_button" |
6 |
android:text="Analyze"/> |
Étape 2: Annoter la transcription
L'API REST Cloud Natural Language offre une option pratique appelée annotateText, qui vous permet d'exécuter une analyse des sentiments et des entités sur un document avec une seule requête HTTP. Nous allons l'utiliser pour analyser notre transcription.
Étant donné que l'analyse doit commencer lorsque l'utilisateur appuie sur le bouton créé à l'étape précédente, ajoutez-lui un OnClickListener
.
1 |
Button analyzeButton = (Button)findViewById(R.id.analyze_button); |
2 |
analyzeButton.setOnClickListener(new View.OnClickListener() { |
3 |
@Override
|
4 |
public void onClick(View view) { |
5 |
// More code here
|
6 |
}
|
7 |
});
|
Pour interagir avec l'API à l'aide de la bibliothèque Google API Client, vous devez créer un objet CloudNaturalLanguage
à l'aide de la classe CloudNaturalLanguage.Builder
. Son constructeur attend également un transport HTTP et une usine JSON.
De plus, en lui affectant une instance CloudNaturalLanguageRequestInitializer
, vous pouvez le forcer à inclure votre clé API dans toutes ses demandes.
1 |
final CloudNaturalLanguage naturalLanguageService = |
2 |
new CloudNaturalLanguage.Builder( |
3 |
AndroidHttp.newCompatibleTransport(), |
4 |
new AndroidJsonFactory(), |
5 |
null
|
6 |
).setCloudNaturalLanguageRequestInitializer( |
7 |
new CloudNaturalLanguageRequestInitializer(CLOUD_API_KEY) |
8 |
).build(); |
Tout le texte que vous souhaitez analyser à l'aide de l'API doit être placé dans un objet Document
. L'objet Document
doit également contenir des informations de configuration, telles que la langue du texte et son formatage en texte brut ou HTML. En conséquence, ajoutez le code suivant:
1 |
String transcript = |
2 |
((TextView)findViewById(R.id.speech_to_text_result)) |
3 |
.getText().toString(); |
4 |
|
5 |
Document document = new Document(); |
6 |
document.setType("PLAIN_TEXT"); |
7 |
document.setLanguage("en-US"); |
8 |
document.setContent(transcript); |
Ensuite, vous devez Features
un objet Fonctionnalités spécifiant les entités que vous souhaitez analyser. Le code suivant vous montre comment créer un objet Features
qui indique que vous souhaitez extraire des entités et exécuter uniquement une analyse des sentiments.
1 |
Features features = new Features(); |
2 |
features.setExtractEntities(true); |
3 |
features.setExtractDocumentSentiment(true); |
Vous pouvez maintenant utiliser les objets Document
et Features
pour composer un objet AnnotateTextRequest
, qui peut être transmis à la méthode annotateText()
pour générer un objet AnnotateTextResponse
.
1 |
final AnnotateTextRequest request = new AnnotateTextRequest(); |
2 |
request.setDocument(document); |
3 |
request.setFeatures(features); |
4 |
|
5 |
AsyncTask.execute(new Runnable() { |
6 |
@Override
|
7 |
public void run() { |
8 |
AnnotateTextResponse response = |
9 |
naturalLanguageService.documents() |
10 |
.annotateText(request).execute(); |
11 |
|
12 |
// More code here
|
13 |
}
|
14 |
}
|
Notez que nous générons la réponse dans un nouveau thread car les opérations réseau ne sont pas autorisées sur le thread d'interface utilisateur.
Vous pouvez extraire une liste d'entités de l'objet AnnotateTextResponse
en appelant sa méthode getEntities()
. De même, vous pouvez extraire le sentiment général de la transcription en appelant la méthode getDocumentSentiment()
. Cependant, pour obtenir le score réel du sentiment, vous devez également appeler la méthode getScore()
, qui renvoie un float
.
Comme vous vous en doutez, un score de sentiment égal à zéro signifie que le sentiment est neutre, un score supérieur à zéro signifie que le sentiment est positif et un score inférieur à zéro signifie qu'il est négatif.
Ce que vous faites avec la liste des entités et le score de sentiment appartient bien entendu à vous. Pour l'instant, affichons-les simplement à l'aide d'une instance AlertDialog
.
1 |
final List<Entity> entityList = response.getEntities(); |
2 |
final float sentiment = response.getDocumentSentiment().getScore(); |
3 |
|
4 |
runOnUiThread(new Runnable() { |
5 |
@Override
|
6 |
public void run() { |
7 |
String entities = ""; |
8 |
for(Entity entity:entityList) { |
9 |
entities += "\n" + entity.getName().toUpperCase(); |
10 |
}
|
11 |
AlertDialog dialog = |
12 |
new AlertDialog.Builder(MainActivity.this) |
13 |
.setTitle("Sentiment: " + sentiment) |
14 |
.setMessage("This audio file talks about :" |
15 |
+ entities) |
16 |
.setNeutralButton("Okay", null) |
17 |
.create(); |
18 |
dialog.show(); |
19 |
}
|
20 |
});
|
Avec le code ci-dessus, le score de sentiment sera affiché dans le titre de la boîte de dialogue et la liste des entités sera affichée dans son corps.
Si vous exécutez l'application maintenant, vous devriez être capable d'analyser le contenu des fichiers audio, ainsi que de les transcrire.

Conclusion
Vous savez maintenant comment utiliser conjointement les API Cloud Speech et Cloud Natural Language pour créer une application Android qui peut non seulement transcrire un fichier audio, mais également exécuter une analyse d'entité et de sentiment. Dans ce didacticiel, vous avez également appris à utiliser les bibliothèques d'Android Storage Access Framework et de l'API Google Client.
Google a régulièrement ajouté de nouvelles fonctionnalités intéressantes, ainsi que la prise en charge d'un plus grand nombre de langues, aux deux API. Pour rester à jour à leur sujet, consultez la documentation officielle.
Et pendant que vous êtes ici, consultez certains de nos autres articles sur les services en nuage d'applications mobiles et l'apprentissage automatique!