С самых юных лет, с самого первого прочтения залпом "Трех мушкетеров" автор неколебимо убежден, что оптимальный способ обучения чему-либо - практика. Теорию в дальнейшем можно подучить и подточить, друзья-мушкетеры "покажут несколько славных приемов", не проблема. Но, если верить досточтимому мэтру Дюма (а автор ему верит), оптимальный способ интеграции в любую новую для себя сущность - сходу погрузиться в нее с головой, а там как пойдет. Где наша не пропадала, да и, как известно, любой гасконец с детства академик.

Вообще, если интерес возникнет, то это всегда 90% успеха, поверьте... ну, а если не возникнет, что ж. Сэкономите время: стало быть, не ваше. Сейчас, таким образом, самонадеянный и скорый на подъем аффтор, всегда готовый выхватить шпагу при виде гнусного тролля на любом интернет-форуме - предлагает всем debutants потратить всего лишь полчаса-час на то, чтобы заинтересоваться сразу несколькими технологиями, в числе которых язык программирования Ruby, API Google Cloud Text to Speech, облачная PaaS-платформа Heroku и git.

К слову. Предвидя сделанные на языке растреклятых англичан, исконных врагов любого истинного француза комментарии в стиле "Is ruby dead?", в том смысле, а есть ли смысл вообще этим заниматься... автор предлагает всем любителям потрепаться-ни-о-чем-в-инете временно оставить эту животрепещущую тематику, сменив ее на рекомендации по изготовлению чудодейственного бальзама, наподобие того, что дала в путь-дорогу д`Артаньяну любящая его матушка, и который помог бы, в духе дня, раз и навсегда избавиться от спама за подписью того или иного эйчара, русскоговорящего или европейца/американца, несколько раз в неделю присылающих абсолютно ненужные автору инвайты на позицию Ruby Developer. Ненужные не потому, что автор, вволю напрактиковавшись и слегка "подточив" теорию, привык получать приглашения исключительно и самолично из рук аж самого CTO Armand-Jean du Plessis, duc de Richelieu... а потому, что за все годы работы - ни одного проекта, ни одной должности от HR он не получил, так уж сложилось.

Чего и вам от души желает. Если какой-либо институт и мертв, то это почти наверняка Human Resource, по крайней мере, у нас в России (как с этим обстоят дела у Бекингема - Бог весть, не знаю). Все остальное покамест работает... это была, так сказать, литературная прелюдия, ну а теперь сходу к практике, с места в карьер. "Сударь, вы ошиблись! Нас не трое, нас четверо!"

Итак. Цель сегодняшних наших упражнений - построение приложения, работающего с API Google Cloud Text to Speech, иными словами - конвертера текста в звук, и с очень неплохим качеством. Правда, все чаще раздаются голоса, дескать, IBM Text-to-Speech API круче, но это мы оставим, с вашего позволения, для следующей статьи... "голоса" обычно не скрывают, что IBM API обходится недешево, гугловский же сервис возможно использовать практически бесплатно (находим и внимательно читаем Terms of Service). Но вам понадобится волшебный ключ, нечто в стиле "то, что сделал предъявитель сего, сделано по моему приказанию и для блага государства" в формате JSON, для получения которого, вполне возможно, придется засветить ваш MasterCard здесь. Может быть, даже заморозят на недельку кровный ваш $1, ничего? - ну всяко это не так страшно, как в военное де-факто время совершать вояж за линию фронта, будучи вдохновленным одним лишь лукавым взглядом г-жи Бонасье, согласитесь.

Также зарегистрируйте Free account Heroku, куда мы с вами намереваемся пушить ваше первое приложение на основе фреймворка Ruby on Rails, скачайте и установите git и Heroku toolbelt для своей OS.

Немного о структуре приложения. Как уже сказано выше, это rails-app, полноценный веб-интерфейс для API Google Cloud Text to Speech: аутентификация реализована посредством device (полистайте доку, там немало интересного на случай, если захотите что-то изменить в предлагаемом техническом решении), сконфигурированного таким образом, что возможен лишь один пользователь. Что нам и нужно: сразу после деплоя приложения на Heroku вы зарегистрируетесь в нем, подтвердив указанный вами email, и дальнейшие регистрации будут невозможны (изменить или сбросить пароль вы, при необходимости, сможете).

Интерфейс выполнен в духе минимализма, под которым автор понимает Bootstrap 4 и кое-какие джаваскрипты; информационные flash-сообщения панели управления - средствами ajax, благо он как никто родной для Ruby on Rails. Заказчик-киевлянин, для которого был выполнен этот rails-app, он же старый мой приятель, скупой как кардинал Мазарини - очень просил "без излишеств, можно вообще без стилей", ну и вот... впрочем, помимо ожидания, получилось вполне элегантно. Представленный далее короткий ролик не самый новый, с момента его создания приложение было рефакторено и получило новые свойства, но какое-то визуальное представление способен дать.

Да, и "о фичах". На момент публикации этого материала Google-Cloud-TTS-Rails способен работать с текстом (также поддерживается SSML) на любом из 18 языков, конвертируя в один из следующих, по желанию, форматов: MP3 (MPEG Audio Layer III), WAV (LINEAR16) and OGG (OGG_OPUS), поддерживаются оба доступных voice type: WaveNet и Basic. Также интерфейс приложения позволяет корректировать скорость произношения...

...с чего, пожалуй, и начнем этот краткий экскурс в программный код. Меню регулировки скорости реализовано как хелпер, посредством которого получаем в HTML выпадающее меню (drop-down list), диапазон значений от 0.25 до 4.0 (обусловлено API), шаг 0.25, значение по-дефолту 1.0. Привыкайте, это рельсы:

module SoundHelper
  def speaking_rate
    select_tag 'speaking_rate', options_for_select(
      0.25.step(by: 0.25, to: 4.0), selected: '1.0'
    ), { class: 'btn' }
  end
end

Да, к слову. Те, кто не хотят вникать в код, возможно, им это сто лет не нужно... имеют возможность пропустить вышесказанное/поименованное мимо, соответственно, ушей и глаз, равно как и еще парочку фрагментов кода, воспоследующих далее. Имеете полное право, почему нет. Я сейчас сделаю краткую паузу на то, чтобы in two words рассказать, как залить из гитхаба на Heroku полностью готовое к работе приложение, вам понадобятся на вашем рабочем компе лишь Heroku CLI и git, как уже и говорил. Ruby и postgreSQL в этом случае без надобности.

Клонируйте приложение с гитхаба и по окончании перейдите во вновь созданный каталог, набрав в консоли:

git clone https://github.com/cmirnow/Google-Cloud-TTS-Rails.git
cd Google-Cloud-TTS-Rails

Бросьте файл, содержащий ваш персональный ключ YOUR_KEY_NAME.json, в корень директории приложения (название значения не имеет). Далее:

git add .   
git commit -m "my first commit"
heroku create
git push heroku master
heroku run rake db:migrate

Откройте панель администрирования Heroku, YOUR_NEW_APPLICATION -> 'Settings' -> 'Reveal Config Vars', и введите следующие пары key/value:


key: GOOGLE_APPLICATION_CREDENTIALS value: YOUR_KEY_NAME.json

key: DOMAIN_NAME value: YOUR_HEROKU_DOMAIN ### i.e 'https://***************.herokuapp.com' without quotes.

key: GMAIL_USER_NAME value: YOUR_GMAIL_LOGIN

key: GMAIL_PASSWORD value: YOUR_GMAIL_PASSWORD ### (An App Password is a 16-digit passcode that gives an app or device restricted access to your Google Account without having to divulge your personal password and complete access to your Google Account).


Как видите, потребуется указать доступ к почтовому серверу, чтобы Google-Cloud-TTS-Rails смог отослать вам письмо в ходе регистрации аккаунта, также на случай необходимости сброса забытого пароля. И - на этом все, после регистрации приложение полностью готово к работе. Лимит текста "за один раз" - 5000 знаков, обусловлено Google. Надеюсь, вам понравится.

Мне же осталось показать всего только очень несложную логику работы приложения. Сейчас не буду подробно останавливаться на rails-валидациях, скажу лишь, что по дефолту проверяется только количество введенных знаков, и вы сможете добавить или исключить, при желании, самые разнообразные проверки:

class Validation
	include ActiveModel::Model
	attr_accessor :request
	validates :request, presence: true, length: {in:3..4999}
end

Контроллер, как ему и предназначено судьбой, служит связующим звеном между интерфейсом пользователя и собсно сервисом, вызывая метод класса TtsConversion со следующими параметрами:

  def conversion
    audio_format = TtsConversion.index(client, synthesis_input, voice, audio, params[:codec])
    success_info(audio_format)
  end

  def client
    Google::Cloud::TextToSpeech.text_to_speech
  end

  def synthesis_input
    { params[:text_or_ssml] => params[:request] }
  end

  def voice
    { language_code: params[:lang], name: params[:voicename] }
  end

  def audio
    { audio_encoding: params[:codec], speaking_rate: params[:speaking_rate].to_f }
  end
class TtsConversion
  def self.index(*args)
    response = args[0].synthesize_speech input: args[1], voice: args[2], audio_config: args[3]
    File.open 'public/output/output.' + audio_format(args[4]).to_s, 'wb' do |file|
      file.write response.audio_content
      audio_format(args[4]).to_s
    end
  end

  def self.audio_format(codec)
  	case codec
  	when "LINEAR16"
  		'wav'
    when "OGG_OPUS"
      'ogg'
  	else
  		'mp3'
  	end
  end
end

Всю работу свершает, по сути, gem 'google-cloud-text_to_speech', передавая конвертируемый текст и выбранные параметры в API Google Cloud Text to Speech и получая обратно звук в цифре. Вот, пожалуй, и все.