Sdílet prostřednictvím


Rozpoznávání řeči pomocí služby Azure Speech

Azure Speech Service je cloudové rozhraní API, které nabízí následující funkce:

  • Převod řeči na text přepisuje zvukové soubory nebo datové proudy na text.
  • Převod textu na řeč převede vstupní text na syntetizovaný řeč podobný člověku.
  • Překlad řeči umožňuje překlad řeči v reálném čase, více jazyků pro převod řeči na text i řeč na řeč.
  • Hlasoví asistenti můžou pro aplikace vytvářet rozhraní konverzace podobné člověku.

Tento článek vysvětluje, jak se v ukázkové Xamarin.Forms aplikaci implementuje převod řeči na text pomocí služby Azure Speech. Následující snímky obrazovky ukazují ukázkovou aplikaci v iOSu a Androidu:

Snímky obrazovky ukázkové aplikace v iOSu a Androidu

Vytvoření prostředku služby Azure Speech

Služba Azure Speech je součástí služeb Azure Cognitive Services, která poskytuje cloudová rozhraní API pro úlohy, jako je rozpoznávání obrázků, rozpoznávání řeči a překlad a vyhledávání Bingu. Další informace najdete v tématu Co jsou služby Azure Cognitive Services?

Ukázkový projekt vyžaduje vytvoření prostředku Azure Cognitive Services na webu Azure Portal. Prostředek služeb Cognitive Services je možné vytvořit pro jednu službu, jako je služba Speech, nebo jako prostředek s více službami. Postup vytvoření prostředku služby Speech je následující:

  1. Přihlaste se k webu Azure Portal.
  2. Vytvořte prostředek s více službami nebo jednou službou.
  3. Získejte informace o klíči rozhraní API a oblasti pro váš prostředek.
  4. Aktualizujte ukázkový soubor Constants.cs .

Podrobný průvodce vytvořením prostředku najdete v tématu Vytvoření prostředku služeb Cognitive Services.

Poznámka:

Pokud ještě nemáte předplatné Azure, vytvořte si bezplatný účet před tím, než začnete. Jakmile máte účet, můžete vytvořit prostředek jedné služby na úrovni Free a vyzkoušet službu.

Konfigurace aplikace pomocí služby Speech

Po vytvoření prostředku služeb Cognitive Services je možné soubor Constants.cs aktualizovat pomocí oblasti a klíče rozhraní API z vašeho prostředku Azure:

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

Instalace balíčku služby NuGet Speech

Ukázková aplikace používá balíček NuGet Microsoft.CognitiveServices.Speech k připojení ke službě Azure Speech. Nainstalujte tento balíček NuGet do sdíleného projektu a každého projektu platformy.

Vytvoření rozhraní IMicrophoneService

Každá platforma vyžaduje oprávnění pro přístup k mikrofonu. Ukázkový projekt poskytuje rozhraní ve sdíleném IMicrophoneService projektu a používá Xamarin.FormsDependencyService k získání implementací platformy rozhraní.

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

Vytvoření rozložení stránky

Ukázkový projekt definuje základní rozložení stránky v souboru MainPage.xaml . Klíčové prvky rozložení jsou prvky Button , které spustí proces přepisu, Label který bude obsahovat přepisovaný text a který ActivityIndicator se má zobrazit, když probíhá přepis:

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

Implementace služby Speech

Soubor MainPage.xaml.cs kódu obsahuje veškerou logiku pro odesílání zvuku a přijímání přepisovaného textu ze služby Azure Speech.

Konstruktor MainPage získá instanci IMicrophoneService rozhraní z DependencyService:

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

    public MainPage()
    {
        InitializeComponent();

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

    // ...
}

Metoda TranscribeClicked se volá při klepnutí instance transcribeButton :

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

Metoda TranscribeClicked provede následující:

  1. Zkontroluje, jestli má aplikace přístup k mikrofonu, a ukončí se včas, pokud ne.
  2. Vytvoří instanci SpeechRecognizer třídy, pokud ještě neexistuje.
  3. Zastaví průběžný přepis, pokud právě probíhá.
  4. Vloží časové razítko a spustí průběžný přepis, pokud neprobíhá.
  5. Upozorní aplikaci, aby aktualizovala svůj vzhled na základě nového stavu aplikace.

Zbývající část MainPage metod třídy jsou pomocné rutiny pro zobrazení stavu aplikace:

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

Metoda UpdateTranscription zapíše poskytnuté newText string do elementu Label s názvem transcribedText. Tato aktualizace vynutí, aby se tato aktualizace stala ve vlákně uživatelského rozhraní, aby ji bylo možné volat z libovolného kontextu, aniž by to způsobilo výjimky. Zapíše InsertDateTimeRecord aktuální datum a čas do transcribedText instance a označí začátek nového přepisu. Nakonec metoda aktualizuje Button a ActivityIndicator prvky tak, aby odrážely, UpdateDisplayState zda probíhá přepis.

Vytváření služeb mikrofonu platformy

Aplikace musí mít přístup k mikrofonu pro shromažďování dat řeči. Rozhraní IMicrophoneService musí být implementováno a registrováno u DependencyService každé platformy, aby aplikace fungovala.

Android

Ukázkový projekt definuje implementaci IMicrophoneService pro Android s názvem 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);
            }
        }
    }
}

Obsahuje AndroidMicrophoneService následující funkce:

  1. Atribut Dependency registruje třídu pomocí DependencyService.
  2. Metoda GetPermissionAsync zkontroluje, jestli jsou oprávnění požadovaná na základě verze sady Android SDK, a volání RequestMicPermissions , pokud oprávnění ještě nebyla udělena.
  3. Metoda RequestMicPermissions používá Snackbar třídu k vyžádání oprávnění od uživatele, pokud je požadován odůvodnění, jinak přímo požaduje oprávnění zvukového záznamu.
  4. Metoda OnRequestPermissionResult se volá s bool výsledkem, jakmile uživatel odpoví na žádost o oprávnění.

Třída MainActivity je přizpůsobená tak, aby po dokončení žádostí o oprávnění aktualizovala AndroidMicrophoneService instanci:

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

Třída MainActivity definuje statický odkaz, Instancekterý je vyžadován objektem AndroidMicrophoneService při vyžádání oprávnění. Přepíše metodu OnRequestPermissionsResult aktualizace objektu AndroidMicrophoneService , pokud je žádost o oprávnění schválena nebo odepřena uživatelem.

Aplikace pro Android musí nakonec obsahovat oprávnění k nahrávání zvuku v souboru AndroidManifest.xml :

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

iOS

Ukázkový projekt definuje implementaci IMicrophoneService pro iOS s názvem 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);
            });
        }
    }
}

Obsahuje iOSMicrophoneService následující funkce:

  1. Atribut Dependency registruje třídu pomocí DependencyService.
  2. Metoda GetPermissionAsync volá RequestMicPermissions žádosti o oprávnění od uživatele zařízení.
  3. Metoda RequestMicPermissions používá sdílenou AVAudioSession instanci k vyžádání oprávnění k záznamu.
  4. Metoda OnRequestPermissionResult aktualizuje TaskCompletionSource instanci zadanou bool hodnotou.

Nakonec musí aplikace pro iOS Info.plist obsahovat zprávu s informacemi o tom, proč aplikace žádá o přístup k mikrofonu. Upravte soubor Info.plist tak, aby zahrnoval následující značky v elementu <dict> :

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

UWP

Ukázkový projekt definuje implementaci IMicrophoneService pro UPW s názvem 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
        }
    }
}

Obsahuje UWPMicrophoneService následující funkce:

  1. Atribut Dependency registruje třídu pomocí DependencyService.
  2. Metoda GetPermissionAsync se pokusí inicializovat MediaCapture instanci. Pokud se to nezdaří, spustí se žádost uživatele o povolení mikrofonu.
  3. Metoda OnRequestPermissionResult existuje pro splnění rozhraní, ale není vyžadována pro implementaci UPW.

Nakonec musí upW Package.appxmanifest určit, že aplikace používá mikrofon. Poklikejte na soubor Package.appxmanifest a vyberte možnost Mikrofon na kartě Schopnosti v sadě Visual Studio 2019:

Snímek obrazovky manifestu v sadě Visual Studio 2019

Testování aplikace

Spusťte aplikaci a klikněte na tlačítko Přepis . Aplikace by měla požádat o přístup k mikrofonu a zahájit proces přepisu. Animace ActivityIndicator bude zobrazovat, že přepis je aktivní. Při mluvení bude aplikace streamovat zvuková data do prostředku azure Speech Services, který bude reagovat přepisovaným textem. Přepsaný text se zobrazí v elementu Label při jeho přijetí.

Poznámka:

Emulátory Androidu se nepodaří načíst a inicializovat knihovny služby Speech. Pro platformu Android se doporučuje testování na fyzickém zařízení.