При разработке интерактивных интерфейсов в 1С:Предприятии часто возникает необходимость звукового сопровождения действий пользователя. Например, это может быть сигнал об успешном сканировании штрихкода, уведомление об ошибке проведения документа или звуковой сигнал при получении нового сообщения в чате. Однако стандартные попытки воспроизвести аудиофайл часто приводят к неприятному эффекту: основной поток клиентского приложения «зависает» на время проигрывания звука, интерфейс перестает реагировать на нажатия клавиш, а пользователь теряет драгоценные секунды.
В этой статье мы подробно разберем, почему возникает блокировка интерфейса, и проанализируем современные и классические способы реализации фонового (неблокирующего) воспроизведения аудио в среде 1С:Предприятие.
Прежде чем перейти к рабочим решениям, выясним причину ограничений платформы. Начинающие разработчики часто пытаются применить два очевидных инструмента:
ПодключитьОбработчикОжидания не решает проблему параллельности. Этот механизм работает в основном (единственном) потоке клиентского приложения. Когда наступает время срабатывания обработчика, платформа прерывает действия пользователя, выполняет процедуру и только после ее завершения возвращает управление интерфейсу. Если внутри процедуры запускается синхронный звук, интерфейс все равно зависнет.Для решения задачи нам необходимы клиентские асинхронные механизмы. Рассмотрим четыре наиболее эффективных способа реализации.
Это один из самых гибких и современных подходов, работающий как в тонком клиенте, так и в веб-клиенте. Начиная с версии 8.3.14, платформа 1С использует современный движок Chromium (WebKit) для рендеринга полей HTML-документов. Это позволяет нам задействовать стандартные возможности HTML5 и JavaScript для асинхронного воспроизведения звука.
Разберем по шагам, как это реализовать:
Строка (например, АдресЗвуковойСтраницы) и вынесем его на форму как Поле HTML документа. Сделаем его невидимым или зададим минимальный размер (1х1 пиксель), чтобы он не мешал пользователю.<audio> и JavaScript-функцией воспроизведения.Рассмотрим пример формирования HTML-кода на сервере и его последующего воспроизведения на клиенте:
&НаСервере
Функция ПолучитьHTMLКодЗвука(ДвоичныеДанныеЗвука)
// Кодируем аудиофайл (wav или mp3) в строку Base64
СтрокаBase64 = ПолучитьBase64СтрокуИзДвоичныхДанных(ДвоичныеДанныеЗвука);
// Формируем HTML с тегом audio и JS-скриптом управления
ТекстHTML =
"<html>
|<head>
| <script type='text/javascript'>
| function playAudio() {
| var player = document.getElementById('audioPlayer');
| if (player) {
| player.currentTime = 0; // Сбрасываем на начало
| player.play();
| }
| }
| </script>
|</head>
|<body style='margin:0; padding:0; overflow:hidden;'>
| <audio id='audioPlayer' style='display:none;'>
| <source src='data:audio/wav;base64," + СтрокаBase64 + "' type='audio/wav'>
| </audio>
|</body>
|</html>";
Возврат ТекстHTML;
КонецФункции
После того как HTML-код загружен в реквизит формы, связанный с Полем HTML документа, мы можем в любой момент асинхронно запустить воспроизведение звука с помощью вызова JavaScript-функции из кода 1С:
&НаКлиенте
Процедура ВоспроизвестиЗвукЧерезHTML()
ДокументHTML = Элементы.ПолеHTMLЗвук.Документ;
Если ДокументHTML <> Неопределено Тогда
// Вызываем JS-функцию playAudio()
ДокументHTML.defaultView.playAudio();
КонецЕсли;
КонецПроцедуры
Поскольку движок Chromium обрабатывает тег <audio> в собственном системном потоке, интерфейс 1С остается полностью отзывчивым. Пользователь может продолжать вводить данные, пока проигрывается аудиофайл.
Если ваши пользователи гарантированно работают на операционной системе Windows в тонком или толстом клиенте, можно обойтись без использования экранных форм и HTML-полей. Windows предоставляет встроенные мультимедийные интерфейсы, доступ к которым легко получить через COM-объекты.
Рассмотрим два наиболее популярных объекта:
А. Использование Speech API (SAPI.SpVoice)
Этот системный объект обычно используется для синтеза речи, но он также умеет воспроизводить аудиопотоки асинхронно. Проанализируем пример кода:
&НаКлиенте
Процедура ПроигратьЧерезSAPI(ПутьКФайлу)
Попытка
Голос = Новый COMОбъект("SAPI.SpVoice");
ПотокФайла = Новый COMОбъект("SAPI.SpFileStream");
// Открываем аудиофайл (поддерживается формат WAV)
ПотокФайла.Open(ПутьКФайлу);
// Флаг 1 (SVSFlagsAsync) указывает воспроизводить звук асинхронно
Голос.SpeakStream(ПотокФайла, 1);
Исключение
// Обработка ошибки инициализации COM-объекта
ЗаписьЖурналаРегистрации("Озвучивание", СистемнаяИнформацияПошлин.Ошибка, , , ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Б. Использование проигрывателя Windows Media (WMPlayer.OCX)
Этот способ позволяет проигрывать файлы более широкого спектра форматов (включая MP3) в фоновом режиме:
&НаКлиенте
Процедура ПроигратьЧерезWMP(ПутьКФайлу)
Попытка
Плеер = Новый COMОбъект("WMPlayer.OCX");
Плеер.URL = ПутьКФайлу;
// Запуск воспроизведения происходит автоматически при установке URL
Плеер.controls.play();
Исключение
Сообщить("Не удалось запустить системный проигрыватель: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Важное ограничение: Использование COM-объектов абсолютно несовместимо с операционными системами Linux, macOS и не поддерживается при работе через веб-браузер.
В старых версиях платформы запуск внешнего приложения блокировал поток выполнения. С появлением в платформе 8.3.18 новых механизмов асинхронности (конструкции Асинх / Ждать) у разработчиков появилась возможность эффективно управлять внешними процессами операционной системы.
Для реализации этого метода можно использовать стороннюю легковесную консольную утилиту воспроизведения звука (например, популярную микро-утилиту cmdmp3.exe для Windows или стандартный aplay для Linux).
Разберем пример кода асинхронного вызова внешнего плеера:
&НаКлиенте
Асинх Процедура ВоспроизвестиФайлАсинхронно(ПутьКУтилите, ПутьКЗвуку)
ПараметрыЗапуска = """" + ПутьКЗвуку + """";
Попытка
// Метод выполняет запуск приложения в отдельном процессе ОС без ожидания его завершения
Ожидать ЗапуститьСистемноеПриложениеАсинх(ПутьКУтилите, ПараметрыЗапуска);
Исключение
ЗаписатьЛогОшибки(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Этот способ позволяет полностью изолировать процесс воспроизведения звука от процесса 1С. Однако он требует наличия внешних исполняемых файлов на диске клиента и правильной настройки путей доступа к ним.
Для создания максимально надежного, быстрого и профессионального решения разработчики прибегают к созданию собственных или использованию готовых внешних компонент (ВК), написанных на C++ или C# с использованием технологии Native API.
Принцип работы внешней компоненты следующий:
PlaySound в Windows или системный вызов библиотеки ALSA в ОС Linux).Такой подход гарантирует нулевую задержку интерфейса 1С и позволяет гибко управлять воспроизведением (например, регулировать громкость, ставить на паузу или мгновенно прерывать проигрывание при возникновении определенных событий).
Выбор конкретного метода зависит от архитектуры вашей информационной системы: