122 lines
3.3 KiB
Go
122 lines
3.3 KiB
Go
package ass
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"sub-cli/internal/model"
|
|
)
|
|
|
|
// Generate 生成ASS文件
|
|
func Generate(assFile model.ASSFile, filePath string) error {
|
|
// 确保目录存在
|
|
dir := filepath.Dir(filePath)
|
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
|
return fmt.Errorf("创建目录失败: %w", err)
|
|
}
|
|
|
|
// 创建或覆盖文件
|
|
file, err := os.Create(filePath)
|
|
if err != nil {
|
|
return fmt.Errorf("创建ASS文件失败: %w", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
// 写入脚本信息
|
|
if _, err := file.WriteString(ASSHeader + "\n"); err != nil {
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
}
|
|
|
|
for key, value := range assFile.ScriptInfo {
|
|
if _, err := file.WriteString(fmt.Sprintf("%s: %s\n", key, value)); err != nil {
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
}
|
|
}
|
|
|
|
// 写入样式信息
|
|
if _, err := file.WriteString("\n" + ASSStylesHeader + "\n"); err != nil {
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
}
|
|
|
|
// 写入样式格式行
|
|
if len(assFile.Styles) > 0 {
|
|
var formatString string
|
|
for _, style := range assFile.Styles {
|
|
if formatString == "" && style.Properties["Format"] != "" {
|
|
formatString = style.Properties["Format"]
|
|
if _, err := file.WriteString(fmt.Sprintf("Format: %s\n", formatString)); err != nil {
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
// 如果没有找到格式行,写入默认格式
|
|
if formatString == "" {
|
|
defaultFormat := "Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding"
|
|
if _, err := file.WriteString(fmt.Sprintf("Format: %s\n", defaultFormat)); err != nil {
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
}
|
|
}
|
|
|
|
// 写入样式定义
|
|
for _, style := range assFile.Styles {
|
|
if style.Properties["Style"] != "" {
|
|
if _, err := file.WriteString(fmt.Sprintf("Style: %s\n", style.Properties["Style"])); err != nil {
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 写入事件信息
|
|
if _, err := file.WriteString("\n" + ASSEventsHeader + "\n"); err != nil {
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
}
|
|
|
|
// 写入事件格式行
|
|
if _, err := file.WriteString(DefaultFormat + "\n"); err != nil {
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
}
|
|
|
|
// 写入事件行
|
|
for _, event := range assFile.Events {
|
|
eventLine := formatEventLine(event)
|
|
if _, err := file.WriteString(eventLine + "\n"); err != nil {
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// formatEventLine 将事件格式化为ASS文件中的一行
|
|
func formatEventLine(event model.ASSEvent) string {
|
|
// 格式化时间戳
|
|
startTime := formatASSTimestamp(event.StartTime)
|
|
endTime := formatASSTimestamp(event.EndTime)
|
|
|
|
// 构建事件行
|
|
var builder strings.Builder
|
|
if event.Type == "Comment" {
|
|
builder.WriteString("Comment: ")
|
|
} else {
|
|
builder.WriteString("Dialogue: ")
|
|
}
|
|
|
|
builder.WriteString(fmt.Sprintf("%d,%s,%s,%s,%s,%d,%d,%d,%s,%s",
|
|
event.Layer,
|
|
startTime,
|
|
endTime,
|
|
event.Style,
|
|
event.Name,
|
|
event.MarginL,
|
|
event.MarginR,
|
|
event.MarginV,
|
|
event.Effect,
|
|
event.Text))
|
|
|
|
return builder.String()
|
|
}
|