TTS Engine Custom - Microsoft Neural Voices with SSML


(Jerson Jr) #1

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


(Communication Technologies) #2

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


#3

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.


(system) closed #4

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.