Голосовое управление web-плеером, или скрещиваем CMU Sphinx с Selenium WebDriver
В этой статье я описывал создание веб mp3 плеера и домашней аудиосистемы.Сам плеер можно увидеть здесь.Возникла идея — прикрутить к плееру голосовое управление.После часа-другого поиска в интернете решение нашлось: CMU Sphinx — для распознавания речи + Selenium WebDriver — для программного управления браузером.
Итак, начнем.Разработку велась в IDE Eclipse.Для начала нужно преобразовать наш проект в проект Maven: right click на проекте — Configure — Convert to Maven Project.
В файл pom.xml нужно добавить следующее:
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
public
public
public
public
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