Bagikan melalui


Pengenalan ucapan menggunakan Azure Speech Service

Azure Speech Service adalah API berbasis cloud yang menawarkan fungsionalitas berikut:

  • Ucapan ke teks mentranskripsikan file audio atau streaming ke teks.
  • Teks ke ucapan mengonversi teks input menjadi ucapan yang disintesis seperti manusia.
  • Terjemahan ucapan memungkinkan terjemahan multi-bahasa real-time untuk ucapan ke teks dan ucapan ke ucapan.
  • Asisten suara dapat membuat antarmuka percakapan seperti manusia untuk aplikasi.

Artikel ini menjelaskan bagaimana ucapan ke teks diimplementasikan dalam aplikasi sampel Xamarin.Forms menggunakan Azure Speech Service. Cuplikan layar berikut menunjukkan aplikasi sampel di iOS dan Android:

Cuplikan layar aplikasi sampel di iOS dan Android

Membuat sumber daya Azure Speech Service

Azure Speech Service adalah bagian dari Azure Cognitive Services, yang menyediakan API berbasis cloud untuk tugas seperti pengenalan gambar, pengenalan dan terjemahan ucapan, dan pencarian Bing. Untuk informasi selengkapnya, lihat Apa itu Azure Cognitive Services?.

Proyek sampel memerlukan sumber daya Azure Cognitive Services untuk dibuat di portal Azure Anda. Sumber daya Cognitive Services dapat dibuat untuk satu layanan, seperti Layanan Ucapan, atau sebagai sumber daya multi-layanan. Langkah-langkah untuk membuat sumber daya Layanan Ucapan adalah sebagai berikut:

  1. Masuk ke portal Azure Anda.
  2. Buat sumber daya multi-layanan atau layanan tunggal.
  3. Dapatkan kunci API dan informasi wilayah untuk sumber daya Anda.
  4. Perbarui sampel file Constants.cs .

Untuk panduan langkah demi langkah untuk membuat sumber daya, lihat Membuat sumber daya Cognitive Services.

Catatan

Jika Anda tidak memiliki langganan Azure, buatlah akun gratis sebelum Anda memulai. Setelah Anda memiliki akun, sumber daya layanan tunggal dapat dibuat di tingkat gratis untuk mencoba layanan.

Mengonfigurasi aplikasi Anda dengan Layanan Ucapan

Setelah membuat sumber daya Cognitive Services, file Constants.cs dapat diperbarui dengan wilayah dan kunci API dari sumber daya Azure Anda:

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

Menginstal paket NuGet Speech Service

Aplikasi sampel menggunakan paket NuGet Microsoft.CognitiveServices.Speech untuk menyambungkan ke Azure Speech Service. Instal paket NuGet ini di proyek bersama dan setiap proyek platform.

Membuat antarmuka IMicrophoneService

Setiap platform memerlukan izin untuk mengakses mikrofon. Proyek sampel menyediakan IMicrophoneService antarmuka dalam proyek bersama, dan menggunakan Xamarin.FormsDependencyService untuk mendapatkan implementasi platform antarmuka.

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

Membuat tata letak halaman

Proyek sampel menentukan tata letak halaman dasar dalam file MainPage.xaml . Elemen tata letak kunci adalah Button yang memulai proses transkripsi, untuk Label berisi teks yang ditranskripsikan, dan untuk ActivityIndicator ditampilkan saat transkripsi sedang berlangsung:

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

Menerapkan Layanan Ucapan

File MainPage.xaml.cs code-behind berisi semua logika untuk mengirim audio dan menerima teks yang ditranskripsikan dari Azure Speech Service.

MainPage Konstruktor mendapatkan instans IMicrophoneService antarmuka dari DependencyService:

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

    public MainPage()
    {
        InitializeComponent();

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

    // ...
}

Metode TranscribeClicked ini dipanggil ketika transcribeButton instans diketuk:

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

Metode TranscribeClicked melakukan hal berikut:

  1. Memeriksa apakah aplikasi memiliki akses ke mikrofon dan keluar lebih awal jika tidak.
  2. Membuat instans SpeechRecognizer kelas jika belum ada.
  3. Menghentikan transkripsi berkelanjutan jika sedang berlangsung.
  4. Menyisipkan tanda waktu dan memulai transkripsi berkelanjutan jika tidak sedang berlangsung.
  5. Memberi tahu aplikasi untuk memperbarui penampilannya berdasarkan status aplikasi baru.

Sisa metode kelas adalah pembantu MainPage untuk menampilkan status aplikasi:

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

Metode UpdateTranscription menulis yang disediakan newTextstring ke Label elemen bernama transcribedText. Ini memaksa pembaruan ini terjadi pada utas UI sehingga dapat dipanggil dari konteks apa pun tanpa menyebabkan pengecualian. menulis InsertDateTimeRecord tanggal dan waktu saat ini ke transcribedText instans untuk menandai awal transkripsi baru. Akhirnya, metode memperbarui UpdateDisplayStateButton elemen dan ActivityIndicator untuk mencerminkan apakah transkripsi sedang berlangsung atau tidak.

Membuat layanan mikrofon platform

Aplikasi harus memiliki akses mikrofon untuk mengumpulkan data ucapan. Antarmuka IMicrophoneService harus diimplementasikan dan didaftarkan dengan DependencyService pada setiap platform agar aplikasi berfungsi.

Android

Proyek sampel mendefinisikan implementasi untuk Android yang IMicrophoneService disebut 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);
            }
        }
    }
}

memiliki AndroidMicrophoneService fitur berikut:

  1. Atribut Dependency mendaftarkan kelas dengan DependencyService.
  2. Metode ini GetPermissionAsync memeriksa apakah izin diperlukan berdasarkan versi Android SDK, dan memanggil RequestMicPermissions jika izin belum diberikan.
  3. Metode ini RequestMicPermissions menggunakan Snackbar kelas untuk meminta izin dari pengguna jika diperlukan alasan, jika tidak, metode ini secara langsung meminta izin perekaman audio.
  4. Metode OnRequestPermissionResult ini dipanggil dengan hasil bool setelah pengguna merespons permintaan izin.

Kelas MainActivity disesuaikan untuk memperbarui AndroidMicrophoneService instans ketika permintaan izin selesai:

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

Kelas MainActivity menentukan referensi statis yang disebut Instance, yang diperlukan oleh AndroidMicrophoneService objek saat meminta izin. Ini mengambil alih OnRequestPermissionsResult metode untuk memperbarui AndroidMicrophoneService objek ketika permintaan izin disetujui atau ditolak oleh pengguna.

Terakhir, aplikasi Android harus menyertakan izin untuk merekam audio dalam file AndroidManifest.xml :

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

iOS

Proyek sampel mendefinisikan implementasi untuk iOS yang IMicrophoneService disebut 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);
            });
        }
    }
}

memiliki iOSMicrophoneService fitur berikut:

  1. Atribut Dependency mendaftarkan kelas dengan DependencyService.
  2. Metode ini GetPermissionAsync memanggil RequestMicPermissions untuk meminta izin dari pengguna perangkat.
  3. Metode ini RequestMicPermissions menggunakan instans bersama AVAudioSession untuk meminta izin perekaman.
  4. Metode memperbarui OnRequestPermissionResultTaskCompletionSource instans dengan nilai yang disediakan bool .

Terakhir, info.plist aplikasi iOS harus menyertakan pesan yang memberi tahu pengguna mengapa aplikasi meminta akses ke mikrofon. Edit file Info.plist untuk menyertakan tag berikut dalam <dict> elemen :

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

UWP

Proyek sampel mendefinisikan IMicrophoneService implementasi untuk UWP yang disebut 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
        }
    }
}

memiliki UWPMicrophoneService fitur berikut:

  1. Atribut Dependency mendaftarkan kelas dengan DependencyService.
  2. Metode ini GetPermissionAsync mencoba menginisialisasi MediaCapture instans. Jika gagal, ia meluncurkan permintaan pengguna untuk mengaktifkan mikrofon.
  3. Metode ini OnRequestPermissionResult ada untuk memenuhi antarmuka tetapi tidak diperlukan untuk implementasi UWP.

Terakhir, UWP Package.appxmanifest harus menentukan bahwa aplikasi menggunakan mikrofon. Klik dua kali file Package.appxmanifest dan pilih opsi Mikrofon pada tab Kemampuan di Visual Studio 2019:

Cuplikan layar manifes di Visual Studio 2019

Uji aplikasi

Jalankan aplikasi dan klik tombol Mentranskripsikan . Aplikasi harus meminta akses mikrofon dan memulai proses transkripsi. Akan ActivityIndicator menganimasikan, menunjukkan bahwa transkripsi aktif. Saat Anda berbicara, aplikasi akan mengalirkan data audio ke sumber daya Azure Speech Services, yang akan merespons dengan teks yang ditranskripsikan. Teks yang ditranskripsikan akan muncul di elemen seperti Label yang diterima.

Catatan

Emulator Android gagal memuat dan menginisialisasi pustaka Layanan Ucapan. Pengujian pada perangkat fisik direkomendasikan untuk platform Android.