NGINX 中每个文件名和后端路由的不同行为

NGINX 中每个文件名和后端路由的不同行为

这几天我一直在思考这个问题,但找不到一个“优雅”的解决方案。我想使用 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)

  • 请注意,打包程序对于 DASH 和 HLS 共享相同的实时应用程序和段。

现在,由于我无法控制的原因,CDN 需要使用不同的路径处理 DASH 和 HLS。除此之外,同一个 Origin 流在不同的环境和通道块中被重复使用多次。由于这个原因,我的 Origin 从 CDN/Edges 收到如下请求:

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

等等....

此时,在转发请求之前我需要的是:

  1. 将“live-dash”或“live-hls”更改为常见的“liveapplication”
  2. 从 URI 中剥离环境和通道块
  3. 按原样传递剩余部分,但:3a) 为名为 master.m3u8 和 manifest.mpd 的文件以及所有媒体块设置一个非常长的缓存 3b) 为名为 playlist.m3u8 的文件设置一个非常短的缓存(请注意,这些文件与相关块位于同一子目录中)

我正在考虑临时解决定义类似以下服务器的问题:

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;
}

附言:添加的标题是为了让我验证位置是否确实与预期匹配......

但它肯定不起作用。

我暂时“修补”了该问题,将所有位置替换为一个位置,例如:

       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

相关内容