108 lines
2.7 KiB
Go
108 lines
2.7 KiB
Go
// Package utils 提供工具函数
|
|
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"gitea.malaihome.work/ans/podcast-search-go/model"
|
|
)
|
|
|
|
// SrtParser 用于解析SRT格式的转录文件
|
|
type SrtParser struct {
|
|
// SRT格式匹配正则表达式
|
|
srtMatcher *regexp.Regexp
|
|
// 换行符匹配正则表达式
|
|
newlineMatcher *regexp.Regexp
|
|
}
|
|
|
|
// NewSrtParser 创建新的SRT解析器
|
|
func NewSrtParser() *SrtParser {
|
|
return &SrtParser{
|
|
srtMatcher: regexp.MustCompile(
|
|
`(\d*)\s?((\d{2}):(\d{2}):(\d{2})[,|.](\d{3})) +--> +((\d{2}):(\d{2}):(\d{2})[,|.](\d{3})).*[\r\n]+\s*([^\r\n]+(\n|\r|\n)(?:.*))`,
|
|
),
|
|
newlineMatcher: regexp.MustCompile(`[\r\n]+`),
|
|
}
|
|
}
|
|
|
|
// Parse 解析SRT格式的转录文件
|
|
func (p *SrtParser) Parse(srtData string) (*model.Transcript, error) {
|
|
matches := p.srtMatcher.FindAllStringSubmatch(srtData, -1)
|
|
subtitles := make([]model.Subtitle, 0)
|
|
i := 0
|
|
|
|
for _, match := range matches {
|
|
i++
|
|
|
|
// 索引可能存在也可能不存在
|
|
index := i
|
|
if match[1] != "" {
|
|
parsedIndex, err := strconv.Atoi(match[1])
|
|
if err == nil {
|
|
index = parsedIndex
|
|
}
|
|
}
|
|
|
|
// 解析开始时间
|
|
startTimeHours, _ := strconv.Atoi(match[3])
|
|
startTimeMinutes, _ := strconv.Atoi(match[4])
|
|
startTimeSeconds, _ := strconv.Atoi(match[5])
|
|
startTimeMilliseconds, _ := strconv.Atoi(match[6])
|
|
|
|
// 解析结束时间
|
|
endTimeHours, _ := strconv.Atoi(match[8])
|
|
endTimeMinutes, _ := strconv.Atoi(match[9])
|
|
endTimeSeconds, _ := strconv.Atoi(match[10])
|
|
endTimeMilliseconds, _ := strconv.Atoi(match[11])
|
|
|
|
// 计算开始和结束时间的Duration
|
|
startDuration := time.Duration(startTimeHours)*time.Hour +
|
|
time.Duration(startTimeMinutes)*time.Minute +
|
|
time.Duration(startTimeSeconds)*time.Second +
|
|
time.Duration(startTimeMilliseconds)*time.Millisecond
|
|
|
|
endDuration := time.Duration(endTimeHours)*time.Hour +
|
|
time.Duration(endTimeMinutes)*time.Minute +
|
|
time.Duration(endTimeSeconds)*time.Second +
|
|
time.Duration(endTimeMilliseconds)*time.Millisecond
|
|
|
|
// 解析文本内容
|
|
textLines := p.newlineMatcher.Split(match[12], -1)
|
|
text := ""
|
|
|
|
// 处理文本行
|
|
for _, line := range textLines {
|
|
if text == "" {
|
|
text = line
|
|
} else if strings.HasSuffix(text, " ") || strings.HasPrefix(line, " ") {
|
|
text += line
|
|
} else {
|
|
text += " " + line
|
|
}
|
|
}
|
|
|
|
// 创建字幕
|
|
subtitle := model.Subtitle{
|
|
Index: index,
|
|
Start: startDuration,
|
|
End: endDuration,
|
|
Data: strings.TrimSpace(text),
|
|
Speaker: "", // SRT格式通常不包含发言人信息
|
|
}
|
|
|
|
subtitles = append(subtitles, subtitle)
|
|
}
|
|
|
|
if len(subtitles) == 0 {
|
|
return nil, fmt.Errorf("解析SRT失败: 未找到有效的字幕")
|
|
}
|
|
|
|
return &model.Transcript{
|
|
Subtitles: subtitles,
|
|
}, nil
|
|
}
|