subParserHub.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package sub_parser_hub
  2. import (
  3. "github.com/allanpk716/ChineseSubFinder/internal/common"
  4. "github.com/allanpk716/ChineseSubFinder/internal/ifaces"
  5. "github.com/allanpk716/ChineseSubFinder/internal/pkg/language"
  6. "github.com/allanpk716/ChineseSubFinder/internal/pkg/log_helper"
  7. languageConst "github.com/allanpk716/ChineseSubFinder/internal/types/language"
  8. "github.com/allanpk716/ChineseSubFinder/internal/types/subparser"
  9. "path/filepath"
  10. "regexp"
  11. "strings"
  12. )
  13. type SubParserHub struct {
  14. Parser []ifaces.ISubParser
  15. }
  16. // NewSubParserHub 处理的字幕文件需要符合 [siteName]_ 的前缀描述,是本程序专用的
  17. func NewSubParserHub(parser ifaces.ISubParser, _parser ...ifaces.ISubParser) *SubParserHub {
  18. s := SubParserHub{}
  19. s.Parser = make([]ifaces.ISubParser, 0)
  20. s.Parser = append(s.Parser, parser)
  21. if len(_parser) > 0 {
  22. for _, one := range _parser {
  23. s.Parser = append(s.Parser, one)
  24. }
  25. }
  26. return &s
  27. }
  28. // DetermineFileTypeFromFile 确定字幕文件的类型,是双语字幕或者某一种语言等等信息,如果返回 nil ,那么就说明都没有字幕的格式匹配上
  29. func (p SubParserHub) DetermineFileTypeFromFile(filePath string) (bool, *subparser.FileInfo, error) {
  30. for _, parser := range p.Parser {
  31. bFind, subFileInfo, err := parser.DetermineFileTypeFromFile(filePath)
  32. if err != nil {
  33. return false, nil, err
  34. }
  35. if bFind == false {
  36. continue
  37. }
  38. // 正常至少应该匹配一个吧,不然就是最外层继续返回 nil 出去了
  39. // 简体和繁体字幕的判断,通过文件名来做到的,基本就算个补判而已
  40. //newLang := IsChineseSimpleOrTraditional(filePath, subFileInfo.Lang)
  41. subFileInfo.Name = filepath.Base(filePath)
  42. //subFileInfo.Lang = newLang
  43. subFileInfo.FileFullPath = filePath
  44. subFileInfo.FromWhereSite = p.getFromWhereSite(filePath)
  45. return true, subFileInfo, nil
  46. }
  47. // 如果返回 nil ,那么就说明都没有字幕的格式匹配上
  48. return false, nil, nil
  49. }
  50. // DetermineFileTypeFromBytes 确定字幕文件的类型,是双语字幕或者某一种语言等等信息,如果返回 nil ,那么就说明都没有字幕的格式匹配上
  51. // 如果要做字幕的时间轴匹配,很可能需要一个功能 sub_helper.MergeMultiDialogue4EngSubtitle,但是仅仅是合并了 English 字幕时间轴
  52. func (p SubParserHub) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (bool, *subparser.FileInfo, error) {
  53. for _, parser := range p.Parser {
  54. bFind, subFileInfo, err := parser.DetermineFileTypeFromBytes(inBytes, nowExt)
  55. if err != nil {
  56. return false, nil, err
  57. }
  58. if bFind == false {
  59. continue
  60. }
  61. return true, subFileInfo, nil
  62. }
  63. // 如果返回 nil ,那么就说明都没有字幕的格式匹配上
  64. return false, nil, nil
  65. }
  66. // IsSubHasChinese 字幕文件是否包含中文
  67. func (p SubParserHub) IsSubHasChinese(fileFPath string) bool {
  68. // 增加判断已存在的字幕是否有中文
  69. bFind, file, err := p.DetermineFileTypeFromFile(fileFPath)
  70. if err != nil {
  71. log_helper.GetLogger().Errorln("IsSubHasChinese.DetermineFileTypeFromFile", fileFPath, err)
  72. return false
  73. }
  74. if bFind == false {
  75. log_helper.GetLogger().Warnln("IsSubHasChinese.DetermineFileTypeFromFile", fileFPath, "not support SubType")
  76. return false
  77. }
  78. if language.HasChineseLang(file.Lang) == false {
  79. log_helper.GetLogger().Warnln("IsSubHasChinese.HasChineseLang", fileFPath, "not chinese sub, is ", file.Lang.String())
  80. return false
  81. }
  82. return true
  83. }
  84. // getFromWhereSite 从文件名找出是从那个网站下载的。这里的文件名的前缀是下载时候标记好的,比较特殊
  85. func (p SubParserHub) getFromWhereSite(filePath string) string {
  86. fileName := filepath.Base(filePath)
  87. var re = regexp.MustCompile(`^\[(\w+)\]_`)
  88. matched := re.FindStringSubmatch(fileName)
  89. if matched == nil || len(matched) < 1 {
  90. return ""
  91. }
  92. return matched[1]
  93. }
  94. // IsSubTypeWanted 这里匹配的字幕的格式,不包含 Ext 的 . 小数点,注意,仅仅是包含关系
  95. func IsSubTypeWanted(subName string) bool {
  96. nowLowerName := strings.ToLower(subName)
  97. if strings.Contains(nowLowerName, common.SubTypeASS) ||
  98. strings.Contains(nowLowerName, common.SubTypeSSA) ||
  99. strings.Contains(nowLowerName, common.SubTypeSRT) {
  100. return true
  101. }
  102. return false
  103. }
  104. // IsSubExtWanted 输入的字幕文件名,判断后缀名是否符合期望的字幕后缀名列表
  105. func IsSubExtWanted(subName string) bool {
  106. inExt := filepath.Ext(subName)
  107. switch strings.ToLower(inExt) {
  108. case common.SubExtSSA, common.SubExtASS, common.SubExtSRT:
  109. return true
  110. default:
  111. return false
  112. }
  113. }
  114. // IsEmbySubCodecWanted 从 Emby api 拿到字幕的 sub 类型 string (Codec) 是否是符合本程序要求的
  115. func IsEmbySubCodecWanted(inSubCodec string) bool {
  116. tmpString := strings.ToLower(inSubCodec)
  117. if tmpString == common.SubTypeSRT ||
  118. tmpString == common.SubTypeASS ||
  119. tmpString == common.SubTypeSSA {
  120. return true
  121. }
  122. return false
  123. }
  124. // IsEmbySubChineseLangStringWanted 是否是 Emby 自己解析出来的中文语言类型
  125. func IsEmbySubChineseLangStringWanted(inLangString string) bool {
  126. isWanted := false
  127. tmpString := strings.ToLower(inLangString)
  128. nextString := tmpString
  129. spStrings := strings.Split(tmpString, "[")
  130. if len(spStrings) > 1 {
  131. // 去除 chi[xunlie] 类似的标记
  132. nextString = spStrings[0]
  133. } else {
  134. // 去除 chinese(简英,zimuku)
  135. spStrings = strings.Split(tmpString, "(")
  136. if len(spStrings) > 1 {
  137. nextString = spStrings[0]
  138. }
  139. }
  140. // 先判断 ISO 标准的和变种的支持列表
  141. if language.IsSupportISOString(nextString) {
  142. // fmt.Println("###: ERROR")
  143. isWanted = true
  144. }
  145. // 再判断之前支持的列表
  146. switch nextString {
  147. case languageConst.Emby_chinese_chs,
  148. languageConst.Emby_chinese_cht,
  149. languageConst.Emby_chinese_chi:
  150. // chi chs cht
  151. isWanted = true
  152. case replaceLangString(languageConst.Emby_chinese):
  153. // chinese,这个比较特殊,是本程序定义的 chinese 的字段,再 Emby API 下特殊的字幕命名字段
  154. isWanted = true
  155. }
  156. return isWanted
  157. }
  158. func replaceLangString(inString string) string {
  159. tmpString := strings.ToLower(inString)
  160. one := strings.ReplaceAll(tmpString, ".", "")
  161. two := strings.ReplaceAll(one, "_", "")
  162. return two
  163. }