met4citizen / TalkingHead

Talking Head (3D): A JavaScript class for real-time lip-sync using Ready Player Me full-body 3D avatars.
MIT License
349 stars 107 forks source link

Get current playing segment for subtitles #46

Closed anmol1905 closed 5 months ago

anmol1905 commented 5 months ago

Hello I am using the head.speakAudio function for talking and head.speakMarker function to know that the speech ended.

Is there any prebuilt function or callback to know which segment is being played right now so that It can be shown as a subtitle?

I see in the code there are some callbacks called onsubtitles but I didn't quite understand how to use it

Thank you

met4citizen commented 5 months ago

Hi. The speakAudio method has a callback function that is called for each word when that word is spoken. Below is a short example that outputs each word to the console.

function showSubtitle(word) {
  console.log(word);
}
...
head.speakAudio(audio, {}, showSubtitle);

However, if you want to show longer text segments, instead of displaying them word-by-word, you can use the audio object and its timed markers. In this approach, you first need to construct your text segments and their timestamps in order, and then add the callback functions and their start times (in milliseconds) to the audio object's markers and mtimes arrays. Here is an example.

function showSubtitle(text) {
  console.log(text);
}
function clearSubtitle() {
}
...
let subtitles = [
  { text: "First sentence.", start: 0, end: 1000 },
  { text: "Second sentence.", start: 1100, end: 2000 }
];
...
audio.markers = [];
audio.mtimes = [];
subtitles.forEach( x => {
  audio.markers.push( showSubtitle.bind(null, x.text), clearSubtitle );
  audio.mtimes.push( x.start, x.end );
});
head.speakAudio(audio);

This is not a complete solution, but I hope it gives you the general idea.

anmol1905 commented 5 months ago

Thank you very much!