Настраиваем потоковую передачу мультимедиа с использованием утилиты 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
Добрый день
Как сделать трансляцию если в папке 2 файла?
у меня при открытии playlist.m3u8 открывается файл который добавлен последним
Здравствуйте. Имеется ввиду исходных файлов для трансляции всего 2? Должно одинаково работать внезависимости от количества файлов. Проверьте, генерируются ли файлы сегментов
Как мне после обработки положить плейлисты в отдельную папку с оригинальным названием? Файлы сегментов генерируются. Спасибо за ответ
Грубо говоря, у меня в папке на диске есть собранные m3u8 стримы, как мне передать их в index файл чтобы они стримились, и отображались полностью, сейчас я вижу только фалы с именами playlist.m3u8 playlist00.ts playlist01.ts и т.д.
Скрипт stream-udp в цикле случайно выбирает файлы из указанной папки и перенаправляет видео/аудио потоки через UDP на loopback-интерфейс. Если в папке вместо медиафайла будет плейлист, то в принципе тоже должно работать (возможно, нужны будут допольнительные параметры при запуске ffmpeg). Что из себя представляет плейлист?
В данный момент у меня по адресу 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/ в таком виде.
Спасибо Александр за скорый ответ.
Контейнер транслирует все файлы случайно в одном потоке. Если нужено параллельно несколько файлов транслировать, то нужно запускть несколько контейнеров