Голосовое управление web-плеером, или скрещиваем CMU Sphinx с Selenium WebDriver

В этой статье я описывал создание веб mp3 плеера и домашней аудиосистемы.Сам плеер можно увидеть здесь.Возникла идея — прикрутить к плееру голосовое управление.После часа-другого поиска в интернете решение нашлось: CMU Sphinx — для распознавания речи + Selenium WebDriver — для программного управления браузером.

Итак, начнем.Разработку велась в IDE Eclipse.Для начала нужно преобразовать наш проект в проект Maven: right click на проекте — Configure — Convert to Maven Project.

В файл pom.xml нужно добавить следующее:

snapshots-repo https://oss.sonatype.org/content/repositories/snapshots false true edu.cmu.sphinx sphinx4-core 1.0-SNAPSHOT Также нам понадобится:

1. Русская акустическая модель (скачать можно здесь)— скачиваем последнюю версию архива, и копируем папку zero_ru.cd_cont_4000 в нашу папку с исходниками.

2. Selenium WebDriver для Java (скачать) — подключаем к проекту jar-файл библиотеки из архива.

3. Эти файлы — для генерирования транскрипций русских слов используем dict2transcript.pl.

И так, можно начать работу над программой.

С помощью скрипта dict2transcript.pl составляем наш словарь — mydict.dict:

cranberries k r y n bb i rr i s gromche g r oo m ch i iskat i s k aa tt kinoproby kk i n a p r oo b y minus mm ii n u s nautilus n ay u tt ii l u s nazad n ay z aa t number1 a dd ii n number3 t rr ii number10 dd je ss i tt number30 t rr ii c ay tt pausa p aa u z ay plus p ll ju s rammstein r aa m sh t ay j n snaipery s n aa j pp i r y start s t ay r t tishe tt ii sh y Затем составляем grammar-файл — mygrammar.gram:

#JSGF V1.0;

grammar mygrammar;

public = start;

public = pausa;

public = tishe; public = gromche;

public = (plus|minus)(number1|number3|number10|number30);

public = iskat; public = (cranberries|kinoproby|nautilus|rammstein|snaipery); И вот, собственно, исходник программы на Java:

package jatx.sphinxtest;

import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver;

import edu.cmu.sphinx.api.Configuration; import edu.cmu.sphinx.api.LiveSpeechRecognizer; import edu.cmu.sphinx.api.SpeechResult; import edu.cmu.sphinx.result.WordResult;

public class Main { private static final WebDriver driver = new FirefoxDriver (); private static int volume = 100; private static final String[] prefixes = {«plus», «minus», «iskat»}; private static final String[] artists = {«cranberries», «kinoproby», «nautilus», «rammstein», «snaipery»}; private static final String[] numbers = {«number1», «number3», «number10», «number30»}; static { driver.manage ().window ().maximize (); music (); } public static void main (String[] args) { Configuration configuration = new Configuration (); configuration.setAcousticModelPath («resource:/jatx/sphinxtest/zero_ru.cd_cont_4000»); configuration.setDictionaryPath («resource:/jatx/sphinxtest/mydict.dict»); configuration.setUseGrammar (true); configuration.setGrammarPath («resource:/jatx/sphinxtest»); configuration.setGrammarName («mygrammar»); try { LiveSpeechRecognizer recognizer = new LiveSpeechRecognizer (configuration); recognizer.startRecognition (true); String prefix = »; while (true) { SpeechResult result = recognizer.getResult ();

for (WordResult r: result.getWords ()) { try { String cmd = r.getWord ().toString (); if (cmd.equals («tishe»)) volumeDown (); if (cmd.equals («gromche»)) volumeUp (); if (cmd.equals («start»)) play (); if (cmd.equals («pausa»)) pause (); for (String pref: prefixes) { if (cmd.equals (pref)) prefix = pref; } for (String artist: artists) { if (cmd.equals (artist)&&prefix.equals («iskat»)) changeArtist (artist); } for (String number: numbers) { if (cmd.equals (number)) { Integer num = Integer.parseInt (number.replace («number»,»)); if (prefix.equals («minus»)) rev (num); if (prefix.equals («plus»)) fwd (num); } } //System.out.println (cmd); } catch (Exception e) { e.printStackTrace (); } } } } catch (Exception e) { e.printStackTrace (); } }

private static void music () { System.out.println («music»);

driver.get («http://home.tabatsky.ru/mp3player/desktop.jsp»); } private static void volumeDown () { System.out.println («volume down»); volume = (volume>10? volume-20: volume); setVolume (volume); }

private static void volumeUp () { System.out.println («volume up»); volume = (volume<90?volume+20:volume); setVolume(volume); } private static void setVolume(int volume) { JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("$('#volume_slider').slider('value'," + Integer.valueOf(volume) + ")"); js.executeScript("window.setVolume("+Double.valueOf(volume/100.0)+")"); } private static void play() { System.out.println("start"); WebElement track = driver.findElement(By.id("0")); track.click(); } private static void pause() { System.out.println("pause"); JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("$('#toogle').trigger('click')"); } private static void fwd(int n) { System.out.println("plus " + Integer.valueOf(n).toString()); WebElement fwd = driver.findElement(By.id("fwd")); for (int i=0; i

© Habrahabr.ru