Cum să faci un editor de sinteză a vorbirii

Publicat: 2022-03-10
Rezumat rapid ↬ Asistentii vocali sunt în drum spre casele, încheieturile și buzunarele oamenilor. Asta înseamnă că o parte din conținutul nostru va fi rostit cu voce tare cu ajutorul sintezei vocale digitale. În acest tutorial, veți învăța cum să creați un editor What You Get Is What You Hear (WYGIWYH) pentru sinteza vorbirii folosind editorul Sanity.io pentru Text portabil.

Când Steve Jobs a dezvăluit Macintosh-ul în 1984, acesta ne-a spus „Bună ziua” de pe scenă. Chiar și în acel moment, sinteza vorbirii nu era cu adevărat o tehnologie nouă: Bell Labs a dezvoltat vocoder-ul încă de la sfârșitul anilor 30, iar conceptul unui computer cu asistent vocal a devenit conștientizat de oameni când Stanley Kubrick a făcut din vocoder vocea HAL9000 în 2001: A Space Odyssey (1968).

Nu înainte de introducerea Apple Siri, Amazon Echo și Google Assistant la mijlocul anilor 2015, interfețele vocale și-au găsit drumul în casele, încheieturile și buzunarele unui public mai larg. Suntem încă într-o fază de adoptare, dar se pare că acești asistenți vocali sunt aici pentru a rămâne.

Cu alte cuvinte, web-ul nu mai este doar text pasiv pe un ecran . Editorii web și designerii UX trebuie să se obișnuiască să creeze conținut și servicii care ar trebui să fie rostite cu voce tare.

Ne îndreptăm deja rapid spre utilizarea sistemelor de management al conținutului care ne permit să lucrăm cu conținutul nostru fără cap și prin intermediul API-urilor. Piesa finală este de a crea interfețe editoriale care facilitează adaptarea conținutului pentru voce. Deci haideți să facem exact asta!

Mai multe după săritură! Continuați să citiți mai jos ↓

Ce este SSML

În timp ce browserele web folosesc specificația W3C pentru HyperText Markup Language (HTML) pentru a reda vizual documentele, majoritatea asistenților vocali folosesc limbajul de marcare a sintezei vorbirii (SSML) atunci când generează vorbire.

Un exemplu minim folosind elementul rădăcină <speak> și etichetele de paragraf ( <p> ) și propoziție ( <s> ):

 <speak> <p> <s>This is the first sentence of the paragraph.</s> <s>Here's another sentence.</s> </p> </speak>
Apăsați pe redare pentru a asculta fragmentul:

Acolo unde SSML devine existent este atunci când introducem etichete pentru <emphasis> și <prosody> (pitch):

 <speak> <p> <s>Put some <emphasis strength="strong">extra weight on these words</emphasis></s> <s>And say <prosody pitch="high" rate="fast">this a bit higher and faster</prosody>!</s> </p> </speak>
Apăsați pe redare pentru a asculta fragmentul:

SSML are mai multe funcții, dar acest lucru este suficient pentru a înțelege elementele de bază. Acum, să aruncăm o privire mai atentă la editorul pe care îl vom folosi pentru a realiza interfața de editare a sintezei vorbirii.

Editorul pentru text portabil

Pentru a face acest editor, vom folosi editorul pentru Text portabil care apare în Sanity.io. Textul portabil este o specificație JSON pentru editarea textului îmbogățit, care poate fi serializată în orice limbaj de marcare, cum ar fi SSML. Aceasta înseamnă că puteți utiliza cu ușurință același fragment de text în mai multe locuri, folosind diferite limbaje de marcare.

Editorul implicit al Sanity.io pentru Text portabil
Editorul implicit al Sanity.io pentru Text portabil (previzualizare mare)

Instalarea Sanity

Sanity.io este o platformă pentru conținut structurat care vine cu un mediu de editare open-source construit cu React.js. Este nevoie de două minute pentru a pune totul în funcțiune.

Tastați npm i -g @sanity/cli && sanity init în terminalul dvs. și urmați instrucțiunile. Alegeți „gol”, când vi se solicită un șablon de proiect.

Dacă nu doriți să urmați acest tutorial și să faceți acest editor de la zero, puteți și clona codul acestui tutorial și urmați instrucțiunile din README.md .

Când editorul este descărcat, rulați sanity start în folderul de proiect pentru al porni. Va porni un server de dezvoltare care utilizează Hot Module Reloading pentru a actualiza modificările pe măsură ce editați fișierele sale.

Cum să configurați schemele în Sanity Studio

Crearea fișierelor Editor

Vom începe prin a crea un folder numit ssml-editor în folderul / schemas. În acel folder, vom pune câteva fișiere goale:

 /ssml-tutorial/schemas/ssml-editor ├── alias.js ├── emphasis.js ├── annotations.js ├── preview.js ├── prosody.js ├── sayAs.js ├── blocksToSSML.js ├── speech.js ├── SSMLeditor.css └── SSMLeditor.js

Acum putem adăuga scheme de conținut în aceste fișiere. Schemele de conținut sunt cele care definesc structura de date pentru textul îmbogățit și ceea ce Sanity Studio folosește pentru a genera interfața editorială. Sunt obiecte JavaScript simple, care necesită în mare parte doar un name și un type .

Putem adăuga, de asemenea, un title și o description pentru a face un pic mai frumos pentru editori. De exemplu, aceasta este o schemă pentru un câmp text simplu pentru un title :

 export default { name: 'title', type: 'string', title: 'Title', description: 'Titles should be short and descriptive' } 
Sanity Studio cu un câmp de titlu și un editor pentru Text portabil
Studioul cu câmpul nostru de titlu și editorul implicit (previzualizare mare)

Textul portabil este construit pe ideea de text îmbogățit ca date. Acest lucru este puternic, deoarece vă permite să interogați textul dvs. îmbogățit și să îl convertiți în aproape orice marcaj doriți.

Este o serie de obiecte numite „blocuri” pe care le puteți considera „paragrafe”. Într-un bloc, există o serie de spații de copii. Fiecare bloc poate avea un stil și un set de definiții de marcaj, care descriu structurile de date distribuite pe intervalele de copii.

Sanity.io vine cu un editor care poate citi și scrie în Text portabil și este activat prin plasarea tipului de block într-un câmp array , astfel:

 // speech.js export default { name: 'speech', type: 'array', title: 'SSML Editor', of: [ { type: 'block' } ] }

O matrice poate fi de mai multe tipuri. Pentru un editor SSML, acestea ar putea fi blocuri pentru fișierele audio, dar acest lucru nu intră în domeniul de aplicare al acestui tutorial.

Ultimul lucru pe care vrem să-l facem este să adăugăm un tip de conținut unde acest editor poate fi folosit. Majoritatea asistenților folosesc un model de conținut simplu de „intenții” și „împliniri”:

  • Intenții
    De obicei, o listă de șiruri utilizate de modelul AI pentru a delimita ceea ce utilizatorul dorește să facă.
  • Împliniri
    Acest lucru se întâmplă atunci când se identifică o „intenție”. O împlinire este adesea – sau cel puțin – vine cu un fel de răspuns.

Deci, să creăm un tip de conținut simplu numit fulfillment care să folosească editorul de sinteză a vorbirii. Creați un fișier nou numit fulfilment.js și salvați-l în folderul /schema :

 // fulfillment.js export default { name: 'fulfillment', type: 'document', title: 'Fulfillment', of: [ { name: 'title', type: 'string', title: 'Title', description: 'Titles should be short and descriptive' }, { name: 'response', type: 'speech' } ] }

Salvați fișierul și deschideți schema.js . Adaugă-l în studioul tău astfel:

 // schema.js import createSchema from 'part:@sanity/base/schema-creator' import schemaTypes from 'all:part:@sanity/base/schema-type' import fullfillment from './fullfillment' import speech from './speech' export default createSchema({ name: 'default', types: schemaTypes.concat([ fullfillment, speech, ]) })

Dacă acum rulați sanity start în interfața de linie de comandă din folderul rădăcină al proiectului, studioul va porni local și veți putea adăuga intrări pentru îndepliniri. Puteți menține studioul în funcțiune în timp ce continuăm, deoarece se va reîncărca automat cu noi modificări atunci când salvați fișierele.

Adăugarea SSML la editor

În mod implicit, tipul de block vă va oferi un editor standard pentru text bogat orientat vizual, cu stiluri de titlu, stiluri de decorare pentru accentuare și puternice, adnotări pentru linkuri și liste. Acum vrem să le înlocuim pe cele cu conceptele auditive găsite în SSML.

Începem cu definirea diferitelor structuri de conținut, cu descrieri utile pentru editori, pe care le vom adăuga la block din SSMLeditorSchema.js ca configurații pentru annotations . Acestea sunt „accent”, „alias”, „prozodie” și „spune ca”.

Accent

Începem cu „accent”, care controlează cât de multă greutate este pusă pe textul marcat. Îl definim ca un șir cu o listă de valori predefinite din care utilizatorul poate alege:

 // emphasis.js export default { name: 'emphasis', type: 'object', title: 'Emphasis', description: 'The strength of the emphasis put on the contained text', fields: [ { name: 'level', type: 'string', options: { list: [ { value: 'strong', title: 'Strong' }, { value: 'moderate', title: 'Moderate' }, { value: 'none', title: 'None' }, { value: 'reduced', title: 'Reduced' } ] } } ] }

Alias

Uneori termenul scris și cel vorbit diferă. De exemplu, doriți să utilizați abrevierea unei expresii într-un text scris, dar să citiți cu voce tare întreaga frază. De exemplu:

 <s>This is a <sub alias="Speech Synthesis Markup Language">SSML</sub> tutorial</s>
Apăsați pe redare pentru a asculta fragmentul:

Câmpul de intrare pentru alias este un șir simplu:

 // alias.js export default { name: 'alias', type: 'object', title: 'Alias (sub)', description: 'Replaces the contained text for pronunciation. This allows a document to contain both a spoken and written form.', fields: [ { name: 'text', type: 'string', title: 'Replacement text', } ] }

Prozodie

Cu proprietatea prozodie putem controla diferite aspecte despre cum ar trebui rostit textul, cum ar fi înălțimea, rata și volumul. Markup-ul pentru aceasta poate arăta astfel:

 <s>Say this with an <prosody pitch="x-low">extra low pitch</prosody>, and this <prosody rate="fast" volume="loud">loudly with a fast rate</prosody></s>
Apăsați pe redare pentru a asculta fragmentul:

Această intrare va avea trei câmpuri cu opțiuni de șir predefinite:

 // prosody.js export default { name: 'prosody', type: 'object', title: 'Prosody', description: 'Control of the pitch, speaking rate, and volume', fields: [ { name: 'pitch', type: 'string', title: 'Pitch', description: 'The baseline pitch for the contained text', options: { list: [ { value: 'x-low', title: 'Extra low' }, { value: 'low', title: 'Low' }, { value: 'medium', title: 'Medium' }, { value: 'high', title: 'High' }, { value: 'x-high', title: 'Extra high' }, { value: 'default', title: 'Default' } ] } }, { name: 'rate', type: 'string', title: 'Rate', description: 'A change in the speaking rate for the contained text', options: { list: [ { value: 'x-slow', title: 'Extra slow' }, { value: 'slow', title: 'Slow' }, { value: 'medium', title: 'Medium' }, { value: 'fast', title: 'Fast' }, { value: 'x-fast', title: 'Extra fast' }, { value: 'default', title: 'Default' } ] } }, { name: 'volume', type: 'string', title: 'Volume', description: 'The volume for the contained text.', options: { list: [ { value: 'silent', title: 'Silent' }, { value: 'x-soft', title: 'Extra soft' }, { value: 'medium', title: 'Medium' }, { value: 'loud', title: 'Loud' }, { value: 'x-loud', title: 'Extra loud' }, { value: 'default', title: 'Default' } ] } } ] }

Spune As

Ultimul pe care vrem să îl includem este <say-as> . Această etichetă ne permite să exercităm un pic mai mult control asupra modului în care anumite informații sunt pronunțate. Îl putem folosi chiar și pentru a semnaliza cuvinte dacă trebuie să redactați ceva în interfețele vocale. Este @!%& util!

 <s>Do I have to <say-as interpret-as="expletive">frakking</say-as> <say-as interpret-as="verbatim">spell</say-as> it out for you!?</s>
Apăsați pe redare pentru a asculta fragmentul:
 // sayAs.js export default { name: 'sayAs', type: 'object', title: 'Say as...', description: 'Lets you indicate information about the type of text construct that is contained within the element. It also helps specify the level of detail for rendering the contained text.', fields: [ { name: 'interpretAs', type: 'string', title: 'Interpret as...', options: { list: [ { value: 'cardinal', title: 'Cardinal numbers' }, { value: 'ordinal', title: 'Ordinal numbers (1st, 2nd, 3th...)' }, { value: 'characters', title: 'Spell out characters' }, { value: 'fraction', title: 'Say numbers as fractions' }, { value: 'expletive', title: 'Blip out this word' }, { value: 'unit', title: 'Adapt unit to singular or plural' }, { value: 'verbatim', title: 'Spell out letter by letter (verbatim)' }, { value: 'date', title: 'Say as a date' }, { value: 'telephone', title: 'Say as a telephone number' } ] } }, { name: 'date', type: 'object', title: 'Date', fields: [ { name: 'format', type: 'string', description: 'The format attribute is a sequence of date field character codes. Supported field character codes in format are {y, m, d} for year, month, and day (of the month) respectively. If the field code appears once for year, month, or day then the number of digits expected are 4, 2, and 2 respectively. If the field code is repeated then the number of expected digits is the number of times the code is repeated. Fields in the date text may be separated by punctuation and/or spaces.' }, { name: 'detail', type: 'number', validation: Rule => Rule.required() .min(0) .max(2), description: 'The detail attribute controls the spoken form of the date. For detail='1' only the day fields and one of month or year fields are required, although both may be supplied' } ] } ] }

Acum le putem importa într-un fișier annotations.js , ceea ce face lucrurile puțin mai ordonate.

 // annotations.js export {default as alias} from './alias' export {default as emphasis} from './emphasis' export {default as prosody} from './prosody' export {default as sayAs} from './sayAs'

Acum putem importa aceste tipuri de adnotări în schemele noastre principale:

 // schema.js import createSchema from "part:@sanity/base/schema-creator" import schemaTypes from "all:part:@sanity/base/schema-type" import fulfillment from './fulfillment' import speech from './ssml-editor/speech' import { alias, emphasis, prosody, sayAs } from './annotations' export default createSchema({ name: "default", types: schemaTypes.concat([ fulfillment, speech, alias, emphasis, prosody, sayAs ]) })

În cele din urmă, acum le putem adăuga la editor astfel:

 // speech.js export default { name: 'speech', type: 'array', title: 'SSML Editor', of: [ { type: 'block', styles: [], lists: [], marks: { decorators: [], annotations: [ {type: 'alias'}, {type: 'emphasis'}, {type: 'prosody'}, {type: 'sayAs'} ] } } ] }

Observați că am adăugat și matrice goale la styles și decorators . Acest lucru dezactivează stilurile și decoratorii impliciti (cum ar fi îndrăzneala și accentul), deoarece nu au prea mult sens în acest caz specific.

Personalizarea aspectului și senzației

Acum avem funcționalitatea la locul lui, dar din moment ce nu am specificat nicio pictogramă, fiecare adnotare va folosi pictograma implicită, ceea ce face editorul greu de utilizat pentru autori. Deci, hai să reparăm asta!

Cu editorul pentru Text portabil este posibil să injectați componente React atât pentru pictograme, cât și pentru modul în care ar trebui redat textul marcat. Aici, vom lăsa doar niște emoji să facă treaba pentru noi, dar, evident, ați putea merge departe cu asta, făcându-le dinamice și așa mai departe. Pentru prosody vom face chiar schimbarea pictogramei în funcție de volumul selectat. Rețineți că am omis câmpurile din aceste fragmente pentru concizie, nu ar trebui să le eliminați din fișierele locale.

 // alias.js import React from 'react' export default { name: 'alias', type: 'object', title: 'Alias (sub)', description: 'Replaces the contained text for pronunciation. This allows a document to contain both a spoken and written form.', fields: [ /* all the fields */ ], blockEditor: { icon: () => '', render: ({ children }) => <span>{children} </span>, }, };
 // emphasis.js import React from 'react' export default { name: 'emphasis', type: 'object', title: 'Emphasis', description: 'The strength of the emphasis put on the contained text', fields: [ /* all the fields */ ], blockEditor: { icon: () => '', render: ({ children }) => <span>{children} </span>, }, };
 // prosody.js import React from 'react' export default { name: 'prosody', type: 'object', title: 'Prosody', description: 'Control of the pitch, speaking rate, and volume', fields: [ /* all the fields */ ], blockEditor: { icon: () => '', render: ({ children, volume }) => ( <span> {children} {['x-loud', 'loud'].includes(volume) ? '' : ''} </span> ), }, };
 // sayAs.js import React from 'react' export default { name: 'sayAs', type: 'object', title: 'Say as...', description: 'Lets you indicate information about the type of text construct that is contained within the element. It also helps specify the level of detail for rendering the contained text.', fields: [ /* all the fields */ ], blockEditor: { icon: () => '', render: props => <span>{props.children} </span>, }, }; 
Editorul SSML personalizat
Editorul cu marcajele noastre SSML personalizate (previzualizare mare)

Acum aveți un editor pentru editarea textului care poate fi folosit de asistenții vocali. Dar nu ar fi oarecum util dacă și editorii ar putea previzualiza cum va suna de fapt textul?

Adăugarea unui buton de previzualizare folosind text-to-speech de la Google

Suportul nativ pentru sinteza vorbirii este de fapt pe cale pentru browsere. Dar, în acest tutorial, vom folosi API-ul Text-to-Speech de la Google, care acceptă SSML. Construirea acestei funcționalități de previzualizare va fi, de asemenea, o demonstrație a modului în care serializați Textul portabil în SSML în orice serviciu pentru care doriți să îl utilizați.

Împachetarea editorului într-o componentă React

Începem cu deschiderea fișierului SSMLeditor.js și adăugăm următorul cod:

 // SSMLeditor.js import React, { Fragment } from 'react'; import { BlockEditor } from 'part:@sanity/form-builder'; export default function SSMLeditor(props) { return ( <Fragment> <BlockEditor {...props} /> </Fragment> ); }

Acum am împachetat editorul în propria noastră componentă React. Toate elementele de recuzită de care are nevoie, inclusiv datele pe care le conține, sunt transmise în timp real. Pentru a utiliza efectiv această componentă, trebuie să o importați în fișierul dvs. speech.js :

 // speech.js import React from 'react' import SSMLeditor from './SSMLeditor.js' export default { name: 'speech', type: 'array', title: 'SSML Editor', inputComponent: SSMLeditor, of: [ { type: 'block', styles: [], lists: [], marks: { decorators: [], annotations: [ { type: 'alias' }, { type: 'emphasis' }, { type: 'prosody' }, { type: 'sayAs' }, ], }, }, ], }

Când salvezi acest lucru și studioul se reîncarcă, ar trebui să arate aproape exact la fel, dar asta pentru că nu am început încă să modificăm editorul.

Conversia textului portabil în SSML

Editorul va salva conținutul ca Text portabil, o serie de obiecte în JSON care facilitează convertirea textului îmbogățit în orice format aveți nevoie. Când convertiți Textul portabil într-o altă sintaxă sau format, o numim „serializare”. Prin urmare, „serializatoarele” sunt rețetele pentru cum ar trebui convertit textul bogat. În această secțiune, vom adăuga serializatoare pentru sinteza vorbirii.

Ați creat deja fișierul blocksToSSML.js . Acum va trebui să adăugăm prima noastră dependență. Începeți prin a rula comanda terminalului npm init -y în folderul ssml-editor . Aceasta va adăuga un package.json în care dependențele editorului vor fi listate.

Odată ce ați terminat, puteți rula npm install @sanity/block-content-to-html pentru a obține o bibliotecă care ușurează serializarea textului portabil. Folosim biblioteca HTML, deoarece SSML are aceeași sintaxă XML cu etichete și atribute.

Acesta este o grămadă de cod, așa că nu ezitați să-l copiați și lipiți. Voi explica modelul chiar sub fragment:

 // blocksToSSML.js import blocksToHTML, { h } from '@sanity/block-content-to-html' const serializers = { marks: { prosody: ({ children, mark: { rate, pitch, volume } }) => h('prosody', { attrs: { rate, pitch, volume } }, children), alias: ({ children, mark: { text } }) => h('sub', { attrs: { alias: text } }, children), sayAs: ({ children, mark: { interpretAs } }) => h('say-as', { attrs: { 'interpret-as': interpretAs } }, children), break: ({ children, mark: { time, strength } }) => h('break', { attrs: { time: '${time}ms', strength } }, children), emphasis: ({ children, mark: { level } }) => h('emphasis', { attrs: { level } }, children) } } export const blocksToSSML = blocks => blocksToHTML({ blocks, serializers })

Acest cod va exporta o funcție care preia matricea de blocuri și le va trece în buclă. Ori de câte ori un bloc conține un mark , va căuta un serializator pentru tip. Dacă ați marcat un text pentru a emphasis , aceasta este această funcție din obiectul serializatoare:

 emphasis: ({ children, mark: { level } }) => h('emphasis', { attrs: { level } }, children)

Poate recunoașteți parametrul de unde am definit schema? Funcția h() ne permite să definim un element HTML, adică aici „trișăm” și îl face să returneze un element SSML numit <emphasis> . Îi dăm, de asemenea, level de atribut dacă acesta este definit și plasăm elementele children în el - care în cele mai multe cazuri va fi textul pe care l-ați marcat cu emphasis .

 { "_type": "block", "_key": "f2c4cf1ab4e0", "style": "normal", "markDefs": [ { "_type": "emphasis", "_key": "99b28ed3fa58", "level": "strong" } ], "children": [ { "_type": "span", "_key": "f2c4cf1ab4e01", "text": "Say this strongly!", "marks": [ "99b28ed3fa58" ] } ] }

Acesta este modul în care structura de mai sus în Text portabil este serializată la acest SSML:

 <emphasis level="strong">Say this strongly</emphasis>

Dacă doriți suport pentru mai multe etichete SSML, puteți adăuga mai multe adnotări în schemă și puteți adăuga tipuri de adnotări la secțiunea de marks din serializatoare.

Acum avem o funcție care returnează marcajul SSML din textul nostru îmbogățit marcat. Ultima parte este să facem un buton care ne permite să trimitem acest marcaj către un serviciu text-to-speech.

Adăugarea unui buton de previzualizare care să vă răspundă

În mod ideal, ar fi trebuit să folosim capacitățile de sinteză a vorbirii ale browserului în API-ul web. În acest fel, am fi scăpat cu mai puțin cod și dependențe.

Cu toate acestea, de la începutul anului 2019, suportul nativ pentru browser pentru sinteza vorbirii este încă în stadii incipiente. Se pare că suportul pentru SSML este pe cale și există dovezi ale conceptelor implementărilor JavaScript la nivelul clientului pentru acesta.

Sunt șanse să utilizați oricum acest conținut cu un asistent vocal. Atât Google Assistant, cât și Amazon Echo (Alexa) acceptă SSML ca răspunsuri într-o împlinire. În acest tutorial, vom folosi API-ul text-to-speech de la Google, care, de asemenea, sună bine și acceptă mai multe limbi.

Începeți prin a obține o cheie API prin înscrierea la Google Cloud Platform (va fi gratuit pentru primul milion de caractere procesate). După ce v-ați înscris, puteți crea o nouă cheie API pe această pagină.

Acum puteți deschide fișierul PreviewButton.js și adăugați acest cod la acesta:

 // PreviewButton.js import React from 'react' import Button from 'part:@sanity/components/buttons/default' import { blocksToSSML } from './blocksToSSML' // You should be careful with sharing this key // I put it here to keep the code simple const API_KEY = '<yourAPIkey>' const GOOGLE_TEXT_TO_SPEECH_URL = 'https://texttospeech.googleapis.com/v1beta1/text:synthesize?key=' + API_KEY const speak = async blocks => { // Serialize blocks to SSML const ssml = blocksToSSML(blocks) // Prepare the Google Text-to-Speech configuration const body = JSON.stringify({ input: { ssml }, // Select the language code and voice name (AF) voice: { languageCode: 'en-US', name: 'en-US-Wavenet-A' }, // Use MP3 in order to play in browser audioConfig: { audioEncoding: 'MP3' } }) // Send the SSML string to the API const res = await fetch(GOOGLE_TEXT_TO_SPEECH_URL, { method: 'POST', body }).then(res => res.json()) // Play the returned audio with the Browser's Audo API const audio = new Audio('data:audio/wav;base64,' + res.audioContent) audio.play() } export default function PreviewButton (props) { return <Button style={{ marginTop: '1em' }} onClick={() => speak(props.blocks)}>Speak text</Button> }

Am păstrat acest cod al butonului de previzualizare la un nivel minim pentru a ușura urmărirea acestui tutorial. Desigur, îl puteți construi adăugând stare pentru a arăta dacă previzualizarea este în procesare sau pentru a face posibilă previzualizarea cu diferite voci pe care le acceptă API-ul Google.

Adăugați butonul la SSMLeditor.js :

 // SSMLeditor.js import React, { Fragment } from 'react'; import { BlockEditor } from 'part:@sanity/form-builder'; import PreviewButton from './PreviewButton'; export default function SSMLeditor(props) { return ( <Fragment> <BlockEditor {...props} /> <PreviewButton blocks={props.value} /> </Fragment> ); }

Acum ar trebui să puteți marca textul cu diferite adnotări și să auzi rezultatul când apăsați „Rostiți text”. Cool, nu-i așa?

Ați creat un editor de sinteză a vorbirii și acum ce?

Dacă ați urmat acest tutorial, ați trecut prin cum puteți utiliza editorul pentru Text portabil din Sanity Studio pentru a face adnotări personalizate și a personaliza editorul. Puteți folosi aceste abilități pentru tot felul de lucruri, nu numai pentru a face un editor de sinteză a vorbirii. De asemenea, ați trecut prin cum să serializați Textul portabil în sintaxa de care aveți nevoie. Evident, acest lucru este util și dacă construiți interfețe în React sau Vue. Puteți chiar să utilizați aceste abilități pentru a genera Markdown din Text Portable.

Nu am acoperit cum îl utilizați de fapt împreună cu un asistent vocal. Dacă doriți să încercați, puteți utiliza o mare parte din aceeași logică ca și cu butonul de previzualizare într-o funcție fără server și să-l setați ca punct final API pentru o realizare folosind webhook-uri, de exemplu, cu Dialogflow.

Dacă doriți să scriu un tutorial despre cum să folosesc editorul de sinteză a vorbirii cu un asistent vocal, nu ezitați să-mi dați un indiciu pe Twitter sau să distribuiți în secțiunea de comentarii de mai jos.

Citiți suplimentare despre SmashingMag:

  • Experimentarea cu speechSinteza
  • Îmbunătățirea experienței utilizatorului cu API-ul Web Speech
  • API-uri de accesibilitate: o cheie pentru accesibilitatea web
  • Construirea unui chatbot AI simplu cu API-ul Web Speech și Node.js