fileinfo.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package subparser
  2. import (
  3. "github.com/allanpk716/ChineseSubFinder/internal/common"
  4. "github.com/allanpk716/ChineseSubFinder/internal/pkg/my_util"
  5. "github.com/allanpk716/ChineseSubFinder/internal/types/language"
  6. "math"
  7. "sort"
  8. "time"
  9. )
  10. type FileInfo struct {
  11. Content string // 字幕的内容
  12. FromWhereSite string // 从那个网站下载的
  13. Name string // 字幕的名称,注意,这里需要额外的赋值,不会自动检测
  14. Ext string // 字幕的后缀名
  15. Lang language.MyLanguage // 识别出来的语言
  16. FileFullPath string // 字幕文件的全路径
  17. Data []byte // 字幕的二进制文件内容
  18. Dialogues []OneDialogue // 整个字幕文件的所有对话,如果是做时间轴匹配,就使用原始的
  19. DialoguesFilter []OneDialogue // 整个字幕文件的所有对话,过滤掉特殊字符的对白
  20. DialoguesFilterEx []OneDialogueEx // 整个字幕文件的所有对话,过滤掉特殊字符的对白,这里会把一句话中支持的 中、英、韩、日 四国语言给分离出来
  21. CHLines []string // 抽取出所有的中文对话
  22. OtherLines []string // 抽取出所有的第二语言对话,可能是英文、韩文、日文
  23. }
  24. // SortDialogues 排序对话,时间递减
  25. func (f *FileInfo) SortDialogues() {
  26. sort.Sort(OneDialogueByStartTime(f.Dialogues))
  27. sort.Sort(OneDialogueByStartTime(f.DialoguesFilter))
  28. sort.Sort(OneDialogueByStartTimeEx(f.DialoguesFilterEx))
  29. }
  30. // GetTimeFormat 获取时间轴的格式化格式
  31. func (f FileInfo) GetTimeFormat() string {
  32. if f.Ext == common.SubExtASS || f.Ext == common.SubExtSSA {
  33. return common.TimeFormatPoint2
  34. } else {
  35. return common.TimeFormatPoint3
  36. }
  37. }
  38. // GetDialogueExContent 获取当前字幕文件语言对应索引的对白内容
  39. // 凡是带有 Eng 的返回 Eng,其他的就与对应语言相关
  40. func (f FileInfo) GetDialogueExContent(index int) string {
  41. switch f.Lang {
  42. case language.ChineseSimple, language.ChineseTraditional,
  43. language.ChineseSimpleJapanese, language.ChineseSimpleKorean,
  44. language.ChineseTraditionalJapanese, language.ChineseTraditionalKorean:
  45. // 带有中文的,但是又不是中英的
  46. return f.DialoguesFilterEx[index].ChLine
  47. case language.English, language.ChineseSimpleEnglish, language.ChineseTraditionalEnglish:
  48. return f.DialoguesFilterEx[index].EnLine
  49. case language.Japanese:
  50. return f.DialoguesFilterEx[index].JpLine
  51. case language.Korean:
  52. return f.DialoguesFilterEx[index].KrLine
  53. default:
  54. return f.DialoguesFilterEx[index].EnLine
  55. }
  56. }
  57. // ChangeDialoguesTimeByFramerateRatio 根据帧数比率调整时间轴 对应 ffsubsync -- SubtitleScaler
  58. func (f *FileInfo) ChangeDialoguesTimeByFramerateRatio(framerateRatio float64) error {
  59. timeFormat := f.GetTimeFormat()
  60. f.changeOneDialoguesFramerateRatio(f.Dialogues, framerateRatio, timeFormat)
  61. f.changeOneDialoguesFramerateRatio(f.DialoguesFilter, framerateRatio, timeFormat)
  62. f.changeOneDialogueExsFramerateRatio(f.DialoguesFilterEx, framerateRatio, timeFormat)
  63. return nil
  64. }
  65. func (f *FileInfo) changeOneDialoguesFramerateRatio(oneDialogues []OneDialogue, framerateRatio float64, timeFormat string) {
  66. for i := 0; i < len(oneDialogues); i++ {
  67. timeStart := oneDialogues[i].GetStartTime()
  68. timeEnd := oneDialogues[i].GetEndTime()
  69. timeStartNumber := my_util.Time2SecondNumber(timeStart)
  70. timeEndNumber := my_util.Time2SecondNumber(timeEnd)
  71. scaleTimeStart := my_util.TimeNumber2Time(timeStartNumber * framerateRatio)
  72. scaleTimeEnd := my_util.TimeNumber2Time(timeEndNumber * framerateRatio)
  73. oneDialogues[i].StartTime = my_util.Time2SubTimeString(scaleTimeStart, timeFormat)
  74. oneDialogues[i].EndTime = my_util.Time2SubTimeString(scaleTimeEnd, timeFormat)
  75. }
  76. }
  77. func (f *FileInfo) changeOneDialogueExsFramerateRatio(oneDialogues []OneDialogueEx, framerateRatio float64, timeFormat string) {
  78. for i := 0; i < len(oneDialogues); i++ {
  79. timeStart := oneDialogues[i].GetStartTime()
  80. timeEnd := oneDialogues[i].GetEndTime()
  81. timeStartNumber := my_util.Time2SecondNumber(timeStart)
  82. timeEndNumber := my_util.Time2SecondNumber(timeEnd)
  83. scaleTimeStart := my_util.TimeNumber2Time(timeStartNumber * framerateRatio)
  84. scaleTimeEnd := my_util.TimeNumber2Time(timeEndNumber * framerateRatio)
  85. oneDialogues[i].StartTime = my_util.Time2SubTimeString(scaleTimeStart, timeFormat)
  86. oneDialogues[i].EndTime = my_util.Time2SubTimeString(scaleTimeEnd, timeFormat)
  87. }
  88. }
  89. // GetStartTime 获取的是从 Dialogues 得到的
  90. func (f FileInfo) GetStartTime() time.Time {
  91. startTime := math.MaxFloat64
  92. for i := 0; i < len(f.Dialogues); i++ {
  93. // 找到最小的开始时间
  94. tmpNowStartTimeNumber := my_util.Time2SecondNumber(f.Dialogues[i].GetStartTime())
  95. startTime = math.Min(startTime, tmpNowStartTimeNumber)
  96. }
  97. return my_util.TimeNumber2Time(startTime)
  98. }
  99. // GetEndTime 获取的是从 Dialogues 得到的
  100. func (f FileInfo) GetEndTime() time.Time {
  101. endTime := -math.MaxFloat64
  102. for i := 0; i < len(f.Dialogues); i++ {
  103. // 找到最大的结束时间
  104. tmpNowEndTimeNumber := my_util.Time2SecondNumber(f.Dialogues[i].GetEndTime())
  105. endTime = math.Max(endTime, tmpNowEndTimeNumber)
  106. }
  107. return my_util.TimeNumber2Time(endTime)
  108. }
  109. // GetNumFrames 获取这个字幕的时间 Frame 数量
  110. func (f FileInfo) GetNumFrames() int {
  111. return int(math.Abs((my_util.Time2SecondNumber(f.GetEndTime()) - my_util.Time2SecondNumber(f.GetStartTime())) * 100))
  112. }
  113. // OneDialogue 一句对话
  114. type OneDialogue struct {
  115. StartTime string // 开始时间
  116. EndTime string // 结束时间
  117. StyleName string // StyleName
  118. Lines []string // 台词
  119. }
  120. func (o OneDialogue) GetStartTime() time.Time {
  121. srcTimeStartNow, err := my_util.ParseTime(o.StartTime)
  122. if err != nil {
  123. return time.Time{}
  124. }
  125. return srcTimeStartNow
  126. }
  127. func (o OneDialogue) GetEndTime() time.Time {
  128. srcTimeEndNow, err := my_util.ParseTime(o.EndTime)
  129. if err != nil {
  130. return time.Time{}
  131. }
  132. return srcTimeEndNow
  133. }
  134. type OneDialogueByStartTime []OneDialogue
  135. func (d OneDialogueByStartTime) Len() int {
  136. return len(d)
  137. }
  138. func (d OneDialogueByStartTime) Swap(i, j int) {
  139. d[i], d[j] = d[j], d[i]
  140. }
  141. func (d OneDialogueByStartTime) Less(i, j int) bool {
  142. subStartTimeI, err := my_util.ParseTime(d[i].StartTime)
  143. if err != nil {
  144. return false
  145. }
  146. subStartTimeJ, err := my_util.ParseTime(d[j].StartTime)
  147. if err != nil {
  148. return false
  149. }
  150. return my_util.Time2SecondNumber(subStartTimeI) < my_util.Time2SecondNumber(subStartTimeJ)
  151. }
  152. // OneDialogueEx 一句对话,这里会把一句话中支持的 中、英、韩、日 四国语言给分离出来
  153. type OneDialogueEx struct {
  154. StartTime string // 开始时间
  155. EndTime string // 结束时间
  156. ChLine string
  157. EnLine string
  158. KrLine string
  159. JpLine string
  160. }
  161. func (o OneDialogueEx) GetStartTime() time.Time {
  162. srcTimeStartNow, err := my_util.ParseTime(o.StartTime)
  163. if err != nil {
  164. return time.Time{}
  165. }
  166. return srcTimeStartNow
  167. }
  168. func (o OneDialogueEx) GetEndTime() time.Time {
  169. srcTimeEndNow, err := my_util.ParseTime(o.EndTime)
  170. if err != nil {
  171. return time.Time{}
  172. }
  173. return srcTimeEndNow
  174. }
  175. type OneDialogueByStartTimeEx []OneDialogueEx
  176. func (d OneDialogueByStartTimeEx) Len() int {
  177. return len(d)
  178. }
  179. func (d OneDialogueByStartTimeEx) Swap(i, j int) {
  180. d[i], d[j] = d[j], d[i]
  181. }
  182. func (d OneDialogueByStartTimeEx) Less(i, j int) bool {
  183. subStartTimeI, err := my_util.ParseTime(d[i].StartTime)
  184. if err != nil {
  185. return false
  186. }
  187. subStartTimeJ, err := my_util.ParseTime(d[j].StartTime)
  188. if err != nil {
  189. return false
  190. }
  191. return my_util.Time2SecondNumber(subStartTimeI) < my_util.Time2SecondNumber(subStartTimeJ)
  192. }
  193. const (
  194. Sub_Ext_Mark_Default = ".default" // 指定这个字幕是默认的
  195. Sub_Ext_Mark_Forced = ".forced" // 指定这个字幕是强制的
  196. )