Как запустить воспроизведение звука в 1С в фоновом режиме без блокировки интерфейса?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интерактивных интерфейсов в 1С:Предприятии часто возникает необходимость звукового сопровождения действий пользователя. Например, это может быть сигнал об успешном сканировании штрихкода, уведомление об ошибке проведения документа или звуковой сигнал при получении нового сообщения в чате. Однако стандартные попытки воспроизвести аудиофайл часто приводят к неприятному эффекту: основной поток клиентского приложения «зависает» на время проигрывания звука, интерфейс перестает реагировать на нажатия клавиш, а пользователь теряет драгоценные секунды.

В этой статье мы подробно разберем, почему возникает блокировка интерфейса, и проанализируем современные и классические способы реализации фонового (неблокирующего) воспроизведения аудио в среде 1С:Предприятие.

Почему стандартные методы и фоновые задания не подходят?

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

  1. Обработчик ожидания: Подключение обработчика ожидания через команду ПодключитьОбработчикОжидания не решает проблему параллельности. Этот механизм работает в основном (единственном) потоке клиентского приложения. Когда наступает время срабатывания обработчика, платформа прерывает действия пользователя, выполняет процедуру и только после ее завершения возвращает управление интерфейсу. Если внутри процедуры запускается синхронный звук, интерфейс все равно зависнет.
  2. Фоновые задания: Этот механизм действительно предназначен для параллельных вычислений, но он выполняется строго на сервере 1С. Серверная часть платформы физически не имеет доступа к звуковой карте и аудиосистеме клиентского компьютера (или терминального сеанса). Запуск аудио на сервере либо вызовет ошибку, либо звук проиграется на сервере (в серверной стойке), что не имеет практического смысла для конечного пользователя.

Для решения задачи нам необходимы клиентские асинхронные механизмы. Рассмотрим четыре наиболее эффективных способа реализации.

Способ 1. Воспроизведение через Поле HTML документа (Кроссплатформенный метод)

Это один из самых гибких и современных подходов, работающий как в тонком клиенте, так и в веб-клиенте. Начиная с версии 8.3.14, платформа 1С использует современный движок Chromium (WebKit) для рендеринга полей HTML-документов. Это позволяет нам задействовать стандартные возможности HTML5 и JavaScript для асинхронного воспроизведения звука.

Разберем по шагам, как это реализовать:

  1. Добавим на управляемую форму реквизит с типом Строка (например, АдресЗвуковойСтраницы) и вынесем его на форму как Поле HTML документа. Сделаем его невидимым или зададим минимальный размер (1х1 пиксель), чтобы он не мешал пользователю.
  2. Для обхода ограничений безопасности современных браузеров (политика Autoplay Policy, которая запрещает автоматический запуск аудио без взаимодействия с документом) мы закодируем наш аудиофайл в строку Base64 и встроим его непосредственно в HTML-код страницы.
  3. Подготовим HTML-шаблон с тегом <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С остается полностью отзывчивым. Пользователь может продолжать вводить данные, пока проигрывается аудиофайл.

Способ 2. Использование системных COM-объектов Windows

Если ваши пользователи гарантированно работают на операционной системе 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 и не поддерживается при работе через веб-браузер.

Способ 3. Асинхронный запуск внешних утилит (Платформа 8.3.18+)

В старых версиях платформы запуск внешнего приложения блокировал поток выполнения. С появлением в платформе 8.3.18 новых механизмов асинхронности (конструкции Асинх / Ждать) у разработчиков появилась возможность эффективно управлять внешними процессами операционной системы.

Для реализации этого метода можно использовать стороннюю легковесную консольную утилиту воспроизведения звука (например, популярную микро-утилиту cmdmp3.exe для Windows или стандартный aplay для Linux).

Разберем пример кода асинхронного вызова внешнего плеера:


&НаКлиенте
Асинх Процедура ВоспроизвестиФайлАсинхронно(ПутьКУтилите, ПутьКЗвуку)
    
    ПараметрыЗапуска = """" + ПутьКЗвуку + """";
    
    Попытка
        // Метод выполняет запуск приложения в отдельном процессе ОС без ожидания его завершения
        Ожидать ЗапуститьСистемноеПриложениеАсинх(ПутьКУтилите, ПараметрыЗапуска);
    Исключение
        ЗаписатьЛогОшибки(ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Этот способ позволяет полностью изолировать процесс воспроизведения звука от процесса 1С. Однако он требует наличия внешних исполняемых файлов на диске клиента и правильной настройки путей доступа к ним.

Способ 4. Использование внешних компонент (Native API)

Для создания максимально надежного, быстрого и профессионального решения разработчики прибегают к созданию собственных или использованию готовых внешних компонент (ВК), написанных на C++ или C# с использованием технологии Native API.

Принцип работы внешней компоненты следующий:

  1. 1С передает компоненте путь к звуковому файлу или двоичные данные звука.
  2. Внутри кода компоненты создается полностью независимый от 1С поток операционной системы (системный thread).
  3. Внутри этого фонового потока вызываются низкоуровневые API операционной системы (например, функция PlaySound в Windows или системный вызов библиотеки ALSA в ОС Linux).
  4. Компонента мгновенно возвращает управление в 1С, продолжая воспроизводить звук в параллельном потоке на уровне ядра ОС.

Такой подход гарантирует нулевую задержку интерфейса 1С и позволяет гибко управлять воспроизведением (например, регулировать громкость, ставить на паузу или мгновенно прерывать проигрывание при возникновении определенных событий).

Резюме и рекомендации

Выбор конкретного метода зависит от архитектуры вашей информационной системы:

← На главную