Уже несколько дней я ломаю голову над этой проблемой, но не могу найти "элегантного" решения. Я хотел бы использовать сервер NGINX в качестве источника потоковой передачи для некоторых каналов в реальном времени, которые будут распространяться через разные CDN.
На первый взгляд проблема проста, но когда дело доходит до реального сценария жизни, она становится сложной, и я хочу знать ваше мнение ...
Для начала у меня есть несколько транскодеров, настроенных в качестве бэкэндов, и NGINX должен иметь возможность маршрутизировать к нужному кодеру. Для этого я использовал что-то вроде:
upstream transcoder_pool_01 {
server 192.168.1.1;
server 192.168.1.2;
}
upstream transcoder_pool_02 {
server 192.168.1.3;
server 192.168.1.4;
}
map $livechannel $backend {
channel1 transcoder_pool_01;
channel2 transcoder_pool_02;
channel3 transcoder_pool_03;
}
А до этого все нормально. Теперь наступает трудная часть.
Мой транскодер / упаковщики генерируют потоки по следующей схеме:
Главный манифест HLS: http://ip_address/liveapplication/channel_name/master.m3u8
Единые манифесты битрейта HLS http://ip_address/liveapplication/channel_name/channel_name-RESOLUTION/playlist.m3u8
Манифест DASH: http://ip_address/liveapplication/channel_name/manifest.m3u8
Сегменты: http://ip_address/liveapplication/channel_name/channel_name-RESOLUTION/chunk-xxxxxxx.ts
(или chunk-xxxxxx.mp4, или chunk-xxxxxx.m4s)
Теперь по причинам, не зависящим от меня, CDN требует, чтобы DASH и HLS обрабатывались разными путями. И в дополнение к этому один и тот же исходный поток многократно используется повторно в разных средах и блоках каналов. По этой причине из CDN / Edges мой Origin получает такие запросы:
http://originserver/live-hls/environment-01/channel-block01/channel-name/master.m3u8
или
http://originserver/live-dash/environment-01/channel-block02/channel-name/manifest.mpd
или
http://originserver/live-dash/environment-02/channel-block01/channel-name/channel-name-SD/playlist.m3u8
или
http://originserver/live-dash/environment-02/channel-block01/channel-name/channel-name-SD/chunk-002314.m4s
и так далее....
На этом этапе, прежде чем пересылать запросы, мне нужно:
Я думал временно решить проблему, определив сервер, похожий на:
server {
listen 80;
server_name originserver;
proxy_redirect off;
proxy_http_version 1.1;
proxy_read_timeout 10s;
proxy_send_timeout 10s;
proxy_connect_timeout 10s;
proxy_ignore_headers Cache-Control;
proxy_ignore_headers Set-Cookie;
proxy_cache liveorigin_cache;
proxy_cache_methods GET HEAD;
proxy_cache_key $uri;
proxy_cache_lock on;
proxy_cache_lock_age 5s;
proxy_cache_lock_timeout 1h;
# cache valid for 5 seconds where not specified differently
proxy_cache_valid 200 302 5s;
proxy_cache_valid 404 1s;
location ~ /(live-hls|live-dash)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/(master.m3u8|manifest.mpd) {
proxy_cache_valid 200 400s;
add_header "X-MasterManifest-Tag" "true";
proxy_pass http://$backend/liveapplication/$4/$5;
}
location ~ /(live-hls|live-dash)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/(.*)/playlist.m3u8 {
proxy_cache_valid 200 2s;
add_header "X-Playlist-Tag" "true";
proxy_pass http://$backend/liveapplication/$4/$5/playlist.m3u8;
}
location ~ /(live-hls|live-dash)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/(.*)/(.*).(ts|mp4|fmp4|m4s) {
proxy_cache_valid 200 2s;
add_header "X-Segments-Tag" "true";
proxy_pass http://$backend/liveapplication/$4/$5/$6/$7;
}
p.s .: добавленные заголовки предназначены для меня, чтобы убедиться, что местоположение действительно совпадает с ожидаемым ....
Но это точно не работает.
Я временно «исправил» проблему, заменив все местоположения одним местоположением, например:
location ~ /(live-hls|live-dash)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/(.*) {
set $livechannel $4;
add_header "X-General-Tag" "true";
proxy_pass http://$backend/live/$4/$5;
}
Это работает, но, конечно, все файлы кэшируются одинаково, и, учитывая, что существует неопределенное количество ребер, контактирующих с этим источником, мне действительно нужно уменьшить нагрузку на транскодер.
И я также считаю, что есть подход намного лучше, чем тот, который я думал использовать.
Может быть, используя вложенные локации? Я действительно заблудился.
Спасибо за вашу помощь. Alex