@@ -20,25 +20,23 @@ import (
2020 "regexp"
2121 "strconv"
2222 "strings"
23- "sync"
24- "sync/atomic"
2523
2624 "github.com/gin-gonic/gin"
2725)
2826
29- // 带引用计数的互斥锁
30- type mutexWithRefCount struct {
31- mu sync.Mutex
32- refCount int32 // 使用 atomic 操作
33- }
27+ // // 带引用计数的互斥锁
28+ // type mutexWithRefCount struct {
29+ // mu sync.Mutex
30+ // refCount int32 // 使用 atomic 操作
31+ // }
3432
3533// Emby服务器处理器
3634type EmbyServerHandler struct {
37- server * emby.EmbyServer // Emby 服务器
38- routerRules []RegexpRouteRule // 正则路由规则
39- proxy * httputil.ReverseProxy // 反向代理
40- httpStrmHandler StrmHandlerFunc
41- playbackInfoMutex sync.Map // 视频流处理并发控制,确保同一个 item ID 的重定向请求串行化,避免重复获取缓存
35+ server * emby.EmbyServer // Emby 服务器
36+ routerRules []RegexpRouteRule // 正则路由规则
37+ proxy * httputil.ReverseProxy // 反向代理
38+ httpStrmHandler StrmHandlerFunc
39+ // playbackInfoMutex sync.Map // 视频流处理并发控制,确保同一个 item ID 的重定向请求串行化,避免重复获取缓存
4240}
4341
4442// 初始化
@@ -128,15 +126,15 @@ func (*EmbyServerHandler) GetSubtitleCacheRegexp() *regexp.Regexp {
128126// /Items/:itemId/PlaybackInfo
129127// 强制将 HTTPStrm 设置为支持直链播放和转码、AlistStrm 设置为支持直链播放并且禁止转码
130128func (embyServerHandler * EmbyServerHandler ) ModifyPlaybackInfo (rw * http.Response ) error {
131- // 检查 IsPlayback 参数,如果为 false 则不做修改直接返回
132- // 从响应的请求中获取参数,因为响应对象包含原始请求
133- // 使用不区分大小写的方式获取查询参数
134- isPlayback := getQueryValueCaseInsensitive (rw .Request .URL .Query (), "IsPlayback" )
135- logging .Debugf ("IsPlayback 参数值: '%s' (请求 URL: %s)" , isPlayback , rw .Request .URL .String ())
136- if strings .ToLower (isPlayback ) == "false" {
137- logging .Debug ("IsPlayback=false,跳过 PlaybackInfo 修改" )
138- return nil
139- }
129+ // // 检查 IsPlayback 参数,如果为 false 则不做修改直接返回
130+ // // 从响应的请求中获取参数,因为响应对象包含原始请求
131+ // // 使用不区分大小写的方式获取查询参数
132+ // isPlayback := getQueryValueCaseInsensitive(rw.Request.URL.Query(), "IsPlayback")
133+ // logging.Debugf("IsPlayback 参数值: '%s' (请求 URL: %s)", isPlayback, rw.Request.URL.String())
134+ // if strings.ToLower(isPlayback) == "false" {
135+ // logging.Debug("IsPlayback=false,跳过 PlaybackInfo 修改")
136+ // return nil
137+ // }
140138
141139 defer rw .Body .Close ()
142140 body , err := io .ReadAll (rw .Body )
@@ -254,42 +252,42 @@ func (embyServerHandler *EmbyServerHandler) VideosHandler(ctx *gin.Context) {
254252 // EmbyServer >= 4.9 ====> mediaSourceID = mediasource_31
255253 mediaSourceID := ctx .Query ("mediasourceid" )
256254
257- // 从 URL 中提取 item ID(例如:/emby/videos/43609/stream 中的 43609)
258- var itemID string
259- if matches := constants .EmbyRegexp .Router .VideosHandler .FindStringSubmatch (orginalPath ); len (matches ) > 0 {
260- parts := strings .Split (orginalPath , "/" )
261- for i , part := range parts {
262- if part == "videos" && i + 1 < len (parts ) {
263- itemID = parts [i + 1 ]
264- break
265- }
266- }
267- }
268-
269- // 并发控制:确保同一个 item ID 只有一个任务在运行
270- // 将整个处理流程放在锁内,避免重复查询和重复获取重定向 URL
271- var muWrapper * mutexWithRefCount
272- if itemID != "" {
273- // 加载或创建 mutex wrapper
274- value , _ := embyServerHandler .playbackInfoMutex .LoadOrStore (itemID , & mutexWithRefCount {})
275- muWrapper = value .(* mutexWithRefCount )
276-
277- // 增加引用计数
278- atomic .AddInt32 (& muWrapper .refCount , 1 )
279-
280- // 锁定并处理
281- muWrapper .mu .Lock ()
282- defer func () {
283- muWrapper .mu .Unlock ()
284- // 减少引用计数
285- refCount := atomic .AddInt32 (& muWrapper .refCount , - 1 )
286- // 如果没有其他 goroutine 在使用,删除这个 mutex 以避免内存泄漏
287- if refCount == 0 {
288- embyServerHandler .playbackInfoMutex .Delete (itemID )
289- }
290- }()
291- logging .Debugf ("开始处理 item %s 的 VideosHandler 请求" , itemID )
292- }
255+ // // 从 URL 中提取 item ID(例如:/emby/videos/43609/stream 中的 43609)
256+ // var itemID string
257+ // if matches := constants.EmbyRegexp.Router.VideosHandler.FindStringSubmatch(orginalPath); len(matches) > 0 {
258+ // parts := strings.Split(orginalPath, "/")
259+ // for i, part := range parts {
260+ // if part == "videos" && i+1 < len(parts) {
261+ // itemID = parts[i+1]
262+ // break
263+ // }
264+ // }
265+ // }
266+
267+ // // 并发控制:确保同一个 item ID 只有一个任务在运行
268+ // // 将整个处理流程放在锁内,避免重复查询和重复获取重定向 URL
269+ // var muWrapper *mutexWithRefCount
270+ // if itemID != "" {
271+ // // 加载或创建 mutex wrapper
272+ // value, _ := embyServerHandler.playbackInfoMutex.LoadOrStore(itemID, &mutexWithRefCount{})
273+ // muWrapper = value.(*mutexWithRefCount)
274+
275+ // // 增加引用计数
276+ // atomic.AddInt32(&muWrapper.refCount, 1)
277+
278+ // // 锁定并处理
279+ // muWrapper.mu.Lock()
280+ // defer func() {
281+ // muWrapper.mu.Unlock()
282+ // // 减少引用计数
283+ // refCount := atomic.AddInt32(&muWrapper.refCount, -1)
284+ // // 如果没有其他 goroutine 在使用,删除这个 mutex 以避免内存泄漏
285+ // if refCount == 0 {
286+ // embyServerHandler.playbackInfoMutex.Delete(itemID)
287+ // }
288+ // }()
289+ // logging.Debugf("开始处理 item %s 的 VideosHandler 请求", itemID)
290+ // }
293291
294292 logging .Debugf ("请求 ItemsServiceQueryItem:%s" , mediaSourceID )
295293 itemResponse , err := embyServerHandler .server .ItemsServiceQueryItem (strings .Replace (mediaSourceID , "mediasource_" , "" , 1 ), 1 , "Path,MediaSources" ) // 查询 item 需要去除前缀仅保留数字部分
0 commit comments