iOS Преобразование голоcа в текст на Swift 3

В 2016 году на WWDC Apple представила Speech framework, полезный API для распознавания речи. Speech является основой, которая используется Siri для распознавания речи. Если посмотреть повнимательней, то можно найти много фреймворков распознавания речи, доступных на сегодняшний день, но они либо очень дорого стоят, либо отвратительно работают. В этом уроке мы создадим iOS приложение  для преобразования речи в текст с помощью Speech.

Создание интерфейса в Xcode

Давайте начнем с создания нового проекта iOS -> Single View Application. Укажите имя для проекта SpeechToText. Откройте Main.storyboard и перетащите из библиотеки элементов UILabel, UITextView и UIButton. Добавьте текст, расставьте элементы и задайте относительное положение элементов с помощью констрейнтов.

У меня получилось вот так:

Далее следует добавить аутлеты и экшкны для UITextView и UIButton в класс контроллера.

Подключаем Speech фреймворк

Чтобы использовать SpeechKit мы должны сначала импортировать его и сделать основной контроллер соответствующим протоколу  SFSpeechRecognizerDelegate. Данный протокол имеет один опциональный метод, поэтому при его принятии контроллером компилятор не выдаст ошибок. После всех манипуляций ViewController будет выглядеть так:

Запрос… всех разрешений

Прежде чем использовать распознание речи и Speech Kit мы должны запросить у пользователя разрешение. Это потому, что непосредственно процесс распознания происходит не на iOS устройстве, а на серверах Apple. А это означает, что данные будут переданы через интернет для обработки и только потом вернутся на устройство. Поэтому запрос разрешения необходим. А также, удовлетворяя параноидальной стратегии Apple, нужно запросить разрешение на использование микрофона.

Запросим разрешение на распознание речи в методе viewDidLoad(). Но для начала добавим в файл info.plist сроку с текстом для запроса. Нажмите на + в последней строке, в колонке ключа найдите пункт Privacy — Speech Recognition Usage Description, и в колонку значений введите строку с вопросом.

Также добавим переменную для экземпляра распознаватель речи.

После измените метод viewDidLoad()

Разберем по пунктам:

  1. Пока не известен статус разрешения на распознавание речи, сделаем кнопку записи голосовавшим недоступной.
  2. Для ранее созданного экземпляра speechRecognizer установим делегата. Им будет наш контроллер, который принимает соответствие нужному протоколу.
  3. Вызовем метод класса для запроса разрешения. Этот метод в качестве аргумента принимает функцию, которую вызывает после всех манипуляций с разрешениями, и уже в этом функцию передает статус разрешения. Этот статус мы будем рассматривать в п.5
  4.  Создадим переменную, в которой будем передавать нужное состоянии кнопки в зависимости от результата разрешений
  5. А вот результатов может быть 4. Нас интересует первый вариант. Все варианты результатов, думаю, понятны. Их вариации описаны в комментариях.
  6. Получение и обработка результатов запроса занимает некоторое время. Чтобы не затормаживать пользовательский интерфейс, вся процедура запроса и его обработке происходит в фоновом потоке. А как мы помним из предыдущих статей, изменение интерфейса можно производить только в основном потоке. Поэтому мы получили основной поток  и…
  7. присвоили кнопке записи голоса статус, вычисленный из вариантов полученных разрешений.

Запустите проект и вы увидите мысли разработчиков Apple:

Микрофон

И еще одно разрешение от пользователя. На этот раз микрофона. В файл info.plist добавьте сроку, в колонке ключа найдите пункт Privacy — Microphone Usage Description, и в колонку значений введите строку с нужным вопросом.

Еще раз повторюсь — это текст вопроса, который увидит пользователь при запросе разрешения к микрофону. Но мы еще не пытались получить к нему доступ, поэтому то и вопроса не будет… Но мы к нему подготовились.




Обработка распознавания речи

Мы реализовали авторизацию пользователя, запросы и обработку всех разрешений. Теперь перейдем к реализации непосредственного распознавания речи. Добавим переменные класса ViewController, которым присвоим нужные нам объекты.

Обработка процесса

 

В момент создания задачи распознавания мы должны убедится, что сам процесс вообще возможен. И если по каким либо причинам процесс невозможен, то нужно сделать недоступной кнопку записи. И для этого мы в качестве делегата распознавателя указали наш ViewController. А это означает, что распознаватель будет пытаться вызвать методы делегата, определенные протоколом SFSpeechRecognizerDelegate. Так давайте добавим метод делегата. Я, как и всегда, предпочитаю оформить его в отдельно расширении класса. После декларации класса контроллера добавьте следующие строки

КОМПИЛЯТОР ВЫДАСТ ОШИБКУ! Он скажет что класс контроллера уже соответсвует этому протоку. Это действительно так. Не забудьте убрать соответствие протоколу SFSpeechRecognizerDelegate в строке объявления класса ViewController.

Думаю, все понятно. При изменении статуса доступности распознавателя вызывается этот метод и в зависимости от этого статус меняется доступность кнопки начала записи.

Ну и самое последнее, что мы должны сделать, это написать метод, который будет выполнятся по нажатию кнопки записи.

Внимательно посмотрите на этот метод и самое главное вспомните, в какие моменты происходит управление доступностью кнопки записи. Мы проверяем запущен ли аудио-движок, т.е. пишем ли мы с микрофона и если да, то останавливаем движок, говорим распознавателю, что аудио поток завершился, выключаем кнопку и меняем на ней заголовок. Иначе же, мы запускаем наш метод startRecording() и меняем надпить на кнопке. При этом в этой ветке кода мы не меняем доступность кнопки — она доступна и может остановить запись в любой момент.

Можно тестировать приложение. Запустите на реальном iOS устройстве и нажмите на кнопку начала записи.

При первом запуске будет еще запрос на доступ к микрофону. Мы же его запрограммировали, но еще не давали.

Ну и поговорите с телефоном. Он вас услышит и все запишет.

Что еще нужно знать о Speech в iOS 10

  1. Процесс распознавания речи потребует много энергии и увеличивает расход трафика
  2. Распознавание может длится не более одной минуты за раз
  3. Apple ограничивает количество распознаваний с одного устройства
  4. Apple ограничивает количество распознаваний с оного приложения
  5. Если вы достигните лимита (который не известен), то Apple рекомендует связаться со службой поддержки для увеличения этих лимитов.

Резюме

Мы создали iOS приложение с возможностью распознавания речи. Это приложение использует фреймворк Speech, любезно предоставленный нам компанией Apple.

Привожу полный код ViewController:

Ссылка проекта на GitHub



Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*