Как программно определить длительность видеофайлов в 1С

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

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

В этой статье мы подробно разберем, как решить эту задачу, рассмотрим различные методы получения метаданных и проанализируем, почему стандартные средства ОС иногда могут выдавать неожиданные результаты.

Метод 1: Использование Windows Shell (через COM-объект)

Самый простой и доступный способ для систем под управлением Windows — это обращение к Shell.Application. Этот метод позволяет получить доступ к свойствам файла, которые мы обычно видим в проводнике (правой кнопкой мыши — «Свойства» — «Подробно»). Рассмотрим, как реализовать этот подход в коде 1С.

Для начала проанализируем структуру процедуры, которая перебирает файлы в каталоге и выводит их данные в табличный документ. Основная логика заключается в использовании функции ПолучитьСведенияОФайле, которая обращается к системным объектам Windows.


&НаСервере
Процедура ВыводНазванияФайловНаСервере()
    МассивФайловКаталога = НайтиФайлы(ПутьККаталогу, "*.mp4");
    
    // Подготовка макета
    ПолучаемыйОбъект = РеквизитФормыВЗначение("Отчет");
    МакетНазванияФайлов = ПолучаемыйОбъект.ПолучитьМакет("МакетНазванияФайлов");
    ТДВыводПечати.Очистить();
    
    ОбластьШапка = МакетНазванияФайлов.ПолучитьОбласть("Шапка");
    ТДВыводПечати.Вывести(ОбластьШапка);
    ОбластьСтроки = МакетНазванияФайлов.ПолучитьОбласть("Строки");
    Ном = 1;

    Для каждого ЭлементМассива Из МассивФайловКаталога Цикл
        // Получаем структуру со свойствами "Продолжительность" и "Размер"
        ПолученныеСведения = ПолучитьСведенияОФайле(ЭлементМассива.ПолноеИмя, "Продолжительность;Размер");
        
        ОбластьСтроки.Параметры.Ном = Ном; 
        ОбластьСтроки.Параметры.НазваниеУрока = ЭлементМассива.ИмяБезРасширения;
        
        // Извлекаем значение продолжительности из Соответствия
        ОбластьСтроки.Параметры.Продолжительность = ПолученныеСведения.Получить("Продолжительность");
        ОбластьСтроки.Параметры.Размер = ПолученныеСведения.Получить("Размер");
        
        ТДВыводПечати.Вывести(ОбластьСтроки);
        Ном = Ном + 1;
    КонецЦикла;
КонецПроцедуры

Сама функция ПолучитьСведенияОФайле внутри использует COM-объект Shell.Application. Важно понимать, что в разных версиях Windows индексы свойств могут отличаться. Например, свойство «Продолжительность» может иметь индекс 21 или 27. Чтобы код был универсальным, профессиональные разработчики обычно сначала перебирают все заголовки свойств в цикле, находят индекс по имени «Продолжительность» (или «Duration» для англоязычных ОС), а затем получают значение по этому индексу.

Плюсы метода:

  1. Не требует установки стороннего программного обеспечения.
  2. Работает достаточно быстро на небольших объемах данных.
  3. Возвращает данные в привычном формате (ЧЧ:ММ:СС).

Метод 2: Использование ffprobe (часть пакета FFmpeg)

Если нам нужна высокая точность или кроссплатформенность (например, если сервер 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 или специализированных внешних компонент.

← На главную