„Az összevisszaságban találd meg az egyszerűséget, a hangzavarban a harmóniát...”

Beszélj a weboldalhoz!

Web Speech APIIsmét egy viszonylag friss webes technológiát szeretnék bemutatni. Mindössze egy mikrofon és egy modern webböngésző kell hozzá. A weboldalak hangalapú vezérléséről van szó. Első hallásra érdekesnek tűnik, aztán elkezdesz gondolkozni, hogy Te mire tudnád használni. Majd rájössz, hogy semmire. Talán valamiféle beszélgetős alkalmazás? De hát olyan van már ezer. Vagy a weboldal accessibility javítása miatt? De azzal meg ki törődik... Szóval egy picit "feleslegesnek" tűnhet ez a Web Speech API. Ennek ellenére, szerintem csak fantázia kérdése az, hogy ki mit tud belőle kihozni. Van egy olyan sejtésem, hogy fogunk még hanggal irányítani ötletes weboldalakat.

Jelenleg egyedül a Chrome (25+) támogatja, programunkban így tudjuk ezen fícsör meglétét egyszerűen ellenőrizni:

if (!('webkitSpeechRecognition' in window)) alert("Nincs beszédfelismerés!");

Ha támogatja a rendszer, akkor izzítsuk is be! Hozzunk létre egy új példányt, és konfiguráljuk be ízlésünk szerint:

var recognition = new webkitSpeechRecognition();
recognition.lang = 'hu-HU';
recognition.continuous = true;
recognition.interimResults = true;
recognition.maxAlternatives = 1;

A lang propertyvel beállítottuk a felismerés nyelvét magyarra. Rengeteg nyelvet ismer, sőt, a gyakoribb nyelvek esetében még eltérő dialektusokat is meg tud különböztetni. BCP-47 formában kell megadni, például az új-zélandi angol esetében en-NZ. Ha nincs megadva, akkor a HTML dokumentum nyelvi attribútumait veszi alapul.

A continuous flaggel azt tudod megadni, hogy a hangrögzítés folyamatos legyen, vagy ha abbahagyod a beszédet akkor egyből onend-re fusson, és leálljon. Alapértelmezett értéke false. Tapasztalataim szerint a folyamatos változat esetében is leáll olykor a rögzítés. Például ha fókuszt veszít az oldal, vagy nagyon sokáig nem adsz jelet a mikrofonnak (csendben vagy).

Az interimResults is alapból hamis, ami azt jelenti, hogy csak a véglegesen felismert szöveget adja vissza. És itt el is érkeztünk az első problémához, illetve kényelmetlenséghez. Ajánlott ugyanis ezt az értéket igazra állítani, hogy egyből, beszéd közben is folyamatosan közölje a felismert szöveget. Ezáltal válik gyorssá az alkalmazásunk. Viszont ezt úgy teszi, hogy egy elhangzott szót, kifejezést, több módon is felismerhet, több alternatívát is adhat, így több eredményt is kapunk vissza. Gyakorlatilag folyamatosan bombáz minket az API felismert kifejezésekkel. Ez érthető, a feladat bonyolultságából adódik, nem várható el egyetlen konkrét 100%-os pontosságú válasz. Gondoljunk bele, egy hangrezgést kell szöveggé alakítani, ráadásul nyelvfüggően. A mi feladatunk tehát, hogy úgy írjuk meg programunkat, hogy a kapott ömlesztett eredményekből kiválogassuk a számunkra szükséges elemeket. Javaslom, hogy az "elkapni" kívánt kifejezésekre készítsünk egy tömböt, és ha bármi más érkezik, azokat ignoráljuk.

A maxAlternatives érték azt szabályozza, hogy egy visszaadott eredményen belül hány felismert alternatívát tartalmazzon. Az egy bőven elég lesz, úgyis a felismerés pontossága szerint sorrendezi őket.

recognition.start();
recognition.onstart = function() {
console.log("rögzítés elindul...");
}

A fenti utasítással tudjuk elkezdeni a hangrögzítést az előre beállított konfiguráció szerint. Ekkor beadja a figyelmeztető üzenetet a Chrome, hogy az alkalmazás használni akarja a mikrofont, és hogy engedjük-e neki.

Mikrofon engedélyezése

Ha nem engedjük, akkor többé meg sem kérdezi, alapból nem lesz az adott oldalon elérhető. A címsorban a videókamera gombra kattintva lehet a tiltólistáról kivenni. Viszont ha engedélyezzük, akkor azt nem jegyzi meg! Magyarán folyamatosan, ahányszor csak elstartol a rögzítés, mindig jóvá kell hagyni. Kivétel ez alól, ha HTTPS protokoll alatt fut az oldal, akkor permanensen megjegyzi. Ez nekem azért picit fura. (Ha bemész a beállítások - speciális - adatvédelem - tartalombeállítások menübe, a kivételek kezelésénél mindenhol tudsz weboldalakat hozzáadni, de a média rész alatt, ahol a mikrofon és a kamera van, ott nem.) Az engedélyezés után fut le az onstart esemény.

Faviconban villogó felvétel visszajelzőA rögzítés ideje alatt vessünk egy pillantást a faviconra! A jobb alsó sarkában elkezd egy piros kör villogni. Már csak a szintén villogó REC felírat hiányzik mellőle. A visszajelzés jó dolog, mert jó látni hogy mikor ne mondjunk olyat, ami nem tartozik az NSA-re. :) Illetve azért is, mert ha már nem villog, akkor zátonyra, vagyis onend-re futott a hajó, és ekkor már csak magunkban beszélgetünk. Csak szerintem ezt nem a faviconban kellene megoldani...

Ha már onend, akkor nézzük a többi fontosabb eseményt is:

recognition.onresult = function(event) { ... }
recognition.onerror = function(event) { ... }
recognition.onend = function(event) { ... }

Onerror akkor lehetséges, ha nem engedélyezzük a mikrofont, vagy ismeretlen a beállított nyelv, vagy valami gubanc történik menet közben. Az onerror után rendszerint egyből az onend is lefut. Az onend kiváltódhat még, ha nem folytatólagos a felvétel, vagy ha tabot váltunk, vagy sokáig némaság van.

Web Speech API onresult eventE kettőnél sokkal fontosabb esemény az onresult, ugyanis ebben kapjuk meg a hiteket. Szó ami szó, megoldhatták volna egyszerűbben is... Tartalmazza az eredmények tömbjét, aminek elemein belül a felismert alternatívák tömbje van. Tehát egyetlen esemény lefutása alatt is sok adatot kapunk vissza. De a folyamatos pontosítások és véglegesítések miatt akár tizedmásodpercekkel később kaphatunk egy újabb ilyen tömbös tömböt. A kapott eredmények megfelelő kezelése a programozó dolga, és erősen feladatfüggő.

Web Speech API színfelismerő játékAz itt leírtak gyakorlati prezentálására készítettem egy egyszerű színfelismerő játékot. Van ez a pszichológiai dolog, hogy ha eléd raknak egy színes szöveget, és ki kell mondanod annak színét, akkor sokszor belehibázol, mert magát a szöveget mondod ki. A játékban az a feladat, hogy minél gyorsabban kell a megjelenő szöveg színét kimondani. A program viszonylag gyorsan értékel.

Az eredmények kezelése ebben az esetben úgy történik, hogy csak az általam jóváhagyott szavakkal foglalkozok, minden más találatot mellőzök. Illetve ha egymás után kétszer ugyanaz következne, azt is kihagyom. Tehát csak az új, és a szótáramban szereplő felismert hangokra reagál a program. De simán elképzelhető, hogy egy másik feladatban tök máshogy kell kezelni a visszakapott adatokat, mint például a Chrome demonstrációs oldalán, ahol egy folyamatos szöveget lehet lediktálni.

TIPP: Ha fix szavakkal dolgozol, akkor javaslom, hogy a szótáradba vedd fel azokat a szavakat is, amik csak hasonlóak. Nekem a lila mellé fel kellett vennem a Lillát, a Leilát, de még a Bélát is, mert van, hogy úgy ismerte fel. A játék gördülékeny menetéhez ez a fajta "lazaság" szükséges. Ennek hiányában idegesítő lenne, amikor már ötödjére mondod ki maximális artikuláltsággal hogy szürke, de szőkének érti, és nem enged tovább.

Összegezve tehát nem egy halál precíz dologról van szó, a használati esetek is korlátozottak, de ennek ellenére mégis egy izgalmas dolog. Remélem sikerült kedvet csinálnom ehhez az API-hoz, és lesz egy jó ötleted, ahol Te is használni fogod a jövőben.

Vedd elő a mikrofont, és kattints ide a színfelismerő játékhoz!