feat: add tests

This commit is contained in:
CDN 2025-04-23 16:30:45 +08:00
parent 44c7e9bee5
commit bb87f058f0
Signed by: CDN
GPG key ID: 0C656827F9F80080
17 changed files with 4436 additions and 80 deletions

View file

@ -110,11 +110,14 @@ func syncLRCTimeline(source, target model.Lyrics) model.Lyrics {
Content: target.Content,
}
// Create timeline with same length as target content
result.Timeline = make([]model.Timestamp, len(target.Content))
// Use source timeline if available and lengths match
if len(source.Timeline) > 0 && len(source.Timeline) == len(target.Content) {
result.Timeline = source.Timeline
copy(result.Timeline, source.Timeline)
} else if len(source.Timeline) > 0 {
// If lengths don't match, scale timeline
// If lengths don't match, scale timeline using our improved scaleTimeline function
result.Timeline = scaleTimeline(source.Timeline, len(target.Content))
}
@ -193,6 +196,15 @@ func syncVTTTimeline(source, target model.Subtitle) model.Subtitle {
// Copy target entries
copy(result.Entries, target.Entries)
// 如果源字幕为空或目标字幕为空,直接返回复制的目标内容
if len(source.Entries) == 0 || len(target.Entries) == 0 {
// 确保索引编号正确
for i := range result.Entries {
result.Entries[i].Index = i + 1
}
return result
}
// If source and target have the same number of entries, directly apply timings
if len(source.Entries) == len(target.Entries) {
for i := range result.Entries {
@ -256,10 +268,64 @@ func scaleTimeline(timeline []model.Timestamp, targetCount int) []model.Timestam
sourceLength := len(timeline)
// Handle simple case: same length
if targetCount == sourceLength {
copy(result, timeline)
return result
}
// Handle case where target is longer than source
// We need to interpolate timestamps between source entries
for i := 0; i < targetCount; i++ {
// Scale index to match source timeline
sourceIndex := i * (sourceLength - 1) / (targetCount - 1)
result[i] = timeline[sourceIndex]
if sourceLength == 1 {
// If source has only one entry, use it for all target entries
result[i] = timeline[0]
continue
}
// Calculate a floating-point position in the source timeline
floatIndex := float64(i) * float64(sourceLength-1) / float64(targetCount-1)
lowerIndex := int(floatIndex)
upperIndex := lowerIndex + 1
// Handle boundary case
if upperIndex >= sourceLength {
upperIndex = sourceLength - 1
lowerIndex = upperIndex - 1
}
// If indices are the same, just use the source timestamp
if lowerIndex == upperIndex || lowerIndex < 0 {
result[i] = timeline[upperIndex]
} else {
// Calculate the fraction between the lower and upper indices
fraction := floatIndex - float64(lowerIndex)
// Convert timestamps to milliseconds for interpolation
lowerMS := timeline[lowerIndex].Hours*3600000 + timeline[lowerIndex].Minutes*60000 +
timeline[lowerIndex].Seconds*1000 + timeline[lowerIndex].Milliseconds
upperMS := timeline[upperIndex].Hours*3600000 + timeline[upperIndex].Minutes*60000 +
timeline[upperIndex].Seconds*1000 + timeline[upperIndex].Milliseconds
// Interpolate
resultMS := int(float64(lowerMS) + fraction*float64(upperMS-lowerMS))
// Convert back to timestamp
hours := resultMS / 3600000
resultMS %= 3600000
minutes := resultMS / 60000
resultMS %= 60000
seconds := resultMS / 1000
milliseconds := resultMS % 1000
result[i] = model.Timestamp{
Hours: hours,
Minutes: minutes,
Seconds: seconds,
Milliseconds: milliseconds,
}
}
}
return result
@ -272,7 +338,13 @@ func calculateDuration(start, end model.Timestamp) model.Timestamp {
durationMillis := endMillis - startMillis
if durationMillis < 0 {
durationMillis = 3000 // Default 3 seconds if negative
// Return zero duration if end is before start
return model.Timestamp{
Hours: 0,
Minutes: 0,
Seconds: 0,
Milliseconds: 0,
}
}
hours := durationMillis / 3600000