This commit is contained in:
truewhile
2026-10-13 23:35:06 +08:00
parent 6604691c19
commit d112e8e4db
4 changed files with 200 additions and 20 deletions
+32 -19
View File
@@ -159,28 +159,41 @@ func (b *serviceContainerBuilder) initContentServices() {
b.c.Stream.SetStrmPlayTargetResolver(b.c.Strm.ResolvePlayTargetWithUA)
// 弹幕识别需要把远程 Emby 条目解析为 Media 元数据及可拉取前 16MB 的直链 URL。
if b.c.EmbyRemote != nil {
b.c.Danmaku.SetRemoteMediaResolver(func(ctx context.Context, encodedID string) (*model.Media, string, error) {
mountID, remoteID, ok := DecodeEmbyRemoteID(encodedID)
if !ok {
return nil, "", errors.New("invalid emby remote id")
}
mount, acct, err := b.c.EmbyRemote.ResolveMount(ctx, mountID)
if err != nil || mount == nil || acct == nil {
if err != nil {
return nil, "", err
}
return nil, "", errors.New("emby mount or account not found")
}
m, err := b.c.EmbyRemote.RemoteMediaDetail(ctx, mount, acct, remoteID)
if err != nil || m == nil {
return nil, "", err
}
streamURL, _ := b.c.EmbyRemote.WebStreamURL(ctx, acct, remoteID)
return m, streamURL, nil
})
b.c.Danmaku.SetRemoteMediaResolver(b.resolveDanmakuRemoteMedia)
}
}
// resolveDanmakuRemoteMedia 把远程 Emby 伪 ID 解析成弹幕识别要用的 Media 与直链 URL。
//
// 目录类条目(整部剧/季/目录)自身没有媒体源,拿它的 ID 去请求远程
// /Videos/{id}/stream 只会回 500(Unable to cast object of type 'Series' to type
// 'IHasMediaSources'),哈希层于是每次都在这里白白失败、退回按文件名搜索。所以先按
// 与 /api/stream 相同的规则回落到第一集:算出来的哈希对得上真正播放的那条流,元数据
// (时长、文件名)也才是播放中那一集的。
func (b *serviceContainerBuilder) resolveDanmakuRemoteMedia(ctx context.Context, encodedID string) (*model.Media, string, error) {
mountID, remoteID, ok := DecodeEmbyRemoteID(encodedID)
if !ok {
return nil, "", errors.New("invalid emby remote id")
}
mount, acct, err := b.c.EmbyRemote.ResolveMount(ctx, mountID)
if err != nil || mount == nil || acct == nil {
if err != nil {
return nil, "", err
}
return nil, "", errors.New("emby mount or account not found")
}
playable := b.c.EmbyRemote.PlayableRemoteID(ctx, acct, remoteID)
if strings.TrimSpace(playable) == "" {
playable = remoteID
}
m, err := b.c.EmbyRemote.RemoteMediaDetail(ctx, mount, acct, playable)
if err != nil || m == nil {
return nil, "", err
}
streamURL, _ := b.c.EmbyRemote.WebStreamURL(ctx, acct, playable)
return m, streamURL, nil
}
func (b *serviceContainerBuilder) initAccessAndStorageServices() {
b.c.PlayProfiles = NewPlayProfileService(b.log, b.repos)
b.c.Permissions = NewPermissionService(b.log, b.repos)