TTS Engine Custom - Microsoft Neural Voices with SSML

Important remark

The following procedures were performed in a test environment , the propolys-tts.agi file will be modified and then FreePBX will alert you as per the text below;

Module: “Text To Speech”, File: "/var/www/html/admin/modules/tts/agi-bin/propolys-tts.agi altered "

yum -y install python36u-pip
pip3.6 install requests
mkdir /opt/microsoft
cd /opt/micosoft

create script in python with command:
vim /opt/microsoft/microsoft.py

insert into microsoft.py

import requests
import time, sys
from xml.etree import ElementTree
from xml.sax.saxutils import unescape

    texto=sys.argv[1]
    caminho=sys.argv[2]
    print(texto)
    try:
        input = input
    except NameError:
        pass

    class TextToSpeech(object):
        def __init__(self, subscription_key):
            self.subscription_key = subscription_key
            self.tts = texto
            self.timestr = time.strftime("%Y%m%d-%H%M")
            self.access_token = None

        def get_token(self):
            fetch_token_url = "https://southcentralus.api.cognitive.microsoft.com/sts/v1.0/issueToken"
            headers = {
                'Ocp-Apim-Subscription-Key': 'your key'
            }
            response = requests.post(fetch_token_url, headers=headers)
            self.access_token = str(response.text)

        def save_audio(self):
            base_url = 'https://southcentralus.tts.speech.microsoft.com/'
            path = 'cognitiveservices/v1'
            constructed_url = base_url + path
            headers = {
                'Authorization': 'Bearer ' + self.access_token,
                'Content-Type': 'application/ssml+xml',
                'X-Microsoft-OutputFormat': 'riff-8khz-16bit-mono-pcm',
                'User-Agent': 'curl'
            }
            xml_body = ElementTree.Element('speak', version='1.0')
            xml_body.set('{http://www.w3.org/XML/1998/namespace}lang', 'pt-br')
            voice = ElementTree.SubElement(xml_body, 'voice')
            voice.set('{http://www.w3.org/XML/1998/namespace}lang', 'pt-BR')
            voice.set(
                'name', 'Microsoft Server Speech Text to Speech Voice (pt-BR, FranciscaNeural)')
            voice.text = self.tts

            body = unescape(ElementTree.tostring(xml_body).decode())
            print(body)
            response = requests.post(constructed_url, headers=headers, data=body)
            if response.status_code == 200:
                with open('/var/lib/asterisk/sounds/tts/' + caminho + '.wav', 'wb') as audio:
                    audio.write(response.content)
                    print("\nStatus code: " + str(response.status_code) +
                        "\nYour TTS is ready for playback.\n")
            else:
                print("\nStatus code: " + str(response.status_code) +
                    "\nSomething went wrong. Check your subscription key and headers.\n")

    if __name__ == "__main__":
    subscription_key = "your key"
    app = TextToSpeech(subscription_key)
    app.get_token()
    app.save_audio()

Insert into: /var/www/html/admin/modules/tts/agi-bin/propolys-tts.agi

case 'microsoft':
          exec($enginebin." /opt/microsoft/microsoft.py '$text' '$engine-tts-$hash'");
          break;

Finally

Go to Applications=> Text to Speech and create your TTS with engine with name microsoft and path= /usr/bin/python3.6

Thanks for this. Invaluable. You have helped us so much with the Polly TTS instructions. That has helped enable so much rich functionality.

Has anyone been successful in getting this code to run? At first I had indentation errors which I think I fixed successfully. Now I am getting the below error when running it a compiler to test it.

Traceback (most recent call last):
File “microsoft.py”, line 6, in
texto=sys.argv[1]
IndexError: list index out of range

Also JersonJunior there is a typo in the instructions where microsoft is misspelled on the last line below.