前言

  • 什么是 OpenResty
    OpenResty 是一个基于 Nginx 的 Web 平台,可以使用其 LuaJIT 引擎运行 Lua 脚本。可是使用 Lua 脚本通过 OpenList API 获取到直链。

  • 什么是 OpenList
    这个就不用过多介绍,其提供完整的 API 以及 API 详细文档,能非常方便的满足一些需求。

通过 Lua 脚本,从 emby 播放路径获取媒体文件路径,然后通过这个路径使用 OpenList API 获取在 OpenList 上的对应文件的网盘直链,再进行 302 重定向。

安装 OpenResty 和必要模块

这里以 Debian 12 为例。

  1. 按照依赖
# apt-get -y install --no-install-recommends wget gnupg ca-certificates
  1. 添加 OpenResty 的 GPG 密钥
# wget -O - https://openresty.org/package/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty.gpg
  1. 添加 OpenResty 的软件源
# codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release`# echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list
  1. 安装 OpenResty 和必要模块
# apt-get update && apt-get -y install openresty# opm install ledgetech/lua-resty-http

更多参考:https://openresty.org/en/linux-packages.html

OpenResty 配置

配置路径为 /usr/local/openresty/nginx/conf/nginx.conf,参考:

worker_processes  1;events {    worker_connections  1024;}http {    lua_package_path '/usr/local/openresty/lualib/?.lua;;';    lua_package_cpath '/usr/local/openresty/luarocks/lib/lua/5.1/?.so;;';    init_by_lua_block {        require "resty.http"    }    include       mime.types;    default_type  application/octet-stream;    log_format  main  ' "$request" ';    access_log  logs/access.log  main;    sendfile        on;    keepalive_timeout  65;    upstream emby_backend {        server 127.0.0.1:8096;   # 替换为实际 emby 地址        keepalive 32;    }    server {        listen       80;        server_name  server;        location ~* /emby/videos/(\d+)/(original\.*) {            content_by_lua_block {                local api_key = ngx.var.arg_api_key                local media_source_id = ngx.var.arg_MediaSourceId                                local uri = ngx.var.uri                local video_id_res, video_id_err = ngx.re.match(uri, "/videos/(\\d+)")                if video_id_res then                    video_id = video_id_res[1]                else                    ngx.exit(500)                end                local path = "/Items/" .. video_id .. "/PlaybackInfo"                local item_res = ngx.location.capture(path, {                    method = ngx.HTTP_GET,                    args = { PlaybackInfo = media_source_id, api_key = api_key }                })                if item_res.status == 200 then                    local cjson = require "cjson"                    local data = cjson.decode(item_res.body)                    if data and data.MediaSources then                        local mediaSource = data.MediaSources[1]                        if mediaSource and mediaSource.Path then                            local mediasource_path = mediaSource.Path                            local http = require "resty.http"                            local cjson = require "cjson"                            local httpc = http.new()                            local url = "https://example.com:5244/api/fs/get" -- 替换为实际的网站                            local headers = {                                Authorization = "openlist-token",    -- 将替换为实际的 token                                ["Content-Type"] = "application/json"                            }                            local body = {                                path = mediasource_path,                                password = "",                                page = 1,                                per_page = 0,                                refresh = false                            }                            local json_body = cjson.encode(body)                            local res, err = httpc:request_uri(url, {                                method = "POST",                                headers = headers,                                body = json_body                            })                            local response_body = cjson.decode(res.body)                            local raw_url = response_body.data.raw_url                            ngx.redirect(raw_url, 302)                        else                            ngx.exit(500)                        end                    else                        ngx.exit(500)                    end                else                    ngx.exit(500)                end            }        }        location / {            proxy_pass http://emby_backend;            proxy_http_version 1.1;            proxy_set_header Upgrade $http_upgrade;            proxy_set_header Connection "upgrade";            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 Range $http_range;            proxy_set_header If-Range $http_if_range;            proxy_buffering off;            proxy_request_buffering off;            proxy_connect_timeout 60s;            proxy_send_timeout 600s;            proxy_read_timeout 600s;            send_timeout 600s;            client_max_body_size 10G;            client_body_buffer_size 512k;        }    }}

注意事项

  1. Emby 入库
    入库的路径必须与 OpenList 的一致。可以使用 strm 文件,填入 OpenList对应的文件路径,如:

  2. 配置均为 AI 完成,可能有疏漏的情况。

  3. 此使用方式极大可能覆盖不全所有 Emby 的使用场景,仅作学习参考使用。