Вопрос или проблема
Я использую FFmpeg для создания HLS потоков из RTSP камер. Мне нужно знать точную продолжительность каждого сегмента, не используя ffprobe (слишком медленно) или парсинг m3u8 плейлистов (слишком ресурсоемко). Вот моя текущая команда FFmpeg:
ffmpeg -rtsp_transport tcp -i "rtsp://camera:554/stream" \
-c copy -an -f hls \
-hls_allow_cache 0 \
-hls_flags omit_endlist \
-hls_start_number_source epoch \
-hls_time 10 \
-hls_list_size 3 \
-strftime 1 \
-hls_segment_type mpegts \
-hls_base_url /stream/camera/full/ \
-method PUT \
http://localhost:5000/api/livestream/camera/full/index.m3u8
Что мне нужно, это либо:
Включить точную продолжительность сегмента в имя файла (например, 20240319143022_10.234.ts)
Или включить продолжительность в заголовки/метаданные сегментов, которые можно быстро прочитать
Я пробовал:
- Использовать ffprobe (слишком медленно)
- Парсить m3u8 плейлисты (ресурсоемко)
- Использовать фиксированную продолжительность из -hls_time (недостаточно точно)
Существует ли способ заставить FFmpeg записывать точную продолжительность сегмента либо в имя файла, либо в легко доступные метаданные?
Ответ или решение
Для правильного использования FFmpeg при создании HLS потоков из RTSP камер с точным указанием продолжительности каждого сегмента, предлагаю подробный подход, который минимизирует задержки и использование ресурсов. Исходя из вашего запроса, существует возможность управлять форматом сегментов или метаданных, чтобы сохранить длительность в виде, удобном для чтения.
Решение: Указание продолжительности сегмента в имени файла
Альтернативный подход к вашему текущему использованию FFmpeg заключается в добавлении информации о длительности в самом имени файла. Это можно реализовать с помощью шаблонов именования и применения FFmpeg к дополнительной фильтрации.
К сожалению, сами по себе ffmpeg
и hls_time
не обеспечивают автоматического включения точных значений продолжительности, поскольку имя файла формируется на основе заданных вами параметров без учета изменений в длительности сегмента. Однако, мы можем интегрировать статус длительности в саму строку с помощью применения пользовательских скриптов.
-
Использование скриптов для динамической генерации имен файлов. Вы можете создать промежуточный скрипт на основе Python или Shell, который будет отслеживать сегменты и вычислять их длительность. Для управления полученными данными используйте:
ffmpeg -i "rtsp://camera:554/stream" -c copy -f hls -hls_time 10 live.m3u8 -hls_segment_filename "segment_%03d_%d.ts"
После этого скрипт будет добавлять длительность к имени сегмента, переименовывая файлы на основе их реальной длительности.
Включение продолжительности в заголовки или метаданные
Также можно попробовать вывести информацию о длительности сегмента непосредственно в метаданные источника, но это потребует первого выполнения FFmpeg с некоторыми параметрами.
-
Изменение параметров для добавления метаданных. Вы можете включать пользовательские метаданные, хотя точность может варьироваться. Примените следующий модификатор:
-metadata duration="10.234"
Убедитесь, что вы обновляете значение вручную в зависимости от сегмента, или создайте скрипт, который будет автоматизировать этот процесс.
-
Использование дополнительных функций контейнера MPEG-TS. MPEG-TS сам по себе не поддерживает сложные метаданные, однако, обрамление Audio/Video элементами, такими как PMT, могут включать определенную информацию, включая временные метки.
Резюме
Для получения точной продолжительности сегментов в HLS с использованием FFmpeg можно использовать метод динамического изменения имени файла на основе информации от потоков или метаданных. Внедряя скрипты для автоматизации этого процесса, вы значительно снижаете затраты на ресурсы, избегая постоянного анализа файлов через ffprobe
или тяжелых запросов к m3u8 плейлистам.
Если вам нужно дальнейшее расширение этой логики или помощь в разработке соответствующего скрипта, пожалуйста, дайте знать.