Freigeben über


Spracherkennung mit Azure Speech Service

Azure Speech Service ist eine cloudbasierte API, die die folgenden Funktionen bietet:

  • Sprach-zu-Text transkribiert Audiodateien oder Datenströme in Text.
  • Text-zu-Sprache wandelt Eingabetext in eine synthetisierte Sprache des Menschen um.
  • Die Sprachübersetzung ermöglicht die Echtzeitübersetzung, multisprachige Übersetzung sowohl für Sprache zu Text als auch für Sprache zu Sprache.
  • Sprachassistenten können benutzerähnliche Unterhaltungsschnittstellen für Anwendungen erstellen.

In diesem Artikel wird erläutert, wie Sprach-zu-Text in der Beispielanwendung Xamarin.Forms mithilfe des Azure-Sprachdiensts implementiert wird. Die folgenden Screenshots zeigen die Beispielanwendung unter iOS und Android:

Screenshots der Beispielanwendung unter iOS und Android

Erstellen einer Azure Speech Service-Ressource

Azure Speech Service ist Teil von Azure Cognitive Services, das cloudbasierte APIs für Aufgaben wie Bilderkennung, Spracherkennung und Übersetzung und Bing-Suche bereitstellt. Weitere Informationen finden Sie unter Was sind Azure Cognitive Services?.

Für das Beispielprojekt muss eine Azure Cognitive Services-Ressource in Ihrem Azure-Portal erstellt werden. Eine Cognitive Services-Ressource kann für einen einzelnen Dienst, z. B. Speech Service, oder als Multi-Service-Ressource erstellt werden. Die Schritte zum Erstellen einer Speech Service-Ressource lauten wie folgt:

  1. Melden Sie sich bei Ihrem Azure-Portal an.
  2. Erstellen Sie eine Mehrdienst- oder Einzeldienstressource.
  3. Rufen Sie den API-Schlüssel und die Regionsinformationen für Ihre Ressource ab.
  4. Aktualisieren Sie das Beispiel Constants.cs Datei.

Eine schrittweise Anleitung zum Erstellen einer Ressource finden Sie unter Erstellen einer Cognitive Services-Ressource.

Hinweis

Wenn Sie kein Azure-Abonnement besitzen, erstellen Sie ein kostenloses Konto, bevor Sie beginnen. Sobald Sie über ein Konto verfügen, kann eine Einzeldienstressource auf der kostenlosen Ebene erstellt werden, um den Dienst auszuprobieren.

Konfigurieren Ihrer App mit dem Spracherkennungsdienst

Nach dem Erstellen einer Cognitive Services-Ressource kann die Constants.cs Datei mit dem Region- und API-Schlüssel aus Ihrer Azure-Ressource aktualisiert werden:

public static class Constants
{
    public static string CognitiveServicesApiKey = "YOUR_KEY_GOES_HERE";
    public static string CognitiveServicesRegion = "westus";
}

Installieren des NuGet Speech Service-Pakets

Die Beispielanwendung verwendet das Microsoft.CognitiveServices.Speech NuGet-Paket, um eine Verbindung mit dem Azure Speech Service herzustellen. Installieren Sie dieses NuGet-Paket im freigegebenen Projekt und jedem Plattformprojekt.

Erstellen einer IMicrophoneService-Schnittstelle

Jede Plattform erfordert die Berechtigung für den Zugriff auf das Mikrofon. Das Beispielprojekt stellt eine IMicrophoneService Schnittstelle im freigegebenen Projekt bereit und verwendet die Xamarin.FormsDependencyService Plattformimplementierungen der Schnittstelle.

public interface IMicrophoneService
{
    Task<bool> GetPermissionAsync();
    void OnRequestPermissionResult(bool isGranted);
}

Erstellen des Seitenlayouts

Das Beispielprojekt definiert ein einfaches Seitenlayout in der Datei "MainPage.xaml ". Die wichtigsten Layoutelemente sind ein Button Element, das den Transkriptionsprozess startet, einen Label , der den transkribierten Text enthält, und eine ActivityIndicator , die angezeigt werden soll, wann die Transkription ausgeführt wird:

<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>

Implementieren des Sprachdiensts

Die MainPage.xaml.cs CodeBehind-Datei enthält alle Logik zum Senden von Audio und Empfangen von transkribiertem Text vom Azure Speech Service.

Der MainPage Konstruktor ruft eine Instanz der IMicrophoneService Schnittstelle aus dem DependencyService:

public partial class MainPage : ContentPage
{
    SpeechRecognizer recognizer;
    IMicrophoneService micService;
    bool isTranscribing = false;

    public MainPage()
    {
        InitializeComponent();

        micService = DependencyService.Resolve<IMicrophoneService>();
    }

    // ...
}

Die TranscribeClicked Methode wird aufgerufen, wenn auf die transcribeButton Instanz getippt wird:

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();
}

Die TranscribeClicked-Methode führt folgende Schritte aus:

  1. Überprüft, ob die Anwendung frühzeitig auf das Mikrofon zugreifen kann und beendet, wenn dies nicht der Fall ist.
  2. Erstellt eine Instanz der SpeechRecognizer Klasse, wenn sie noch nicht vorhanden ist.
  3. Beendet die fortlaufende Transkription, wenn sie ausgeführt wird.
  4. Fügt einen Zeitstempel ein und startet eine fortlaufende Transkription, wenn sie nicht ausgeführt wird.
  5. Benachrichtigt die Anwendung, ihre Darstellung basierend auf dem neuen Anwendungszustand zu aktualisieren.

Die restlichen MainPage Klassenmethoden sind Hilfsprogramme zum Anzeigen des Anwendungszustands:

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;
        }
    });
}

Die UpdateTranscription Methode schreibt das bereitgestellte newText string Element mit dem Label Namen transcribedText. Sie erzwingt diese Aktualisierung im UI-Thread, sodass sie aus einem beliebigen Kontext aufgerufen werden kann, ohne dass Ausnahmen auftreten. Das InsertDateTimeRecord aktuelle Datum und die aktuelle Uhrzeit werden in die transcribedText Instanz geschrieben, um den Beginn einer neuen Transkription zu markieren. Schließlich aktualisiert die UpdateDisplayState Methode die Button elemente und ActivityIndicator gibt an, ob die Transkription ausgeführt wird.

Erstellen von Plattformmikrofondiensten

Die Anwendung muss über Mikrofonzugriff verfügen, um Sprachdaten zu sammeln. Die IMicrophoneService Schnittstelle muss auf jeder DependencyService Plattform implementiert und registriert werden, damit die Anwendung funktioniert.

Android

Das Beispielprojekt definiert eine IMicrophoneService Implementierung für Android namens 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);
            }
        }
    }
}

Die AndroidMicrophoneService folgenden Features sind verfügbar:

  1. Das Dependency Attribut registriert die Klasse mit der DependencyService.
  2. Die GetPermissionAsync Methode überprüft, ob Berechtigungen basierend auf der Android SDK-Version erforderlich sind, und Aufrufe RequestMicPermissions , wenn noch keine Berechtigung erteilt wurde.
  3. Die RequestMicPermissions Methode verwendet die Snackbar Klasse, um Berechtigungen vom Benutzer anzufordern, wenn eine Begründung erforderlich ist, andernfalls werden direkt Audioaufzeichnungsberechtigungen angefordert.
  4. Die OnRequestPermissionResult Methode wird mit einem bool Ergebnis aufgerufen, nachdem der Benutzer auf die Berechtigungsanforderung geantwortet hat.

Die MainActivity Klasse wird so angepasst, dass die AndroidMicrophoneService Instanz aktualisiert wird, wenn Berechtigungsanforderungen abgeschlossen sind:

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;
        }
    }
}

Die MainActivity Klasse definiert einen statischen Verweis, Instanceder AndroidMicrophoneService beim Anfordern von Berechtigungen vom Objekt benötigt wird. Sie setzt die OnRequestPermissionsResult Methode außer Kraft, um das AndroidMicrophoneService Objekt zu aktualisieren, wenn die Berechtigungsanforderung vom Benutzer genehmigt oder verweigert wird.

Schließlich muss die Android-Anwendung die Berechtigung zum Aufzeichnen von Audio in der AndroidManifest.xml Datei enthalten:

<manifest ...>
    ...
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest>

iOS

Das Beispielprojekt definiert eine IMicrophoneService Implementierung für iOS namens 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);
            });
        }
    }
}

Die iOSMicrophoneService folgenden Features sind verfügbar:

  1. Das Dependency Attribut registriert die Klasse mit der DependencyService.
  2. Die GetPermissionAsync Methode ruft auf RequestMicPermissions , um Berechtigungen vom Gerätebenutzer anzufordern.
  3. Die RequestMicPermissions Methode verwendet die freigegebene AVAudioSession Instanz, um Aufzeichnungsberechtigungen anzufordern.
  4. Die OnRequestPermissionResult Methode aktualisiert die TaskCompletionSource Instanz mit dem bereitgestellten bool Wert.

Schließlich muss die iOS-App Info.plist eine Meldung enthalten, die dem Benutzer angibt, warum die App Zugriff auf das Mikrofon anfordert. Bearbeiten Sie die Datei "Info.plist", um die folgenden Tags in das <dict> Element einzuschließen:

<plist>
    <dict>
        ...
        <key>NSMicrophoneUsageDescription</key>
        <string>Voice transcription requires microphone access</string>
    </dict>
</plist>

UWP

Das Beispielprojekt definiert eine IMicrophoneService Implementierung für UWP namens 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
        }
    }
}

Die UWPMicrophoneService folgenden Features sind verfügbar:

  1. Das Dependency Attribut registriert die Klasse mit der DependencyService.
  2. Die GetPermissionAsync Methode versucht, eine MediaCapture Instanz zu initialisieren. Wenn dies fehlschlägt, wird eine Benutzeranforderung zum Aktivieren des Mikrofons gestartet.
  3. Die OnRequestPermissionResult Methode ist vorhanden, um die Schnittstelle zu erfüllen, ist aber für die UWP-Implementierung nicht erforderlich.

Schließlich muss das UWP Package.appxmanifest angeben, dass die Anwendung das Mikrofon verwendet. Doppelklicken Sie auf die Datei "Package.appxmanifest", und wählen Sie auf der Registerkarte "Funktionen" in Visual Studio 2019 die Option "Mikrofon" aus:

Screenshot des Manifests in Visual Studio 2019

Testen der Anwendung

Führen Sie die App aus, und klicken Sie auf die Schaltfläche "Transcribe ". Die App sollte den Mikrofonzugriff anfordern und den Transkriptionsprozess starten. Die ActivityIndicator Animation zeigt an, dass die Transkription aktiv ist. Während Sie sprechen, streamt die App Audiodaten an die Azure Speech Services-Ressource, die mit transkribiertem Text antwortet. Der transkribierte Text wird beim Empfang im Label Element angezeigt.

Hinweis

Android-Emulatoren können die Sprachdienstbibliotheken nicht laden und initialisieren. Tests auf einem physischen Gerät werden für die Android-Plattform empfohlen.