Skip to content

Commit 72994d7

Browse files
committed
feat: 更新 alistStrmHandler 方法,支持获取转码资源信息
1 parent 34b6db4 commit 72994d7

4 files changed

Lines changed: 125 additions & 18 deletions

File tree

internal/handler/emby.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,13 @@ func (handler *EmbyHandler) VideosHandler(ctx *gin.Context) {
282282
}
283283

284284
case constants.AlistStrm: // 无需判断 *mediasource.Container 是否以Strm结尾,当 AlistStrm 存储的位置有对应的文件时,*mediasource.Container 会被设置为文件后缀
285-
redirectURL := alistStrmHandler(*mediasource.Path, opt.(string))
286-
if redirectURL != "" {
287-
ctx.Redirect(http.StatusFound, redirectURL)
285+
res, err := alistStrmHandler(*mediasource.Path, opt.(string), false)
286+
if err != nil {
287+
logging.Warningf("获取 AlistStrm 重定向 URL 失败: %#v", err)
288+
handler.ReverseProxy(ctx.Writer, ctx.Request)
289+
return
288290
}
291+
ctx.Redirect(http.StatusFound, res.url)
289292
return
290293

291294
case constants.UnknownStrm:

internal/handler/fntv.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,36 @@ func (hanler *FNTVHandler) ModifyStream(rw *http.Response) error {
132132
return nil
133133
}
134134

135-
redirectURL := alistStrmHandler(remoteFilepathRes.String(), opt.(string))
135+
res, err := alistStrmHandler(remoteFilepathRes.String(), opt.(string), true)
136+
if err != nil {
137+
logging.Warningf("获取 AlistStrm 重定向 URL 失败: %#v", err)
138+
rw.Body = io.NopCloser(bytes.NewReader(data))
139+
return nil
140+
}
136141
jsonChain.Set(
137142
"data.direct_link_qualities.0.resolution",
138143
"AlistStrm 直链 - 原画",
139144
).Set(
140145
"data.direct_link_qualities.0.url",
141-
redirectURL,
142-
)
146+
res.url,
147+
).Set("data.file_stream.size", res.fileSize)
148+
149+
for i, resource := range res.transcodeResources {
150+
basePath := "data.direct_link_qualities." + strconv.Itoa(i+1) + "."
151+
jsonChain.Set(
152+
basePath+"resolution",
153+
"AlistStrm 直链 - 转码 "+resource.resolution.name,
154+
).Set(
155+
basePath+"url",
156+
resource.url,
157+
).Set(
158+
basePath+"is_m3u8",
159+
resource.isM3U8,
160+
).Set(
161+
basePath+"expire_at",
162+
int64(time.Since(resource.expireAt).Seconds()),
163+
)
164+
}
143165

144166
default:
145167
logging.Debugf("%s 未匹配任何 Strm 类型,保持原有播放链接不变", filePath)

internal/handler/jellyfin.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,13 @@ func (handler *JellyfinHandler) VideosHandler(ctx *gin.Context) {
245245
}
246246

247247
case constants.AlistStrm: // 无需判断 *mediasource.Container 是否以Strm结尾,当 AlistStrm 存储的位置有对应的文件时,*mediasource.Container 会被设置为文件后缀
248-
redirectURL := alistStrmHandler(*mediasource.Path, opt.(string))
249-
if redirectURL != "" {
250-
ctx.Redirect(http.StatusFound, redirectURL)
248+
res, err := alistStrmHandler(*mediasource.Path, opt.(string), false)
249+
if err != nil {
250+
logging.Warningf("获取 AlistStrm 重定向 URL 失败:%#v", err)
251+
handler.ReverseProxy(ctx.Writer, ctx.Request)
252+
return
251253
}
254+
ctx.Redirect(http.StatusFound, res.url)
252255
return
253256

254257
case constants.UnknownStrm:

internal/handler/strm.go

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ import (
44
"MediaWarp/internal/config"
55
"MediaWarp/internal/logging"
66
"MediaWarp/internal/service"
7+
"MediaWarp/internal/service/alist"
78
"context"
89
"fmt"
910
"net/http"
11+
"net/url"
12+
"path"
13+
"strconv"
14+
"strings"
1015
"time"
1116

1217
"github.com/allegro/bigcache/v3"
@@ -63,22 +68,96 @@ func getHTTPStrmHandler() (StrmHandlerFunc, error) {
6368
}, nil
6469
}
6570

66-
func alistStrmHandler(content string, alistAddr string) string {
71+
type resolutionInfo struct {
72+
width uint
73+
height uint
74+
name string
75+
}
76+
type TranscodeResourceInfo struct {
77+
url string
78+
isM3U8 bool
79+
expireAt time.Time
80+
resolution resolutionInfo
81+
}
82+
83+
type alistStrmResult struct {
84+
url string // 重定向 URL
85+
fileSize int64 // 文件大小(字节)
86+
transcodeResources []TranscodeResourceInfo // 转码资源列表
87+
}
88+
89+
func alistStrmHandler(content string, alistAddr string, needTranscodeResourceInfo bool) (*alistStrmResult, error) {
6790
startTime := time.Now()
6891
defer func() {
6992
logging.Debugf("获取 AlistStrm 重定向 URL 耗时:%s", time.Since(startTime))
7093
}()
7194

72-
alistClient, err := service.GetAlistClient(alistAddr)
95+
client, err := service.GetAlistClient(alistAddr)
7396
if err != nil {
74-
logging.Warning("获取 AlistClient 失败:", err)
75-
return ""
97+
return nil, fmt.Errorf("获取 AlistClient 失败:%w", err)
7698
}
77-
url, err := alistClient.GetFileURL(content, config.AlistStrm.RawURL)
99+
100+
fileData, err := client.FsGet(&alist.FsGetRequest{Path: content, Page: 1})
78101
if err != nil {
79-
logging.Warning("获取文件 URL 失败:", err)
80-
return ""
102+
return nil, fmt.Errorf("获取文件信息失败:%w", err)
81103
}
82-
logging.Infof("AlistStrm 重定向至:%s", url)
83-
return url
104+
105+
res := alistStrmResult{
106+
transcodeResources: make([]TranscodeResourceInfo, 0),
107+
}
108+
109+
if config.AlistStrm.RawURL {
110+
res.url = fileData.RawURL
111+
} else {
112+
var u strings.Builder
113+
u.WriteString(client.GetEndpoint())
114+
if fileData.Sign != "" {
115+
u.WriteString("?sign=" + fileData.Sign)
116+
}
117+
u.WriteString(path.Join("/d", client.GetUserInfo().BasePath, content))
118+
res.url = u.String()
119+
}
120+
logging.Infof("AlistStrm 重定向至:%s", res.url)
121+
122+
res.fileSize = fileData.Size
123+
124+
if needTranscodeResourceInfo {
125+
previewData, err := client.GetVideoPreviewData(content, "")
126+
if err != nil {
127+
logging.Warningf("%#v 获取视频预览信息失败:%w", fileData, err)
128+
return &res, nil // 即使获取预览信息失败,也返回基本的重定向 URL 和文件大小
129+
}
130+
for _, task := range previewData.VideoPreviewPlayInfo.LiveTranscodingTaskList {
131+
if task.Url != "" {
132+
u, err := url.Parse(task.Url)
133+
if err != nil {
134+
logging.Warningf("解析转码资源 URL 失败: %s, URL: %s", err, task.Url)
135+
continue
136+
}
137+
expireStr := u.Query().Get("x-oss-expires")
138+
if expireStr == "" {
139+
logging.Warningf("转码资源 URL 中未找到 x-oss-expires 参数,URL: %s", task.Url)
140+
continue
141+
}
142+
tsInt, err := strconv.ParseInt(expireStr, 10, 64)
143+
if err != nil {
144+
logging.Warningf("解析转码资源 URL 中的 x-oss-expires 参数失败: %w, URL: %s", err, task.Url)
145+
continue
146+
}
147+
info := TranscodeResourceInfo{
148+
url: task.Url,
149+
isM3U8: strings.HasSuffix(u.Path, ".m3u8"),
150+
expireAt: time.Unix(tsInt, 0),
151+
resolution: resolutionInfo{
152+
width: uint(task.TemplateHeight),
153+
height: uint(task.TemplateHeight),
154+
name: task.TemplateName,
155+
},
156+
}
157+
res.transcodeResources = append(res.transcodeResources, info)
158+
}
159+
}
160+
}
161+
162+
return &res, nil
84163
}

0 commit comments

Comments
 (0)