Как интегрировать Google Text-To-Speech в Twilio (или URL с "&" в теге XML)
Я хочу использовать сервис Google Text-To-Speech в Twilio.
Я сгенерировал URL с несколькими параметрами, разделенными амперсандами (&).
Например: http://translate.google.com/translate_tts?ie=UTF-8&q=Hello%20World&tl=en-us
Проблема: когда я пытаюсь поместить этот URL в тег TwiML, у меня возникает исключение, которое написано ниже:
Ошибка в строке 1 документа: ссылка на сущность "q" должна заканчиваться символом ";" разделитель. Убедитесь, что тело ответа является действительным документом XML.
Это TwiML:
<Response>
<Play>http://translate.google.com/translate_tts?ie=UTF-8&q=Hello%20World&tl=en-us</Play>
</Response>
Решения, которые я уже пробовал:
1) Заменить &
с &
Это не помогло для меня. В этом случае я получил еще одно исключение: вернул код состояния HTTP 404. Похоже, Twilio не декодировать &
вернуться к &
,
2) Сохраните вывод Google в файл на сервере и поместите прямую ссылку на этот файл (без знака &) в тег. Должно работать, но похоже на грязный взлом =)
2 ответа
Хорошо, я решил эту проблему третьим способом:
Я сделал "прокси" сервлет для сокрытия всех параметров, необходимых для Google TTS Engine, внутри этого сервлета. Это проще продемонстрировать в коде:
Я поместил URL-адрес моего прокси-сервлета (вместо URL-адреса в Google TTS Engine) в TwiML. Для этого сервлета требуется только один параметр: сообщение, которое будет воспроизводиться. В этом случае я избегаю символа амперсанда в TwiML.
...
String url = Constants.APPLICATION_URL + "/tts/" +"?" + Constants.ParamName.GREETINGS + "=" + greetings;
Play play = new Play(url);
...
Это сервлет прокси (он сопоставлен с /tts/ path). сделать запрос в Google TTS Engine и отправить ответ от него:
...
this.greetings = request.getParameter(Constants.ParamName.GREETINGS);
InputStream input = null;
HttpURLConnection con = null;
OutputStream output = null;
try {
URL obj = new URL("http://translate.google.com/translate_tts?ie=UTF-8&q=" + URLEncoder.encode(greetings, "UTF-8") + "&tl=en-us"));
con = (HttpURLConnection) obj.openConnection();
con.setConnectTimeout(5000);
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.setRequestProperty("Content-Type", "audio/mpeg");
input = con.getInputStream();
response.setContentType("audio/mpeg");
output = response.getOutputStream();
byte[] buffer = new byte[10240];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
}
...
Конечно, это выглядит как грязный хак, но я думаю, что это лучше, чем сохранить временный файл на сервере.
Разместите это здесь, если это будет полезно другим. Я написал пример приложения с открытым исходным кодом, в котором хранятся записи из Google Cloud Text-To-Speech API в Google Cloud Storage. Ответ - это URL-адрес записи, который можно передать<Play>
Глагол TwiML.
Это приложение может быть полезно, если вы хотите использовать TTS на языках, которые поддерживаются Google, но не Twilio. По состоянию на декабрь 2019 года к этим языкам относятся:
- арабский
- Чешский
- Филиппинский
- Греческий
- Венгерский
- индонезийский
- словацкий
- украинец
- вьетнамский
В этой статье поддержки представлен список языков, которые поддерживает функция преобразования текста в речь Twilio.
<Response>
<Play>http://translate.google.com/translate_tts?ie=UTF-8&q=Hello%20World&tl=en-us</Play>
</Response>
синтаксически неверный XML. Это все в порядке
<Response>
<Play>http://translate.google.com/translate_tts?ie=UTF-8&q=Hello%20World&tl=en-us</Play>
</Response>
Если Twilio не может обработать это, вы должны сообщить об ошибке.