Jelajahi Sumber

完成基础的 subtitle_best 对接,还需要测试

Signed-off-by: allan716 <[email protected]>
allan716 2 tahun lalu
induk
melakukan
0341f2e073

+ 40 - 0
pkg/logic/file_downloader/downloader_hub.go

@@ -185,3 +185,43 @@ func (f *FileDownloader) GetEx(supplierName string, browser *rod.Browser, subDow
 		return subInfo, nil
 		return subInfo, nil
 	}
 	}
 }
 }
+
+// GetSubtitleBest supplierName 这个参数一定得是字幕源的名称,通过 s.GetSupplierName() 获取,否则后续的字幕源今日下载量将不能正确统计和判断
+func (f *FileDownloader) GetSubtitleBest(supplierName string, topN int64, season, eps int,
+	title, ext, subSha256, fileDownloadUrl string) (*supplier.SubInfo, error) {
+
+	found, subInfo, err := f.CacheCenter.DownloadFileGet(subSha256)
+	if err != nil {
+		return nil, err
+	}
+	// 如果不存在那么就先下载,然后再存入缓存中
+	if found == false {
+
+		fileData, _, err := pkg.DownFile(f.Log, fileDownloadUrl)
+		if err != nil {
+			return nil, err
+		}
+		// 下载成功需要统计到今天的次数中
+		_, err = f.CacheCenter.DailyDownloadCountAdd(supplierName,
+			pkg.GetPublicIP(f.Log, settings.Get().AdvancedSettings.TaskQueue))
+		if err != nil {
+			f.Log.Warningln(supplierName, "FileDownloader.Get.DailyDownloadCountAdd", err)
+		}
+		// 默认存入都是简体中文的语言类型,后续取出来的时候需要再次调用 SubParser 进行解析
+		inSubInfo := supplier.NewSubInfo(supplierName, topN, title, language.ChineseSimple, fileDownloadUrl, 0, 0, ext, fileData)
+		inSubInfo.Season = season
+		inSubInfo.Episode = eps
+		inSubInfo.SetFileUrlSha256(subSha256)
+		inSubInfo.GetUID()
+
+		err = f.CacheCenter.DownloadFileAdd(inSubInfo)
+		if err != nil {
+			return nil, err
+		}
+
+		return inSubInfo, nil
+	} else {
+		// 如果已经存在缓存中,那么就直接返回
+		return subInfo, nil
+	}
+}

+ 81 - 34
pkg/logic/sub_supplier/subtitle_best/api.go

@@ -4,16 +4,20 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/common"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/common"
 	"github.com/go-resty/resty/v2"
 	"github.com/go-resty/resty/v2"
+	"strconv"
 )
 )
 
 
 type Api struct {
 type Api struct {
-	client *resty.Client
-	token  string
-	apiKey string
+	headerToken string
+	apiKey      string
+}
+
+func NewApi(headerToken string, apiKey string) *Api {
+	return &Api{headerToken: headerToken, apiKey: apiKey}
 }
 }
 
 
 // QueryMovieSubtitle 查询电影的字幕
 // QueryMovieSubtitle 查询电影的字幕
-func (a *Api) QueryMovieSubtitle(imdbID string) (*SubtitleResponse, error) {
+func (a *Api) QueryMovieSubtitle(client *resty.Client, imdbID string) (*SubtitleResponse, *LimitInfo, error) {
 	// 构建请求体
 	// 构建请求体
 	requestBody := SearchMovieSubtitleRequest{
 	requestBody := SearchMovieSubtitleRequest{
 		ImdbID: imdbID,
 		ImdbID: imdbID,
@@ -21,26 +25,26 @@ func (a *Api) QueryMovieSubtitle(imdbID string) (*SubtitleResponse, error) {
 	}
 	}
 
 
 	// 发送请求
 	// 发送请求
-	resp, err := a.client.R().
-		SetHeader("Authorization", "Bearer "+a.token).
+	resp, err := client.R().
+		SetHeader("Authorization", "Bearer "+a.headerToken).
 		SetBody(requestBody).
 		SetBody(requestBody).
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestSearchMovieUrl)
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestSearchMovieUrl)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
 	// 解析响应
 	// 解析响应
 	var subtitleResponse SubtitleResponse
 	var subtitleResponse SubtitleResponse
 	err = json.Unmarshal(resp.Body(), &subtitleResponse)
 	err = json.Unmarshal(resp.Body(), &subtitleResponse)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
-	return &subtitleResponse, nil
+	return &subtitleResponse, NewHeaderInfo(resp), nil
 }
 }
 
 
 // QueryTVEpsSubtitle 查询连续剧 一季 一集的字幕
 // QueryTVEpsSubtitle 查询连续剧 一季 一集的字幕
-func (a *Api) QueryTVEpsSubtitle(imdbID string, season, episode int) (*SubtitleResponse, error) {
+func (a *Api) QueryTVEpsSubtitle(client *resty.Client, imdbID string, season, episode int) (*SubtitleResponse, *LimitInfo, error) {
 	// 构建请求体
 	// 构建请求体
 	requestBody := SearchTVEpsSubtitleRequest{
 	requestBody := SearchTVEpsSubtitleRequest{
 		ImdbID:  imdbID,
 		ImdbID:  imdbID,
@@ -50,26 +54,26 @@ func (a *Api) QueryTVEpsSubtitle(imdbID string, season, episode int) (*SubtitleR
 	}
 	}
 
 
 	// 发送请求
 	// 发送请求
-	resp, err := a.client.R().
-		SetHeader("Authorization", "Bearer "+a.token).
+	resp, err := client.R().
+		SetHeader("Authorization", "Bearer "+a.headerToken).
 		SetBody(requestBody).
 		SetBody(requestBody).
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestSearchTVEpsUrl)
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestSearchTVEpsUrl)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
 	// 解析响应
 	// 解析响应
 	var subtitleResponse SubtitleResponse
 	var subtitleResponse SubtitleResponse
 	err = json.Unmarshal(resp.Body(), &subtitleResponse)
 	err = json.Unmarshal(resp.Body(), &subtitleResponse)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
-	return &subtitleResponse, nil
+	return &subtitleResponse, NewHeaderInfo(resp), nil
 }
 }
 
 
 // QueryTVSeasonPackages 查询连续剧 一季的字幕包 ID 列表
 // QueryTVSeasonPackages 查询连续剧 一季的字幕包 ID 列表
-func (a *Api) QueryTVSeasonPackages(imdbID string, season int) (*SeasonPackagesResponse, error) {
+func (a *Api) QueryTVSeasonPackages(client *resty.Client, imdbID string, season int) (*SeasonPackagesResponse, *LimitInfo, error) {
 	// 构建请求体
 	// 构建请求体
 	requestBody := SearchTVSeasonPackagesRequest{
 	requestBody := SearchTVSeasonPackagesRequest{
 		ImdbID: imdbID,
 		ImdbID: imdbID,
@@ -78,26 +82,26 @@ func (a *Api) QueryTVSeasonPackages(imdbID string, season int) (*SeasonPackagesR
 	}
 	}
 
 
 	// 发送请求
 	// 发送请求
-	resp, err := a.client.R().
-		SetHeader("Authorization", "Bearer "+a.token).
+	resp, err := client.R().
+		SetHeader("Authorization", "Bearer "+a.headerToken).
 		SetBody(requestBody).
 		SetBody(requestBody).
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestSearchTVSeasonPackageUrl)
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestSearchTVSeasonPackageUrl)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
 	// 解析响应
 	// 解析响应
 	var seasonPackageResponse SeasonPackagesResponse
 	var seasonPackageResponse SeasonPackagesResponse
 	err = json.Unmarshal(resp.Body(), &seasonPackageResponse)
 	err = json.Unmarshal(resp.Body(), &seasonPackageResponse)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
-	return &seasonPackageResponse, nil
+	return &seasonPackageResponse, NewHeaderInfo(resp), nil
 }
 }
 
 
 // QueryTVSeasonPackageByID 查询连续剧 一季 一字幕包的字幕
 // QueryTVSeasonPackageByID 查询连续剧 一季 一字幕包的字幕
-func (a *Api) QueryTVSeasonPackageByID(imdbID string, seasonPackageId string) (*SubtitleResponse, error) {
+func (a *Api) QueryTVSeasonPackageByID(client *resty.Client, imdbID string, seasonPackageId string) (*SubtitleResponse, *LimitInfo, error) {
 	// 构建请求体
 	// 构建请求体
 	requestBody := SearchTVSeasonPackageByIDRequest{
 	requestBody := SearchTVSeasonPackageByIDRequest{
 		ImdbID:          imdbID,
 		ImdbID:          imdbID,
@@ -106,29 +110,29 @@ func (a *Api) QueryTVSeasonPackageByID(imdbID string, seasonPackageId string) (*
 	}
 	}
 
 
 	// 发送请求
 	// 发送请求
-	resp, err := a.client.R().
-		SetHeader("Authorization", "Bearer "+a.token).
+	resp, err := client.R().
+		SetHeader("Authorization", "Bearer "+a.headerToken).
 		SetBody(requestBody).
 		SetBody(requestBody).
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestSearchTVSeasonPackageByIDUrl)
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestSearchTVSeasonPackageByIDUrl)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
 	// 解析响应
 	// 解析响应
 	var subtitleResponse SubtitleResponse
 	var subtitleResponse SubtitleResponse
 	err = json.Unmarshal(resp.Body(), &subtitleResponse)
 	err = json.Unmarshal(resp.Body(), &subtitleResponse)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
-	return &subtitleResponse, nil
+	return &subtitleResponse, NewHeaderInfo(resp), nil
 }
 }
 
 
 // GetDownloadUrl 获取字幕下载地址
 // GetDownloadUrl 获取字幕下载地址
-func (a *Api) GetDownloadUrl(subSha256, imdbID string,
+func (a *Api) GetDownloadUrl(client *resty.Client, subSha256, imdbID string,
 	isMovie bool, season, episode int,
 	isMovie bool, season, episode int,
 	seasonPackageId string, language int,
 	seasonPackageId string, language int,
-	token string) (*GetUrlResponse, error) {
+	token string) (*GetUrlResponse, *LimitInfo, error) {
 	// 构建请求体
 	// 构建请求体
 	requestBody := DownloadUrlConvertRequest{
 	requestBody := DownloadUrlConvertRequest{
 		SubSha256:       subSha256,
 		SubSha256:       subSha256,
@@ -143,20 +147,63 @@ func (a *Api) GetDownloadUrl(subSha256, imdbID string,
 	}
 	}
 
 
 	// 发送请求
 	// 发送请求
-	resp, err := a.client.R().
-		SetHeader("Authorization", "Bearer "+a.token).
+	resp, err := client.R().
+		SetHeader("Authorization", "Bearer "+a.headerToken).
 		SetBody(requestBody).
 		SetBody(requestBody).
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestGetDlURLUrl)
 		Post(common.SubSubtitleBestRootUrlDef + common.SubSubtitleBestGetDlURLUrl)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
 	// 解析响应
 	// 解析响应
 	var getUrlResponse GetUrlResponse
 	var getUrlResponse GetUrlResponse
 	err = json.Unmarshal(resp.Body(), &getUrlResponse)
 	err = json.Unmarshal(resp.Body(), &getUrlResponse)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	}
 
 
-	return &getUrlResponse, nil
+	return &getUrlResponse, NewHeaderInfo(resp), nil
+}
+
+type LimitInfo struct {
+	dailyLimit         string
+	dailyCount         string
+	rateLimitLimit     string
+	rateLimitRemaining string
+	rateLimitReset     string
+}
+
+func NewHeaderInfo(resp *resty.Response) *LimitInfo {
+	return &LimitInfo{
+		dailyLimit:         resp.Header().Get("X-Daily-Limit"),
+		dailyCount:         resp.Header().Get("X-Daily-Count"),
+		rateLimitLimit:     resp.Header().Get("X-RateLimit-Limit"),
+		rateLimitRemaining: resp.Header().Get("X-RateLimit-Remaining"),
+		rateLimitReset:     resp.Header().Get("X-RateLimit-Reset"),
+	}
+}
+
+func (h LimitInfo) DailyLimit() int {
+	dailyLimit, _ := strconv.Atoi(h.dailyLimit)
+	return dailyLimit
+}
+
+func (h LimitInfo) DailyCount() int {
+	dailyCount, _ := strconv.Atoi(h.dailyCount)
+	return dailyCount
+}
+
+func (h LimitInfo) RateLimitLimit() int {
+	rateLimitLimit, _ := strconv.Atoi(h.rateLimitLimit)
+	return rateLimitLimit
+}
+
+func (h LimitInfo) RateLimitRemaining() int {
+	rateLimitRemaining, _ := strconv.Atoi(h.rateLimitRemaining)
+	return rateLimitRemaining
+}
+
+func (h LimitInfo) RateLimitReset() int {
+	rateLimitReset, _ := strconv.Atoi(h.rateLimitReset)
+	return rateLimitReset
 }
 }

+ 197 - 22
pkg/logic/sub_supplier/subtitle_best/subtitle_best.go

@@ -1,38 +1,68 @@
 package subtitle_best
 package subtitle_best
 
 
 import (
 import (
+	"github.com/ChineseSubFinder/ChineseSubFinder/pkg"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/logic/file_downloader"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/logic/file_downloader"
+	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/mix_media_info"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/settings"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/settings"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/common"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/common"
+	common2 "github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/common"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/series"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/series"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/supplier"
 	"github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/supplier"
+	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 	"time"
 	"time"
 )
 )
 
 
 type Supplier struct {
 type Supplier struct {
-	log            *logrus.Logger
-	fileDownloader *file_downloader.FileDownloader
-	topic          int
-	isAlive        bool
+	log                *logrus.Logger
+	fileDownloader     *file_downloader.FileDownloader
+	topic              int
+	isAlive            bool
+	api                *Api
+	dailyDownloadCount int
+	dailyDownloadLimit int
+}
+
+func NewSupplier(fileDownloader *file_downloader.FileDownloader) *Supplier {
+
+	sup := Supplier{}
+	sup.api = NewApi(headerToken, settings.Get().SubtitleSources.SubtitleBestSettings.ApiKey)
+	sup.log = fileDownloader.Log
+	sup.fileDownloader = fileDownloader
+	sup.isAlive = true // 默认是可以使用的,如果 check 后,再调整状态
+	sup.dailyDownloadCount = 0
+	sup.dailyDownloadLimit = 0
+
+	if settings.Get().AdvancedSettings.Topic != common2.DownloadSubsPerSite {
+		settings.Get().AdvancedSettings.Topic = common2.DownloadSubsPerSite
+	}
+
+	return &sup
 }
 }
 
 
 func (s *Supplier) CheckAlive() (bool, int64) {
 func (s *Supplier) CheckAlive() (bool, int64) {
 
 
+	// 如果没有设置这个 API 接口,那么就任务是不可用的
+	if settings.Get().SubtitleSources.SubtitleBestSettings.ApiKey == "" {
+		s.isAlive = false
+		return false, 0
+	}
+
 	// 计算当前时间
 	// 计算当前时间
 	startT := time.Now()
 	startT := time.Now()
-	//jsonList, err := s.getSubInfos(checkFileName, checkCID)
-	//if err != nil {
-	//	s.log.Errorln(s.GetSupplierName(), "CheckAlive", "Error", err)
-	//	s.isAlive = false
-	//	return false, 0
-	//}
-	//
-	//if len(jsonList.Sublist) < 1 {
-	//	s.log.Errorln(s.GetSupplierName(), "CheckAlive", "Sublist < 1")
-	//	s.isAlive = false
-	//	return false, 0
-	//}
+
+	client, err := pkg.NewHttpClient()
+	if err != nil {
+		s.log.Errorln(s.GetSupplierName(), "CheckAlive", "Error", err)
+		return false, 0
+	}
+	_, limitInfo, err := s.api.QueryMovieSubtitle(client, "tt00000")
+	if err != nil {
+		s.log.Errorln(s.GetSupplierName(), "CheckAlive.QueryMovieSubtitle", "Error", err)
+		return false, 0
+	}
+	s.updateLimitInfo(limitInfo)
 
 
 	s.isAlive = true
 	s.isAlive = true
 	return true, time.Since(startT).Milliseconds()
 	return true, time.Since(startT).Milliseconds()
@@ -44,12 +74,15 @@ func (s *Supplier) IsAlive() bool {
 
 
 func (s *Supplier) OverDailyDownloadLimit() bool {
 func (s *Supplier) OverDailyDownloadLimit() bool {
 
 
-	if settings.Get().AdvancedSettings.SuppliersSettings.Xunlei.DailyDownloadLimit == 0 {
-		s.log.Warningln(s.GetSupplierName(), "DailyDownloadLimit is 0, will Skip Download")
+	// 如果没有设置这个 API 接口,那么就任务是不可用的
+	if settings.Get().SubtitleSources.SubtitleBestSettings.ApiKey == "" {
+		return true
+	}
+	if s.dailyDownloadCount >= s.dailyDownloadLimit {
 		return true
 		return true
 	}
 	}
 
 
-	// 对于这个接口暂时没有限制
+	// 没有超出限制
 	return false
 	return false
 }
 }
 
 
@@ -62,13 +95,155 @@ func (s *Supplier) GetSupplierName() string {
 }
 }
 
 
 func (s *Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error) {
 func (s *Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error) {
-	return nil, nil
+
+	outSubInfos := make([]supplier.SubInfo, 0)
+	if settings.Get().SubtitleSources.SubtitleBestSettings.Enabled == false {
+		return outSubInfos, nil
+	}
+
+	if settings.Get().SubtitleSources.SubtitleBestSettings.ApiKey == "" {
+		return nil, errors.New("Token is empty")
+	}
+
+	return s.getSubListFromFile(filePath, true, 0, 0)
 }
 }
 
 
 func (s *Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 func (s *Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
-	return nil, nil
+
+	outSubInfos := make([]supplier.SubInfo, 0)
+	if settings.Get().SubtitleSources.SubtitleBestSettings.Enabled == false {
+		return outSubInfos, nil
+	}
+
+	if settings.Get().SubtitleSources.SubtitleBestSettings.ApiKey == "" {
+		return nil, errors.New("Token is empty")
+	}
+
+	return s.downloadSub4Series(seriesInfo)
 }
 }
 
 
 func (s *Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 func (s *Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
-	return nil, nil
+
+	outSubInfos := make([]supplier.SubInfo, 0)
+	if settings.Get().SubtitleSources.SubtitleBestSettings.Enabled == false {
+		return outSubInfos, nil
+	}
+
+	if settings.Get().SubtitleSources.SubtitleBestSettings.ApiKey == "" {
+		return nil, errors.New("Token is empty")
+	}
+
+	return s.downloadSub4Series(seriesInfo)
 }
 }
+
+// 更新当前的下载次数
+func (s *Supplier) updateLimitInfo(limitInfo *LimitInfo) {
+	s.dailyDownloadCount = limitInfo.DailyCount()
+	s.dailyDownloadLimit = limitInfo.DailyLimit()
+}
+
+func (s *Supplier) downloadSub4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
+
+	var allSupplierSubInfo = make([]supplier.SubInfo, 0)
+
+	index := 0
+	// 这里拿到的 seriesInfo ,里面包含了,需要下载字幕的 Eps 信息
+	for _, episodeInfo := range seriesInfo.NeedDlEpsKeyList {
+
+		index++
+		one, err := s.getSubListFromFile(episodeInfo.FileFullPath, false, episodeInfo.Season, episodeInfo.Episode)
+		if err != nil {
+			s.log.Errorln(s.GetSupplierName(), "getSubListFromFile", episodeInfo.FileFullPath, err)
+			continue
+		}
+		if one == nil {
+			// 没有搜索到字幕
+			s.log.Infoln(s.GetSupplierName(), "Not Find Sub can be download",
+				episodeInfo.Title, episodeInfo.Season, episodeInfo.Episode)
+			continue
+		}
+		// 需要赋值给字幕结构
+		for i := range one {
+			one[i].Season = episodeInfo.Season
+			one[i].Episode = episodeInfo.Episode
+		}
+		allSupplierSubInfo = append(allSupplierSubInfo, one...)
+	}
+	// 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SubInfo 中
+	return allSupplierSubInfo, nil
+}
+
+func (s *Supplier) getSubListFromFile(videoFPath string, isMovie bool, season, episode int) ([]supplier.SubInfo, error) {
+
+	defer func() {
+		s.log.Debugln(s.GetSupplierName(), videoFPath, "End...")
+	}()
+
+	s.log.Debugln(s.GetSupplierName(), videoFPath, "Start...")
+
+	outSubInfoList := make([]supplier.SubInfo, 0)
+	mediaInfo, err := mix_media_info.GetMixMediaInfo(s.fileDownloader.MediaInfoDealers, videoFPath, isMovie)
+	if err != nil {
+		s.log.Errorln(s.GetSupplierName(), videoFPath, "GetMixMediaInfo", err)
+		return nil, err
+	}
+
+	client, err := pkg.NewHttpClient()
+	if err != nil {
+		s.log.Errorln(s.GetSupplierName(), "NewHttpClient", "Error", err)
+		return nil, err
+	}
+
+	var subtitle *SubtitleResponse
+	var limitInfo *LimitInfo
+	if isMovie == true {
+		subtitle, limitInfo, err = s.api.QueryMovieSubtitle(client, mediaInfo.ImdbId)
+	} else {
+		subtitle, limitInfo, err = s.api.QueryTVEpsSubtitle(client, mediaInfo.ImdbId, season, episode)
+	}
+	if err != nil {
+		return nil, err
+	}
+	s.updateLimitInfo(limitInfo)
+
+	if len(subtitle.Subtitles) <= 0 {
+		return nil, nil
+	}
+
+	for index, subInfo := range subtitle.Subtitles {
+
+		// 获取具体的下载地址
+		var downloadUrl *GetUrlResponse
+		downloadUrl, limitInfo, err = s.api.GetDownloadUrl(client, subInfo.SubSha256, mediaInfo.ImdbId,
+			subInfo.IsMovie, subInfo.Season, subInfo.Episode,
+			"", subInfo.Language, subInfo.Token)
+		if err != nil {
+			return nil, err
+		}
+		s.updateLimitInfo(limitInfo)
+
+		// 下载地址为空
+		if len(downloadUrl.DownloadLink) < 1 {
+			continue
+		}
+		// 这里需要注意的是 SubtitleBest 的下载地址是时效性的,所以不能以下载地址进行唯一性存储
+		dSubInfo, err := s.fileDownloader.GetSubtitleBest(s.GetSupplierName(), int64(index), subInfo.Season, subInfo.Episode,
+			subInfo.Title, subInfo.Ext, subInfo.SubSha256, downloadUrl.DownloadLink)
+		if err != nil {
+			s.log.Error("FileDownloader.Get", err)
+			continue
+		}
+
+		outSubInfoList = append(outSubInfoList, *dSubInfo)
+		// 如果够了那么多个字幕就返回
+		if len(outSubInfoList) >= settings.Get().AdvancedSettings.Topic {
+			return outSubInfoList, nil
+		}
+	}
+
+	return outSubInfoList, nil
+}
+
+const (
+	headerToken = "5akwmGAbuFWqgaZf9QwT"
+)