Cara Membuat Editor Sintesis Pidato
Diterbitkan: 2022-03-10Ketika Steve Jobs meluncurkan Macintosh pada tahun 1984, ia mengatakan "Halo" kepada kami dari panggung. Bahkan pada saat itu, sintesis ucapan bukanlah teknologi yang benar-benar baru: Bell Labs mengembangkan vocoder sejak akhir 30-an, dan konsep komputer asisten suara membuatnya menjadi perhatian orang-orang ketika Stanley Kubrick menjadikan vocoder sebagai suara HAL9000 pada tahun 2001: A Space Odyssey (1968).
Tidak sebelum pengenalan Apple Siri, Amazon Echo, dan Asisten Google pada pertengahan 2015-an antarmuka suara benar-benar menemukan jalan mereka ke rumah, pergelangan tangan, dan kantong publik yang lebih luas. Kami masih dalam tahap adopsi, tetapi tampaknya asisten suara ini akan tetap ada.
Dengan kata lain, web bukan hanya teks pasif di layar lagi . Editor web dan desainer UX harus terbiasa membuat konten dan layanan yang harus diucapkan dengan lantang.
Kami sudah bergerak cepat menuju penggunaan sistem manajemen konten yang memungkinkan kami bekerja dengan konten kami tanpa kepala dan melalui API. Bagian terakhir adalah membuat antarmuka editorial yang membuatnya lebih mudah untuk menyesuaikan konten untuk suara. Jadi mari kita lakukan itu!
Apa itu SSML?
Sementara browser web menggunakan spesifikasi W3C untuk HyperText Markup Language (HTML) untuk membuat dokumen secara visual, sebagian besar asisten suara menggunakan Speech Synthesis Markup Language (SSML) saat menghasilkan ucapan.
Contoh minimal menggunakan elemen root <speak>
, dan tag paragraf ( <p>
) dan kalimat ( <s>
):
<speak> <p> <s>This is the first sentence of the paragraph.</s> <s>Here's another sentence.</s> </p> </speak>
Di mana SSML menjadi ada adalah ketika kami memperkenalkan tag untuk <emphasis>
dan <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>
SSML memiliki lebih banyak fitur, tetapi ini cukup untuk memahami dasar-dasarnya. Sekarang, mari kita lihat lebih dekat editor yang akan kita gunakan untuk membuat antarmuka pengeditan sintesis ucapan.
Editor Untuk Teks Portabel
Untuk membuat editor ini, kita akan menggunakan editor untuk Portable Text yang ada di Sanity.io. Teks Portabel adalah spesifikasi JSON untuk pengeditan teks kaya, yang dapat diserialisasikan ke dalam bahasa markup apa pun, seperti SSML. Ini berarti Anda dapat dengan mudah menggunakan potongan teks yang sama di beberapa tempat menggunakan bahasa markup yang berbeda.

Memasang Sanitas
Sanity.io adalah platform untuk konten terstruktur yang hadir dengan lingkungan pengeditan sumber terbuka yang dibangun dengan React.js. Dibutuhkan dua menit untuk menyiapkan semuanya.
Ketik npm i -g @sanity/cli && sanity init
ke terminal Anda, dan ikuti petunjuknya. Pilih "kosong", ketika Anda diminta untuk template proyek.
Jika Anda tidak ingin mengikuti tutorial ini dan membuat editor ini dari awal, Anda juga dapat mengkloning kode tutorial ini dan mengikuti petunjuk di README.md
.
Saat editor diunduh, Anda menjalankan sanity start
di folder proyek untuk memulainya. Ini akan memulai server pengembangan yang menggunakan Hot Module Reloading untuk memperbarui perubahan saat Anda mengedit file-nya.
Cara Mengonfigurasi Skema Di Sanity Studio
Membuat File Editor
Kita akan mulai dengan membuat folder bernama ssml-editor di folder /schemas . Di folder itu, kami akan meletakkan beberapa file kosong:
/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
Sekarang kita dapat menambahkan skema konten dalam file-file ini. Skema konten adalah apa yang mendefinisikan struktur data untuk teks kaya, dan apa yang digunakan Sanity Studio untuk menghasilkan antarmuka editorial. Mereka adalah objek JavaScript sederhana yang sebagian besar hanya membutuhkan name
dan type
.
Kami juga dapat menambahkan title
dan description
untuk membuat editor sedikit lebih baik. Misalnya, ini adalah skema untuk bidang teks sederhana untuk title
:
export default { name: 'title', type: 'string', title: 'Title', description: 'Titles should be short and descriptive' }

Teks Portabel dibangun berdasarkan gagasan teks kaya sebagai data. Ini sangat kuat karena memungkinkan Anda menanyakan teks kaya Anda, dan mengubahnya menjadi hampir semua markup yang Anda inginkan.
Ini adalah array objek yang disebut "blok" yang dapat Anda anggap sebagai "paragraf". Dalam sebuah blok, ada sebuah array dari rentang anak-anak. Setiap blok dapat memiliki gaya dan satu set definisi tanda, yang menggambarkan struktur data yang didistribusikan pada rentang anak.
Sanity.io hadir dengan editor yang dapat membaca dan menulis ke Teks Portabel, dan diaktifkan dengan menempatkan tipe block
di dalam bidang array
, seperti ini:
// speech.js export default { name: 'speech', type: 'array', title: 'SSML Editor', of: [ { type: 'block' } ] }
Array dapat terdiri dari beberapa jenis. Untuk editor SSML, itu bisa berupa blok untuk file audio, tetapi itu berada di luar cakupan tutorial ini.
Hal terakhir yang ingin kami lakukan adalah menambahkan tipe konten di mana editor ini dapat digunakan. Sebagian besar asisten menggunakan model konten sederhana "niat" dan "pemenuhan":
- Niat
Biasanya daftar string yang digunakan oleh model AI untuk menggambarkan apa yang ingin dilakukan pengguna. - pemenuhan
Ini terjadi ketika "niat" diidentifikasi. Pemenuhan seringkali — atau setidaknya — datang dengan semacam respons.
Jadi mari kita buat tipe konten sederhana yang disebut fulfillment
yang menggunakan editor sintesis ucapan. Buat file baru bernama pemenuhan.js dan simpan di folder /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' } ] }
Simpan file, dan buka schema.js . Tambahkan ke studio Anda seperti ini:
// 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, ]) })
Jika Anda sekarang menjalankan sanity start
di antarmuka baris perintah Anda di dalam folder root proyek, studio akan memulai secara lokal, dan Anda akan dapat menambahkan entri untuk pemenuhan. Anda dapat membuat studio tetap berjalan saat kami melanjutkan, karena studio akan memuat ulang secara otomatis dengan perubahan baru saat Anda menyimpan file.
Menambahkan SSML ke Editor
Secara default, jenis block
akan memberi Anda editor standar untuk teks kaya berorientasi visual dengan gaya heading, gaya dekorator untuk penekanan dan kuat, anotasi untuk tautan, dan daftar. Sekarang kami ingin menggantinya dengan konsep audial yang ditemukan di SSML.
Kita mulai dengan mendefinisikan struktur konten yang berbeda, dengan deskripsi yang berguna untuk editor, yang akan kita tambahkan ke block
di SSMLeditorSchema.js sebagai konfigurasi untuk annotations
. Yaitu “penekanan”, “alias”, “prosodi”, dan “katakanlah sebagai”.
Tekanan
Kita mulai dengan "penekanan", yang mengontrol berapa banyak bobot yang diberikan pada teks yang ditandai. Kami mendefinisikannya sebagai string dengan daftar nilai yang telah ditentukan sebelumnya yang dapat dipilih pengguna:
// 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
Terkadang istilah tertulis dan lisan berbeda. Misalnya, Anda ingin menggunakan singkatan frasa dalam teks tertulis, tetapi minta seluruh frasa dibacakan. Sebagai contoh:
<s>This is a <sub alias="Speech Synthesis Markup Language">SSML</sub> tutorial</s>
Bidang input untuk alias adalah string sederhana:
// 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', } ] }
Prosodi
Dengan properti prosodi, kita dapat mengontrol berbagai aspek bagaimana teks harus diucapkan, seperti nada, kecepatan, dan volume. Markup untuk ini dapat terlihat seperti ini:
<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>
Input ini akan memiliki tiga bidang dengan opsi string yang telah ditentukan sebelumnya:
// 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' } ] } } ] }
Katakan As
Yang terakhir yang ingin kami sertakan adalah <say-as>
. Tag ini memungkinkan kita untuk sedikit lebih mengontrol bagaimana informasi tertentu diucapkan. Kami bahkan dapat menggunakannya untuk mengeluarkan kata-kata jika Anda perlu menyunting sesuatu di antarmuka suara. Itu @!%& berguna!
<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>
// 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' } ] } ] }
Sekarang kita dapat mengimpor ini dalam file annotations.js , yang membuat segalanya sedikit lebih rapi.

// 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'
Sekarang kita dapat mengimpor jenis anotasi ini ke dalam skema utama kita:
// 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 ]) })
Akhirnya, kita sekarang dapat menambahkan ini ke editor seperti ini:
// 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'} ] } } ] }
Perhatikan bahwa kita juga menambahkan array kosong ke styles
, dan decorators
. Ini menonaktifkan gaya dan dekorator default (seperti huruf tebal dan penekanan) karena tidak masuk akal dalam kasus khusus ini.
Menyesuaikan Tampilan Dan Nuansa
Sekarang kami memiliki fungsionalitas di tempat, tetapi karena kami belum menentukan ikon apa pun, setiap anotasi akan menggunakan ikon default, yang membuat editor sulit digunakan untuk penulis. Jadi mari kita perbaiki itu!
Dengan editor untuk Teks Portabel, dimungkinkan untuk menyuntikkan komponen React baik untuk ikon maupun untuk bagaimana teks yang ditandai harus dirender. Di sini, kami hanya akan membiarkan beberapa emoji melakukan pekerjaan untuk kami, tetapi Anda jelas bisa melangkah jauh dengan ini, menjadikannya dinamis dan sebagainya. Untuk prosody
kami bahkan akan membuat perubahan ikon tergantung pada volume yang dipilih. Perhatikan bahwa saya menghilangkan bidang dalam cuplikan ini untuk singkatnya, Anda tidak boleh menghapusnya di file lokal Anda.
// 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>, }, };

Sekarang Anda memiliki editor untuk mengedit teks yang dapat digunakan oleh asisten suara. Tapi bukankah akan berguna jika editor juga bisa melihat bagaimana teks sebenarnya akan terdengar?
Menambahkan Tombol Pratinjau Menggunakan Google Text-to-Speech
Dukungan sintesis ucapan asli sebenarnya sedang dalam perjalanan untuk browser. Namun dalam tutorial ini, kita akan menggunakan API Text-to-Speech Google yang mendukung SSML. Membangun fungsionalitas pratinjau ini juga akan menjadi demonstrasi bagaimana Anda membuat serial Teks Portabel ke dalam SSML dalam layanan apa pun yang Anda ingin gunakan untuk ini.
Membungkus Editor Dalam Komponen Bereaksi
Kita mulai dengan membuka file SSMLeditor.js dan menambahkan kode berikut:
// SSMLeditor.js import React, { Fragment } from 'react'; import { BlockEditor } from 'part:@sanity/form-builder'; export default function SSMLeditor(props) { return ( <Fragment> <BlockEditor {...props} /> </Fragment> ); }
Kami sekarang telah membungkus editor dalam komponen React kami sendiri. Semua alat peraga yang dibutuhkan, termasuk data yang dikandungnya, diturunkan secara real-time. Untuk benar-benar menggunakan komponen ini, Anda harus mengimpornya ke file speech.js
Anda:
// 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' }, ], }, }, ], }
Ketika Anda menyimpan ini dan studio memuat ulang, itu akan terlihat hampir sama persis, tapi itu karena kami belum mulai mengutak-atik editornya.
Konversi Teks Portabel Ke SSML
Editor akan menyimpan konten sebagai Teks Portabel, larik objek di JSON yang memudahkan konversi teks kaya ke format apa pun yang Anda inginkan. Saat Anda mengonversi Teks Portabel ke dalam sintaks atau format lain, kami menyebutnya "serialisasi". Oleh karena itu, "serializers" adalah resep bagaimana teks kaya harus dikonversi. Di bagian ini, kami akan menambahkan serializer untuk sintesis ucapan.
Anda telah membuat file blockToSSML.js . Sekarang kita perlu menambahkan ketergantungan pertama kita. Mulailah dengan menjalankan perintah terminal npm init -y
di dalam folder ssml-editor
. Ini akan menambahkan package.json tempat dependensi editor akan dicantumkan.
Setelah selesai, Anda dapat menjalankan npm install @sanity/block-content-to-html
untuk mendapatkan pustaka yang memudahkan pembuatan serial Teks Portabel. Kami menggunakan pustaka HTML karena SSML memiliki sintaks XML yang sama dengan tag dan atribut.
Ini adalah sekumpulan kode, jadi jangan ragu untuk menyalin-menempelnya. Saya akan menjelaskan polanya tepat di bawah cuplikan:
// 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 })
Kode ini akan mengekspor fungsi yang mengambil larik blok dan mengulangnya. Setiap kali sebuah blok berisi mark
, ia akan mencari serializer untuk jenisnya. Jika Anda telah menandai beberapa teks untuk memiliki emphasis
, ini berfungsi dari objek serializers:
emphasis: ({ children, mark: { level } }) => h('emphasis', { attrs: { level } }, children)
Mungkin Anda mengenali parameter dari mana kami mendefinisikan skema? Fungsi h()
memungkinkan kita mendefinisikan elemen HTML, yaitu, di sini kita "menipu" dan membuatnya mengembalikan elemen SSML yang disebut <emphasis>
. Kami juga memberikannya level
atribut jika itu didefinisikan, dan menempatkan elemen children
-anak di dalamnya — yang dalam banyak kasus akan menjadi teks yang telah Anda tandai dengan 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" ] } ] }
Begitulah struktur di atas dalam Portable Text diserialkan ke SSML ini:
<emphasis level="strong">Say this strongly</emphasis>
Jika Anda menginginkan dukungan untuk lebih banyak tag SSML, Anda dapat menambahkan lebih banyak anotasi dalam skema, dan menambahkan jenis anotasi ke bagian marks
di serializers.
Sekarang kita memiliki fungsi yang mengembalikan markup SSML dari teks kaya yang telah ditandai. Bagian terakhir adalah membuat tombol yang memungkinkan kita mengirim markup ini ke layanan text-to-speech.
Menambahkan Tombol Pratinjau yang Berbicara Kembali Kepada Anda
Idealnya, kita seharusnya menggunakan kemampuan sintesis ucapan browser di Web API. Dengan begitu, kita akan lolos dengan lebih sedikit kode dan dependensi.
Namun, pada awal 2019, dukungan browser asli untuk sintesis ucapan masih dalam tahap awal. Sepertinya dukungan untuk SSML sedang dalam proses, dan ada bukti konsep implementasi JavaScript sisi klien untuknya.
Kemungkinan Anda akan menggunakan konten ini dengan asisten suara. Baik Google Assistant dan Amazon Echo (Alexa) mendukung SSML sebagai respons dalam pemenuhan. Dalam tutorial ini, kita akan menggunakan API text-to-speech Google, yang juga terdengar bagus dan mendukung beberapa bahasa.
Mulailah dengan mendapatkan kunci API dengan mendaftar ke Google Cloud Platform (gratis untuk 1 juta karakter pertama yang Anda proses). Setelah Anda mendaftar, Anda dapat membuat kunci API baru di halaman ini.
Sekarang Anda dapat membuka file PreviewButton.js Anda, dan menambahkan kode ini ke dalamnya:
// 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> }
Saya telah menjaga kode tombol pratinjau ini seminimal mungkin untuk memudahkan mengikuti tutorial ini. Tentu saja, Anda dapat membuatnya dengan menambahkan status untuk menunjukkan apakah pratinjau sedang diproses atau memungkinkan untuk melihat pratinjau dengan suara berbeda yang didukung oleh API Google.
Tambahkan tombol ke 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> ); }
Sekarang Anda seharusnya dapat menandai teks Anda dengan anotasi yang berbeda, dan mendengar hasilnya saat menekan "Ucapkan teks". Keren, bukan?
Anda Telah Membuat Editor Sintesis Pidato, Dan Sekarang Apa?
Jika Anda telah mengikuti tutorial ini, Anda telah melalui bagaimana Anda dapat menggunakan editor untuk Teks Portabel di Sanity Studio untuk membuat anotasi khusus dan menyesuaikan editor. Anda dapat menggunakan keterampilan ini untuk segala macam hal, tidak hanya untuk membuat editor sintesis ucapan. Anda juga telah melalui cara membuat serial Teks Portabel ke dalam sintaks yang Anda butuhkan. Jelas, ini juga berguna jika Anda sedang membangun frontend di React atau Vue. Anda bahkan dapat menggunakan keterampilan ini untuk menghasilkan penurunan harga dari Teks Portabel.
Kami belum membahas bagaimana Anda sebenarnya menggunakan ini bersama dengan asisten suara. Jika Anda ingin mencoba, Anda dapat menggunakan banyak logika yang sama dengan tombol pratinjau dalam fungsi tanpa server, dan menyetelnya sebagai titik akhir API untuk pemenuhan menggunakan webhook, misalnya dengan Dialogflow.
Jika Anda ingin saya menulis tutorial tentang cara menggunakan editor sintesis ucapan dengan asisten suara, silakan beri saya petunjuk di Twitter atau bagikan di bagian komentar di bawah.
Bacaan Lebih Lanjut tentang SmashingMag:
- Bereksperimen Dengan SpeechSynthesis
- Meningkatkan Pengalaman Pengguna Dengan Web Speech API
- API Aksesibilitas: Kunci Aksesibilitas Web
- Membangun Chatbot AI Sederhana Dengan Web Speech API Dan Node.js