Настраиваем потоковую передачу мультимедиа с использованием утилиты ffmpeg и протокола HLS в контейнере Docker


устанавливаем Docker Engine - Community и Docker Compose, как рассказывается в этой статье

создаем файл /etc/docker/hls/docker-compose.yml

version: '3.8'

networks:
  default:
    ipam:
      config:
        - subnet: 192.168.199.0/24

services:
  hls:
    build:
      context: .
    container_name: hls
    volumes:
      - /var/lib/video:/video
    tmpfs:
      - /usr/local/apache2/htdocs
    networks:
      - default
    ports:
      - 80:80
    environment:
      - URL_PREFIX=http://hls.domain.lan
      - PLAYLIST_NAME=playlist
      - SEGMENT_LENGTH=10
      - SEGMENT_COUNT=30
    restart: always

создаем файл /etc/docker/hls/dockerfile

FROM httpd:bullseye

RUN \
apt-get update && \
apt-get install ffmpeg supervisor -y && \
rm -R /usr/local/apache2/htdocs/*

COPY stream-udp stream-hls /usr/local/sbin/
COPY supervisor-httpd.conf supervisor-stream-udp.conf supervisor-stream-hls.conf /etc/supervisor/conf.d/

ENTRYPOINT /usr/bin/supervisord -n

создаем файл /etc/docker/hls/stream-udp

#!/bin/bash

while true
do
    IFS=$'\n'
    files=($(find /video -maxdepth 1 -type f))
    if [ "${#files[@]}" -gt "0" ]; then
        index=$(shuf -i 0-$((${#files[@]}-1)) -n 1)
        ffmpeg -re -i "${files[$index]}" -vcodec copy -acodec copy -f mpegts udp://127.0.0.1:51386
    else
        sleep 60s
    fi
done

создаем файл /etc/docker/hls/stream-hls

#!/bin/bash

format="%${#SEGMENT_COUNT}d"
destination=/usr/local/apache2/htdocs

ffmpeg \
    -i udp://127.0.0.1:51386 \
    -vcodec copy \
    -acodec copy \
    -f ssegment \
    -segment_list_flags +live \
    -segment_time $SEGMENT_LENGTH \
    -segment_list_entry_prefix $URL_PREFIX/ \
    -segment_list_size $SEGMENT_COUNT \
    -segment_wrap $SEGMENT_COUNT \
    -segment_list "$destination/$PLAYLIST_NAME.m3u8" "$destination/$PLAYLIST_NAME$format.ts"

создаем файл /etc/docker/hls/supervisor-httpd.conf

[program:httpd]
command=httpd-foreground
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor-httpd.out
stderr_logfile=/var/log/supervisor-httpd.err

создаем файл /etc/docker/hls/supervisor-stream-udp.conf

[program:stream-udp]
command=/usr/local/sbin/stream-udp
autostart=true
autorestart=true
stdout_logfile=none
stderr_logfile=none

создаем файл /etc/docker/hls/supervisor-stream-hls.conf

[program:stream-hls]
command=/usr/local/sbin/stream-hls
autostart=true
autorestart=true
stdout_logfile=none
stderr_logfile=none

собираем образ, создаем и запускам контейнер

docker-compose -f /etc/docker/hls/docker-compose.yml up -d

открываем в медиапроигрывателе (например, в SMPlayer) ссылку http://hls.domain.lan/playlist.m3u8

У этой записи 7 комментариев

  1. Игорь

    Добрый день
    Как сделать трансляцию если в папке 2 файла?
    у меня при открытии playlist.m3u8 открывается файл который добавлен последним

    1. Alexander

      Здравствуйте. Имеется ввиду исходных файлов для трансляции всего 2? Должно одинаково работать внезависимости от количества файлов. Проверьте, генерируются ли файлы сегментов

      1. Игорь

        Как мне после обработки положить плейлисты в отдельную папку с оригинальным названием? Файлы сегментов генерируются. Спасибо за ответ

  2. Игорь

    Грубо говоря, у меня в папке на диске есть собранные m3u8 стримы, как мне передать их в index файл чтобы они стримились, и отображались полностью, сейчас я вижу только фалы с именами playlist.m3u8 playlist00.ts playlist01.ts и т.д.

    1. Alexander

      Скрипт stream-udp в цикле случайно выбирает файлы из указанной папки и перенаправляет видео/аудио потоки через UDP на loopback-интерфейс. Если в папке вместо медиафайла будет плейлист, то в принципе тоже должно работать (возможно, нужны будут допольнительные параметры при запуске ffmpeg). Что из себя представляет плейлист?

  3. Игорь

    В данный момент у меня по адресу http://local_address виден следующий список файлов
    Index of /
    playlist.m3u8
    playlist00.ts
    playlist01.ts
    ...
    playlist29.ts

    Как разбить поток по файлам которые лежат в исходной папке с видео файлами *.mpeg?
    Например чтобы вместо playlist.m3u8, playlist00.tsгенерировался индекс по имени файла наспример file1.m3u8, file001.ts...... и file2.m3u8, file201..... как мне изменить исходники чтобы получился индекс на странице index of/ в таком виде.
    Спасибо Александр за скорый ответ.

    1. Alexander

      Контейнер транслирует все файлы случайно в одном потоке. Если нужено параллельно несколько файлов транслировать, то нужно запускть несколько контейнеров

Добавить комментарий