Голосовой информатор через Skype для 1С: Предприятие

от автора

Обработка для 1С в статье позволяет получить аудиофайл с речью, сгенерированной компьютером на основе текстовой строки, позвонить собеседнику через Skype и произнести его. Функциональность выполнена на основе .Net framework и API для Skype. Разработка будет полезна не только для серьезных бизнес-приложений, но и для домашних опытов и шуток друзьям. Для звонков на реальные номера потребуется пополненный баланс на Skype.

Предварительная настройка

Если не предусмотрен в системе русский голос, то его необходимо установить. По умолчанию Windows 7 может читать только английские тексты. Для русификации голоса нужно установить дополнительный русский голос. В Интернете удалось найти только голос ScanSoft Katerina Full 22kHz (до конца не понятна правовая возможность использования этого голоса). Многим может показаться голос медленным. Для его убыстрения необходимо сделать запись в реестре:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\ScanSoftKaterina_Full_22kHz]  "pp type"="email" 

Скайп позволяет взаимодействовать с собой через библиотеку skype4COM.
Необходимо скачать эту библиотеку и выполнить ее регистрацию в реестре через regsvr32 skype4COM.dll. Для данной операции могут потребоваться права администратора.
После попытки использовать Skype в первый раз появится запрос в Skype’е. Нужно дать разрешение программе 1cv8c.exe на использование Skype. Контроль программ, имеющих доступ, можно выполнить через Настройки-Дополнительно-Расширенные настройки-Контроль доступа других программ к Skype.
Для доступа к .Net framework из 1С необходимо установить .Net Bridge. Сейчас последняя версия 4.0.4.

Описание кода C#

Код класса SkypeSpeech разделен на 2 части: генерация звука через класс SpeechSynthesizer и работа со Skype через SKYPE4COMLib.

Генерация звука:

SpeechSynthesizer reader = new SpeechSynthesizer(); if (!String.IsNullOrEmpty(voiceName)) {     var voice = reader.GetInstalledVoices().Where(m => m.VoiceInfo.Name == voiceName).FirstOrDefault();     if (voice != null)         reader.SelectVoice(voiceName); } reader.SetOutputToWaveFile(tempFilePath, new SpeechAudioFormatInfo(     16000,     AudioBitsPerSample.Sixteen,     AudioChannel.Mono ));  reader.Speak(text); reader.SetOutputToNull(); reader.Dispose(); 

Особенности кода следующие. На вход в Skype нужно подать wav-файл с определенными параметрами, поэтому параметры устанавливаются явно. Для управления голосами SpeechSynthesizer используются методы GetInstalledVoices и SelectVoice.

Работа со Skype ведется через Skype4COM. В Сети есть много примеров, например: http://habrahabr.ru/post/139319/. Все примеры, какие я смотрел, отличаются, на мой взгляд, усложненной структурой: логика не умещается в один метод, а распределена между разными методами и событиями. Хотелось уместить всю логику в одну процедуру для наглядности.

Подключение к Skype. Второй параметр в skype.Attach заменен на true. Это значит, что скайп возвратит управление, когда произойдет подключение.

Skype skype = new Skype(); if (!skype.Client.IsRunning)     skype.Client.Start(true, true);  skype.Attach(8, true);  

Звонок через Skype:

Call call = skype.PlaceCall(target); do {      if (call.Status == TCallStatus.clsBusy         || call.Status == TCallStatus.clsCancelled         || call.Status == TCallStatus.clsFailed)         break;      System.Threading.Thread.Sleep(1); } while (call.Status != TCallStatus.clsInProgress);  if (call.Status != TCallStatus.clsInProgress)     return; 

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

call.set_InputDevice(TCallIoDeviceType.callIoDeviceTypeFile, waveFilePath); do {     System.Threading.Thread.Sleep(1000); } while (IsBusy(waveFilePath));  

Метод IsBusy выглядит так:

try {     using (FileStream stream = File.OpenWrite(filePath))     {         stream.Close();         return false;     } } catch (IOException) {     return true; } 

Описание кода 1С

Инициализация происходит в событии формы ПриОткрытии. Создание объекта .Net Bridge.

ПодключитьВнешнююКомпоненту("Elisy.NetBridge4"); AddIn = New("AddIn.ElisyNetBridge4"); net = AddIn.GetNet(); 

Загрузка сборки из GAC:

net.LoadAssembly("System.Speech, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");

Загрузка сборки из макета к обработке:

Макет = ПолучитьМакет("Elisy_SkypeSpeech_dll"); ДвоичныеДанные = Base64String(Макет); assemblyBytes = net.CallStatic("System.Convert", "FromBase64String", ДвоичныеДанные); net.CallStatic("System.Reflection.Assembly", "Load", assemblyBytes); 

За генерацию звука и отправку голосового сообщения через Skype отвечает класс Elisy.SkypeSpeech.SkypeSpeech. Поэтому объект этого типа нужно создать для доступа к нему.

skypeSpeech = net.New("Elisy.SkypeSpeech.SkypeSpeech");

Команда генерации аудио-файла skypeSpeech.CreateSpeech. Первый параметр – имя файла с полным путем, второй параметр – текст сообщения. Третий параметр – имя голоса.

skypeSpeech.CreateSpeech(tempFilePath, Объект.Сообщение, "ScanSoft Katerina_Full_22kHz");

Команда отправки на Skype голосового сообщения skypeSpeech.SendAudioMessage. Первый параметр – номер телефона или имя Skype. Второй параметр – имя аудио-файла.

skypeSpeech.SendAudioMessage(Объект.НомерТелефона, tempFilePath);

Известные проблемы и их решения

Записанный аудиофайл произносит только слова, написанные латинскими буквами, например, Skype. Это означает, что не установлен в систему или не выбран необходимый русский голос. Его необходимо установить. Если это голос не ScanSoft Katerina Full 22kHz, то необходимо подправить вызов skypeSpeech.CreateSpeech(ПутьКФайлу, Объект.Сообщение, «ScanSoft Katerina_Full_22kHz») на нужное имя голоса.

При нажатии «Позвонить по Skype TargetInvokationException с сообщением «Retrieving the COM class factory for component with CLSID {830690FC-BF2F-47A6-AC2D-330BCB402664} failed due to the following error: 80040154 Класс не зарегистрирован (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).». Это означает, что должным образом не зарегистрирована библиотека для доступа к Skype skype4COM.dll. Ее нужно скачать и зарегистрировать с правами администратора через regsvr32 skype4COM.dll.

Что не реализовано

Обработка работает исходя из предположения, что передача передача голосового сообщения будет вестись стандартным образом: звонок – ответ – передача сообщения – завершение звонка. В текущей версии обработки нет анализа статуса: доставлено или недоставлено. Например, телефон у абонента может быть занят или абонент начал слушать сообщение и самостоятельно прервал разговор.

В 1С не удалось удалить временный файл в конце обработки. Это странное явление, которое не удалось побороть, потому что в тестовом приложении через C# временный файл нормально удалялся.

Пример полученного аудио-файла: audio.wav (180,78 kb)

Обработка для 1С: Предприятие: SkypeSpeech.epf (14,21 kb)

ссылка на оригинал статьи http://habrahabr.ru/post/165883/


Комментарии

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

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