Real time Text to Speech (Audio)

Hi community,

I would like to make an avatar speak according to a given text.

I’m good at skinning animations, but have never tried the audio part in PlayCanvas.

Any suggestion on which text to speech API I should use and how to integrate it with PlayCanvas?

I can only think of google translation API, e.g.


There is a Web Speech API, that allows you to implement text-to-speech and speech-to-text.
That is only supported on some platforms:

Hi Max,

It works fine. But it can only speak with the native system language and voice. The API call “window.speechSynthesis.getVoices()” returns an empty list on PlayCanvas. But it runs correct out of PlayCanvas. Any idea what went wrong?

Below is my code:

pc.script.create('SpeechTest', function (app) {
    // Creates a new SpeechTest instance
    var SpeechTest = function (entity) {
        this.entity = entity;

    SpeechTest.prototype = {
        // Called once after all resources are loaded and before the first update
        initialize: function () {

            this.speak("It will automatically generate a wav file which you can easily get with an HTTP request through any");

        // Called every frame, dt is time in seconds since last update
        update: function (dt) {
        speak: function(phrase) {
            if(phrase === "") return;
            var speech = new SpeechSynthesisUtterance(phrase);
            var voices = window.speechSynthesis.getVoices();
            speech.voice = voices.filter(function(voice) { return == 'Google UK English Male'; })[0];

    return SpeechTest;

Have you tried that method on exactly same platforms but in different pages?
I know that some platforms do have only few voices or even only one.

Yes, on Chrome, but different pages. The method seems to have some certain delay.

I’m confused that the speechSynthesis works in a blank webpage but does not work in PlayCanvas.

Could you please help me solve this issue?

Voices are loaded in async in browser, so you need to get voices on callback, check this answer: