Modber Сообщество
профессионалов по 1С

Генератор речи на базе 1С: Предприятие и Skype



Платформы: 1С:Предприятие 8.3, 1С:Предприятие 8.2, Windows
Конфигурации: Другие конфигурации
2013-07-28
2687 
dok042
1  
В статье рассмотрен пример реализации на базе 1С генератора речи, который создает аудио-файл на основе текстовой строки. Функциональность так же позволяет с использованием .Net framework и API позвонить абоненту через Skype, и произнести сгенерированный файл.

Предварительная настройка
ОС Windows 7 читает по умолчанию только английский текст. В нашем примере для русификации голоса используется ScanSoft Katerina Full 22kHz. Если скорость чтения голоса покажется медленным, необходимо сделать запись в реестре:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\ScanSoftKaterina_Full_22kHz]
"pp type"="email"


Для взаимодействия со Skype необходимо скачать библиотеку skype4COM и выполнить ее регистрацию в реестре через regsvr32 skype4COM.dll (могут потребоваться права администратора).

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

Описание кода 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. Второй параметр в 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);


Проблемы и их решения
Проблема: в сгенерированном аудио-файле произносятся слова, написанные только латинскими буквами.
Решение: в систему не установлен или не выбран необходимый русский голос. Если используется не 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.



Бесплатная юридическая
консультация по телефону

8 (499) 350-80-26(Москва)
8 (812) 627-15-62(Спб)

звонок бесплатный

В центре внимания

Комментарии (6)