Azure Konuşma Tanıma Hizmetini kullanarak konuşma tanıma
Azure Konuşma Tanıma Hizmeti, aşağıdaki işlevleri sunan bulut tabanlı bir API'dir:
- Konuşmayı metne dönüştürme, ses dosyalarının veya akışlarının metne dökümünü alır.
- Metin okuma , giriş metnini insan benzeri sentezlenmiş konuşmaya dönüştürür.
- Konuşma çevirisi , hem konuşmayı metne dönüştürme hem de konuşmayı konuşmaya dönüştürme için gerçek zamanlı, çok dilli çeviriyi etkinleştirir.
- Sesli yardımcılar , uygulamalar için insan benzeri konuşma arabirimleri oluşturabilir.
Bu makalede, Azure Konuşma Tanıma Hizmeti kullanılarak örnek Xamarin.Forms uygulamada konuşmayı metne dönüştürmenin nasıl uygulandığı açıklanmaktadır. Aşağıdaki ekran görüntüleri iOS ve Android'de örnek uygulamayı gösterir:
Azure Konuşma Tanıma Hizmeti kaynağı oluşturma
Azure Konuşma Tanıma Hizmeti, görüntü tanıma, konuşma tanıma ve çeviri ve Bing araması gibi görevler için bulut tabanlı API'ler sağlayan Azure Bilişsel Hizmetler'in bir parçasıdır. Daha fazla bilgi için bkz . Azure Bilişsel Hizmetler nedir?.
Örnek proje, Azure portalınızda bir Azure Bilişsel Hizmetler kaynağı oluşturulmasını gerektirir. Bilişsel Hizmetler kaynağı Konuşma Tanıma Hizmeti gibi tek bir hizmet için veya çok hizmetli bir kaynak olarak oluşturulabilir. Konuşma Tanıma Hizmeti kaynağı oluşturma adımları aşağıdaki gibidir:
- Azure portalınızda oturum açın.
- Çok hizmetli veya tek hizmetli bir kaynak oluşturun.
- Kaynağınız için API anahtarını ve bölge bilgilerini alın.
- Örnek Constants.cs dosyasını güncelleştirin.
Kaynak oluşturmaya yönelik adım adım kılavuz için bkz . Bilişsel Hizmetler kaynağı oluşturma.
Not
Azure aboneliğiniz yoksa başlamadan önce ücretsiz bir hesap oluşturun. Hesabınız olduktan sonra, hizmeti denemek için ücretsiz katmanda tek hizmetli bir kaynak oluşturulabilir.
Uygulamanızı Konuşma Tanıma Hizmeti ile yapılandırma
Bilişsel Hizmetler kaynağı oluşturduktan sonra Constants.cs dosyası Azure kaynağınızdan bölge ve API anahtarıyla güncelleştirilebilir:
public static class Constants
{
public static string CognitiveServicesApiKey = "YOUR_KEY_GOES_HERE";
public static string CognitiveServicesRegion = "westus";
}
NuGet Konuşma Tanıma Hizmeti paketini yükleme
Örnek uygulama, Azure Konuşma Tanıma Hizmeti'ne bağlanmak için Microsoft.CognitiveServices.Speech NuGet paketini kullanır. Bu NuGet paketini paylaşılan projeye ve her platform projesine yükleyin.
IMicrophoneService arabirimi oluşturma
Her platform için mikrofona erişim izni gerekir. Örnek proje, paylaşılan projede bir IMicrophoneService
arabirim sağlar ve arabirimin platform uygulamalarını almak için öğesini kullanır Xamarin.FormsDependencyService
.
public interface IMicrophoneService
{
Task<bool> GetPermissionAsync();
void OnRequestPermissionResult(bool isGranted);
}
Sayfa düzenini oluşturma
Örnek proje MainPage.xaml dosyasında temel bir sayfa düzeni tanımlar. Anahtar düzen öğeleri transkripsiyon işlemini başlatan, Button
Label
dökümü alınmış metni içeren bir ve transkripsiyonun ne zaman devam ettiğini gösteren bir ActivityIndicator
öğedir:
<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>
Konuşma Tanıma Hizmetini Uygulama
MainPage.xaml.cs arka planda kod dosyası, Azure Konuşma Tanıma Hizmeti'nden ses göndermeye ve dökümü alınmış metin almaya ilişkin tüm mantığı içerir.
Oluşturucu arabiriminin MainPage
IMicrophoneService
bir örneğini içinden DependencyService
alır:
public partial class MainPage : ContentPage
{
SpeechRecognizer recognizer;
IMicrophoneService micService;
bool isTranscribing = false;
public MainPage()
{
InitializeComponent();
micService = DependencyService.Resolve<IMicrophoneService>();
}
// ...
}
TranscribeClicked
yöntemi, örnek dokunulduğunda transcribeButton
çağrılır:
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();
}
TranscribeClicked
yöntemi aşağıdakileri yapar:
- Uygulamanın mikrofona erişimi olup olmadığını denetler ve erişmezse erken çıkar.
- Henüz yoksa sınıfın
SpeechRecognizer
bir örneğini oluşturur. - Devam ediyorsa sürekli transkripsiyonu durdurur.
- Bir zaman damgası ekler ve devam etmediyse sürekli transkripsiyon başlatır.
- Uygulamaya, yeni uygulama durumuna göre görünümünü güncelleştirmesini bildirir.
Sınıf yöntemlerinin MainPage
geri kalanı, uygulama durumunu görüntülemeye yardımcı olanlardır:
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;
}
});
}
yöntemi, UpdateTranscription
sağlanan Label
newText
string
öğesini adlı transcribedText
öğesine yazar. Özel durumlara neden olmadan herhangi bir bağlamdan çağrılabilmesi için ui iş parçacığında bu güncelleştirmenin gerçekleşmesini zorlar. , InsertDateTimeRecord
yeni transkripsiyonun başlangıcını transcribedText
işaretlemek için geçerli tarih ve saati örneğe yazar. Son olarak, UpdateDisplayState
yöntemi ve ActivityIndicator
öğelerini transkripsiyonun devam edip etmediğini yansıtacak şekilde güncelleştirirButton
.
Platform mikrofon hizmetleri oluşturma
Uygulama konuşma verilerini toplamak için mikrofon erişimine sahip olmalıdır. Uygulamanın IMicrophoneService
çalışması için her platformda arabiriminin uygulanması ve ile DependencyService
kaydedilmesi gerekir.
Android
Örnek proje, Android için adlı AndroidMicrophoneService
bir IMicrophoneService
uygulama tanımlar:
[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);
}
}
}
}
AndroidMicrophoneService
aşağıdaki özelliklere sahiptir:
Dependency
özniteliği sınıfını ileDependencyService
kaydeder.- Yöntemi,
GetPermissionAsync
Android SDK sürümüne göre izinlerin gerekli olup olmadığını denetler ve izin henüz verilmemişse çağırırRequestMicPermissions
. RequestMicPermissions
yöntemi, rasyonalite gerekiyorsa kullanıcıdan izin istemek için sınıfını kullanırSnackbar
, aksi takdirde doğrudan ses kaydı izinleri istemektedir.- Kullanıcı
OnRequestPermissionResult
izin isteğine yanıt verdikten sonra yöntemi birbool
sonuçla çağrılır.
sınıf MainActivity
, izin istekleri tamamlandığında örneği güncelleştirmek AndroidMicrophoneService
için özelleştirilir:
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;
}
}
}
sınıfı, MainActivity
izinler istenirken nesnesi tarafından AndroidMicrophoneService
gerekli olan adlı Instance
statik başvuruyu tanımlar. İzin isteği kullanıcı tarafından onaylandığında veya reddedildiğinde nesnesini güncelleştirmek AndroidMicrophoneService
için yöntemini geçersiz kılarOnRequestPermissionsResult
.
Son olarak, Android uygulamasının AndroidManifest.xml dosyasına ses kaydetme iznini içermesi gerekir:
<manifest ...>
...
<uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest>
iOS
Örnek proje, iOS için adlı iOSMicrophoneService
bir IMicrophoneService
uygulama tanımlar:
[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);
});
}
}
}
iOSMicrophoneService
aşağıdaki özelliklere sahiptir:
Dependency
özniteliği sınıfını ileDependencyService
kaydeder.- yöntemi,
GetPermissionAsync
cihaz kullanıcısından izin istemek için öğesini çağırırRequestMicPermissions
. - yöntemi,
RequestMicPermissions
kayıt izinleri istemek için paylaşılanAVAudioSession
örneği kullanır. - yöntemi,
OnRequestPermissionResult
örneği sağlananbool
değerle güncelleştirirTaskCompletionSource
.
Son olarak, iOS uygulaması Info.plist'in kullanıcıya uygulamanın neden mikrofona erişim isteğinde bulunduğunu belirten bir ileti içermesi gerekir. Info.plist dosyasını öğesinin içine <dict>
aşağıdaki etiketleri içerecek şekilde düzenleyin:
<plist>
<dict>
...
<key>NSMicrophoneUsageDescription</key>
<string>Voice transcription requires microphone access</string>
</dict>
</plist>
UWP
Örnek proje, UWP için adlı UWPMicrophoneService
bir IMicrophoneService
uygulama tanımlar:
[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
}
}
}
UWPMicrophoneService
aşağıdaki özelliklere sahiptir:
Dependency
özniteliği sınıfını ileDependencyService
kaydeder.GetPermissionAsync
yöntemi birMediaCapture
örneği başlatmayı dener. Bu başarısız olursa, mikrofonu etkinleştirmek için bir kullanıcı isteği başlatır.OnRequestPermissionResult
Yöntemi arabirimi karşılamak için var, ancak UWP uygulaması için gerekli değildir.
Son olarak, UWP Package.appxmanifest uygulamasının mikrofonu kullandığını belirtmesi gerekir. Package.appxmanifest dosyasına çift tıklayın ve Visual Studio 2019'daki Özellikler sekmesindeki Mikrofon seçeneğini belirleyin:
Uygulamayı test etme
Uygulamayı çalıştırın ve Döküm düğmesine tıklayın. Uygulama mikrofon erişimi istemeli ve transkripsiyon işlemini başlatmalıdır. ActivityIndicator
, transkripsiyonun etkin olduğunu göstererek animasyon oluşturur. Siz konuşurken uygulama ses verilerini Azure Konuşma Hizmetleri kaynağına akışla aktaracak ve metin dökümüyle yanıt verecektir. Dökümü alınan metin öğesinde Label
görünür.
Not
Android öykünücüleri Konuşma Tanıma Hizmeti kitaplıklarını yükleyip başlatamaz. Android platformu için fiziksel bir cihazda test edilmesi önerilir.