Intégrer la traduction vocale à votre application Android

Ce tutoriel explique comment ajouter une fonctionnalité de traduction vocale à votre application Android. L'exemple de ce tutoriel utilise un microservice qui reçoit un message audio, le traduit en un ensemble de langues prédéfinies et stocke les messages traduits dans des fichiers audio. L'application cliente Android télécharge et lit les fichiers audio traduits à la demande de l'utilisateur.

Présentation de la solution

La solution comprend les composants suivants :

Microservice

Le microservice est mis en œuvre sur Cloud Functions for Firebase et utilise les produits Cloud AI suivants pour traduire les messages :

Le microservice stocke les messages audio traduits dans un bucket de Cloud Storage for Firebase.

Application cliente

Le composant client est une application Android qui enregistre des messages audio et télécharge les messages traduits à partir du bucket Cloud Storage. L'exemple fourni ici est une application de chat utilisée dans le tutoriel Créer une application Android à l'aide de Firebase et de l'environnement flexible App Engine. Ce tutoriel décrit comment étendre l'exemple d'application afin de mettre en œuvre la fonctionnalité de traduction vocale.

Le schéma suivant illustre l'interaction entre le microservice et l'application cliente :

Architecture de haut niveau de la solution

Le microservice effectue les tâches suivantes :

  1. Il reçoit le message audio encodé en base64.
  2. Il transcrit le message audio à l'aide de l'API Speech-to-Text.
  3. Il traduit le message transcrit à l'aide de l'API Translation.
  4. Il synthétise le message traduit à l'aide de l'API Text-to-Speech.
  5. Il stocke le message audio traduit dans un bucket Cloud Storage.
  6. Il renvoie la réponse au client. Celle-ci inclut les paramètres régionaux du message audio traduit.

Architecture du microservice

L'application cliente effectue les tâches suivantes :

  1. Elle enregistre le message audio en suivant les bonnes pratiques de l'API Speech-to-Text pour une plus grande précision. L'application utilise le microphone de l'appareil pour enregistrer le contenu audio.
  2. Elle encode le message audio en base64.
  3. Elle envoie une requête HTTP au microservice, qui inclut le message audio encodé.
  4. Elle reçoit la réponse HTTP du microservice, qui inclut les paramètres régionaux du message audio traduit.
  5. Elle envoie une requête au bucket Cloud Storage pour récupérer le fichier contenant le message audio traduit.
  6. Elle lit le message audio traduit.

Objectifs

Ce tutoriel explique comment :

  • utiliser Cloud Functions for Firebase pour créer un microservice qui encapsule la logique nécessaire à la traduction de messages audio à l'aide des produits Cloud AI suivants :
    • API Speech-to-Text
    • API Translation
    • API Text-to-Speech
  • utiliser les API Android Framework pour enregistrer du contenu audio, en suivant les recommandations sur l'envoi de données audio à l'API Speech-to-Text ;
  • Utiliser la bibliothèque Cronet pour importer les données audio à partir de l'application cliente dans le microservice, ainsi que pour télécharger les messages traduits à partir de Cloud Storage. Pour en savoir plus sur la bibliothèque Cronet, consultez la page expliquant comment effectuer des opérations réseau à l'aide de Cronet dans la documentation destinée aux développeurs Android.

Coûts

Ce tutoriel étend l'exemple d'application mis en œuvre grâce aux instructions de la page Créer une application Android à l'aide de Firebase et de l'environnement flexible App Engine. Consultez la section Coûts du tutoriel indiqué, en tenant compte des frais supplémentaires suivants :

  • Firebase définit des quotas pour l'utilisation de Cloud Functions, qui spécifient les limites de ressources, de durée et de débit. Pour en savoir plus, consultez la page Quotas et limites de la documentation de Firebase.
  • L'utilisation de l'API Speech-to-Text fait l'objet d'une facturation mensuelle basée sur la longueur du message audio traité. Vous bénéficiez chaque mois d'une certaine durée de traitement gratuite. Pour en savoir plus, consultez la page Tarifs de l'API Speech-to-Text.
  • L'utilisation de l'API Translation est facturée mensuellement en fonction du nombre de caractères envoyés à l'API en vue d'un traitement. Pour en savoir plus, consultez la page relative aux tarifs de l'API Translation.
  • L'utilisation de l'API Text-to-Speech est facturée mensuellement en fonction du nombre de caractères à synthétiser en audio. Vous pouvez utiliser chaque mois un certain nombre de caractères gratuitement. Pour en savoir plus, consultez la page relative aux tarifs de l'API Text-to-Speech.
  • Les frais d'utilisation de Firebase Storage sont traités comme des frais Google Cloud Storage. Pour en savoir plus, consultez la page relative aux tarifs de Cloud Storage.

Avant de commencer

Suivez le tutoriel Créer une application Android à l'aide de Firebase et de l'environnement flexible App Engine, puis installez les logiciels suivants :

Utilisez un appareil exécutant Android version 7.0 (API de niveau 24) ou ultérieure pour tester la fonctionnalité de traduction vocale.

Cloner l'exemple de code

Exécutez la commande suivante pour cloner le dépôt nodejs-docs-samples, qui inclut le code du microservice :

git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

Activer la facturation et les API pour le projet Google Cloud

Ce tutoriel utilise le projet Playchat, créé en suivant les instructions de la page "Créer une application Android à l'aide de Firebase et de l'environnement flexible App Engine". Ce projet nécessite les API App Engine Admin et Compute Engine.

Le microservice nécessite les API suivantes pour traiter les requêtes de traduction vocale :

  • API Text-to-Speech
  • API Cloud Translation
  • API Speech-to-Text

Pour activer les API requises, procédez comme suit :

  1. Dans Google Cloud Console, sélectionnez le projet Playchat.

    Accéder à la page Projets

  2. Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

  3. Activer les API App Engine, Speech-to-Text, Translation, and Text-to-Speech.

    Activer les API

Configurer le bucket par défaut sur Cloud Storage for Firebase

Le microservice utilise le bucket Cloud Storage par défaut du projet Firebase pour stocker les fichiers audio traduits. Vous devez activer l'accès en lecture aux comptes utilisateur qui souhaitent récupérer les fichiers audio.

Pour activer l'accès en lecture, vous avez besoin de l'ID de l'utilisateur Firebase du compte. Pour récupérer cet ID utilisateur, procédez comme suit :

  1. Dans le menu de gauche de la console Firebase, sélectionnez Authentification dans le groupe Développer.
  2. Prenez note de la valeur ID utilisateur du compte utilisateur avec lequel vous souhaitez tester l'application. L'ID utilisateur est une chaîne de 28 caractères.

Pour activer l'accès en lecture au compte utilisateur, vous devez créer une règle de sécurité relative au stockage en procédant comme suit :

  1. Dans le menu de gauche de la console Firebase, sélectionnez Stockage dans le groupe Développer.
  2. Prenez note de l'URL du bucket par défaut, au format gs://[FIREBASE_PROJECT_ID].appspot.com, qui apparaît à côté d'une icône de lien. Vous avez besoin de cette valeur pour déployer le microservice.
  3. Sur la page Stockage, accédez à la section Règles et ajoutez la règle suivante dans la section service firebase.storage :

     match /b/{bucket}/o {
       match /{allPaths=**} {
         allow read: if request.auth.uid == "[ACCOUNT_USER_UID]";
       }
     }
    

    Remplacez ACCOUNT_USER_UID par la valeur d'ID utilisateur obtenue lors des étapes précédentes.

Pour en savoir plus, consultez la page Get Started with Storage Security Rules (Premiers pas avec les règles de sécurité relatives au stockage) de la documentation Firebase.

Créer et déployer le microservice

Pour créer le microservice, ouvrez une fenêtre de terminal et accédez au dossier functions/speech-to-speech/functions du dépôt nodejs-docs-samples que vous avez cloné dans la section précédente.

Le code du microservice inclut un fichier .nvmrc qui déclare la version de Node.js que vous devez utiliser pour exécuter l'application. Exécutez la commande suivante pour configurer NVM et installer les dépendances du microservice :

nvm install && nvm use && npm install

Connectez-vous à Firebase à l'aide de l'interface de ligne de commande en exécutant la commande suivante :

firebase login

Le microservice nécessite les variables d'environnement suivantes :

  • OUTPUT_BUCKET, qui correspond au bucket Cloud Storage par défaut du projet Firebase.
  • SUPPORTED_LANGUAGE_CODES, qui correspond à la liste de codes de langues compatibles avec le microservice, séparés par des virgules.

Exécutez les commandes suivantes pour déclarer les données d'environnement requises dans l'interface de ligne de commande. Remplacez l'espace réservé FIREBASE_PROJECT_ID par la valeur recherchée dans la section précédente.

firebase functions:config:set playchat.output_bucket="gs://[FIREBASE_PROJECT_ID].appspot.com"
firebase functions:config:set playchat.supported_language_codes="en,es,fr"

Configurer l'application Android

L'exemple d'application Playchat nécessite l'URL du microservice pour activer les fonctionnalités de traduction vocale. Pour récupérer l'URL du microservice, procédez comme suit :

  1. Dans le menu de gauche de la console Firebase, sélectionnez Fonctions dans le groupe Développer.
  2. L'URL du microservice s'affiche dans la colonne Déclencheur, au format https://[REGION_ID]-[FIREBASE_PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME].

Pour configurer l'application afin qu'elle fonctionne avec le microservice, ouvrez le fichier app/src/main/res/values/speech_translation.xml dans le dépôt firebase-android-client, puis remplacez la valeur du champ speechToSpeechEndpoint par l'URL du microservice.

Exécuter l'application Android

Pour exploiter la fonctionnalité de traduction vocale dans l'application, vous devez utiliser un appareil permettant l'enregistrement audio à l'aide du micro intégré, tel qu'un dispositif matériel.

Pour utiliser la fonctionnalité de traduction vocale dans l'application, procédez comme suit :

  1. Assurez-vous que le dispositif matériel utilise l'une des langues configurées dans la section Créer et déployer le microservice. Pour modifier la langue, ouvrez l'application Settings (Paramètres) sur l'appareil, puis sélectionnez System > Languages & input > Languages (Système > Langues et saisie > Langues).
  2. Ouvrez le projet Playchat dans Android Studio, puis connectez le dispositif matériel à votre ordinateur à l'aide d'un câble USB. Pour en savoir plus, consultez la page expliquant comment configurer un appareil pour le développement.
  3. Cliquez sur Run (Exécuter) dans Android Studio pour créer et exécuter l'application sur l'appareil.
  4. Sur l'application Playchat, appuyez sur l'icône en forme de microphone pour démarrer l'enregistrement, enregistrez un court message, puis appuyez de nouveau sur cette icône pour arrêter l'enregistrement.
  5. Après quelques secondes, l'application Playchat affiche le texte du message enregistré à l'écran. Appuyez sur le message pour lire la version audio.
  6. Configurez l'appareil afin d'utiliser une autre langue compatible.
  7. L'application Playchat affiche le message précédemment enregistré dans cette nouvelle langue. Appuyez sur le message pour lire la version audio dans cette nouvelle langue.

La capture d'écran suivante montre l'application Playchat affichant un message traduit en français :

Fonctionnalité de traduction vocale sous Android

Explorer le code

L'application cliente effectue les tâches suivantes pour assurer la compatibilité de la fonctionnalité de traduction vocale :

  1. Elle enregistre le contenu audio à l'aide des paramètres recommandés décrits dans les bonnes pratiques de l'API Speech-to-Text.
  2. Elle encode le message audio en base64 pour le représenter dans un format de chaîne pouvant être intégré à une requête HTTP.
  3. Elle envoie une requête HTTP au microservice. La requête comprend le message audio codé, ainsi que des métadonnées fournissant des informations supplémentaires sur la charge utile. L'application gère les requêtes réseau à l'aide de la bibliothèque Cronet.
  4. Lorsque l'utilisateur souhaite écouter le message traduit, l'application télécharge le fichier audio correspondant en envoyant une requête HTTP authentifiée au bucket Cloud Storage, qui stocke les messages traduits.

L'exemple de code suivant affiche les constantes utilisées par l'exemple pour spécifier les paramètres de configuration d'enregistrement :

private static final int AUDIO_SOURCE = MediaRecorder.AudioSource.UNPROCESSED;
private static final int SAMPLE_RATE_IN_HZ = 16000;
private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
  • AUDIO_SOURCE : MediaRecorder.AudioSource.UNPROCESSED indique une source audio non traitée, car l'utilisation d'algorithmes de traitement du signal, tels que la réduction du bruit ou le contrôle de gain, réduit la précision de la reconnaissance.
  • SAMPLE_RATE_IN_HZ : l'échantillon utilise la valeur 16,000 pour le taux d'échantillonnage natif de la source audio.
  • CHANNEL_CONFIG : AudioFormat.CHANNEL_IN_MONO indique un seul canal audio dans l'enregistrement. L'échantillon part du principe que l'enregistrement ne comporte la voix que d'une personne.
  • AUDIO_FORMAT : AudioFormat.ENCODING_PCM_16BIT indique le format de données audio PCM linéaire, utilisant 16 bits par échantillon. Le format PCM linéaire est un format sans perte, recommandé pour la reconnaissance vocale.

L'application cliente utilise l'API AudioRecord pour enregistrer du contenu audio à partir du microphone intégré, et stocke un fichier .WAV sur l'appareil. Pour en savoir plus, consultez la classe RecordingHelper de l'exemple Playchat.

Pour encoder le message audio en base64, l'exemple utilise la classe Base64 d'Android Framework. Le message audio encodé ne doit pas inclure de sauts de ligne, qui sont omis à l'aide de l'option NO_WRAP. L'exemple suivant montre comment encoder le message audio à l'aide de la classe Base64 :

public static String encode(File inputFile) throws IOException {
    byte[] data = new byte[(int) inputFile.length()];
    DataInputStream input = new DataInputStream(new FileInputStream(inputFile));
    int readBytes = input.read(data);
    Log.i(TAG, readBytes + " read from input file.");
    input.close();
    return Base64.encodeToString(data, Base64.NO_WRAP);
}

Pour envoyer le message audio encodé au microservice, l'application cliente émet une requête HTTP disposant des paramètres suivants :

  • Méthode : POST
  • Type de contenu : application/json
  • Corps : objet JSON possédant les attributs suivants :
    • encoding, qui correspond à la chaîne LINEAR16.
    • sampleRateHertz, qui correspond au taux d'échantillonnage du contenu audio enregistré. Par exemple, 16000.
    • languageCode, qui correspond au code de langue du message enregistré. L'application cliente suppose que le message est enregistré dans la langue configurée dans les paramètres de l'appareil (par exemple, en-US).
    • audioContent, qui correspond au message audio encodé en base64.

L'exemple suivant montre comment créer un objet JSON incluant les attributs requis dans le corps de la requête :

JSONObject requestBody = new JSONObject();
try {
    requestBody.put("encoding", SPEECH_TRANSLATE_ENCODING);
    requestBody.put("sampleRateHertz", sampleRateInHertz);
    requestBody.put("languageCode", context.getResources().getConfiguration().getLocales().get(0));
    requestBody.put("audioContent", base64EncodedAudioMessage);
} catch(JSONException e) {
    Log.e(TAG, e.getLocalizedMessage());
    translationListener.onTranslationFailed(e);
}

Pour en savoir plus sur la création de la requête HTTP, consultez la classe SpeechTranslationHelper de l'exemple d'application Playchat.

Pour récupérer les fichiers audio du bucket Cloud Storage, l'application utilise une URL de téléchargement qui inclut un jeton pouvant être révoqué à partir de la console Firebase, si vous le souhaitez. Vous pouvez obtenir l'URL de téléchargement en appelant la méthode getDownloadUrl(), comme indiqué dans l'exemple suivant :

FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference gsReference = storage.getReferenceFromUrl(gcsUrl);
gsReference.getDownloadUrl().addOnCompleteListener(getDownloadUriListener);

Le microservice effectue les tâches suivantes pour permettre la compatibilité avec la fonctionnalité de traduction vocale :

  1. Il reçoit les requêtes de traduction vocale, qui incluent le message audio encodé en base64.
  2. Il envoie le contenu audio encodé à l'API Speech-to-Text et reçoit une transcription dans la langue source.
  3. Pour chacune des langues compatibles, il envoie la transcription à l'API Translation et reçoit le texte traduit.
  4. Pour chacune des langues compatibles, il envoie le texte traduit à l'API Cloud Text-to-Speech et reçoit le message audio traduit.
  5. Il importe les fichiers audio traduits dans le bucket Cloud Storage.

Le microservice utilise le résultat d'un appel à une API Cloud comme entrée de l'appel de la prochaine API, comme illustré dans l'exemple de code suivant :

const [sttResponse] = await callSpeechToText(
  inputAudioContent,
  inputEncoding,
  inputSampleRateHertz,
  inputLanguageCode
);

// The data object contains one or more recognition
// alternatives ordered by accuracy.
const transcription = sttResponse.results
  .map(result => result.alternatives[0].transcript)
  .join('\n');
responseBody.transcription = transcription;
responseBody.gcsBucket = outputBucket;

const translations = [];
supportedLanguageCodes.forEach(async languageCode => {
  const translation = {languageCode: languageCode};
  const outputFilename =
    request.body.outputFilename ||
    `${uuid.v4()}.${outputAudioEncoding.toLowerCase()}`;

  try {
    const [textTranslation] = await callTextTranslation(
      languageCode,
      transcription
    );
    translation.text = textTranslation;

    const [{audioContent}] = await callTextToSpeech(
      languageCode,
      textTranslation
    );
    const path = `${languageCode}/${outputFilename}`;

    console.log('zzx', audioContent);

    await uploadToCloudStorage(path, audioContent);

    console.log(`Successfully translated input to ${languageCode}.`);
    translation.gcsPath = path;
    translations.push(translation);
    if (translations.length === supportedLanguageCodes.length) {
      responseBody.translations = translations;
      console.log(`Response: ${JSON.stringify(responseBody)}`);
      response.status(200).send(responseBody);
    }
  } catch (error) {
    console.error(
      `Partial error in translation to ${languageCode}: ${error}`
    );
    translation.error = error.message;
    translations.push(translation);
    if (translations.length === supportedLanguageCodes.length) {
      responseBody.translations = translations;
      console.log(`Response: ${JSON.stringify(responseBody)}`);
      response.status(200).send(responseBody);
    }
  }
});

Nettoyer

Pour éviter que les ressources utilisées dans ce tutoriel soient facturées sur votre compte Google Cloud, procédez comme suit :

Supprimer le projet Google Cloud et Firebase

Le moyen le plus simple d'arrêter les frais de facturation consiste à supprimer le projet que vous avez créé dans le cadre de ce tutoriel. Bien que vous ayez créé le projet dans la console Firebase, vous pouvez également le supprimer dans Google Cloud Console, car les projets Firebase et Google Cloud ne font qu'un.

  1. Dans Cloud Console, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Supprimer les versions autres que celles par défaut de votre application App Engine

Si vous ne souhaitez pas supprimer votre projet Google Cloud et Firebase, vous pouvez réduire les coûts en supprimant les versions autres que celles par défaut de votre application d'environnement flexible App Engine.

  1. Dans Cloud Console, accédez à la page Versions pour App Engine.

    Accéder à la page "Versions"

  2. Cochez la case correspondant à la version de l'application autre que celle par défaut que vous souhaitez supprimer.
  3. Pour supprimer la version de l'application, cliquez sur  Supprimer.