При работе с мультимедийными данными в 1С часто возникает задача автоматического анализа видеофайлов. Типичная ситуация: в каталоге хранятся видеоуроки или записи вебинаров, и нам необходимо вывести в отчет их точную продолжительность. Проблема заключается в том, что размер файла (в мегабайтах) далеко не всегда пропорционален его длительности. Два файла одинакового объема могут иметь разницу в хронометраже в несколько раз из-за разного битрейта и алгоритмов сжатия.
В этой статье мы подробно разберем, как решить эту задачу, рассмотрим различные методы получения метаданных и проанализируем, почему стандартные средства ОС иногда могут выдавать неожиданные результаты.
Самый простой и доступный способ для систем под управлением Windows — это обращение к Shell.Application. Этот метод позволяет получить доступ к свойствам файла, которые мы обычно видим в проводнике (правой кнопкой мыши — «Свойства» — «Подробно»). Рассмотрим, как реализовать этот подход в коде 1С.
Для начала проанализируем структуру процедуры, которая перебирает файлы в каталоге и выводит их данные в табличный документ. Основная логика заключается в использовании функции ПолучитьСведенияОФайле, которая обращается к системным объектам Windows.
&НаСервере
Процедура ВыводНазванияФайловНаСервере()
МассивФайловКаталога = НайтиФайлы(ПутьККаталогу, "*.mp4");
// Подготовка макета
ПолучаемыйОбъект = РеквизитФормыВЗначение("Отчет");
МакетНазванияФайлов = ПолучаемыйОбъект.ПолучитьМакет("МакетНазванияФайлов");
ТДВыводПечати.Очистить();
ОбластьШапка = МакетНазванияФайлов.ПолучитьОбласть("Шапка");
ТДВыводПечати.Вывести(ОбластьШапка);
ОбластьСтроки = МакетНазванияФайлов.ПолучитьОбласть("Строки");
Ном = 1;
Для каждого ЭлементМассива Из МассивФайловКаталога Цикл
// Получаем структуру со свойствами "Продолжительность" и "Размер"
ПолученныеСведения = ПолучитьСведенияОФайле(ЭлементМассива.ПолноеИмя, "Продолжительность;Размер");
ОбластьСтроки.Параметры.Ном = Ном;
ОбластьСтроки.Параметры.НазваниеУрока = ЭлементМассива.ИмяБезРасширения;
// Извлекаем значение продолжительности из Соответствия
ОбластьСтроки.Параметры.Продолжительность = ПолученныеСведения.Получить("Продолжительность");
ОбластьСтроки.Параметры.Размер = ПолученныеСведения.Получить("Размер");
ТДВыводПечати.Вывести(ОбластьСтроки);
Ном = Ном + 1;
КонецЦикла;
КонецПроцедуры
Сама функция ПолучитьСведенияОФайле внутри использует COM-объект Shell.Application. Важно понимать, что в разных версиях Windows индексы свойств могут отличаться. Например, свойство «Продолжительность» может иметь индекс 21 или 27. Чтобы код был универсальным, профессиональные разработчики обычно сначала перебирают все заголовки свойств в цикле, находят индекс по имени «Продолжительность» (или «Duration» для англоязычных ОС), а затем получают значение по этому индексу.
Плюсы метода:
Если нам нужна высокая точность или кроссплатформенность (например, если сервер 1С работает под управлением Linux), использование Shell-объектов Windows не подойдет. В этом случае на помощь приходит ffprobe — консольная утилита для анализа медиаконтента.
Рассмотрим, как можно автоматизировать получение данных через ffprobe в 1С. Мы можем запустить внешнее приложение, перенаправить его вывод в файл или прочитать напрямую из потока. Проанализируем пример команды для получения длительности в секундах:
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input_file.mp4
В 1С это реализуется через ЗапуститьПриложение. Разберем пример кода, который возвращает результат во временный файл:
Функция ПолучитьДлительностьЧерезFFProbe(ПутьКФайлу)
ИмяВыходногоФайла = ПолучитьИмяВременногоФайла("txt");
Команда = "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 """ + ПутьКФайлу + """ > """ + ИмяВыходногоФайла + """";
// Запускаем и ждем завершения
ЗапуститьПриложение(Команда, , Истина);
Чтение = Новый ЧтениеТекста(ИмяВыходногоФайла);
РезультатСекунды = Чтение.ПрочитатьСтроку();
Чтение.Закрыть();
УдалитьФайлы(ИмяВыходногоФайла);
Возврат Число(РезультатСекунды);
КонецФункции
Этот метод гораздо надежнее, так как он анализирует структуру самого видеопотока, а не просто считывает метаданные из заголовка файла, которые могут быть повреждены или отсутствовать.
Разберем техническую причину, по которой автор вопроса заметил несоответствие размера и продолжительности. Это связано с понятием битрейта. Видео — это поток данных, передаваемых в единицу времени.
Проанализируем основные факторы:
При внедрении системы учета видеофайлов в 1С, рекомендуем придерживаться следующих правил:
1. Кэширование данных: Чтение свойств файла — операция ресурсоемкая (особенно по сети). Если вы один раз получили длительность видео, сохраните её в реквизит справочника или регистр сведений. Не стоит вычислять её каждый раз при открытии формы.
2. Обработка ошибок: Всегда проверяйте существование файла перед попыткой получить его свойства. Используйте конструкцию Попытка...Исключение, так как COM-объекты или внешние утилиты могут вернуть ошибку при доступе к занятому файлу.
3. Формат времени: Помните, что Windows Shell возвращает строку вида "00:05:23", а ffprobe возвращает число секунд (например, "323.45"). Выясним заранее, в каком виде вам удобнее хранить данные. Для расчетов (например, суммирования общего времени курса) лучше использовать секунды (тип Число).
В заключение отметим, что для простых офисных задач вполне достаточно метода с Shell.Application, но если вы строите профессиональную систему управления медиа-контентом, лучше смотреть в сторону FFmpeg или специализированных внешних компонент.