كيفية عمل محرر تركيب الكلام

نشرت: 2022-03-10
ملخص سريع ↬ المساعدون الصوتيون في طريقهم إلى منازل الناس ومعصمهم وجيوبهم. هذا يعني أنه سيتم نطق بعض المحتوى الخاص بنا بصوت عالٍ بمساعدة تركيب الكلام الرقمي. في هذا البرنامج التعليمي ، ستتعلم كيفية إنشاء محرر ما تحصل عليه هو ما تسمعه (WYGIWYH) لتركيب الكلام باستخدام محرر Sanity.io للنص المحمول.

عندما كشف ستيف جوبز النقاب عن Macintosh في عام 1984 ، قال لنا "مرحبًا" من المسرح. حتى في تلك المرحلة ، لم يكن تركيب الكلام حقًا تقنية جديدة: طورت Bell Labs المشفر الصوتي في وقت مبكر في أواخر الثلاثينيات ، وجعل مفهوم الكمبيوتر المساعد الصوتي في وعي الناس عندما جعل ستانلي كوبريك المشفر الصوتي صوتًا HAL9000 في عام 2001: رحلة فضائية (1968).

لم يكن قبل تقديم Apple's Siri و Amazon Echo و Google Assistant في منتصف عام 2015 أن الواجهات الصوتية وجدت طريقها فعليًا إلى المنازل والمعصمين والجيوب العامة. ما زلنا في مرحلة التبني ، ولكن يبدو أن هؤلاء المساعدين الصوتيين موجودون لتبقى.

بمعنى آخر ، لم يعد الويب مجرد نص سلبي على الشاشة بعد الآن . يجب أن يعتاد محررو الويب ومصممي تجربة المستخدم على إنشاء محتوى وخدمات يجب التحدث بها بصوت عالٍ.

نحن نتحرك بالفعل بسرعة نحو استخدام أنظمة إدارة المحتوى التي تتيح لنا العمل مع المحتوى الخاص بنا بلا رأس وعبر واجهات برمجة التطبيقات. الجزء الأخير هو إنشاء واجهات تحريرية تسهل تخصيص المحتوى للصوت. لذلك دعونا نفعل ذلك بالضبط!

المزيد بعد القفز! أكمل القراءة أدناه ↓

ما هو SSML

بينما تستخدم متصفحات الويب مواصفات W3C للغة ترميز النص التشعبي (HTML) لعرض المستندات بصريًا ، فإن معظم المساعدين الصوتيين يستخدمون لغة ترميز تركيب الكلام (SSML) عند توليد الكلام.

مثال بسيط باستخدام عنصر الجذر <speak> وعلامات الفقرة ( <p> ) والجملة ( <s> ):

 <speak> <p> <s>This is the first sentence of the paragraph.</s> <s>Here's another sentence.</s> </p> </speak>
اضغط تشغيل للاستماع إلى المقتطف:

مكان وجود SSML هو عندما نقدم علامات لـ <emphasis> و <prosody> (خطوة):

 <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 على المزيد من الميزات ، ولكن هذا يكفي للتعرف على الأساسيات. الآن ، دعنا نلقي نظرة فاحصة على المحرر الذي سنستخدمه لإنشاء واجهة تحرير تركيب الكلام.

محرر النص المحمول

لإنشاء هذا المحرر ، سنستخدم محرر النص المحمول الذي يتميز به Sanity.io. يُعد النص المحمول أحد مواصفات JSON لتحرير النص المنسق ، والذي يمكن تحويله إلى أي لغة ترميز ، مثل SSML. هذا يعني أنه يمكنك بسهولة استخدام نفس مقتطف النص في أماكن متعددة باستخدام لغات ترميز مختلفة.

محرر Sanity.io الافتراضي للنص المحمول
محرر Sanity.io الافتراضي للنص المحمول (معاينة كبيرة)

تركيب العقل

Sanity.io عبارة عن نظام أساسي للمحتوى المنظم الذي يأتي مع بيئة تحرير مفتوحة المصدر تم إنشاؤها باستخدام React.js. يستغرق الأمر دقيقتين للحصول على كل شيء وتشغيله.

اكتب npm i -g @sanity/cli && sanity init في جهازك ، واتبع التعليمات. اختر "فارغ" ، عندما يُطلب منك نموذج مشروع.

إذا كنت لا ترغب في اتباع هذا البرنامج التعليمي وإنشاء هذا المحرر من البداية ، فيمكنك أيضًا استنساخ رمز هذا البرنامج التعليمي واتباع التعليمات الموجودة في README.md .

عندما يتم تنزيل المحرر ، تقوم بتشغيل sanity start في مجلد المشروع لبدء تشغيله. سيبدأ خادم تطوير يستخدم Hot Module Reloading لتحديث التغييرات أثناء تحرير ملفاته.

كيفية تكوين المخططات في Sanity Studio

إنشاء ملفات المحرر

سنبدأ بإنشاء مجلد يسمى ssml-editor في المجلد / schemas . في هذا المجلد ، سنضع بعض الملفات الفارغة:

 /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

الآن يمكننا إضافة مخططات المحتوى في هذه الملفات. مخططات المحتوى هي التي تحدد بنية البيانات للنص المنسق ، وما يستخدمه Sanity Studio لإنشاء واجهة التحرير. إنها كائنات JavaScript بسيطة تتطلب في الغالب name type فقط.

يمكننا أيضًا إضافة title description لجعله أفضل قليلاً للمحررين. على سبيل المثال ، هذا مخطط لحقل نص بسيط title :

 export default { name: 'title', type: 'string', title: 'Title', description: 'Titles should be short and descriptive' } 
Sanity Studio مع حقل عنوان ومحرر للنص المحمول
الاستوديو مع حقل العنوان والمحرر الافتراضي (معاينة كبيرة)

تم بناء النص المتنقل على فكرة النص المنسق كبيانات. هذا قوي لأنه يتيح لك الاستعلام عن نصك الغني وتحويله إلى أي ترميز تريده.

إنها مجموعة من الكائنات تسمى "الكتل" والتي يمكنك التفكير فيها على أنها "فقرات". في الكتلة ، هناك مجموعة من الأطفال الممتد. يمكن أن تحتوي كل كتلة على نمط ومجموعة من تعريفات العلامات ، والتي تصف هياكل البيانات الموزعة على الامتدادات الفرعية.

يأتي Sanity.io مع محرر يمكنه القراءة والكتابة إلى Portable Text ، ويتم تنشيطه عن طريق وضع نوع block داخل حقل array ، مثل هذا:

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

يمكن أن تكون المصفوفة من أنواع متعددة. بالنسبة لمحرر SSML ، يمكن أن تكون هذه كتل لملفات الصوت ، ولكن هذا يقع خارج نطاق هذا البرنامج التعليمي.

آخر شيء نريد القيام به هو إضافة نوع محتوى حيث يمكن استخدام هذا المحرر. يستخدم معظم المساعدين نموذج محتوى بسيطًا لـ "النوايا" و "الإنجازات":

  • النوايا
    عادةً ما تكون قائمة بالسلاسل التي يستخدمها نموذج الذكاء الاصطناعي لتحديد ما يريد المستخدم إنجازه.
  • الإنجازات
    يحدث هذا عندما يتم تحديد "النية". غالبًا ما يأتي الإنجاز - أو على الأقل - مصحوبًا بنوع من الاستجابة.

لذلك دعونا نصنع نوعًا بسيطًا من المحتوى يسمى fulfillment يستخدم محرر تركيب الكلام. اصنع ملفًا جديدًا يسمى reamment.js واحفظه في مجلد / 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' } ] }

احفظ الملف وافتح schema.js . أضفه إلى الاستوديو الخاص بك مثل هذا:

 // 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, ]) })

إذا قمت الآن بتشغيل sanity start في واجهة سطر الأوامر داخل المجلد الجذر للمشروع ، فسيبدأ الاستوديو محليًا ، وستكون قادرًا على إضافة إدخالات لعمليات الاستيفاء. يمكنك الاستمرار في تشغيل الاستوديو أثناء استمرارنا ، حيث سيتم إعادة تحميله تلقائيًا مع التغييرات الجديدة عند حفظ الملفات.

إضافة SSML إلى المحرر

بشكل افتراضي ، يمنحك نوع block محررًا قياسيًا للنص المنسق الموجه بصريًا مع أنماط العناوين وأنماط الزخرفة للتأكيد والتعليقات التوضيحية للارتباطات والقوائم. نريد الآن تجاوز تلك المفاهيم السمعية الموجودة في SSML.

نبدأ بتحديد هياكل المحتوى المختلفة ، مع الأوصاف المفيدة للمحررين ، والتي سنضيفها إلى block في SSMLeditorSchema.js كتكوينات annotations . هذه هي "التركيز" و "الاسم المستعار" و "العرض" و "قل كـ".

تشديد

نبدأ بـ "التركيز" ، الذي يتحكم في مقدار الوزن الذي يتم وضعه على النص المحدد. نحددها كسلسلة بقائمة من القيم المحددة مسبقًا التي يمكن للمستخدم الاختيار من بينها:

 // 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' } ] } } ] }

الاسم المستعار

في بعض الأحيان يختلف المصطلح المكتوب والمنطوق. على سبيل المثال ، تريد استخدام اختصار عبارة في نص مكتوب ، ولكن اجعل العبارة بأكملها تُقرأ بصوت عالٍ. علي سبيل المثال:

 <s>This is a <sub alias="Speech Synthesis Markup Language">SSML</sub> tutorial</s>
اضغط تشغيل للاستماع إلى المقتطف:

حقل الإدخال للاسم المستعار عبارة عن سلسلة بسيطة:

 // 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', } ] }

علم العروض

باستخدام خاصية prosody ، يمكننا التحكم في الجوانب المختلفة لكيفية نطق النص ، مثل درجة الصوت والسرعة والحجم. يمكن أن يبدو ترميز هذا على النحو التالي:

 <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>
اضغط تشغيل للاستماع إلى المقتطف:

سيحتوي هذا الإدخال على ثلاثة حقول بخيارات سلسلة محددة مسبقًا:

 // 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' } ] } } ] }

قل كـ

آخر ما نريد تضمينه هو <say-as> . تتيح لنا هذه العلامة ممارسة قدر أكبر من التحكم في كيفية نطق معلومات معينة. يمكننا حتى استخدامه لتجاهل الكلمات إذا كنت بحاجة إلى تنقيح شيء ما في واجهات الصوت. هذا @!٪ ومفيد!

 <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' } ] } ] }

يمكننا الآن استيراد هذه الملفات في ملف annotations.js ، مما يجعل الأمور أكثر تنظيمًا.

 // 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'

يمكننا الآن استيراد أنواع التعليقات التوضيحية هذه إلى مخططاتنا الرئيسية:

 // 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 ]) })

أخيرًا ، يمكننا الآن إضافة هذه إلى المحرر مثل هذا:

 // 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'} ] } } ] }

لاحظ أننا أضفنا أيضًا المصفوفات الفارغة إلى styles decorators . يؤدي هذا إلى تعطيل الأنماط والديكورات الافتراضية (مثل الجرأة والتأكيد) نظرًا لأنها لا تعني ذلك كثيرًا في هذه الحالة المحددة.

تخصيص الشكل والمظهر

الآن لدينا الوظيفة في مكانها الصحيح ، ولكن نظرًا لأننا لم نحدد أي رموز ، فإن كل تعليق توضيحي سيستخدم الأيقونة الافتراضية ، مما يجعل المحرر صعب الاستخدام بالفعل للمؤلفين. لذلك دعونا نصلح ذلك!

باستخدام محرر Portable Text ، من الممكن حقن مكونات React لكل من الرموز وكيفية عرض النص المحدد. هنا ، سنترك بعض الرموز التعبيرية تقوم بالعمل نيابةً عنا ، ولكن من الواضح أنه يمكنك المضي قدمًا في هذا الأمر ، مما يجعلها ديناميكية وما إلى ذلك. بالنسبة إلى prosody ، سنقوم حتى بتغيير الرمز وفقًا لمستوى الصوت المحدد. لاحظ أنني حذفت الحقول الموجودة في هذه المقتطفات للإيجاز ، ولا يجب إزالتها في ملفاتك المحلية.

 // 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>, }, }; 
محرر SSML المخصص
المحرر بعلامات SSML المخصصة الخاصة بنا (معاينة كبيرة)

الآن لديك محرر لتحرير النص يمكن استخدامه بواسطة المساعدين الصوتيين. لكن ألن يكون مفيدًا نوعًا ما إذا كان بإمكان المحررين أيضًا معاينة كيف سيبدو النص في الواقع؟

إضافة زر معاينة باستخدام تحويل النص إلى كلام من Google

دعم تركيب الكلام الأصلي في طريقه بالفعل إلى المتصفحات. ولكن في هذا البرنامج التعليمي ، سنستخدم واجهة برمجة تطبيقات تحويل النص إلى كلام من Google والتي تدعم SSML. سيكون إنشاء وظيفة المعاينة هذه أيضًا عرضًا لكيفية إجراء تسلسل للنص المحمول في SSML في أي خدمة تريد استخدام هذا من أجلها.

تغليف المحرر في مكون رد فعل

نبدأ بفتح ملف SSMLeditor.js وإضافة الكود التالي:

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

لقد قمنا الآن بلف المحرر في مكون React الخاص بنا. يتم تمرير جميع الدعائم التي تحتاجها ، بما في ذلك البيانات التي تحتوي عليها ، في الوقت الفعلي. لاستخدام هذا المكون فعليًا ، يجب عليك استيراده إلى ملف 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' }, ], }, }, ], }

عند حفظ هذا وإعادة تحميل الاستوديو ، يجب أن يبدو متماثلًا إلى حد كبير ، لكن هذا لأننا لم نبدأ في تعديل المحرر بعد.

تحويل النص المحمول إلى SSML

سيقوم المحرر بحفظ المحتوى كنص محمول ، وهي مجموعة من الكائنات في JSON تسهل تحويل النص المنسق إلى أي تنسيق تريده. عندما تقوم بتحويل Portable Text إلى صيغة أو تنسيق آخر ، فإننا نسمي ذلك "التسلسل". ومن ثم ، فإن "المتسلسلات" هي وصفات لكيفية تحويل النص المنسق. في هذا القسم ، سنضيف المسلسلات لتركيب الكلام.

لقد قمت بالفعل بإنشاء ملف blockToSSML.js . الآن سنحتاج إلى إضافة التبعية الأولى. ابدأ بتشغيل الأمر الطرفي npm init -y داخل مجلد ssml-editor . سيضيف هذا package.json حيث سيتم سرد تبعيات المحرر.

بمجرد الانتهاء من ذلك ، يمكنك تشغيل npm install @sanity/block-content-to-html للحصول على مكتبة تسهل إجراء تسلسل للنص المحمول. نحن نستخدم مكتبة HTML لأن SSML لها نفس بنية XML مع العلامات والسمات.

هذه مجموعة من التعليمات البرمجية ، لذلك لا تتردد في نسخها ولصقها. سأشرح النمط الموجود أسفل المقتطف مباشرةً:

 // 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 })

سيقوم هذا الرمز بتصدير وظيفة تأخذ مجموعة الكتل وتكرارها. عندما تحتوي الكتلة على mark ، فإنها تبحث عن مُسلسل للنوع. إذا قمت بتمييز بعض النصوص emphasis عليها ، فهذه الوظيفة من كائن المسلسل:

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

ربما تتعرف على المعلمة من حيث حددنا المخطط؟ تسمح لنا الوظيفة h() بتعريف عنصر HTML ، أي هنا نقوم "بالغش" ونجعله يعيد عنصر SSML يسمى <emphasis> . نمنحها أيضًا level السمة إذا تم تحديد ذلك ، children العناصر الفرعية بداخله - والذي سيكون في معظم الحالات هو النص الذي قمت بتمييزه مع 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" ] } ] }

هذه هي الطريقة التي يتم بها إجراء تسلسل للبنية أعلاه في Portable Text إلى SSML هذا:

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

إذا كنت تريد دعم المزيد من علامات SSML ، يمكنك إضافة المزيد من التعليقات التوضيحية في المخطط ، وإضافة أنواع التعليقات التوضيحية إلى قسم marks في المسلسلات.

الآن لدينا وظيفة تقوم بإرجاع ترميز SSML من نصنا المنسق المرمز. الجزء الأخير هو إنشاء زر يتيح لنا إرسال هذا الترميز إلى خدمة تحويل النص إلى كلام.

إضافة زر معاينة يتحدث إليك

من الناحية المثالية ، كان يجب أن نستخدم إمكانيات تركيب الكلام للمتصفح في واجهة برمجة تطبيقات الويب. بهذه الطريقة ، كنا سنتخلص من القليل من التعليمات البرمجية والتبعيات.

اعتبارًا من أوائل عام 2019 ، لا يزال دعم المتصفح الأصلي لتركيب الكلام في مراحله الأولى. يبدو أن دعم SSML في الطريق ، وهناك دليل على مفاهيم تطبيقات JavaScript من جانب العميل له.

من المحتمل أنك ستستخدم هذا المحتوى مع مساعد صوتي على أي حال. يدعم كل من Google Assistant و Amazon Echo (Alexa) SSML كاستجابات في الوفاء. في هذا البرنامج التعليمي ، سنستخدم واجهة برمجة تطبيقات تحويل النص إلى كلام من Google ، والتي تبدو جيدة أيضًا وتدعم عدة لغات.

ابدأ بالحصول على مفتاح API عن طريق الاشتراك في Google Cloud Platform (سيكون مجانيًا لأول مليون حرف تقوم بمعالجته). بمجرد التسجيل ، يمكنك إنشاء مفتاح API جديد في هذه الصفحة.

يمكنك الآن فتح ملف PreviewButton.js وإضافة هذا الرمز إليه:

 // 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> }

لقد احتفظت برمز زر المعاينة هذا إلى الحد الأدنى لتسهيل متابعة هذا البرنامج التعليمي. بالطبع ، يمكنك بناؤه عن طريق إضافة حالة لإظهار ما إذا كانت المعاينة قيد المعالجة أو تجعل من الممكن المعاينة بالأصوات المختلفة التي تدعمها واجهة برمجة تطبيقات Google.

أضف الزر إلى 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> ); }

الآن يجب أن تكون قادرًا على ترميز النص باستخدام التعليقات التوضيحية المختلفة ، وسماع النتيجة عند الضغط على "نطق النص". رائع ، أليس كذلك؟

لقد أنشأت محررًا لتركيب الكلام ، وماذا الآن؟

إذا كنت قد اتبعت هذا البرنامج التعليمي ، فقد تعرفت على كيفية استخدام محرر Portable Text في Sanity Studio لعمل تعليقات توضيحية مخصصة وتخصيص المحرر. يمكنك استخدام هذه المهارات لجميع أنواع الأشياء ، وليس فقط لإنشاء محرر تركيب الكلام. لقد مررت أيضًا بكيفية إجراء تسلسل للنص المحمول في البنية التي تحتاجها. من الواضح أن هذا مفيد أيضًا إذا كنت تبني واجهات أمامية في React أو Vue. يمكنك حتى استخدام هذه المهارات لإنشاء Markdown من Portable Text.

لم نقم بتغطية كيفية استخدامك لهذا مع المساعد الصوتي. إذا كنت ترغب في المحاولة ، يمكنك استخدام الكثير من نفس المنطق كما هو الحال مع زر المعاينة في وظيفة بدون خادم ، وتعيينها كنقطة نهاية API للوفاء باستخدام خطافات الويب ، على سبيل المثال مع Dialogflow.

إذا كنت تريد مني كتابة برنامج تعليمي حول كيفية استخدام محرر تركيب الكلام مع مساعد صوت ، فلا تتردد في إعطائي تلميحًا على Twitter أو مشاركته في قسم التعليقات أدناه.

مزيد من القراءة على SmashingMag:

  • تجربة تركيب الكلام
  • تحسين تجربة المستخدم مع Web Speech API
  • إمكانية الوصول APIs: مفتاح الوصول إلى الويب
  • بناء روبوت محادثة AI بسيط باستخدام واجهة برمجة تطبيقات Web Speech و Node.js