使用工具

https://github.com/bpking1/embyExternalUrl

本文章仅对Emby的使用演示,其他媒体库自行参考

先来效果展示:右上角 20MB/s

Vidhub 连接 Emby

img

Strm

脚本读取Strm中的内容获得链接后替换,如果你有能力的话可以修改为读取文件路径然后替换,这样就不需要生成Strm了,具体怎么生成可以百度查查其他帖子。

emby-nginx

工具一共需要修改两个文件

  1. constant.js

我对 embyMountPath 做了特别说明,其他的按照你的实际情况填写即可

主要是embyMountPath这个需要特别注意一下替换后的路径关系,如果错了会导致无法播放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// export constant allocation
// Emby 局域网 IP
const embyIp = "http://10.0.0.2";
// Emby 端口
const embyPort = 8096;
// 不要动
const embyHost = embyIp + ":" + embyPort;

// alist token, 在alist后台查看
const alistToken = "";
const alistIp = "http://10.0.0.10";
const alistPort = 5244;
// 访问宿主机上5244端口的alist地址, 要注意iptables给容器放行端口

// 不要动
const alistAddr = alistIp + ":" + alistPort;

// emby/jellyfin api key, 在emby/jellyfin后台设置
const embyApiKey = "";
// 公网域名, 按需填写, eg: http://youralist.com
const publicDomain = "";
// alist公网地址, 用于需要alist server代理流量的情况, 按需填写

// 不要动
const alistPublicAddr = publicDomain + ":" + alistPort;

// 工具的原理是通过替换的路径去alist查询真实链接,然后进行302转发
// 这个变量经过替换后和 alist 中的路径一致即可
// 处理前
// /volume3/Movie/MoviesLink/Strm/aliyun/电影/奇异博士(系列)/奇异博士 (2016)/奇异博士 (2016) - 2160p.mkv
// 处理后(将根据此路径获得alist直链)
// aliyun/电影/奇异博士(系列)/奇异博士 (2016)/奇异博士 (2016) - 2160p.mkv
// 最后请求查询的地址为:http://alist:5244/aliyun/电影/奇异博士(系列)/奇异博士 (2016)/奇异博士 (2016) - 2160p.mkv
const embyMountPath = "/volume3/Movie/MoviesLink/Strm";

// 使用AList直链播放挂载的NAS本地视频时,可能存在卡顿与花屏,若出现,请启用,使用emby/jellyfin原始链接
const changeAlistToEmby = false;
// !!!风险功能,是否允许转发strm文件内部url直链到客户端,不建议开启,建议strm文件内部只填路径
// 可能存在明文密码,默认禁止并交给原始emby/jellyfin中转处理,仅供调试,泄露密码后果自行承担
const allowRemoteStrmRedirect = false;

export default {
embyIp,
embyPort,
embyHost,
embyMountPath,
alistToken,
alistIp,
alistPort,
alistAddr,
embyApiKey,
publicDomain,
alistPublicAddr,
changeAlistToEmby,
allowRemoteStrmRedirect
}

  1. emby.conf

我这边配置了 ssl 和域名 使用了 https 如果必须要的话删除即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# Load the njs script
js_path /etc/nginx/conf.d/;
js_import emby2Pan from emby.js;
js_import embyLive from emby-live.js;
# Cache images, subtitles
proxy_cache_path /var/cache/nginx/emby/images levels=1:2 keys_zone=emby_images:100m max_size=1g inactive=30d use_temp_path=off;
proxy_cache_path /var/cache/nginx/emby/subtitles levels=1:2 keys_zone=emby_subtitles:10m max_size=1g inactive=30d use_temp_path=off;
## The below will force all nginx traffic to SSL, make sure all other server blocks only listen on 443
# server {
# listen 80 default_server;
# server_name _;
# return 301 https://$host$request_uri;
# }
## Start of actual server blocks
server {
listen 443 ssl;
server_name 你的域名;
add_header 'Referrer-Policy' 'no-referrer';
set $emby 内网emby地址; #emby/jellyfin address
ssl_certificate /etc/nginx/ssl/ssl.pem;
ssl_certificate_key /etc/nginx/ssl/ssl.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
gzip on;
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types
text/plain
text/css
text/js
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
image/svg+xml;
## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc.
client_max_body_size 20M;
# default is 4k
subrequest_output_buffer_size 200k;
# # Security / XSS Mitigation Headers
# add_header X-Frame-Options "SAMEORIGIN";
# add_header X-XSS-Protection "1; mode=block";
# add_header X-Content-Type-Options "nosniff";
# aliDrive direct stream need no-referrer
add_header 'Referrer-Policy' 'no-referrer';

# Proxy sockets traffic for jellyfin-mpv-shim and webClient
location ~* /(socket|embywebsocket) {
# Proxy emby/jellyfin Websockets traffic
proxy_pass $emby;
## WEBSOCKET SETTINGS ## Used to pass two way real time info to and from emby and the client.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_connect_timeout 1h;
proxy_send_timeout 1h;
proxy_read_timeout 1h;
tcp_nodelay on; ## Sends data as fast as it can not buffering large chunks, saves about 200ms per request.
}
# Cache the Subtitles
location ~* /videos/(.*)/Subtitles {
proxy_pass $emby;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;

proxy_cache emby_subtitles;
proxy_cache_revalidate on;
proxy_cache_lock_timeout 10s;
proxy_cache_lock on;
proxy_cache_valid 200 30d;
proxy_cache_key $request_uri;
add_header X-Cache-Status $upstream_cache_status; # This is only to check if cache is working
}

# Proxy PlaybackInfo
location ~ ^(.*)/proxy(/.*)$ {
gunzip on; # Jellyfin has gzip,subrequest need this,Emby no gzip but compatible
client_body_in_file_only clean;
rewrite ^(.*)/proxy(/.*)$ $1$2 break;
proxy_pass $emby$request_uri; # Emby need $request_uri,Jellyfin not need but compatible
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
# Disable buffering when the nginx proxy gets very resource heavy upon streaming
proxy_buffering off;
proxy_pass_request_body on;
proxy_pass_request_headers on;
add_header X-Proxy-Success "yes";
}
location ~* /Items/(.*)/PlaybackInfo {
client_body_in_file_only clean;
if ($args ~* "IsPlayback=true") {
js_content emby2Pan.transferPlaybackInfo;
break;
}
proxy_pass $emby;
}
# Redirect the stream to njs
location ~* /videos/(.*)/stream {
# Cache alist direct link
add_header Cache-Control max-age=3600;
js_content emby2Pan.redirect2Pan;
}
# Redirect the live to njs
location ~* /videos/(.*)/live {
js_content embyLive.directLive;
}
location ~* /videos/(.*)/master {
js_content embyLive.directLive;
}
# Redirect Audio the stream to njs
location ~* /Audio/(.*)/universal {
# Cache alist direct link
add_header Cache-Control max-age=3600;
js_content emby2Pan.redirect2Pan;
}
# for webClient download ,android is SyncService api
location ~* /Items/([^/]+)/Download {
js_content emby2Pan.redirect2Pan;
}
# Emby for android download ,this is SyncService api only Emby
location ~* /Sync/JobItems/(.*)/File {
# Cache alist direct link
add_header Cache-Control max-age=3600;
js_content emby2Pan.redirect2Pan;
}

# Cache the images
location ~ /Items/(.*)/Images {
proxy_pass $emby;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;

proxy_cache emby_images;
proxy_cache_revalidate on;
proxy_cache_lock_timeout 10s;
proxy_cache_lock on;
proxy_cache_valid 200 30d;
proxy_cache_key $request_uri;
add_header X-Cache-Status $upstream_cache_status; # This is only to check if cache is working
}

## Disables access to swagger/openapi interface
location ~* /(swagger|openapi) {
return 404;
}

location / {
# Proxy main emby/jellyfin traffic
proxy_pass $emby;
# client_max_body_size 1000M; ## Allows for mobile device large photo uploads.
#proxy_set_header X-Real-IP $http_CF_Connecting_IP; ## if you use cloudflare un-comment this line and comment out above line.
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
# Disable buffering when the nginx proxy gets very resource heavy upon streaming
proxy_buffering off;

## ADDITIONAL SECURITY SETTINGS ##
## Optional settings to improve security ##
## add these after you have completed your testing and ssl setup ##
## NOTICE: For the Strict-Transport-Security setting below, I would recommend ramping up to this value ##
## See https://hstspreload.org/ read through the "Deployment Recommendations" section first! ##
# add_header 'Referrer-Policy' 'origin-when-cross-origin';
# add_header Strict-Transport-Security "max-age=15552000; preload" always;
# add_header X-Frame-Options "SAMEORIGIN" always;
# add_header X-Content-Type-Options "nosniff" always;
# add_header X-XSS-Protection "1; mode=block" always;
}
}

SSL

SSL的配置在第二个文件配置好域名后,将证书文件放到 ssl 文件夹中并且命名为 ssl.pemssl.key即可

docker-compose

作者的compose没搞懂为啥开了那么多东西下面是我自己修改了一下的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '3.8'

services:
service.nginx:
image: nginx:alpine
container_name: emby-nginx
ports:
- "8096:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/embyCache:/var/cache/nginx/emby
- ./nginx/ssl:/etc/nginx/ssl
restart: always