Reconnaissance vocale à l’aide d’Azure Speech Service
Azure Speech Service est une API basée sur le cloud qui offre les fonctionnalités suivantes :
- La reconnaissance vocale transcrit des fichiers audio ou des flux en texte.
- La synthèse vocale convertit le texte d’entrée en synthèse vocale de type humain.
- La traduction vocale permet une traduction en temps réel en plusieurs langues pour la reconnaissance vocale et la reconnaissance vocale.
- Les assistants vocaux peuvent créer des interfaces de conversation de type humain pour les applications.
Cet article explique comment la reconnaissance vocale est implémentée dans l’exemple d’application Xamarin.Forms à l’aide du service Azure Speech. Les captures d’écran suivantes montrent l’exemple d’application sur iOS et Android :
Créer une ressource Azure Speech Service
Azure Speech Service fait partie d’Azure Cognitive Services, qui fournit des API basées sur le cloud pour des tâches telles que la reconnaissance d’images, la reconnaissance vocale et la traduction vocale et la recherche Bing. Pour plus d’informations, consultez Qu’est-ce qu’Azure Cognitive Services ?.
L’exemple de projet nécessite la création d’une ressource Azure Cognitive Services dans votre Portail Azure. Une ressource Cognitive Services peut être créée pour un seul service, tel que le service Speech, ou en tant que ressource multiservices. Les étapes de création d’une ressource de service Speech sont les suivantes :
- Connectez-vous à votre Portail Azure.
- Créez une ressource multiservices ou à service unique.
- Obtenez les informations de clé d’API et de région pour votre ressource.
- Mettez à jour l’exemple de fichier Constants.cs .
Pour obtenir un guide pas à pas pour créer une ressource, consultez Créer une ressource Cognitive Services.
Remarque
Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer. Une fois que vous disposez d’un compte, une ressource à service unique peut être créée au niveau gratuit pour essayer le service.
Configurer votre application avec le service Speech
Après avoir créé une ressource Cognitive Services, le fichier Constants.cs peut être mis à jour avec la région et la clé API à partir de votre ressource Azure :
public static class Constants
{
public static string CognitiveServicesApiKey = "YOUR_KEY_GOES_HERE";
public static string CognitiveServicesRegion = "westus";
}
Installer le package du service NuGet Speech
L’exemple d’application utilise le package NuGet Microsoft.CognitiveServices.Speech pour se connecter au service Azure Speech. Installez ce package NuGet dans le projet partagé et chaque projet de plateforme.
Créer une interface IMicrophoneService
Chaque plateforme nécessite l’autorisation d’accéder au microphone. L’exemple de projet fournit une IMicrophoneService
interface dans le projet partagé et utilise les Xamarin.FormsDependencyService
implémentations de plateforme de l’interface.
public interface IMicrophoneService
{
Task<bool> GetPermissionAsync();
void OnRequestPermissionResult(bool isGranted);
}
Créer la mise en page
L’exemple de projet définit une mise en page de base dans le fichier MainPage.xaml . Les éléments de disposition clés sont un Button
élément qui démarre le processus de transcription, un Label
pour contenir le texte transcrit et un ActivityIndicator
à afficher lorsque la transcription est en cours :
<ContentPage ...>
<StackLayout>
<Frame ...>
<ScrollView x:Name="scroll"
...>
<Label x:Name="transcribedText"
... />
</ScrollView>
</Frame>
<ActivityIndicator x:Name="transcribingIndicator"
IsRunning="False" />
<Button x:Name="transcribeButton"
...
Clicked="TranscribeClicked"/>
</StackLayout>
</ContentPage>
Implémenter le service Speech
Le fichier code-behind MainPage.xaml.cs contient toute la logique permettant d’envoyer du texte audio et de recevoir du texte transcrit à partir du service Azure Speech.
Le MainPage
constructeur obtient une instance de l’interface IMicrophoneService
à partir de :DependencyService
public partial class MainPage : ContentPage
{
SpeechRecognizer recognizer;
IMicrophoneService micService;
bool isTranscribing = false;
public MainPage()
{
InitializeComponent();
micService = DependencyService.Resolve<IMicrophoneService>();
}
// ...
}
La TranscribeClicked
méthode est appelée lorsque l’instance transcribeButton
est tapée :
async void TranscribeClicked(object sender, EventArgs e)
{
bool isMicEnabled = await micService.GetPermissionAsync();
// EARLY OUT: make sure mic is accessible
if (!isMicEnabled)
{
UpdateTranscription("Please grant access to the microphone!");
return;
}
// initialize speech recognizer
if (recognizer == null)
{
var config = SpeechConfig.FromSubscription(Constants.CognitiveServicesApiKey, Constants.CognitiveServicesRegion);
recognizer = new SpeechRecognizer(config);
recognizer.Recognized += (obj, args) =>
{
UpdateTranscription(args.Result.Text);
};
}
// if already transcribing, stop speech recognizer
if (isTranscribing)
{
try
{
await recognizer.StopContinuousRecognitionAsync();
}
catch(Exception ex)
{
UpdateTranscription(ex.Message);
}
isTranscribing = false;
}
// if not transcribing, start speech recognizer
else
{
Device.BeginInvokeOnMainThread(() =>
{
InsertDateTimeRecord();
});
try
{
await recognizer.StartContinuousRecognitionAsync();
}
catch(Exception ex)
{
UpdateTranscription(ex.Message);
}
isTranscribing = true;
}
UpdateDisplayState();
}
La méthode TranscribeClicked
effectue les opérations suivantes :
- Vérifie si l’application a accès au microphone et quitte tôt si ce n’est pas le cas.
- Crée une instance de
SpeechRecognizer
classe si elle n’existe pas déjà. - Arrête la transcription continue si elle est en cours.
- Insère un horodatage et démarre la transcription continue si elle n’est pas en cours.
- Avertit l’application de mettre à jour son apparence en fonction de l’état de la nouvelle application.
Le reste des méthodes de classe sont des helpers pour afficher l’état de MainPage
l’application :
void UpdateTranscription(string newText)
{
Device.BeginInvokeOnMainThread(() =>
{
if (!string.IsNullOrWhiteSpace(newText))
{
transcribedText.Text += $"{newText}\n";
}
});
}
void InsertDateTimeRecord()
{
var msg = $"=================\n{DateTime.Now.ToString()}\n=================";
UpdateTranscription(msg);
}
void UpdateDisplayState()
{
Device.BeginInvokeOnMainThread(() =>
{
if (isTranscribing)
{
transcribeButton.Text = "Stop";
transcribeButton.BackgroundColor = Color.Red;
transcribingIndicator.IsRunning = true;
}
else
{
transcribeButton.Text = "Transcribe";
transcribeButton.BackgroundColor = Color.Green;
transcribingIndicator.IsRunning = false;
}
});
}
La UpdateTranscription
méthode écrit l’élément fourni Label
newText
string
nommé .transcribedText
Elle force cette mise à jour à se produire sur le thread d’interface utilisateur afin qu’elle puisse être appelée à partir de n’importe quel contexte sans provoquer d’exceptions. Écrit InsertDateTimeRecord
la date et l’heure actuelles dans l’instance transcribedText
pour marquer le début d’une nouvelle transcription. Enfin, la UpdateDisplayState
méthode met à jour les éléments et ActivityIndicator
les Button
éléments pour refléter si la transcription est en cours ou non.
Créer des services de microphone de plateforme
L’application doit disposer d’un accès microphone pour collecter des données vocales. L’interface IMicrophoneService
doit être implémentée et inscrite auprès de chaque DependencyService
plateforme pour que l’application fonctionne.
Android
L’exemple de projet définit une IMicrophoneService
implémentation pour Android appelée AndroidMicrophoneService
:
[assembly: Dependency(typeof(AndroidMicrophoneService))]
namespace CognitiveSpeechService.Droid.Services
{
public class AndroidMicrophoneService : IMicrophoneService
{
public const int RecordAudioPermissionCode = 1;
private TaskCompletionSource<bool> tcsPermissions;
string[] permissions = new string[] { Manifest.Permission.RecordAudio };
public Task<bool> GetPermissionAsync()
{
tcsPermissions = new TaskCompletionSource<bool>();
if ((int)Build.VERSION.SdkInt < 23)
{
tcsPermissions.TrySetResult(true);
}
else
{
var currentActivity = MainActivity.Instance;
if (ActivityCompat.CheckSelfPermission(currentActivity, Manifest.Permission.RecordAudio) != (int)Permission.Granted)
{
RequestMicPermissions();
}
else
{
tcsPermissions.TrySetResult(true);
}
}
return tcsPermissions.Task;
}
public void OnRequestPermissionResult(bool isGranted)
{
tcsPermissions.TrySetResult(isGranted);
}
void RequestMicPermissions()
{
if (ActivityCompat.ShouldShowRequestPermissionRationale(MainActivity.Instance, Manifest.Permission.RecordAudio))
{
Snackbar.Make(MainActivity.Instance.FindViewById(Android.Resource.Id.Content),
"Microphone permissions are required for speech transcription!",
Snackbar.LengthIndefinite)
.SetAction("Ok", v =>
{
((Activity)MainActivity.Instance).RequestPermissions(permissions, RecordAudioPermissionCode);
})
.Show();
}
else
{
ActivityCompat.RequestPermissions((Activity)MainActivity.Instance, permissions, RecordAudioPermissionCode);
}
}
}
}
Les AndroidMicrophoneService
fonctionnalités suivantes sont les suivantes :
- L’attribut
Dependency
inscrit la classe avec leDependencyService
. - La
GetPermissionAsync
méthode vérifie si les autorisations sont requises en fonction de la version du Kit de développement logiciel (SDK) Android et appelleRequestMicPermissions
si l’autorisation n’a pas déjà été accordée. - La
RequestMicPermissions
méthode utilise laSnackbar
classe pour demander des autorisations à l’utilisateur si une justification est requise, sinon elle demande directement des autorisations d’enregistrement audio. - La
OnRequestPermissionResult
méthode est appelée avec unbool
résultat une fois que l’utilisateur a répondu à la demande d’autorisations.
La MainActivity
classe est personnalisée pour mettre à jour l’instance AndroidMicrophoneService
lorsque les demandes d’autorisations sont terminées :
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
IMicrophoneService micService;
internal static MainActivity Instance { get; private set; }
protected override void OnCreate(Bundle savedInstanceState)
{
Instance = this;
// ...
micService = DependencyService.Resolve<IMicrophoneService>();
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
// ...
switch(requestCode)
{
case AndroidMicrophoneService.RecordAudioPermissionCode:
if (grantResults[0] == Permission.Granted)
{
micService.OnRequestPermissionResult(true);
}
else
{
micService.OnRequestPermissionResult(false);
}
break;
}
}
}
La MainActivity
classe définit une référence statique appelée Instance
, qui est requise par l’objet lors de la AndroidMicrophoneService
demande d’autorisations. Il remplace la OnRequestPermissionsResult
méthode pour mettre à jour l’objet AndroidMicrophoneService
lorsque la demande d’autorisations est approuvée ou refusée par l’utilisateur.
Enfin, l’application Android doit inclure l’autorisation d’enregistrer l’audio dans le fichier AndroidManifest.xml :
<manifest ...>
...
<uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest>
iOS
L’exemple de projet définit une IMicrophoneService
implémentation pour iOS appelée iOSMicrophoneService
:
[assembly: Dependency(typeof(iOSMicrophoneService))]
namespace CognitiveSpeechService.iOS.Services
{
public class iOSMicrophoneService : IMicrophoneService
{
TaskCompletionSource<bool> tcsPermissions;
public Task<bool> GetPermissionAsync()
{
tcsPermissions = new TaskCompletionSource<bool>();
RequestMicPermission();
return tcsPermissions.Task;
}
public void OnRequestPermissionResult(bool isGranted)
{
tcsPermissions.TrySetResult(isGranted);
}
void RequestMicPermission()
{
var session = AVAudioSession.SharedInstance();
session.RequestRecordPermission((granted) =>
{
tcsPermissions.TrySetResult(granted);
});
}
}
}
Les iOSMicrophoneService
fonctionnalités suivantes sont les suivantes :
- L’attribut
Dependency
inscrit la classe avec leDependencyService
. - La
GetPermissionAsync
méthode appelleRequestMicPermissions
pour demander des autorisations à l’utilisateur de l’appareil. - La
RequestMicPermissions
méthode utilise l’instance partagéeAVAudioSession
pour demander des autorisations d’enregistrement. - La
OnRequestPermissionResult
méthode met à jour l’instanceTaskCompletionSource
avec la valeur fourniebool
.
Enfin, l’application iOS Info.plist doit inclure un message indiquant à l’utilisateur pourquoi l’application demande l’accès au microphone. Modifiez le fichier Info.plist pour inclure les balises suivantes dans l’élément <dict>
:
<plist>
<dict>
...
<key>NSMicrophoneUsageDescription</key>
<string>Voice transcription requires microphone access</string>
</dict>
</plist>
UWP
L’exemple de projet définit une IMicrophoneService
implémentation pour UWP appelée UWPMicrophoneService
:
[assembly: Dependency(typeof(UWPMicrophoneService))]
namespace CognitiveSpeechService.UWP.Services
{
public class UWPMicrophoneService : IMicrophoneService
{
public async Task<bool> GetPermissionAsync()
{
bool isMicAvailable = true;
try
{
var mediaCapture = new MediaCapture();
var settings = new MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
await mediaCapture.InitializeAsync(settings);
}
catch(Exception ex)
{
isMicAvailable = false;
}
if(!isMicAvailable)
{
await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-microphone"));
}
return isMicAvailable;
}
public void OnRequestPermissionResult(bool isGranted)
{
// intentionally does nothing
}
}
}
Les UWPMicrophoneService
fonctionnalités suivantes sont les suivantes :
- L’attribut
Dependency
inscrit la classe avec leDependencyService
. - La
GetPermissionAsync
méthode tente d’initialiser uneMediaCapture
instance. En cas d’échec, il lance une demande d’utilisateur pour activer le microphone. - La
OnRequestPermissionResult
méthode existe pour satisfaire l’interface, mais n’est pas requise pour l’implémentation UWP.
Enfin, le package.appxmanifest UWP doit spécifier que l’application utilise le microphone. Double-cliquez sur le fichier Package.appxmanifest et sélectionnez l’option Microphone sous l’onglet Fonctionnalités de Visual Studio 2019 :
Test de l’application
Exécutez l’application, puis cliquez sur le bouton Transcrire . L’application doit demander l’accès au microphone et commencer le processus de transcription. L’animation ActivityIndicator
s’animera, montrant que la transcription est active. À mesure que vous parlez, l’application diffuse en continu des données audio vers la ressource Azure Speech Services, qui répond avec du texte transcrit. Le texte transcrit apparaît dans l’élément Label
tel qu’il est reçu.
Remarque
Les émulateurs Android ne peuvent pas charger et initialiser les bibliothèques du service Speech. Le test sur un appareil physique est recommandé pour la plateforme Android.