الحصول على أحداث وضعية الوجه لمزامنة حركة الشفاه
ملاحظة
في هذا الوقت ، تتوفر أحداث viseme فقط للأصوات العصبية.
الفيسيم هو الوصف المرئي للفونيم في اللغة المنطوقة. يحدد موضع الوجه والفم عندما يتحدث الشخص كلمة. يصور كل فيسيم وضعيات الوجه الرئيسية لمجموعة محددة من الفونيمات.
يمكنك استخدام visemes للتحكم في حركة نماذج الصورة الرمزية 2D و 3D ، بحيث تتطابق حركات الفم تماما مع الكلام الاصطناعي. على سبيل المثال، يمكنك:
- قم بإنشاء مساعد صوتي افتراضي متحرك للأكشاك الذكية ، وبناء خدمات متكاملة متعددة الأوضاع لعملائك.
- بناء نشرات إخبارية غامرة وتحسين تجارب الجمهور بحركات الوجه والفم الطبيعية.
- قم بإنشاء المزيد من الصور الرمزية للألعاب التفاعلية والشخصيات الكرتونية التي يمكنها التحدث بمحتوى ديناميكي.
- اصنع مقاطع فيديو أكثر فعالية لتعليم اللغة تساعد متعلمي اللغة على فهم سلوك الفم لكل كلمة وفونيم.
- يمكن للأشخاص الذين يعانون من ضعف السمع أيضا التقاط الأصوات بصريا ومحتوى الكلام "المقروء للشفاه" الذي يظهر الوجوه على وجه متحرك.
لمزيد من المعلومات حول visemes، شاهد هذا الفيديو التمهيدي.
يمكن ل Azure Neural TTS إنتاج visemes مع الكلام
يحول تحويل النص العصبي إلى كلام (TTS العصبي) نص الإدخال أو SSML (لغة ترميز توليف الكلام) إلى كلام مركب نابض بالحياة. يمكن أن يكون إخراج الصوت الكلامي مصحوبا بمعرفات viseme وطوابع زمنية للإزاحة. يحدد كل معرف viseme وضعا معينا في الكلام المرصود ، مثل موضع الشفاه والفك واللسان عند إنتاج فونيم معين. باستخدام محرك تقديم 2D أو 3D ، يمكنك استخدام هذه الأحداث viseme لتحريك الصورة الرمزية الخاصة بك.
يتم توضيح سير العمل العام ل viseme في المخطط الانسيابي التالي:

يتم وصف معرف Visemeوإخراج إزاحة الصوت في الجدول التالي:
| عنصر Visme | الوصف |
|---|---|
| معرف فيسيم | رقم صحيح يحدد viseme. بالنسبة للغة الإنجليزية (الولايات المتحدة) ، نقدم 22 وجها مختلفا ، يصور كل منها شكل الفم لمجموعة محددة من الفونيمات. لا توجد مراسلات فردية بين visemes و phonemes. في كثير من الأحيان ، تتوافق العديد من الفونيمات مع فيسيم واحد ، لأنها تبدو متشابهة على وجه السماعة عند إنتاجها ، مثل s و z. لمزيد من المعلومات المحددة، راجع جدول تعيين الفونيمات إلى المعرفات viseme. |
| إزاحة الصوت | وقت بدء كل viseme ، في القراد (100 نانو ثانية). |
الحصول على أحداث viseme باستخدام "حزمة تطوير البرامج (SDK)" الخاصة بالكلام
للحصول على رؤية واضحة للخطاب المركب، اشترك في الحدث في VisemeReceived حزمة SDK للكلام.
يوضح المقتطف التالي كيفية الاشتراك في حدث viseme:
using (var synthesizer = new SpeechSynthesizer(speechConfig, audioConfig))
{
// Subscribes to viseme received event
synthesizer.VisemeReceived += (s, e) =>
{
Console.WriteLine($"Viseme event received. Audio offset: " +
$"{e.AudioOffset / 10000}ms, viseme id: {e.VisemeId}.");
};
var result = await synthesizer.SpeakSsmlAsync(ssml));
}
auto synthesizer = SpeechSynthesizer::FromConfig(speechConfig, audioConfig);
// Subscribes to viseme received event
synthesizer->VisemeReceived += [](const SpeechSynthesisVisemeEventArgs& e)
{
cout << "viseme event received. "
// The unit of e.AudioOffset is tick (1 tick = 100 nanoseconds), divide by 10,000 to convert to milliseconds.
<< "Audio offset: " << e.AudioOffset / 10000 << "ms, "
<< "viseme id: " << e.VisemeId << "." << endl;
};
auto result = synthesizer->SpeakSsmlAsync(ssml).get();
SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
// Subscribes to viseme received event
synthesizer.VisemeReceived.addEventListener((o, e) -> {
// The unit of e.AudioOffset is tick (1 tick = 100 nanoseconds), divide by 10,000 to convert to milliseconds.
System.out.print("Viseme event received. Audio offset: " + e.getAudioOffset() / 10000 + "ms, ");
System.out.println("viseme id: " + e.getVisemeId() + ".");
});
SpeechSynthesisResult result = synthesizer.SpeakSsmlAsync(ssml).get();
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)
# Subscribes to viseme received event
speech_synthesizer.viseme_received.connect(lambda evt: print(
"Viseme event received: audio offset: {}ms, viseme id: {}.".format(evt.audio_offset / 10000, evt.viseme_id)))
result = speech_synthesizer.speak_ssml_async(ssml).get()
var synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig, audioConfig);
// Subscribes to viseme received event
synthesizer.visemeReceived = function (s, e) {
window.console.log("(Viseme), Audio offset: " + e.audioOffset / 10000 + "ms. Viseme ID: " + e.visemeId);
}
synthesizer.speakSsmlAsync(ssml);
SPXSpeechSynthesizer *synthesizer =
[[SPXSpeechSynthesizer alloc] initWithSpeechConfiguration:speechConfig
audioConfiguration:audioConfig];
// Subscribes to viseme received event
[synthesizer addVisemeReceivedEventHandler: ^ (SPXSpeechSynthesizer *synthesizer, SPXSpeechSynthesisVisemeEventArgs *eventArgs) {
NSLog(@"Viseme event received. Audio offset: %fms, viseme id: %lu.", eventArgs.audioOffset/10000., eventArgs.visemeId);
}];
[synthesizer speakSsml:ssml];
فيما يلي مثال على إخراج viseme.
(Viseme), Viseme ID: 1, Audio offset: 200ms.
(Viseme), Viseme ID: 5, Audio offset: 850ms.
……
(Viseme), Viseme ID: 13, Audio offset: 2350ms.
بعد الحصول على إخراج viseme، يمكنك استخدام هذه الأحداث لدفع حركة الأحرف. يمكنك بناء شخصياتك الخاصة وتحريكها تلقائيا.
بالنسبة للأحرف 2D ، يمكنك تصميم حرف يناسب السيناريو الخاص بك واستخدام رسومات متجهة قابلة للتحجيم (SVG) لكل معرف viseme للحصول على موضع وجه يستند إلى الوقت. مع العلامات الزمنية التي يتم توفيرها في حدث viseme ، ستتم معالجة SVGs المصممة بشكل جيد مع تعديلات سلسة ، وتوفر رسوما متحركة قوية للمستخدمين. على سبيل المثال، يعرض الرسم التوضيحي التالي حرفا أحمر الشفاه مصمما لتعلم اللغة.

بالنسبة لشخصيات 3D ، فكر في الشخصيات كدمى سلسلة. سيد الدمية يسحب الأوتار من حالة إلى أخرى وقوانين الفيزياء تفعل الباقي وتدفع الدمية للتحرك بسلاسة. يعمل إخراج viseme كمفتاح دمية لتوفير جدول زمني للعمل. يحدد محرك الرسوم المتحركة القوانين الفيزيائية للعمل. من خلال استيفاء الإطارات باستخدام خوارزميات ميسرة ، يمكن للمحرك إنشاء رسوم متحركة عالية الجودة.
تعيين الفونيمات إلى visemes
تختلف Visemes حسب اللغة والإعدادات المحلية. تحتوي كل لغة على مجموعة من المرئيات التي تتوافق مع الفونيمات الخاصة بها. يقوم توثيق الحروف الهجائية الصوتية SSML بتعيين معرفات viseme إلى الفونيمات الأبجدية الصوتية الدولية (IPA) المقابلة.