sub_timeline_fixer_helper.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package sub_timeline_fixer
  2. import (
  3. "github.com/allanpk716/ChineseSubFinder/internal/common"
  4. "github.com/allanpk716/ChineseSubFinder/internal/logic/emby_helper"
  5. "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/ass"
  6. "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/srt"
  7. "github.com/allanpk716/ChineseSubFinder/internal/pkg"
  8. embyHelper "github.com/allanpk716/ChineseSubFinder/internal/pkg/emby_api"
  9. "github.com/allanpk716/ChineseSubFinder/internal/pkg/sub_parser_hub"
  10. "github.com/allanpk716/ChineseSubFinder/internal/pkg/sub_timeline_fixer"
  11. "github.com/allanpk716/ChineseSubFinder/internal/types/emby"
  12. "os"
  13. "path"
  14. "time"
  15. )
  16. type SubTimelineFixerHelper struct {
  17. embyApi *embyHelper.EmbyApi
  18. embyHelper *emby_helper.EmbyHelper
  19. EmbyConfig emby.EmbyConfig
  20. subParserHub *sub_parser_hub.SubParserHub
  21. threads int
  22. timeOut time.Duration
  23. }
  24. func NewSubTimelineFixerHelper(embyConfig emby.EmbyConfig) *SubTimelineFixerHelper {
  25. sub := SubTimelineFixerHelper{
  26. EmbyConfig: embyConfig,
  27. embyHelper: emby_helper.NewEmbyHelper(embyConfig),
  28. embyApi: embyHelper.NewEmbyApi(embyConfig),
  29. subParserHub: sub_parser_hub.NewSubParserHub(ass.NewParser(), srt.NewParser()),
  30. threads: 6,
  31. timeOut: 60 * time.Second,
  32. }
  33. return &sub
  34. }
  35. func (s SubTimelineFixerHelper) FixRecentlyItemsSubTimeline() error {
  36. items, err := s.embyApi.GetRecentlyItems()
  37. if err != nil {
  38. return err
  39. }
  40. for _, item := range items.Items {
  41. err = s.fixOneVideoSub(item.Id)
  42. if err != nil {
  43. return err
  44. }
  45. }
  46. return nil
  47. }
  48. func (s SubTimelineFixerHelper) fixOneVideoSub(videoId string) error {
  49. // internalEngSub 默认第一个是 srt 然后第二个是 ass,就不要去遍历了
  50. found, internalEngSub, exCh_EngSub, err := s.embyHelper.GetInternalEngSubAndExChineseEnglishSub(videoId)
  51. if err != nil {
  52. return err
  53. }
  54. if found == false {
  55. return nil
  56. }
  57. // 从外置双语(中英)字幕中找对对应的内置 srt 字幕进行匹配比较
  58. for _, exSubInfo := range exCh_EngSub {
  59. inSelectSubIndex := 1
  60. if exSubInfo.Ext == common.SubExtSRT {
  61. inSelectSubIndex = 0
  62. }
  63. bFound, err := s.fixSubTimeline(internalEngSub[inSelectSubIndex], exSubInfo)
  64. if err != nil {
  65. return err
  66. }
  67. if bFound == false {
  68. continue
  69. }
  70. }
  71. return nil
  72. }
  73. func (s SubTimelineFixerHelper) fixSubTimeline(enSubFile emby.SubInfo, ch_enSubFile emby.SubInfo) (bool, error) {
  74. bFind, infoBase, err := s.subParserHub.DetermineFileTypeFromBytes(enSubFile.Content, enSubFile.Ext)
  75. if err != nil {
  76. return false, err
  77. }
  78. if bFind == false {
  79. return false, nil
  80. }
  81. infoBase.Name = enSubFile.FileName
  82. bFind, infoSrc, err := s.subParserHub.DetermineFileTypeFromBytes(ch_enSubFile.Content, ch_enSubFile.Ext)
  83. if err != nil {
  84. return false, err
  85. }
  86. if bFind == false {
  87. return false, nil
  88. }
  89. infoSrc.Name = ch_enSubFile.FileName
  90. // 把原始的文件缓存下来
  91. if pkg.IsDir(path.Join(tmpFolder, infoBase.Name)) == false {
  92. err = os.MkdirAll(path.Join(tmpFolder, infoBase.Name), os.ModePerm)
  93. if err != nil {
  94. return false, err
  95. }
  96. }
  97. offsetTime, err := sub_timeline_fixer.GetOffsetTime(infoBase, infoSrc, path.Join(tmpFolder, infoBase.Name, "bar.html"))
  98. if err != nil {
  99. return false, err
  100. }
  101. // 偏移很小就无视了
  102. if offsetTime < 0.2 {
  103. _ = pkg.ClearFolder(path.Join(tmpFolder, infoBase.Name))
  104. return false, nil
  105. }
  106. err = s.saveOrgSubFile(path.Join(tmpFolder, infoBase.Name, infoBase.Name+infoBase.Ext), infoBase.Content)
  107. if err != nil {
  108. return false, err
  109. }
  110. err = s.saveOrgSubFile(path.Join(tmpFolder, infoBase.Name, infoSrc.Name+infoSrc.Ext), infoSrc.Content)
  111. if err != nil {
  112. return false, err
  113. }
  114. err = sub_timeline_fixer.FixSubTimeline(infoSrc, offsetTime, path.Join(tmpFolder, infoBase.Name, infoBase.Name+".chinese(fix)"+ch_enSubFile.Ext))
  115. if err != nil {
  116. return false, err
  117. }
  118. return true, nil
  119. }
  120. func (s SubTimelineFixerHelper) saveOrgSubFile(desSaveSubFileFullPath string, content string) error {
  121. dstFile, err := os.Create(desSaveSubFileFullPath)
  122. if err != nil {
  123. return err
  124. }
  125. defer func() {
  126. _ = dstFile.Close()
  127. }()
  128. _, err = dstFile.WriteString(content)
  129. if err != nil {
  130. return err
  131. }
  132. return nil
  133. }
  134. const tmpFolder = "tmpSubFix"