Обычно серверы по требованию или прямой трансляции используют модуль nginx-rtmp в качестве сервера, а затем используют ffmpeg или obs для отправки потока. Клиент использует протоколы rtmp, http-flv, hls или Dash для получения перекодированных данных и воспроизведения. это.
В Интернете существует множество методов компиляции nginx+nginx-rtmp-module, но доступных методов компиляции openresy+nginx-rtmp-module мало. Эта статья начинается с компиляции модулей и описывает, как создавать серверы по требованию и прямые трансляции.
Сначала загрузите исходный код openresty: https://github.com/openresty/openresty, если вы компилируете только nginx-rtmp-module, вы можете скачать https://github.com/arut/nginx-rtmp-module. Если вы хотите дополнительно поддерживать протокол http-flv, вы можете скачать https://github.com/winshining/nginx-http-flv-module.git, последний включает первый.
Затем компилируем openresty
cd openresty/openresty-1.25.3.1
./configure --add-module=../../nginx-http-flv-module
Затем
make
sudo make install
Компиляция завершена, но в ходе практики возникли следующие проблемы, которыми стоит поделиться:
openresty/openresty-1.25.3.1/../../nginx-http-flv-module/hls/ngx_rtmp_hls_module.c:2059:27: error: use of undeclared identifier 'NGX_RTMP_FRAME_IDR'
frame.key = (ftype == NGX_RTMP_FRAME_IDR);
^
10 errors generated.
make[2]: *** [objs/addon/hls/ngx_rtmp_hls_module.o] Error 1
make[1]: *** [build] Error 2
make: *** [all] Error 2
Причина проблемы в том, что у нас неправильная конфигурация. Модуль nginx-http-flv-module содержит функции модуля nginx-rtmp-module. Вам нужно только установить модуль nginx-http-flv-module. Другими словами, следующий метод настройки неверен.
./configure --add-module=../../nginx-rtmp-module --add-module=../../nginx-http-flv-module
Затем появляется предупреждение во время процесса сборки.
ld: warning: dylib (/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/libstdc++.dylib) was built for newer macOS version (11.3) than being linked (11.1)
Просто установите переменные среды
export MACOSX_DEPLOYMENT_TARGET=11.3
Потом я столкнулся с этим при установке
cp: /openresty/openresty-1.25.3.1/build/resty.index: No such file or directory
make: *** [install] Error 1
build/pod: No such file or directory
make: *** [install] Error 1
Я не нашел хорошего решения двух вышеупомянутых проблем в Интернете. Визуально эти два файла не оказывают существенного влияния на установку. Мое решение - создать их перед установкой.
touch build/resty.index
touch build/pod
Тогда проблема решена. После правильной установки на дисплее будет следующее:
mkdir -p /usr/local/openresty/site/lualib /usr/local/openresty/site/pod /usr/local/openresty/site/manifest
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/local/openresty/bin/openresty
Затем мы бежим
/usr/local/openresty/bin/openresty
ps aux |grep openresty
xiazemin 28175 0.0 0.0 4268424 732 s016 S+ 16:27 0:00.00 grep openresty
root 25010 0.0 0.0 4306592 584 ?? Ss 16:27 0:00.00 nginx: master process /usr/local/openresty/bin/openresty
Об ошибках не сообщается, что указывает на успешную компиляцию.
Затем мы устанавливаем ffmpeg для потоковой передачи. Непосредственная установка ffmpeg будет настолько медленной, что заставит вас усомниться в своей жизни. Решительно сдавайтесь и используйте установку образа Docker напрямую.
docker pull jrottenberg/ffmpeg
Using default tag: latest
latest: Pulling from jrottenberg/ffmpeg
docker.io/jrottenberg/ffmpeg:latest
Затем зайдите в Интернет и скачайте материал в формате mp4 на свой локальный компьютер. На этом наши приготовления завершены.
Затем приступим к настройке нашего rtmp-сервера, файл конфигурации выглядит следующим образом:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1985; #not default port 1935
application myapp {
live on;
#для rtmp Движок устанавливает максимальное количество соединений. По умолчанию off
max_connections 1024;
# Не включать запись
record off;
}
application hls{
live on;
hls on;
hls_path ./hls;
hls_fragment 1s;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 8080;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
location /live {
flv_live on;
}
location /hls {
#server hls fragments
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias ./hls;
expires -1;
#Междоменный доступ должен быть разрешен
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}
# rtmp stat
location /stat {
rtmp_stat all;
#rtmp_stat_format json;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root ./html/rtmp;
}
# rtmp control
location /control {
rtmp_control all;
add_header Access-Control-Allow-Origin *;
}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
Конфигурация rtmp аналогична настройке http и включает три уровня: rtmp, сервер и приложение. После завершения настройки запускаем openresty
ps aux |grep -E "openresty|nginx" |grep -v grep |awk '{print $2}' |xargs sudo kill -9 && /usr/local/openresty/bin/openresty -p $PWD/ -c conf/nginx.conf
Затем мы запускаем ffmpeg, чтобы протолкнуть поток
docker run -v $(pwd):$(pwd) jrottenberg/ffmpeg:latest -re -i $(pwd)/demo.mp4 -vcodec copy -f flv rtmp://host.docker.internal:1985/hls/stream
После успешной отправки на дисплей выводится следующее:
[flv @ 0xae7e00] Failed to update header with correct filesize.
frame= 929 fps= 30 q=-1.0 Lsize= 7624kB time=00:00:30.93 bitrate=2018.7kbits/s speed= 1x
video:7101kB audio:484kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.511305%
Если вы столкнулись со следующей ошибкой во время процесса отправки
Metadata:
handler_name : Core Media Audio
rtmp://host.docker.internal:1985/zbcs/room: Input/output error
Причина в том, что путь push неверен. После того, как префикс hls приложения совпадет, необходимо добавить каталог, соответствующий нашему ключу push. Другими словами, следующий поток push-уведомлений неверен:
docker run -v $(pwd):$(pwd) jrottenberg/ffmpeg:latest -re -i $(pwd)/demo.mp4 -vcodec copy -f flv rtmp://host.docker.internal:1985/hls
После успешной отправки мы можем загрузить инструмент vlc для получения потока и войти в vlc.
rtmp://localhost:1985/hls/stream
Вы можете увидеть эффект воспроизведения видео. Чтобы предотвратить преждевременное завершение отправки и влияние на наше тестирование, вы можете настроить циклическую отправку:
docker run -v $(pwd):$(pwd) jrottenberg/ffmpeg:latest -stream_loop -1 -re -i $(pwd)/demo.mp4 -vcodec copy -f flv rtmp://host.docker.internal:1985/hls/stream
Оглядываясь назад на наш каталог hls, мы видим следующий список файлов:
% ls ./hls
stream-20.ts stream-23.ts stream-26.ts stream-29.ts
stream-18.ts stream-21.ts stream-24.ts stream-27.ts stream.m3u8
stream-19.ts stream-22.ts stream-25.ts stream-28.ts
Поток.m3u8 и пакет ts-файлов. После успешной передачи будет создан индексный файл m3u8 по пути приема (/hls) модуля nginx rtmp, который мы настроили ранее. m3u8 фактически является индексом файла ts, который ffmpeg разделит данные источника прямой трансляции. во множество файлов ts. Access m3u8 может получить порядок воспроизведения файлов ts и воспроизводить их один за другим. Когда файлы ts достигают определенного количества, предыдущие бесполезные файлы ts будут автоматически удалены, а если ffmpeg прекратит передачу, файлы под файлами ts будут автоматически удалены. папка также будет автоматически очищена.
На данный момент мы завершили потоковую передачу по требованию и потоковую передачу по запросу игрока. Как продвинуть прямой эфир? На самом деле, это очень просто. Мы можем заменить ffmpeg инструментом потоковой передачи obs, который аналогичен нашей ежедневной потоковой передаче. obs устанавливает адрес push-сервера на
rtmp://localhost:1985/hls/stream
Следует отметить, что адрес сервера
rtmp://127.0.0.1:1985/hls/
Ключ
stream
В противном случае push-поток завершится неудачей. На этом этапе был представлен простой процесс установки сервера прямой трансляции и по требованию. Позже мы подробно расскажем, как реализовать потоковую передачу push-уведомлений на стороне воспроизведения, потоковую передачу по запросу на стороне просмотра и управление воспроизведением веб-версии, так что следите за обновлениями.