chore: seperate large files
This commit is contained in:
parent
ebbf516689
commit
76e1298ded
44 changed files with 5745 additions and 4173 deletions
186
internal/format/ass/converter.go
Normal file
186
internal/format/ass/converter.go
Normal file
|
@ -0,0 +1,186 @@
|
|||
package ass
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"sub-cli/internal/model"
|
||||
)
|
||||
|
||||
// ConvertToSubtitle 将ASS文件转换为通用字幕格式
|
||||
func ConvertToSubtitle(filePath string) (model.Subtitle, error) {
|
||||
// 解析ASS文件
|
||||
assFile, err := Parse(filePath)
|
||||
if err != nil {
|
||||
return model.Subtitle{}, fmt.Errorf("解析ASS文件失败: %w", err)
|
||||
}
|
||||
|
||||
// 创建通用字幕结构
|
||||
subtitle := model.NewSubtitle()
|
||||
subtitle.Format = "ass"
|
||||
|
||||
// 转换标题
|
||||
if title, ok := assFile.ScriptInfo["Title"]; ok {
|
||||
subtitle.Title = title
|
||||
}
|
||||
|
||||
// 转换事件为字幕条目
|
||||
for i, event := range assFile.Events {
|
||||
// 只转换对话类型的事件
|
||||
if event.Type == "Dialogue" {
|
||||
entry := model.SubtitleEntry{
|
||||
Index: i + 1,
|
||||
StartTime: event.StartTime,
|
||||
EndTime: event.EndTime,
|
||||
Text: event.Text,
|
||||
Styles: make(map[string]string),
|
||||
Metadata: make(map[string]string),
|
||||
}
|
||||
|
||||
// 记录样式信息
|
||||
entry.Styles["style"] = event.Style
|
||||
|
||||
// 记录ASS特有信息
|
||||
entry.Metadata["Layer"] = fmt.Sprintf("%d", event.Layer)
|
||||
entry.Metadata["Name"] = event.Name
|
||||
entry.Metadata["MarginL"] = fmt.Sprintf("%d", event.MarginL)
|
||||
entry.Metadata["MarginR"] = fmt.Sprintf("%d", event.MarginR)
|
||||
entry.Metadata["MarginV"] = fmt.Sprintf("%d", event.MarginV)
|
||||
entry.Metadata["Effect"] = event.Effect
|
||||
|
||||
subtitle.Entries = append(subtitle.Entries, entry)
|
||||
}
|
||||
}
|
||||
|
||||
return subtitle, nil
|
||||
}
|
||||
|
||||
// ConvertFromSubtitle 将通用字幕格式转换为ASS文件
|
||||
func ConvertFromSubtitle(subtitle model.Subtitle, filePath string) error {
|
||||
// 创建ASS文件结构
|
||||
assFile := model.NewASSFile()
|
||||
|
||||
// 设置标题
|
||||
if subtitle.Title != "" {
|
||||
assFile.ScriptInfo["Title"] = subtitle.Title
|
||||
}
|
||||
|
||||
// 转换字幕条目为ASS事件
|
||||
for _, entry := range subtitle.Entries {
|
||||
event := model.NewASSEvent()
|
||||
event.Type = "Dialogue"
|
||||
event.StartTime = entry.StartTime
|
||||
event.EndTime = entry.EndTime
|
||||
event.Text = entry.Text
|
||||
|
||||
// 检查是否有ASS特有的元数据
|
||||
if layer, ok := entry.Metadata["Layer"]; ok {
|
||||
fmt.Sscanf(layer, "%d", &event.Layer)
|
||||
}
|
||||
|
||||
if name, ok := entry.Metadata["Name"]; ok {
|
||||
event.Name = name
|
||||
}
|
||||
|
||||
if marginL, ok := entry.Metadata["MarginL"]; ok {
|
||||
fmt.Sscanf(marginL, "%d", &event.MarginL)
|
||||
}
|
||||
|
||||
if marginR, ok := entry.Metadata["MarginR"]; ok {
|
||||
fmt.Sscanf(marginR, "%d", &event.MarginR)
|
||||
}
|
||||
|
||||
if marginV, ok := entry.Metadata["MarginV"]; ok {
|
||||
fmt.Sscanf(marginV, "%d", &event.MarginV)
|
||||
}
|
||||
|
||||
if effect, ok := entry.Metadata["Effect"]; ok {
|
||||
event.Effect = effect
|
||||
}
|
||||
|
||||
// 处理样式
|
||||
if style, ok := entry.Styles["style"]; ok {
|
||||
event.Style = style
|
||||
} else {
|
||||
// 根据基本样式设置ASS样式
|
||||
if _, ok := entry.Styles["bold"]; ok {
|
||||
// 创建一个加粗样式(如果尚未存在)
|
||||
styleName := "Bold"
|
||||
found := false
|
||||
for _, style := range assFile.Styles {
|
||||
if style.Name == styleName {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
boldStyle := model.ASSStyle{
|
||||
Name: styleName,
|
||||
Properties: map[string]string{
|
||||
"Format": "Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding",
|
||||
"Style": "Bold,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,1,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1",
|
||||
},
|
||||
}
|
||||
assFile.Styles = append(assFile.Styles, boldStyle)
|
||||
}
|
||||
|
||||
event.Style = styleName
|
||||
}
|
||||
|
||||
if _, ok := entry.Styles["italic"]; ok {
|
||||
// 创建一个斜体样式(如果尚未存在)
|
||||
styleName := "Italic"
|
||||
found := false
|
||||
for _, style := range assFile.Styles {
|
||||
if style.Name == styleName {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
italicStyle := model.ASSStyle{
|
||||
Name: styleName,
|
||||
Properties: map[string]string{
|
||||
"Format": "Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding",
|
||||
"Style": "Italic,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,1,0,0,100,100,0,0,1,2,2,2,10,10,10,1",
|
||||
},
|
||||
}
|
||||
assFile.Styles = append(assFile.Styles, italicStyle)
|
||||
}
|
||||
|
||||
event.Style = styleName
|
||||
}
|
||||
|
||||
if _, ok := entry.Styles["underline"]; ok {
|
||||
// 创建一个下划线样式(如果尚未存在)
|
||||
styleName := "Underline"
|
||||
found := false
|
||||
for _, style := range assFile.Styles {
|
||||
if style.Name == styleName {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
underlineStyle := model.ASSStyle{
|
||||
Name: styleName,
|
||||
Properties: map[string]string{
|
||||
"Format": "Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding",
|
||||
"Style": "Underline,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,1,0,100,100,0,0,1,2,2,2,10,10,10,1",
|
||||
},
|
||||
}
|
||||
assFile.Styles = append(assFile.Styles, underlineStyle)
|
||||
}
|
||||
|
||||
event.Style = styleName
|
||||
}
|
||||
}
|
||||
|
||||
assFile.Events = append(assFile.Events, event)
|
||||
}
|
||||
|
||||
// 生成ASS文件
|
||||
return Generate(assFile, filePath)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue