Синтаксис и применение ПараметрыПотоковогоРаспознаванияРечи.По умолчанию в платформе 1С:Предприятие. Описание и примеры кода.
Синтаксис
Новый ПараметрыПотоковогоРаспознаванияРечиПолное описание, параметры и ограничения
ПараметрыПотоковогоРаспознаванияРечи.По умолчанию
ПараметрыПотоковогоРаспознаванияРечи (SpeechToTextStreamingParameters)
По умолчанию
Синтаксис:
Новый ПараметрыПотоковогоРаспознаванияРечи
Методическая информация
Практические примеры
Получить реальную модель, установить на свой стенд и распознавать фразу только локально
Полный жизненный цикл одной модели: выбор настоящего каталога, проверка двух конструкторов идентификатора, реальный адрес временного хранилища, установка, интерактивный локальный микрофон, адресная остановка и удаление только возвращённой собственной установки.
Где и как запускать
Полный клиентский модуль управляемой формы собственного эксклюзивного стенда УчебнаяЛокальнаяМодель85.Пульт; толстый клиент8.5.1.1343 в режиме Управляемое приложение, роль с Администрирование данных.
Подготовка
Создайте с нуля отдельную пустую базу УчебнаяЛокальнаяМодель85 на платформе8.5.1.1343. Не переименовывайте рабочую базу. Нужен только один пользователь, один сеанс, одно окно, без расширений, фоновых заданий, подписок, общих реквизитов-разделителей и прикладных объектов.
В конфигураторе создайте Обработки → УчебнаяЛокальнаяМодель85 → Формы → Пульт, тип Управляемая. Код ниже — полный клиентский модуль формы. Запускайте толстый клиент в режиме Управляемое приложение, не тонкий, веб- или мобильный клиент.
Пользователю стенда нужны права Администрирование данных для установки и удаления модели. Код не повышает права и не содержит логина или токена. Проверка имени конфигурации сама по себе не доказывает изоляцию; условия пустоты и единственного пользователя обязательны.
До опыта на стенде не должно быть зарегистрированных данных речи, параметров подключения сеанса/базы или локальных моделей. Начальная проверка ничего из этого не сбрасывает. При наличии состояния используйте другой новый стенд, а не удаляйте найденные чужие записи.
Для настоящего каталога и получения публичной модели потребуется доступ к сервису речи. Справка допускает получение публичных моделей без аутентификации; фактическая доступность, лицензия, сеть и ресурсы проверяются отдельно. Никакой фиктивный endpoint не прописан.
Добавьте реквизиты СогласиеУстановки и СогласиеМикрофона типа Булево, Итог типа Строка неограниченной длины. Покажите оба флажка и многострочный Итог только для просмотра. Собственный дескриптор, флаги и ключ держатся в закрытых переменных модуля.
Добавьте четыре команды: УстановитьСвоюМодель, НачатьСвойПоток, ОстановитьСвойПоток, УдалитьСвоюМодель. Назначьте одноимённые процедуры с параметром Команда. Назначьте ПриОткрытии(Отказ) и ПередЗакрытием с четырьмя параметрами.
Процедура СвояФразаПолучена должна оставаться экспортной с тремя параметрами. Выходной ПродолжитьРаспознавание передаётся по ссылке, без Знач. ОписаниеОповещения получает ЭтотОбъект управляемой формы, не ЭтаФорма обычной формы.
Нажмите F7 и обновите только стенд. F7 не доказывает доступность сервиса, установленную модель или работу микрофона. Здесь runtimeVerifiedScenarios=0: ни модель, ни микрофон, ни сервис не запускались.
Перед установкой оцените свободное место и память: модель скачивается и сохраняется в информационной базе, а установленные модели загружаются в память при первом входе в соответствующую область данных. Это не небольшой временный текстовый файл.
Установите согласие установки и нажмите УстановитьСвоюМодель. Получение и установка разделены: первая операция возвращает адрес временного хранилища, вторая принимает именно его. Установка не запускает микрофон.
Затем отдельно согласитесь на микрофон, нажмите НачатьСвойПоток, произнесите свою безобидную учебную фразу и явно нажмите ОстановитьСвойПоток. ТолькоЛокальное запрещает подмену облачным распознаванием, но каталог и предыдущее скачивание сами не являются офлайн-операциями.
После адресной остановки нажмите УдалитьСвоюМодель. Используется идентификатор фактически возвращённого дескриптора установки, не любой каталожный идентификатор. Не допускайте других использующих модель пользователей: удаление прекращает такие распознавания.
При исключении установки до получения дескриптора исход может быть неизвестен. Не повторяйте установку и не угадывайте ID для удаления. Администратор должен исследовать только этот заранее пустой отдельный стенд; принудительное завершение теряет память окна.
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Перем СвояГотовность;
Перем СвояПопыткаУстановки;
Перем СвояМодель;
Перем СвойКлючПотока;
Перем СвояПопыткаПотока;
&НаКлиенте
Процедура ПриОткрытии(Отказ)
СвояГотовность = Ложь;
СвояПопыткаУстановки = Ложь;
СвояМодель = Неопределено;
СвойКлючПотока = "";
СвояПопыткаПотока = Ложь;
СогласиеУстановки = Ложь;
СогласиеМикрофона = Ложь;
Итог = "Модель ещё не получена; микрофон выключен";
ПроверитьСвойСтенд();
СвояГотовность = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0
Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0
Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0
Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или ТранзакцияАктивна() Тогда
ВызватьИсключение "Нужен пустой собственный стенд без разделителей, регистров и чужой транзакции";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвоеОкно()
ПроверитьСвойСтенд();
Если Не СвояГотовность Тогда
ВызватьИсключение "Нужно открытое собственное окно";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция ПолучитьНастоящийКаталог()
Каталог = РаботаСРечью.ПолучитьОписаниеМоделейРаспознавания();
Если ТипЗнч(Каталог) <> Тип("Массив") Тогда
ВызватьИсключение "Нужен настоящий каталог моделей платформы";
КонецЕсли;
Для Каждого Описание Из Каталог Цикл
Если ТипЗнч(Описание) <> Тип("ОписаниеМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Неверный тип реального дескриптора модели";
КонецЕсли;
КонецЦикла;
Возврат Каталог;
КонецФункции
&НаКлиенте
Функция ВыбратьСвоюМодельДляПолучения()
Если РаботаСРечью.ПолучитьДанныеРаботыСРечьюИнформационнойБазы() <> Неопределено
Или РаботаСРечью.ПолучитьПараметрыВнешнегоПодключенияИнформационнойБазы() <> Неопределено
Или РаботаСРечью.ПолучитьПараметрыВнешнегоПодключенияСеанса() <> Неопределено Тогда
ВызватьИсключение "У стенда уже есть данные речи или подключение; чужое состояние не меняется";
КонецЕсли;
Каталог = ПолучитьНастоящийКаталог();
Для Каждого Описание Из Каталог Цикл
Если Описание.ДоступнаВЛокальномВарианте Тогда
ВызватьИсключение "На стенде уже есть локальная модель; опыт не присваивает себе её владение";
КонецЕсли;
КонецЦикла;
Для Каждого Описание Из Каталог Цикл
Если Описание.ДоступнаДляПолучения Тогда
Параметры = Описание.ПолучитьПараметры();
Если ТипЗнч(Параметры) <> Тип("ПараметрыМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Каталог должен вернуть реальные параметры";
КонецЕсли;
Если НРег(Лев(Параметры.КодЯзыка, 2)) = "ru" Тогда
Возврат Описание;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ВызватьИсключение "В настоящем каталоге нет доступной для получения русскоязычной модели";
КонецФункции
&НаКлиенте
Процедура ПроверитьПредставленияНастоящегоИдентификатора(Идентификатор)
Если ТипЗнч(Идентификатор) <> Тип("ИдентификаторМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Нужен идентификатор существующей модели из реального каталога";
КонецЕсли;
Представление = Строка(Идентификатор);
ИзСтроки = Новый ИдентификаторМоделиРаспознаванияРечи(Представление);
ИсходныйUUID = Новый УникальныйИдентификатор(Представление);
ИзUUID = Новый ИдентификаторМоделиРаспознаванияРечи(ИсходныйUUID);
Если ИзСтроки <> Идентификатор Или ИзUUID <> Идентификатор Тогда
ВызватьИсключение "Преобразования должны восстановить именно реальный исходный идентификатор";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура УстановитьСвоюМодель(Команда)
ПроверитьСвоеОкно();
Если Не СогласиеУстановки Тогда
ВызватьИсключение "Подтвердите скачивание и постоянную установку модели только на своём стенде";
КонецЕсли;
Если СвояПопыткаУстановки Или СвояМодель <> Неопределено Или СвояПопыткаПотока Тогда
ВызватьИсключение "Предыдущая установка должна быть адресно завершена; повтор по неизвестному исходу запрещён";
КонецЕсли;
Кандидат = ВыбратьСвоюМодельДляПолучения();
ПроверитьПредставленияНастоящегоИдентификатора(Кандидат.ИдентификаторМодели);
Итог = "Получается модель из настоящего каталога; постоянная установка ещё не начиналась";
Адрес = РаботаСРечью.ПолучитьМодельРаспознаванияВоВременноеХранилище(Кандидат.ИдентификаторМодели);
Если ТипЗнч(Адрес) <> Тип("Строка") Или Адрес = "" Тогда
ВызватьИсключение "Нужен настоящий непустой адрес временного хранилища, возвращённый платформой";
КонецЕсли;
СвояПопыткаУстановки = Истина;
Итог = "Начата собственная установка; при потере ответа нельзя угадывать идентификатор для удаления";
Установленная = РаботаСРечью.УстановитьМодельРаспознаванияДляИнформационнойБазы(Адрес);
Если ТипЗнч(Установленная) <> Тип("ОписаниеМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Нет действительного ответа установки; повтор запрещён до проверки администратором";
КонецЕсли;
СвояМодель = Установленная;
Если ТипЗнч(СвояМодель.ИдентификаторМодели) <> Тип("ИдентификаторМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Ответ не содержит действительного идентификатора собственной установки";
КонецЕсли;
Если Не СвояМодель.ДоступнаВЛокальномВарианте Тогда
ВызватьИсключение "Ответ установки не подтвердил локальную доступность; можно удалить только возвращённую свою модель";
КонецЕсли;
Итог = "Своя модель установлена: " + Строка(СвояМодель.ИдентификаторМодели) + "; микрофон не включён";
КонецПроцедуры
&НаКлиенте
Процедура НачатьСвойПоток(Команда)
ПроверитьСвоеОкно();
Если Не СогласиеМикрофона Тогда
ВызватьИсключение "Подтвердите интерактивный захват только своего микрофона";
КонецЕсли;
Если СвояМодель = Неопределено Или СвояПопыткаПотока Тогда
ВызватьИсключение "Нужна подтверждённая собственная установка без предыдущего потока";
КонецЕсли;
Если Не СвояМодель.ДоступнаВЛокальномВарианте Или Не РаботаСРечью.ПоддерживаетсяПотоковоеРаспознавание() Тогда
ВызватьИсключение "Локальная модель или поток недоступны";
КонецЕсли;
Модель = СвояМодель.ПолучитьПараметры();
Если ТипЗнч(Модель) <> Тип("ПараметрыМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Нужны реальные параметры своей установленной модели";
КонецЕсли;
Параметры = Новый ПараметрыПотоковогоРаспознаванияРечи;
ПроверитьОтсутствиеЗаписи(Параметры);
Параметры.ПолучатьПромежуточныеРезультаты = Ложь;
СвойКлючПотока = "УчебныйЛокальныйПоток85-" + Строка(Новый УникальныйИдентификатор);
Оповещение = Новый ОписаниеОповещения("СвояФразаПолучена", ЭтотОбъект, СвойКлючПотока);
СвояПопыткаПотока = Истина;
Итог = "Запускается микрофон только для локального распознавания; после фразы явно остановите свой поток";
РаботаСРечью.НачатьПотоковоеРаспознавание(СвойКлючПотока, Оповещение, Модель,
ВариантИспользованияРасположенияРаботыСРечью.ТолькоЛокальное, Параметры);
КонецПроцедуры
&НаКлиенте
Процедура СвояФразаПолучена(РезультатРаспознавания, ПродолжитьРаспознавание, ДополнительныеПараметры) Экспорт
ПродолжитьРаспознавание = Ложь;
Если Не СвояГотовность Или Не СвояПопыткаПотока Или ДополнительныеПараметры <> СвойКлючПотока Тогда
Возврат;
КонецЕсли;
Если Не СогласиеМикрофона Тогда
Итог = "Согласие отозвано; продолжение отклонено. Явно остановите свой поток";
Возврат;
КонецЕсли;
Если ТипЗнч(РезультатРаспознавания) <> Тип("РезультатРаспознаванияРечи") Тогда
Итог = "Нет настоящего результата; продолжение отклонено";
Возврат;
КонецЕсли;
Фразы = РезультатРаспознавания.ДанныеФраз;
Если ТипЗнч(Фразы) <> Тип("Массив") Или Фразы.Количество() = 0 Тогда
Итог = "Настоящий результат не содержит фраз; продолжение отклонено";
Возврат;
КонецЕсли;
Фраза = Фразы[0];
Если ТипЗнч(Фраза) <> Тип("ДанныеФразыРаспознаванияРечи") Тогда
Итог = "Неожиданный тип фразы; продолжение отклонено";
Возврат;
КонецЕсли;
Итог = "Локальная фраза: " + Фраза.Фраза + "; окончательная: "
+ Строка(РезультатРаспознавания.РаспознаваниеФразыЗавершено)
+ "; исходная уверенность: " + Строка(Фраза.Уверенность)
+ ". Продолжение отклонено; нажмите ОстановитьСвойПоток";
КонецПроцедуры
&НаКлиенте
Процедура ОстановитьСвойПоток(Команда)
ПроверитьСвоеОкно();
Если СвояПопыткаПотока Тогда
Если СвойКлючПотока = "" Тогда
ВызватьИсключение "Без собственного ключа остановка запрещена";
КонецЕсли;
РаботаСРечью.ОстановитьПотоковоеРаспознавание(СвойКлючПотока);
СвояПопыткаПотока = Ложь;
СвойКлючПотока = "";
КонецЕсли;
Итог = "Адресная остановка своего потока завершена; модель остаётся установленной";
КонецПроцедуры
&НаКлиенте
Процедура УдалитьСвоюМодель(Команда)
ПроверитьСвоеОкно();
Если СвояПопыткаПотока Тогда
ВызватьИсключение "Сначала явно остановите свой поток; удаление способно прервать использующие модель распознавания";
КонецЕсли;
Если СвояМодель = Неопределено Тогда
ВызватьИсключение "Без фактического ответа своей установки нельзя угадывать объект удаления";
КонецЕсли;
Идентификатор = СвояМодель.ИдентификаторМодели;
Если ТипЗнч(Идентификатор) <> Тип("ИдентификаторМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Нужен действительный идентификатор возвращённой собственной установки";
КонецЕсли;
РаботаСРечью.УдалитьМодельРаспознаванияДляИнформационнойБазы(Идентификатор);
Для Каждого Описание Из ПолучитьНастоящийКаталог() Цикл
Если Описание.ИдентификаторМодели = Идентификатор И Описание.ДоступнаВЛокальномВарианте Тогда
ВызватьИсключение "Локальная модель ещё видна; владение не сбрасывается до подтверждения";
КонецЕсли;
КонецЦикла;
СвояМодель = Неопределено;
СвояПопыткаУстановки = Ложь;
СогласиеУстановки = Ложь;
СогласиеМикрофона = Ложь;
Итог = "Возвращённая собственная модель больше не доступна локально; чужие модели и настройки не удалялись";
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
СтандартнаяОбработка = Истина;
Если СвояПопыткаПотока Или СвояПопыткаУстановки Тогда
Отказ = Истина;
ТекстПредупреждения = "Остановите свой поток и удалите подтверждённую свою модель. Если ответ установки потерян, нужен администратор именно этого отдельного стенда";
Если Не ЗавершениеРаботы Тогда
Сообщить(ТекстПредупреждения);
КонецЕсли;
Возврат;
КонецЕсли;
СвояГотовность = Ложь;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьОтсутствиеЗаписи(Параметры)
Если ТипЗнч(Параметры) <> Тип("ПараметрыПотоковогоРаспознаванияРечи") Тогда
ВызватьИсключение "Нужны только собственные новые параметры потока";
КонецЕсли;
ОбработчикЗаписи = Параметры.ОбработчикОстановкиАудиозаписи;
Если ОбработчикЗаписи = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ОбработчикЗаписи) <> Тип("ОписаниеОповещения") Тогда
ВызватьИсключение "Неизвестная настройка записи аудио; захват запрещён";
КонецЕсли;
Если ЗначениеЗаполнено(ОбработчикЗаписи.ИмяПроцедуры)
Или ОбработчикЗаписи.Модуль <> Неопределено
Или ЗначениеЗаполнено(ОбработчикЗаписи.ИмяПроцедурыОбработкиОшибки)
Или ОбработчикЗаписи.МодульОбработкиОшибки <> Неопределено Тогда
ВызватьИсключение "В собственных новых параметрах уже задана обработка записи; этот опыт её не разрешает";
КонецЕсли;
КонецПроцедуры
#Иначе
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Отказ = Истина;
ВызватьИсключение "Только толстый клиент управляемого приложения";
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
СтандартнаяОбработка = Истина;
КонецПроцедуры
&НаКлиенте
Процедура УстановитьСвоюМодель(Команда)
ВызватьИсключение "Нужен толстый клиент управляемого приложения";
КонецПроцедуры
&НаКлиенте
Процедура НачатьСвойПоток(Команда)
ВызватьИсключение "Нужен толстый клиент управляемого приложения";
КонецПроцедуры
&НаКлиенте
Процедура ОстановитьСвойПоток(Команда)
ВызватьИсключение "Нужен толстый клиент управляемого приложения";
КонецПроцедуры
&НаКлиенте
Процедура УдалитьСвоюМодель(Команда)
ВызватьИсключение "Нужен толстый клиент управляемого приложения";
КонецПроцедуры
#КонецЕслиРазбор по шагам
Каталог полностью проверяется на уже доступные локальные модели, прежде чем выбирается первый реально доступный для получения дескриптор с кодом языка ru. Версия, акустика, грамматика и ID не сочиняются.
Оба конструктора ИдентификаторМоделиРаспознаванияРечи работают с представлениями одного фактического ID. Строка и UUID восстанавливают этот же объект, сравнение проверяет roundtrip; случайный UUID не выдаётся за существующую модель.
ПолучитьМодельРаспознаванияВоВременноеХранилище получает типизированный ID каталога. Строка Адрес приходит из настоящего ответа; её не заменяют путём к несуществующему архиву или URL.
Перед постоянным изменением флаг попытки выставляется в Истина. УстановитьМодельРаспознаванияДляИнформационнойБазы принимает настоящий адрес и возвращает ОписаниеМоделиРаспознаванияРечи. Именно этот ответ сохраняет доказательство владения.
Настоящие параметры получаем от установленной модели. Свежие параметры потока проходят проверку отсутствия настроенной записи, окончательная фраза запрашивается отключением промежуточных результатов.
НачатьПотоковоеРаспознавание получает ТолькоЛокальное и уникальный собственный ключ. Уведомление содержит этот ключ и клиентский модуль управляемой формы. Чужие потоки не останавливаются, глобальный stop без аргумента запрещён.
Callback отклоняет продолжение по умолчанию, показывает только действительный результат своего текущего потока, текст фразы и исходную уверенность. Текст не исполняется; отклонение продолжения не подменяет явную команду адресной остановки.
Удаление доступно только после подтверждённого возврата собственного stop и при наличии действительного ID возвращённой установки. Затем каталог проверяет отсутствие локальной доступности именно этого ID; облачный дескриптор может остаться.
Состояние владения и согласия сбрасывается только после подтверждения. ПередЗакрытием не скачивает, не удаляет и не вызывает сервер: незавершённый опыт сначала надо завершить явными командами.
Как проверить результат
Без первого согласия получения и установки нет, без второго согласия микрофон не стартует. Команды остановки и удаления не требуют повторного согласия на захват или скачивание.
На другой версии, в другом клиенте, рабочей базе, стенде с разделителями/регистрами или существующим состоянием речи опыт должен отказать до установки. Не изменяйте проверки ради запуска в production.
В каталоге должна быть реально доступная для получения русская модель; пустой каталог, отсутствие языка или недоступность публичной модели являются честным отказом, не поводом создавать дескриптор вручную.
Два roundtrip должны дать именно исходный фактический ID. UUID берётся из представления настоящего ID, а не Новый УникальныйИдентификатор без аргумента.
При нормальном ручном запуске строка Итог после установки содержит ID из возвращённой модели. До нажатия отдельного старта захвата нет. Локальный старт должен отказать, если локальная модель недоступна, а не молча уйти в облако.
Повторный старт до остановки и повторная установка до удаления запрещены. Запоздалый callback с предыдущим ключом не меняет Итог нового потока. Отзыв согласия отклоняет продолжение; для немедленной остановки при тишине нажмите кнопку stop.
Удаление до остановки отвергается. После удаления тот же ID не должен быть локально доступен; другой облачный вариант не означает провал удаления.
Исключение после начала установки сохраняет флаг попытки. Без фактического возвращённого ID автоматическое удаление запрещено; общий сброс регистрационных данных не используется как неописанная замена удаления модели.
Ожидаемый результат
В разрешённом ручном опыте настоящая модель получена и установлена в собственную пустую базу; своя фраза распознана только локально, свой поток адресно остановлен и возвращённая собственная установка удалена. Здесь этот результат ещё не получен: выполнены только статические проверки.
На что обратить внимание
Методы установки и удаления реально меняют данные информационной базы и требуют Администрирование данных. Это не пример только для памяти; изоляция нового стенда обязательна.
ТолькоЛокальное относится к распознаванию, а не к каталогу или скачиванию. Установка может использовать интернет и значительные ресурсы; не обещайте полностью офлайн-подготовку.
Удаление выгружает модель и прекращает использующие её распознавания. Даже правильный ID опасен в общей рабочей базе: пример разрешён только при эксклюзивном владении одним пустым стендом.
Временное хранилище управляется платформой. Получение модели туда не означает постоянную установку, файл на диске пользователя или резервную копию; срок жизни адреса нельзя произвольно продлевать.
Идентификатор каталога используется для получения. Для удаления нельзя присваивать владение этому каталожному объекту: берётся только фактический ID ответа собственного вызова установки.
Нет транзакционной гарантии для сетевого вызова установки. Исключение или потеря ответа могут оставить запись; повтор запрещён и требуется проверка администратором своего отдельного стенда, без угадывания исхода.
Окно хранит владение в памяти. Принудительное завершение приложения может потерять ID и ключ; ПередЗакрытием не является долговечным журналом. Не закрывайте сеанс, пока свой опыт нормально не очищен.
Локальные модели не поддерживаются мобильной платформой. Широкая доступность отдельных методов в справке не означает, что этот полный сценарий переносим в любой клиент.
Контроль по метаданным не доказывает отсутствие фоновых задач, расширений или второго сеанса. Эти условия проверяет администратор до опыта; код не может безопасно отключать чужие процессы.
Выполнены только статические проверки, runtimeVerifiedScenarios=0. 1С, сервис, скачивание модели и микрофон не запускались; новые файлы аудио, резервные копии и архивы не создавались.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Распознавать учебные фразы с микрофона без сохранения аудио и остановить только свой поток
Собственная управляемая форма запускает интерактивный микрофонный поток с двумя реальными фразами своей сеансовой грамматики. Новые параметры включают промежуточные варианты, а privacy-проверка не допускает настроенной записи; текст не выполняет команды.
Где и как запускать
Полный клиентский модуль управляемой формы собственного окна УчебныйМикрофонРечи85.Пульт; толстый клиент8.5.1.1343 в режиме управляемого приложения, собственный микрофон и реальная заранее подготовленная модель.
Подготовка
Создайте новую отдельную базу УчебныйМикрофонРечи85, платформа8.5.1.1343. Не переименовывайте рабочую базу, не запускайте пример в production и не включайте чужие грамматики ради прохождения опыта.
Используйте толстый клиент в режиме Управляемое приложение. В конфигураторе: Обработки → УчебныйМикрофонРечи85 → Формы → Пульт, тип Управляемая. Код ниже — полный модуль этой формы с клиентскими директивами и защитой от других клиентов.
Администратор заранее готовит реальное подключение к сервису и/или собственную доступную локальную модель. В фактическом каталоге должна быть модель с кодом языка, начинающимся на ru. Нет выдуманного URL, токена, модели или автоматической установки.
Проверьте микрофон, разрешения ОС, условия тарифа и передачу аудио в сервис. Авто ищет подходящую локальную модель, затем может обратиться к внешнему распознаванию. Не обещайте пользователю полностью локальную обработку только по этому значению.
Добавьте реквизиты Согласие типа Булево и Итог типа Строка неограниченной длины. Согласие выведите флажком, многострочный Итог сделайте только для просмотра. Ключи не вводятся пользователем и не являются реквизитами формы.
Создайте команды НачатьСвойПоток и ОстановитьСвойОпыт. Назначьте одноимённые процедуры с параметром Команда и выведите кнопки команд. Назначьте события ПриОткрытии(Отказ) и ПередЗакрытием с четырьмя параметрами.
Оставьте экспортными клиентские процедуры СвояГипотезаПолучена с тремя параметрами и СвояОшибкаПотока с тремя параметрами. Выходные Булево ПродолжитьРаспознавание и СтандартнаяОбработка не объявляйте через Знач.
Нажмите F7 и обновите только собственный стенд. F7 не доказывает работу микрофона, доступность модели или сервиса; здесь runtimeVerifiedScenarios=0 и захват не запускался.
Откройте только одно собственное окно. Установите согласие непосредственно перед интерактивным нажатием НачатьСвойПоток. Произнесите выбрать учебную книгу или завершить учебный опыт, затем вручную остановите свой опыт.
Грамматика сеанса создаётся под новым собственным GUID-ключом. Она содержит обычный массив строк, а не SRGS/ABNF. Дополнительные грамматики базы внешнее потоковое распознавание не использует.
Этот опыт намеренно не настраивает сохранение аудио. В установленной справке и поле обработчика записи, и поля ОписаниеОповещения readonly; способ их настройки через setter не выдумывается. Код читает настоящий свежий объект и запрещает старт, если у записи уже есть обработчик.
Снять согласие можно в любое время. Следующий настоящий callback отклонит продолжение, но при тишине callback может не появиться: для немедленной адресной остановки нажмите ОстановитьСвойОпыт, даже со снятым согласием.
После остановки проверяется отсутствие только своего ключа грамматики. Никаких файлов, резервных копий, архивов, выгрузки звука или запуска распознанных команд нет. Здесь 1С, микрофон и сервис не запускались.
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Перем СвояГотовность;
Перем СвойКлючПотока;
Перем СвойКлючГрамматики;
Перем СвояПопыткаПотока;
Перем СвояПопыткаГрамматики;
Перем СвойЗапросОстановки;
Перем СвоиУведомления;
&НаКлиенте
Процедура ПриОткрытии(Отказ)
СвояГотовность = Ложь;
Согласие = Ложь;
СвойКлючПотока = "";
СвойКлючГрамматики = "";
СвояПопыткаПотока = Ложь;
СвояПопыткаГрамматики = Ложь;
СвойЗапросОстановки = Ложь;
СвоиУведомления = 0;
Итог = "Подготовьте собственный микрофон и модель; запись аудио этим окном не настраивается";
Попытка
ПроверитьСвойСтенд();
СвояГотовность = Истина;
Исключение
Отказ = Истина;
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвойСтенд()
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Не запускайте захват звука внутри чужой транзакции";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвоеОкно()
ПроверитьСвойСтенд();
Если Не СвояГотовность Тогда
ВызватьИсключение "Нужно собственное открытое учебное окно";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура НачатьСвойПоток(Команда)
ПроверитьСвоеОкно();
Если Не Согласие Тогда
ВызватьИсключение "Нужно явное согласие на захват микрофона и возможную передачу учебной фразы в сервис";
КонецЕсли;
Если СвояПопыткаПотока Или СвояПопыткаГрамматики Тогда
ВызватьИсключение "Сначала остановите и очистите только свой предыдущий опыт";
КонецЕсли;
Итог = "Проверка возможности потока; захват микрофона ещё не начался";
Если Не РаботаСРечью.ПоддерживаетсяПотоковоеРаспознавание() Тогда
ВызватьИсключение "Потоковое распознавание этим клиентом не поддерживается";
КонецЕсли;
Модель = ПолучитьНастоящуюРусскуюМодель();
Параметры = Новый ПараметрыПотоковогоРаспознаванияРечи;
ПроверитьОтсутствиеЗаписи(Параметры);
Параметры.ИспользоватьТолькоДополнительныеГрамматики = Истина;
Параметры.ПолучатьПромежуточныеРезультаты = Истина;
Параметры.ПолучатьВариантыПромежуточныхГипотез = Истина;
СвойКлючГрамматики = "УчебнаяФраза85-" + Строка(Новый УникальныйИдентификатор);
СвойКлючПотока = "УчебныйПоток85-" + Строка(Новый УникальныйИдентификатор);
КлючиДо = ПолучитьНастоящиеКлючиГрамматик();
Если КлючиДо.Найти(СвойКлючГрамматики) <> Неопределено Тогда
ВызватьИсключение "Ключ уже существовал; чужая грамматика не заменяется";
КонецЕсли;
Фразы = Новый Массив;
Фразы.Добавить("выбрать учебную книгу");
Фразы.Добавить("завершить учебный опыт");
СвояПопыткаГрамматики = Истина;
Попытка
РаботаСРечью.УстановитьДополнительнуюГрамматикуСеанса(СвойКлючГрамматики, Фразы);
Если ПолучитьНастоящиеКлючиГрамматик().Найти(СвойКлючГрамматики) = Неопределено Тогда
ВызватьИсключение "Сеанс ещё не подтвердил собственную дополнительную грамматику";
КонецЕсли;
Дополнительные = Параметры.ДополнительныеГрамматики;
Если ТипЗнч(Дополнительные) <> Тип("Массив") Или Дополнительные.Количество() <> 0 Тогда
ВызватьИсключение "Нужна собственная новая пустая коллекция ключей параметров потока";
КонецЕсли;
Дополнительные.Добавить(СвойКлючГрамматики);
Если Дополнительные.Количество() <> 1 Или Дополнительные[0] <> СвойКлючГрамматики Тогда
ВызватьИсключение "Коллекция должна содержать только действительный собственный ключ";
КонецЕсли;
Оповещение = Новый ОписаниеОповещения("СвояГипотезаПолучена", ЭтотОбъект, СвойКлючПотока,
"СвояОшибкаПотока", ЭтотОбъект);
Если Оповещение.ИмяПроцедурыОбработкиОшибки <> "СвояОшибкаПотока"
Или Оповещение.МодульОбработкиОшибки <> ЭтотОбъект Тогда
ВызватьИсключение "Уведомление должно сохранить настоящий обработчик ошибок собственного модуля";
КонецЕсли;
СвойЗапросОстановки = Ложь;
СвоиУведомления = 0;
СвояПопыткаПотока = Истина;
Итог = "Запускается собственный микрофон. Произнесите одну из двух учебных фраз и явно остановите опыт";
РаботаСРечью.НачатьПотоковоеРаспознавание(СвойКлючПотока, Оповещение, Модель,
ВариантИспользованияРасположенияРаботыСРечью.Авто, Параметры);
Исключение
Итог = "Начало собственного опыта не подтверждено. Не запускайте второй поток; используйте ОстановитьСвойОпыт для сохранённых собственных ключей";
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьОтсутствиеЗаписи(Параметры)
Если ТипЗнч(Параметры) <> Тип("ПараметрыПотоковогоРаспознаванияРечи") Тогда
ВызватьИсключение "Нужны только собственные новые параметры потока";
КонецЕсли;
ОбработчикЗаписи = Параметры.ОбработчикОстановкиАудиозаписи;
Если ОбработчикЗаписи = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ОбработчикЗаписи) <> Тип("ОписаниеОповещения") Тогда
ВызватьИсключение "Неизвестная настройка записи аудио; захват запрещён";
КонецЕсли;
Если ЗначениеЗаполнено(ОбработчикЗаписи.ИмяПроцедуры)
Или ОбработчикЗаписи.Модуль <> Неопределено
Или ЗначениеЗаполнено(ОбработчикЗаписи.ИмяПроцедурыОбработкиОшибки)
Или ОбработчикЗаписи.МодульОбработкиОшибки <> Неопределено Тогда
ВызватьИсключение "В собственных новых параметрах уже задана обработка записи; этот опыт её не разрешает";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура СвояГипотезаПолучена(РезультатРаспознавания, ПродолжитьРаспознавание, ДополнительныеПараметры) Экспорт
ПродолжитьРаспознавание = Ложь;
Если Не СвояГотовность Или Не СвояПопыткаПотока
Или ДополнительныеПараметры <> СвойКлючПотока Тогда
Возврат;
КонецЕсли;
Если Не Согласие Или СвойЗапросОстановки Тогда
СвойЗапросОстановки = Истина;
Итог = "Продолжение собственного потока отклонено; нажмите ОстановитьСвойОпыт для адресного завершения и удаления своей грамматики";
Возврат;
КонецЕсли;
Если ТипЗнч(РезультатРаспознавания) <> Тип("РезультатРаспознаванияРечи") Тогда
СвойЗапросОстановки = Истина;
Итог = "Получен не настоящий результат потока; продолжение отклонено";
Возврат;
КонецЕсли;
СвоиУведомления = СвоиУведомления + 1;
Если СвоиУведомления >= 20 Тогда
СвойЗапросОстановки = Истина;
Итог = "Достигнут учебный предел20уведомлений; дальнейшее продолжение отклонено. Явно остановите свой опыт";
Возврат;
КонецЕсли;
Варианты = РезультатРаспознавания.ДанныеФраз;
Если ТипЗнч(Варианты) <> Тип("Массив") Или Варианты.Количество() > 100 Тогда
СвойЗапросОстановки = Истина;
Итог = "Неожиданный массив гипотез; продолжение отклонено";
Возврат;
КонецЕсли;
Если Варианты.Количество() = 0 Тогда
Итог = "Пришло настоящее уведомление без гипотез: " + Строка(СвоиУведомления);
Иначе
Гипотеза = Варианты[0];
Если ТипЗнч(Гипотеза) <> Тип("ДанныеФразыРаспознаванияРечи") Тогда
СвойЗапросОстановки = Истина;
Итог = "В вариантах найден не объект фразы; продолжение отклонено";
Возврат;
КонецЕсли;
Итог = ?(РезультатРаспознавания.РаспознаваниеФразыЗавершено, "Окончательная фраза: ", "Промежуточная гипотеза: ")
+ Гипотеза.Фраза + "; исходная уверенность: " + Строка(Гипотеза.Уверенность)
+ "; вариантов: " + Строка(Варианты.Количество())
+ "; уведомлений: " + Строка(СвоиУведомления);
КонецЕсли;
ПродолжитьРаспознавание = Истина;
КонецПроцедуры
&НаКлиенте
Процедура СвояОшибкаПотока(Ошибка, СтандартнаяОбработка, ДополнительныеПараметры) Экспорт
СтандартнаяОбработка = Истина;
Если Не СвояГотовность Или ДополнительныеПараметры <> СвойКлючПотока Тогда
СтандартнаяОбработка = Ложь;
Возврат;
КонецЕсли;
Если ТипЗнч(Ошибка) <> Тип("ИнформацияОбОшибке") Тогда
Итог = "Обработчик получил неожиданный объект ошибки";
Иначе
Итог = "Ошибка собственного уведомления; стандартная диагностика остаётся включённой. Остановите только собственный опыт";
КонецЕсли;
СвойЗапросОстановки = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ОстановитьСвойОпыт(Команда)
ПроверитьСвоеОкно();
Итог = "Адресное завершение только своего опыта; результат ещё не подтверждён";
Если СвояПопыткаПотока Тогда
Если СвойКлючПотока = "" Тогда
ВызватьИсключение "Без собственного ключа нельзя останавливать поток";
КонецЕсли;
РаботаСРечью.ОстановитьПотоковоеРаспознавание(СвойКлючПотока);
СвояПопыткаПотока = Ложь;
СвойКлючПотока = "";
КонецЕсли;
Если СвояПопыткаГрамматики Тогда
Если СвойКлючГрамматики = "" Тогда
ВызватьИсключение "Без собственного ключа нельзя удалять грамматику";
КонецЕсли;
Если ПолучитьНастоящиеКлючиГрамматик().Найти(СвойКлючГрамматики) <> Неопределено Тогда
РаботаСРечью.УдалитьДополнительнуюГрамматикуСеанса(СвойКлючГрамматики);
КонецЕсли;
Если ПолучитьНастоящиеКлючиГрамматик().Найти(СвойКлючГрамматики) <> Неопределено Тогда
ВызватьИсключение "Удаление своей грамматики ещё не подтверждено";
КонецЕсли;
СвояПопыткаГрамматики = Ложь;
СвойКлючГрамматики = "";
КонецЕсли;
СвойЗапросОстановки = Ложь;
Итог = "Вызов остановки только своего потока завершён, собственная сеансовая грамматика отсутствует. Запись аудио и файл этим окном не создавались";
КонецПроцедуры
&НаКлиенте
Функция ПолучитьНастоящиеКлючиГрамматик()
Ключи = РаботаСРечью.ПолучитьДополнительныеГрамматикиСеанса();
Если ТипЗнч(Ключи) <> Тип("Массив") Тогда
ВызватьИсключение "Нужен настоящий массив ключей сеансовых грамматик";
КонецЕсли;
Для Каждого Ключ Из Ключи Цикл
Если ТипЗнч(Ключ) <> Тип("Строка") Тогда
ВызватьИсключение "Ключ грамматики должен быть строкой";
КонецЕсли;
КонецЦикла;
Возврат Ключи;
КонецФункции
&НаКлиенте
Функция ПолучитьНастоящуюРусскуюМодель()
Модели = РаботаСРечью.ПолучитьОписаниеМоделейРаспознавания();
Если ТипЗнч(Модели) <> Тип("Массив") Тогда
ВызватьИсключение "Нужен настоящий каталог моделей";
КонецЕсли;
Для Каждого Описание Из Модели Цикл
Если ТипЗнч(Описание) <> Тип("ОписаниеМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "В каталоге найден не дескриптор модели";
КонецЕсли;
Если Описание.ДоступнаВЛокальномВарианте Или Описание.ДоступнаВоВнешнемВарианте Тогда
Параметры = Описание.ПолучитьПараметры();
Если ТипЗнч(Параметры) <> Тип("ПараметрыМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Нужны реальные параметры выбранной модели";
КонецЕсли;
Если НРег(Лев(Параметры.КодЯзыка, 2)) = "ru" Тогда
Возврат Параметры;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ВызватьИсключение "Нет доступной модели с настоящим кодом языка, начинающимся на ru";
КонецФункции
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
СтандартнаяОбработка = Истина;
Если СвояПопыткаПотока Или СвояПопыткаГрамматики Тогда
Отказ = Истина;
ТекстПредупреждения = "Сначала остановите только свой поток и удалите свою грамматику кнопкой ОстановитьСвойОпыт";
Если Не ЗавершениеРаботы Тогда
Сообщить(ТекстПредупреждения);
КонецЕсли;
Возврат;
КонецЕсли;
СвояГотовность = Ложь;
КонецПроцедуры
#Иначе
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Отказ = Истина;
ВызватьИсключение "Нужен толстый клиент в режиме управляемого приложения";
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
СтандартнаяОбработка = Истина;
КонецПроцедуры
&НаКлиенте
Процедура НачатьСвойПоток(Команда)
ВызватьИсключение "Этот урок требует толстый клиент управляемого приложения";
КонецПроцедуры
&НаКлиенте
Процедура ОстановитьСвойОпыт(Команда)
ВызватьИсключение "Этот урок требует толстый клиент управляемого приложения";
КонецПроцедуры
#КонецЕслиРазбор по шагам
ПоддерживаетсяПотоковоеРаспознавание проверяет возможность клиента. Истина не означает разрешение микрофона, готовую модель, сеть или действительность аккаунта; все эти условия проверяются отдельно.
Параметры модели получаем от настоящего дескриптора каталога. ПараметрыПотоковогоРаспознаванияРечи создаются своим no-argument конструктором, а не приходят неизвестным входным объектом.
Privacy-проверка читает ОбработчикОстановкиАудиозаписи. Если он отсутствует или в настоящем описании нет настроенных процедур и модулей, запись не настраивается. Ссылка и все readonly-поля уведомления никогда не заменяются и не изменяются.
Три изменяемых Булево включают использование только дополнительных грамматик, промежуточные результаты и варианты промежуточных гипотез. Это действующие параметры, реально передаваемые в НачатьПотоковоеРаспознавание.
Своя грамматика создаётся для сеанса под новым ключом и проверяется через настоящий массив ключей. ДополнительныеГрамматики — readonly-ссылка на собственный массив: добавляется элемент существующей коллекции, новое значение самого свойства не присваивается.
ОписаниеОповещения создаётся конструктором с собственными обработчиком, модулем ЭтотОбъект и ключом потока. Обработчик ошибки задаётся также через конструктор; два readonly-поля проверяют его реальные имя и модуль, не заполняются setter-ом.
Флаги попытки выставляются до соответствующего изменения или старта. При потере ответа свои ключи не забываются и новый поток не запускается. ОстановитьСвойОпыт разрешён после снятия согласия и работает только с этими закрытыми переменными.
Callback по умолчанию выставляет ПродолжитьРаспознавание=Ложь, затем принимает только своё открытое окно и текущий ключ. Действительный результат и безопасные ограничения позволяют вернуть Истина; старые callback не оживляют новый поток.
Флаг РаспознаваниеФразыЗавершено отличает промежуточную гипотезу от окончательной фразы, а не завершает всю сессию. Выводится первая настоящая альтернатива и исходная уверенность; текст никогда не исполняется как команда.
Учебный предел20уведомлений отклоняет дальнейшее продолжение, но не является таймером или доказательством закрытия аудиоустройства. Собственный ключ удерживается до отдельного адресного стопа; при тишине нужен ручной стоп.
Остановка сначала вызывает native stop со своим ключом. Лишь после его успешного возврата очищается владение потоком; затем удаляется только собственная грамматика и реальный getter подтверждает её отсутствие.
Как проверить результат
Без согласия НачатьСвойПоток должен отказаться. ОстановитьСвойОпыт остаётся доступным после снятия согласия и не вызывает stop без ключа.
При неподдерживаемом клиенте, другой версии, чужой базе или отсутствии подходящей фактической модели захват не должен начинаться. Если новый объект неожиданно содержит обработчик записи, privacy-проверка должна запретить старт.
В собственных параметрах коллекция ДополнительныеГрамматики должна содержать один фактически созданный ключ; прямого присваивания readonly-свойства нет. Чужая ранее существовавшая грамматика не заменяется.
При реальном распознавании текст и варианты должны приходить из ответа платформы. Промежуточная строка может меняться; окончательная фраза не должна объявляться завершением всего потока.
Повторное начало до адресной остановки и очистки запрещено. После успешной остановки запоздалый callback со старым ключом отклоняет продолжение и не перезаписывает состояние нового опыта.
После отзыва согласия следующий callback отклоняет продолжение. Для гарантированного намерения немедленно остановить захват пользователь нажимает адресную команду, а не ждёт новой гипотезы.
Проверяйте удаление только собственной грамматики по её фактическому ключу. Не удаляйте весь набор, если сервис или другой пользователь изменил свои записи параллельно.
Ошибка синхронного старта сохраняет владение попыткой для адресной очистки. Наличие настроенного error-handler у уведомления не выдаётся за гарантию доставки всех ошибок потока.
Ожидаемый результат
В собственном ручном опыте интерактивный поток показывает реальные промежуточные и окончательные фразы из своей грамматики; затем адресно остановлен и своя грамматика удалена. Сохранение аудио этим окном не настроено и не выполняется.
На что обратить внимание
Справка разрешает запуск только интерактивно с осведомлённостью пользователя о захвате звука. ПриОткрытии не запускает поток, а Согласие каждый раз сбрасывается в Ложь.
Readonly-ссылка на коллекцию не равна разрешению заменить свойство. Здесь меняется только массив собственной новой конфигурации потока; readonly-обработчик записи и поля уведомлений не мутируются.
Справка не предоставляет документированного setter-а ОбработчикОстановкиАудиозаписи и не показывает соответствующего аргумента конструктора параметров. Этот урок осмысленно проверяет отсутствие записи, а не обещает несуществующий способ её включения.
Авто не гарантирует отсутствие облака: сначала ищет подходящую локальную модель, затем внешнюю. При внешнем потоке грамматики информационной базы недоступны; в уроке используются только собственные ключи грамматики сеанса.
Распознанная фраза не является авторизованной командой пользователя. Код ничего не удаляет, не проводит документы и не исполняет текст; уверенность не трактуется как гарантированный процент.
ПолучатьВариантыПромежуточныхГипотез может увеличить объём результатов. Пределы100вариантов и20уведомлений — собственные учебные ограничения после получения объектов, не лимиты аллокаций платформы и не ограничение длительности тишины.
Оповещение содержит корректно сконструированный обработчик ошибок, но для StartStreaming не обещается, что абсолютно все ошибки будут доставлены по этому пути. Синхронные ошибки остаются исключениями; после любой неопределённости выполняется только адресный стоп собственного ключа.
Управляемое завершение приложения не допускает серверных вызовов и открытие своих окон. ПередЗакрытием здесь лишь сообщает о незавершённом опыте; принудительное завершение ОС может потерять память и ключи.
Локальное отсутствие записи в настройках этого окна не является обещанием о политике хранения аудио стороннего сервиса. Тариф, обработка и хранение облаком должны быть согласованы отдельно до передачи звука.
Этот код не запускался, runtimeVerifiedScenarios=0. Файлы, резервные копии и архивы не создавались; исходники и рабочие базы не изменялись.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.