Использование Google Speech API для управления компьютером

в 10:26, , рубрики: Delphi, Google, Google API

Добрый день всем хабражителям.

На хабре уже писалось несколько статей о использовании Google Speech API, в том числе о его применении при создании Умного дома.

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

Кому интересно, прошу под кат.

Для разработки я использую Embarcadero RAD Studio XE и несколько бесплатных вспомогательных компонентов (JEDI Core, JEDI VCL, New Audio Components for Delphi, Synapse, uJSON, CoolTrayIcon)

В статье «Используем Google Voice Search в своем приложении .NET» было описано как работает Google Speech API и какие есть тонкости.

Опишу алгоритм моей программы и некоторые нюансы использования вспомогательных компонентов.

1. Запись звука в формате FLAC

Для этого я использую компонент New Audio Components for Delphi. Звук записываем в формат FLAC с частотой 8 кГц и сохраняем в файл.

За запись отвечает VCL компонент DXAudioIn1, в нем же прописаны настройки записи (1 канал и частота 8 кГц)

Далее данные с DXAudioIn1 идут на FastGainIndicator1 у которого на OnGainData стоит обработка уровней, если уровень упал N раз ниже установленного (красный указатель), то происходит остановка записи и отправка данных в Google.
Так же я сделал возможность начать автоматическую запись при превышении уровня на какой-то порог M раз (синий указатель).

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

И в конце данные с FastGainIndicator1 идут на компонент FLACOut1, который и осуществляет запись непосредственно в файл в формате FLAC.

За начало записи отвечает процедура StartRecord.

2. Отправка файла в Google для распознавания и прием ответа

Записанный файл с помощью библиотеки Synapse отправляется в Google на распознавание.

Какие есть тонкости при работе с Synapse и тем, что данные нужно отправлять используя HTTPS?

а) Необходимо наличие библиотек libeay32.dll и ssleay32.dll
б) В uses необходимо подключить файл SSL_OpenSSL

За отправку файла отвечает функция HTTPPostFile.

Вызывается она просто:
HTTPPostFile('https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU', 'userfile', ExtractFilename(OutFileName), Stream, StrList);

, где
Stream — это поток TFileStream в который мы читаем наш записанный файл в формате FLAC.
StrList — это TStringList с ответом от Google.

Сама функция HTTPPostFile довольно проста, но есть в ней и тонкости:

function TMainForm.HTTPPostFile(Const URL, FieldName, FileName: String; Const Data: TStream; Const ResultData: TStrings): Boolean;
const
  CRLF = #$0D + #$0A;
var
  HTTP: THTTPSend;
  Bound, Str: String;
begin
  Bound := IntToHex(Random(MaxInt), 8) + '_Synapse_boundary';
  HTTP := THTTPSend.Create;
  try
    Str := '--' + Bound + CRLF;
    Str := Str + 'content-disposition: form-data; name="' + FieldName + '";';
    Str := Str + ' filename="' + FileName + '"' + CRLF;
    Str := Str + 'Content-Type: audio/x-flac; rate=8000' + CRLF + CRLF;
    HTTP.Document.Write(Pointer(Str)^, Length(Str));
    HTTP.Document.CopyFrom(Data, 0);
    Str := CRLF + '--' + Bound + '--' + CRLF;
    HTTP.Document.Write(Pointer(Str)^, Length(Str));
    HTTP.MimeType := 'audio/x-flac; rate=8000, boundary=' + Bound;
    Result := HTTP.HTTPMethod('POST', URL);
    ResultData.LoadFromStream(HTTP.Document);
  finally
    HTTP.Free;
  end;
end;

3. Парсинг строки ответа от Google и выполнение команды

Строка ответа от Google приходит в формаnе JSON, например:

{«status»:0,«id»:«5e34348f2887c7a3cc27dc3695ab4575-1»,«hypotheses»:[{«utterance»:«блокнот»,«confidence»:0.7581704}]}

Для парсинга я использую библиотеку uJSON.

Что означают поля ответа:
поле status = 0 — запись успешно распознана
поле status = 5 — запись не распознана
поле id — это уникальный идентификатор запроса
поле hypotheses — результат распознования, в нем 2 подполя:
utterance — распознанная фраза
confidence — достоверность распознавания

Отправка файла, разбор ответа, поиск и выполнение команды я вынес в отдельный поток JvThreadRecognize.

Списки команд хранятся в файле MSpeechCommand.ini, пример файла:

блокнот;notepad.exe
свернуть все программы;scriptShow_Desktop.scf
заблокировать компьютер;scriptLock_Workstation.cmd
выключить компьютер;scriptHalt_Workstation.cmd
перезагрузить компьютер;scriptReboot_Workstation.cmd
завершить сеанс;scriptLogoff_Workstation.cmd
запустить qip;C:Program FilesQIP Infiuminfium.exe
интернет;firefox.exe

Итоги: Данная программа не претендует на звание законченной, это лишь пример использования Google Speech API для выполнения некоторых команд на компьютере (пока это только запуск приложений и выполнение системных команд). Но никто не мешает доработать её и научить двигать мышкой, набирать текст в текстовом редакторе и т.д.

Готовая сборка программы и исходники (GPLv3) доступны на code.google.com/p/mspeech/

Буду рад услышать конструктивную критику и пожелания. Спасибо.

Автор: Sleuthhound


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js