Feat: alist subtitle support (#49)

pull/150/head
zijiren233 10 months ago
parent 45d036a36d
commit 2d9f0f2b93

@ -13,6 +13,7 @@ import (
"github.com/synctv-org/synctv/internal/db"
"github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/vendor"
"github.com/synctv-org/synctv/utils"
"github.com/synctv-org/vendors/api/alist"
"github.com/zijiren233/gencontainer/refreshcache"
"github.com/zijiren233/go-uhc"
@ -90,33 +91,34 @@ const (
AlistProvider115 = "115 Cloud"
)
type AlistSubtitle struct {
Name string
URL string
Type string
Cache *SubtitleDataCache
}
type AlistMovieCacheData struct {
URL string
Subtitles map[string]string
Subtitles []*AlistSubtitle
Provider string
Ali *AlistAliCache
}
type AlistAliCache struct {
M3U8ListFile []byte
Subtitles []*AliSubtitle
}
type AliSubtitle struct {
Raw *alist.FsOtherResp_VideoPreviewPlayInfo_LiveTranscodingSubtitleTaskList
Cache *AliSubtitleCache
}
type AliSubtitleCache = refreshcache.RefreshCache[[]byte, struct{}]
type SubtitleDataCache = refreshcache.RefreshCache[[]byte, struct{}]
func newAliSubtitlesCacheInitFunc(list []*alist.FsOtherResp_VideoPreviewPlayInfo_LiveTranscodingSubtitleTaskList) []*AliSubtitle {
caches := make([]*AliSubtitle, len(list))
func newAliSubtitles(list []*alist.FsOtherResp_VideoPreviewPlayInfo_LiveTranscodingSubtitleTaskList) []*AlistSubtitle {
caches := make([]*AlistSubtitle, len(list))
for i, v := range list {
if v.Status != "finished" {
return nil
}
url := v.Url
caches[i] = &AliSubtitle{
caches[i] = &AlistSubtitle{
Cache: refreshcache.NewRefreshCache(func(ctx context.Context, args ...struct{}) ([]byte, error) {
r, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
@ -132,7 +134,9 @@ func newAliSubtitlesCacheInitFunc(list []*alist.FsOtherResp_VideoPreviewPlayInfo
}
return io.ReadAll(resp.Body)
}, 0),
Raw: v,
Name: v.Language,
URL: v.Url,
Type: utils.GetFileExtension(v.Url),
}
}
return caches
@ -216,10 +220,26 @@ func NewAlistMovieCacheInitFunc(movie *model.Movie) func(ctx context.Context, ar
if err != nil {
return nil, err
}
if cache.Subtitles == nil {
cache.Subtitles = make(map[string]string)
}
cache.Subtitles[resp.Name] = resp.RawUrl
cache.Subtitles = append(cache.Subtitles, &AlistSubtitle{
Name: related.Name,
URL: resp.RawUrl,
Type: utils.GetFileExtension(resp.Name),
Cache: refreshcache.NewRefreshCache(func(ctx context.Context, args ...struct{}) ([]byte, error) {
r, err := http.NewRequestWithContext(ctx, http.MethodGet, resp.RawUrl, nil)
if err != nil {
return nil, err
}
resp, err := uhc.Do(r)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("status code: %d", resp.StatusCode)
}
return io.ReadAll(resp.Body)
}, -1),
})
}
}
@ -236,8 +256,8 @@ func NewAlistMovieCacheInitFunc(movie *model.Movie) func(ctx context.Context, ar
}
cache.Ali = &AlistAliCache{
M3U8ListFile: genAliM3U8ListFile(fo.VideoPreviewPlayInfo.LiveTranscodingTaskList),
Subtitles: newAliSubtitlesCacheInitFunc(fo.VideoPreviewPlayInfo.LiveTranscodingSubtitleTaskList),
}
cache.Subtitles = append(cache.Subtitles, newAliSubtitles(fo.VideoPreviewPlayInfo.LiveTranscodingSubtitleTaskList)...)
}
return cache, nil
}

@ -965,12 +965,12 @@ func proxyVendorMovie(ctx *gin.Context, movie *op.Movie) {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
if id >= len(data.Ali.Subtitles) {
if id >= len(data.Subtitles) {
log.Errorf("proxy vendor movie error: %v", "id out of range")
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("id out of range"))
return
}
data, err := data.Ali.Subtitles[id].Cache.Get(ctx)
data, err := data.Subtitles[id].Cache.Get(ctx)
if err != nil {
log.Errorf("proxy vendor movie error: %v", err)
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
@ -1172,13 +1172,13 @@ func genVendorMovie(ctx context.Context, user *op.User, opMovie *op.Movie, userA
return nil, err
}
for name, url := range data.Subtitles {
for _, subt := range data.Subtitles {
if movie.Base.Subtitles == nil {
movie.Base.Subtitles = make(map[string]*dbModel.Subtitle, len(data.Subtitles))
}
movie.Base.Subtitles[name] = &dbModel.Subtitle{
URL: url,
Type: utils.GetFileExtension(name),
movie.Base.Subtitles[subt.Name] = &dbModel.Subtitle{
URL: subt.URL,
Type: subt.Type,
}
}
@ -1194,15 +1194,16 @@ func genVendorMovie(ctx context.Context, user *op.User, opMovie *op.Movie, userA
movie.Base.Url = u.String()
movie.Base.Type = "m3u8"
for i, s := range data.Ali.Subtitles {
for i, subt := range data.Subtitles {
if movie.Base.Subtitles == nil {
movie.Base.Subtitles = make(map[string]*dbModel.Subtitle, len(data.Ali.Subtitles))
movie.Base.Subtitles = make(map[string]*dbModel.Subtitle, len(data.Subtitles))
}
movie.Base.Subtitles[s.Raw.Language] = &dbModel.Subtitle{
movie.Base.Subtitles[subt.Name] = &dbModel.Subtitle{
URL: fmt.Sprintf("/api/movie/proxy/%s/%s?t=subtitle&id=%d", movie.RoomID, movie.ID, i),
Type: utils.GetUrlExtension(s.Raw.Url),
Type: subt.Type,
}
}
case cache.AlistProvider115:
if movie.Base.Proxy {
rawPath, err := url.JoinPath("/api/movie/proxy", movie.RoomID, movie.ID)
@ -1214,6 +1215,8 @@ func genVendorMovie(ctx context.Context, user *op.User, opMovie *op.Movie, userA
}
movie.Base.Url = u.String()
movie.Base.Type = utils.GetUrlExtension(data.URL)
// TODO: proxy subtitle
} else {
data, err = alistCache.GetRefreshFunc()(ctx, &cache.AlistMovieCacheFuncArgs{
UserCache: creator.Value().AlistCache(),
@ -1223,6 +1226,13 @@ func genVendorMovie(ctx context.Context, user *op.User, opMovie *op.Movie, userA
return nil, fmt.Errorf("refresh 115 movie cache error: %w", err)
}
movie.Base.Url = data.URL
movie.Base.Subtitles = make(map[string]*dbModel.Subtitle, len(data.Subtitles))
for _, subt := range data.Subtitles {
movie.Base.Subtitles[subt.Name] = &dbModel.Subtitle{
URL: subt.URL,
Type: subt.Type,
}
}
}
default:

Loading…
Cancel
Save