При автоматизации рабочих мест на складе или производстве часто возникает необходимость звукового оповещения пользователя: успешное сканирование штрихкода, ошибка проверки, предупреждение о расхождении. В платформе 1С:Предприятие нет прямого универсального метода вроде ВоспроизвестиЗвук() для тонкого клиента настольных операционных систем. Одним из распространенных способов решения этой задачи является использование элемента формы Поле HTML-документа, в котором запускается аудио через тег <audio> или JavaScript.
Однако на практике разработчики часто сталкиваются с ситуацией, когда код написан без синтаксических ошибок, но звук не проигрывается. Разберем по шагам, почему возникает эта проблема, как правильно настроить HTML-плеер и какие существуют альтернативные способы воспроизведения аудиосигналов.
Выясним основные причины, из-за которых встроенный браузер платформы может блокировать воспроизведение аудио:
Поле HTML-документа, но у элемента установлено свойство Видимость = Ложь (или элемент свернут до нулевых размеров), встроенный браузерный движок оптимизирует ресурсы и полностью приостанавливает выполнение медиа-контента. Элемент обязательно должен иметь Видимость = Истина.<source> указан тип audio/mpeg (или наоборот), плеер не сможет декодировать поток. Для файлов MP3 следует использовать audio/mpeg, а для WAV — audio/wav.Base64Строка() разбивает результат на строки символами перевода строки через каждые 72 символа. Разрывы внутри Data URI (data:audio/mp3;base64,...) часто приводят к тому, что браузер считает ссылку поврежденной. Рекомендуется использовать функцию ПолучитьBase64СтрокуИзДвоичныхДанных(), которая формирует непрерывный поток данных.Рассмотрим правильную реализацию механизма на управляемой форме. Добавим реквизит формы АудиоПлеерHTML с типом Строка и свяжем его с элементом формы Поле HTML-документа. Зададим элементу минимальные размеры (например, высоту 1), но оставим свойство Видимость = Истина.
Разберем код модуля управляемой формы:
&НаСервере
Функция ПолучитьЗвуковыеДанныеВBase64()
Результат = Новый Структура;
// Получаем двоичные данные из общих макетов
ДД_Успех = ПолучитьОбщийМакет("ЗвукУспеха");
ДД_Ошибка = ПолучитьОбщийМакет("ЗвукОшибки");
// Формируем непрерывные строки Base64 без переводов строк
Результат.Вставить("Успех", ПолучитьBase64СтрокуИзДвоичныхДанных(ДД_Успех));
Результат.Вставить("Ошибка", ПолучитьBase64СтрокуИзДвоичныхДанных(ДД_Ошибка));
Возврат Результат;
КонецФункции
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЗвуковыеСемплы = ПолучитьЗвуковыеДанныеВBase64();
ЗвукУспехаBase64 = ЗвуковыеСемплы.Успех;
ЗвукОшибкиBase64 = ЗвуковыеСемплы.Ошибка;
КонецПроцедуры
&НаКлиенте
Процедура ВоспроизвестиЗвуковойСигнал(ТипСигнала = "Успех")
СтрокаBase64 = ?(ТипСигнала = "Успех", ЗвукУспехаBase64, ЗвукОшибкиBase64);
МеткаВремени = Формат(ТекущаяУниверсальнаяДатаВМиллисекундах(), "ЧГ=0");
// Генерируем разметку с уникальным комментарием для принудительного обновления
АудиоПлеерHTML =
"<!DOCTYPE html>
|<html>
|<head><meta charset='utf-8'></head>
|<body style='margin:0; padding:0; background:transparent;'>
| <!-- " + МеткаВремени + " -->
| <audio autoplay='autoplay'>
| <source src='data:audio/mpeg;base64," + СтрокаBase64 + "' type='audio/mpeg'>
| </audio>
|</body>
|</html>";
КонецПроцедуры
Если задача выполняется исключительно на клиентах под управлением ОС Windows, и требуется расширенное управление звуком (например, регулировка стереобаланса по каналам для двух независимых рабочих мест), рассмотрим использование штатного компонента WMPlayer.OCX:
&НаКлиенте
Процедура ВоспроизвестиЧерезWMPlayer(ПутьКФайлу, Канал = "Центр")
Попытка
Плеер = Новый COMОбъект("WMPlayer.OCX");
// Настройка баланса: -100 (только левый канал), 100 (только правый канал), 0 (стереоцентр)
Если Канал = "Левый" Тогда
Плеер.settings.balance = -100;
ИначеЕсли Канал = "Правый" Тогда
Плеер.settings.balance = 100;
Иначе
Плеер.settings.balance = 0;
КонецЕсли;
Плеер.URL = ПутьКФайлу;
Плеер.controls.play();
Исключение
Сообщить("Не удалось инициализировать медиаплеер: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
В случаях, когда использование встроенного браузера нежелательно из-за потребления памяти, а COM-объекты заблокированы политиками безопасности, можно применить метод ЗапуститьПриложение(). Для этого используется внешняя легковесная консольная утилита или плеер с поддержкой фонового запуска.
Посмотрим на пример запуска через плеер командной строки:
&НаКлиенте
Процедура ЗапуститьВнешнийПлеер(ПутьКФайлуЗвука)
ПутьКПлееру = """C:\Program Files\MPC-HC\mpc-hc64.exe""";
ПутьКФайлу = """" + ПутьКФайлуЗвука + """";
// Ключи запуска:
// /minimized - запуск в минимизированном окне
// /nofocus - не перехватывать фокус ввода у 1С
// /play - начать воспроизведение
// /close - закрыть процесс после завершения звука
СтрокаКоманды = ПутьКПлееру + " " + ПутьКФайлу + " /minimized /play /close /nofocus";
ЗапуститьПриложение(СтрокаКоманды);
КонецПроцедуры
Если конфигурация разрабатывается под мобильный клиент или мобильное приложение (например, для ТСД под управлением Android), обращаться к HTML-полю или внешним утилитам не требуется. В платформе предусмотрен штатный объект СредстваМультимедиа:
// Воспроизведение заранее подготовленного аудиофайла
СредстваМультимедиа.ВоспроизвестиАудио(ПутьКАудиофайлу);
// Синтез голосового оповещения
СредстваМультимедиа.ВоспроизвестиТекст("Товар успешно добавлен");
Проанализируем плюсы и минусы рассмотренных подходов: