refactor
This commit is contained in:
parent
aedc4a4518
commit
9b0e2ed6dc
15 changed files with 693 additions and 540 deletions
79
internal/sync/sync.go
Normal file
79
internal/sync/sync.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package sync
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"sub-cli/internal/format/lrc"
|
||||
"sub-cli/internal/model"
|
||||
)
|
||||
|
||||
// SyncLyrics synchronizes the timeline of a source lyrics file with a target lyrics file
|
||||
func SyncLyrics(sourceFile, targetFile string) error {
|
||||
sourceFmt := strings.TrimPrefix(filepath.Ext(sourceFile), ".")
|
||||
targetFmt := strings.TrimPrefix(filepath.Ext(targetFile), ".")
|
||||
|
||||
// Currently only supports LRC files
|
||||
if sourceFmt != "lrc" || targetFmt != "lrc" {
|
||||
return fmt.Errorf("sync only supports LRC files currently")
|
||||
}
|
||||
|
||||
source, err := lrc.Parse(sourceFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing source file: %w", err)
|
||||
}
|
||||
|
||||
target, err := lrc.Parse(targetFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing target file: %w", err)
|
||||
}
|
||||
|
||||
// Apply timeline from source to target
|
||||
syncedLyrics := syncTimeline(source, target)
|
||||
|
||||
// Write the synced lyrics to the target file
|
||||
return lrc.Generate(syncedLyrics, targetFile)
|
||||
}
|
||||
|
||||
// syncTimeline applies the timeline from the source lyrics to the target lyrics
|
||||
func syncTimeline(source, target model.Lyrics) model.Lyrics {
|
||||
result := model.Lyrics{
|
||||
Metadata: target.Metadata,
|
||||
Content: 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
|
||||
} else if len(source.Timeline) > 0 {
|
||||
// If lengths don't match, scale timeline
|
||||
result.Timeline = scaleTimeline(source.Timeline, len(target.Content))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// scaleTimeline scales a timeline to match a different number of entries
|
||||
func scaleTimeline(timeline []model.Timestamp, targetCount int) []model.Timestamp {
|
||||
if targetCount <= 0 || len(timeline) == 0 {
|
||||
return []model.Timestamp{}
|
||||
}
|
||||
|
||||
result := make([]model.Timestamp, targetCount)
|
||||
|
||||
if targetCount == 1 {
|
||||
result[0] = timeline[0]
|
||||
return result
|
||||
}
|
||||
|
||||
sourceLength := len(timeline)
|
||||
|
||||
for i := 0; i < targetCount; i++ {
|
||||
// Scale index to match source timeline
|
||||
sourceIndex := i * (sourceLength - 1) / (targetCount - 1)
|
||||
result[i] = timeline[sourceIndex]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue