Android

Android Uygulamalarında Sesi Yazıya Dönüştürmek

Bu blog yazısında Android işletim sisteminde sesin yazıya çevrilmesi konusuna eğileceğiz. Normalde sesi yazıya çevirmek için yapay zekâ ile uğraşmak gerekse de, bu ayrı bir uzmanlık alanı ve profesyonellik gerektiren bir daldır. Neyse ki, Android'de sesi kolay bir şekilde yazıya çevirm...

Bu blog yazısında Android işletim sisteminde sesin yazıya çevrilmesi konusuna eğileceğiz. Normalde sesi yazıya çevirmek için yapay zekâ ile uğraşmak gerekse de, bu ayrı bir uzmanlık alanı ve profesyonellik gerektiren bir daldır. Neyse ki, Android'de sesi kolay bir şekilde yazıya çevirmek için kullanabileceğimiz bir Google altyapı hizmeti mevcut. Google bu altyapıyı kendi ürünü olan Google Now uygulamasında da kullanıyor.

Google'ın bu servisini kullanabilmek için RecognizerIntent isimli sınıfını kullanmalıyız. Bu sınıf arka planda Google sunucularuyla iletişime geçip, bize yazıyı sonuç olarak döndürür (Yapay zekâ servisi ile iletişime geçer).

Uygulamada bu servisi kullanmanın iki farklı yolu var. Şimdi bu yollara göz atalım.

 

Basit yöntem

İlk olarak basit yönteme bakalım. startActivity metodu ile RecognizerIntent isimli intent nesnesi çalıştırılır. Bunun çalıştırılmasından sonra karşımıza mikrofon bulunan bir Google penceresi çıkar .

Biz bu pencerecik göründüğünde konuşuruz ve konuşma bittikten hemen sonra bu sınıf arka planda Google ile iletişime geçerek konuşma sonucunu onActivityResult() isimli Activity metoduna döndürür.

Programın hangi kısmında bu özelliği kullanacaksanız, o bölgede bu kodları yazabilirsiniz.

[code] Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

 intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());

 intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Bir şeyler söyleyin");

  intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);

 intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,”en-US”);

 intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);

 startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);[/code]

Kodu satır satır inceleyelim:

  • İlk satırda RecognizerIntent aracılığıyla sesi yazıya çevirme servisi çağırılır.
  • İkinci satırda başvuruyu tanımlamak için uygulama paketinin ismini bu servise gönderiyoruz.
  • Üçüncü satırda diyalogda görünmesini istediğimiz bir yazıyı ekliyoruz.
  • Dördüncü satırda dil modelini veriyoruz. (Serbest Dil Modeli, Web Arama Temellerine Dayalı Bir Dil Modeli)
  • Beşinci satırda Opsiyonel olarak dil ataması yapabiliyoruz. (IETF Language Tag BCP 47)
  • Altıncı satırda arama sonucu olarak maksimum kaç tane sonuç döneceğini belirtiyoruz.
  • Yedinci satırda ise bir Activity metodu olan startActivityForResult() ile servisi başlatıp, pencereciği ekrana çıkarıyoruz. startActivityForResult() metodunun ikinci parametresi ise kısaca istek ID'sidir. Bir başka deyişle, siz birden fazla startActivityForResult() çağırmış olabilirsiniz sonuçları da karşılarken bu ID'e göre karşılarsınız. Global bölgede private static final int VOICE_RECOGNITION_REQUEST_CODE = 1; tanımlaması yapmayı unutmayın. Ayrıca her farklı startActivityForResult() gönderiminize farklı ID'ler verin. Buradaki 1 ID'si sadece sesi yazıya çevirme servisine ait olur.

 

Sonuçlar nereye gelecek? Görelim:

[code]protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == VOICE_RECOGNITION_REQUEST_CODE; resultCode == RESULT_OK) {

          ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

} super.onActivityResult(requestCode, resultCode, data); }[/code]

startActivityForResult() isteğini yolladığımız Activity dosyasına yine bir activity metodu olan onActivityResult() metodunu dâhil edelim. Sesi yazıya çevirmenin ve diğer startActivityForResult() sonuçlarının hepsi bu metoda geri dönecektir. Buradaki önemli kısım requestCode'dir. requestCode az önce bahsedilen istek ID'si yani deminki sorgumuzdaki 1'dir. Önemli olan ikinci yer ise matches değişkeni ve ona data aktardığımız yerdir. İşte burası, sonucu bir ArrayList'e yüklediğimiz yerdir.

Sonucun nasıl geldiğini gördük, birinci yol bu kadar. Dezavantajını soracak olursanız, Google'ın verdiği pencereciği kullanma zorunluluğunuz var. Bu işi sanki kendiniz yapıyormuş gibi kendinize özel pencerecik vs. hazırlayıp yapmak istiyorsanız, ikinci yola geçelim.

 

Gelişkin yöntem

İkinci yol, birinci yola göre birazcık daha karmaşık ama gelişkin bir yöntem.

İkinci yolda yine arka planda haberleşmeyi RecognizerIntent üzerinden sürdürür, fakat ses kayıt işlemlerinin tüm aşamalarını size açar istediğiniz gibi müdahale edip istediğiniz pencereciği gösterebilirsiniz. Tüm işlemlere başlamadan önce manifest dosyamıza aşağıda verdiğim izin (permission) eklemesini yapalım. Bu izin sayesinde mikrofonla ses kaydı yapabilme yetkisi kazanıyoruz.

[code]<uses-permission android:name="android.permission.RECORD_AUDIO" ></uses-permission>

SpeechRecognizer speechRecognizer;

ProgressDialog loadingDialog; Context context;

@Override protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        context = this; }[/code]

Buradaki kilit nokta, SpeechRecognizer isimli kayıt aşamalarını kontrol edebileceğimiz bir sınıfımızın olmasıdır. Aşağıda ise işlem safhalarını kontrol edebileceğimiz, kendimize ait basit bir pencere (diyalog) tanımladık. Şimdi devam edelim. Mesela bir düğmeye bastığımızda ses kayıt işlemi başlayacak senaryosu üzerinden hareket edelim.

Buradan sonra yazdığım kodların hepsinin bir düğmenin tıklama eventinde olduğunu farz edelim.

[code]loadingDialog = new ProgressDialog(context);

loadingDialog.setCancelable(false);

loadingDialog.setMessage("Lütfen Konuşun"); loadingDialog.show();

speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context);[/code]

Bu kısımda ise pencereciği tanımlıyor ve göstertiyoruz. Aşağıdaysa SpeechRecognizer sınıfını oluşturuyoruz. Tek bir noktamız kaldı, o da kayıt aşamalarını dinleyen RecognitionListener arayüzünü SpeechRecognizer sınıfına tanımlamak.

[code]speechRecognizer.setRecognitionListener(new RecognitionListener() {

        @Override public void onRmsChanged(float rmsdB) {

                 // TODO Auto-generated method stub

        }

        @Override public void onResults(Bundle results) {

                 loadingDialog.dismiss();

                 ArrayList speechResultSentence = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

        } @Override public void onReadyForSpeech(Bundle params) {

            // TODO Auto-generated method stub

       } @Override public void onPartialResults(Bundle partialResults) {

          // TODO Auto-generated method stub

       } @Override public void onEvent(int eventType, Bundle params) {

          // TODO Auto-generated method stub

      } @Override public void onError(int error) {

          loadingDialog.dismiss();

         Toast.makeText(getApplicationContext(), "Bir Hata Oluştu Lütfen Tekrar Deneyin...", Toast.LENGTH_SHORT).show();

      } @Override public void onEndOfSpeech() { loadingDialog .setMessage("Kayıt Bitti.Sonuçlar Getiriliyor");

      } @Override public void onBufferReceived(byte[] buffer) { }

         @Override public void onBeginningOfSpeech() {

           loadingDialog.setMessage("Kayıt Başladı");

       } });[/code]

Bu listenerda SpeechRecognizer sınıfına yükledikten sonra kodu açıklayalım. Kısaca ses kayıt aşamalarının hepsini buradan kontrol ediyoruz. onBeginningOfSpeech ses verdiğiniz an tetiklenir. Konuşmayı bitirdiğiniz an onEndOfSpeech metodu tetiklenir ve diyaloğun yazısı değiştirilir. Ses anlaşılmaz ise bir hatayla karşılaşırsa onError metodu tetiklenir. Her şey hatasız gerçekleşirse onResult metodu tetiklenir ve sonuç buraya yine ArrayList olarak yansır.

Ses kayıtla ve pencerecik yönetimiyle ilgili tüm aşamalarda tamam. Şimdi arka planda çalışacak ses çevrim kısmını ayarlayıp bitiriyoruz.

[code]Intent recognizerIntent = new Intent( RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());

recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);

recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);

 speechRecognizer.startListening(recognizerIntent); [/code]

Arka planda Google ile iletişime geçmesi için bir RecognizerIntent oluşturup gerekli parametreleri veriyoruz ve SpeechRecognizer sınıfına gönderip arka plan işlemlerini de noktalıyoruz.

[code]@Override protected void onDestroy() {

if (speechRecognizer != null) {

     speechRecognizer.stopListening();

     speechRecognizer.cancel();

     speechRecognizer.destroy(); }

     super.onDestroy(); }[/code]

Activity'nin onDestroy bloğunda bu servisleri sonlandırmayı unutmuyoruz. Sonlandırma yapmazsak ses kayıt servisi hâlâ aktif olabilir ve biz Activity'i sonlandırdığımızda hatayla karşılaşırız.

Blog yazısında anlatılan kodların bulunduğu örnek projeyi Github'a yüklenmiş halde bu bağlantıdan indirebilirsiniz.

Son bir şey daha var: Yukarıdaki örneğe göre telefonunuzda bir sesi metne dönüştürürseniz, sonucunu bildirmenizden mutluluk duyarım. Takıldığınız yerde soru sormaktan lütfen çekinmeyin :).

 

 

Uyarı: Bu projeler sadece gerçek cihazlarda çalışır. Emülatörde Speech to Text araçlarını kullanamazsınız!

Yorumlar

Cansu Aktaş
25.12.2018 - 05:35

Harika bir yazı. Paylaşım için teşekkürler.

Sedat
11.07.2017 - 03:05

Merhaba Ahmet Bey, çok güzel bir yazı,çok faydalı , basit uygulamayı çalıştırmakta sıkıntı yaşamadım ancak ikinci kısımda anlattıklarınızı çalıştıramadım. Github dosyasını indirip kopyaladım yine çalışmadı . Yardımcı olabilir misiniz?

Teşekkürler.

ilhan
28.03.2017 - 09:25

iyi günler android stüdio da bir kaç komutu tanımlayıp nete bağlanmadan çağırn bi program yapmak mümkün mü?

mesela rehberi tanımlayıp sesli söyldiğimizde uygulama otomatik olarak açılacak Teşekkürler..

 

RF
04.12.2015 - 09:04

Türkçe sesi yazıya çeviren yeni uygulama çıktı: voicedocs.com

Duygu
16.12.2015 - 01:17

Merhaba , basit yöntem de onActivityResult içinde bulunan diziyi editTexte yazdırmak istiyorum , onActivityResult içinden mi çekmeliyim ? yoksa editText in java tetikeleme fonksiyonunda mı? Bu dizi global mı anlayamadım

Sinan
17.11.2015 - 02:55

Merhaba Paylaşım için teşekkürler ben google sunduğu bu yapıyı sadece butona koymaya çalışıyorum ama bir türlü başarılı olamadım 

Salihcan
09.05.2015 - 04:52

Yapabilen varsa proje dosyasını atabilirmi

Eyüp KAYA
28.12.2014 - 01:25

Sesi yazıya dönüştürmek Güzel işte şimdi bu ingilizceyi iyi çeviri Türkçeyi kötü çevirir. Nasıl deniyenler verim iyimidir ?

Havva Nur
12.11.2014 - 01:31

burdaki iki yolu da denedim kodları çalıştrdım ama yazdırmıyor yani yazıya dönüştürmüyor nerde hata olabilir acaba ? sürekli bir hata oluştu diyor

Oğuzhan İNCE
26.08.2014 - 04:43

Emülatörde Speech to Text araçlarını kullanabilmemizin bir yolu yok mudur ?

Ahmet Burak Demirkoparan
26.08.2014 - 04:49

Malesef bir ses çıkışına ihtiyaç duyduğu için direk çalıştırılamıyor Google'den baktım pek sağlıklı bir yöntem göremedim.

Oğuzhan İNCE
26.08.2014 - 05:00
Pekala. Teşekkürler.
Burcu
25.08.2014 - 09:27

Bilgilendirme için teşekkürler