mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-11 12:48:12 +08:00
102 lines
2.0 KiB
Go
102 lines
2.0 KiB
Go
package player
|
|
|
|
import (
|
|
"AynaLivePlayer/event"
|
|
"github.com/spf13/cast"
|
|
"regexp"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
var timeTagRegex = regexp.MustCompile("\\[[0-9]+:[0-9]+(\\.[0-9]+)?\\]")
|
|
|
|
type LyricLine struct {
|
|
Time float64 // in seconds
|
|
Lyric string
|
|
}
|
|
|
|
type Lyric struct {
|
|
Lyrics []LyricLine
|
|
Handler *event.Handler
|
|
prev float64
|
|
}
|
|
|
|
func (l *Lyric) Reload(lyric string) {
|
|
tmp := make(map[float64]LyricLine)
|
|
times := make([]float64, 0)
|
|
for _, line := range strings.Split(lyric, "\n") {
|
|
lrc := timeTagRegex.ReplaceAllString(line, "")
|
|
for _, time := range timeTagRegex.FindAllString(line, -1) {
|
|
ts := strings.Split(time[1:len(time)-1], ":")
|
|
t := cast.ToFloat64(ts[0])*60 + cast.ToFloat64(ts[1])
|
|
times = append(times, t)
|
|
tmp[t] = LyricLine{
|
|
Time: t,
|
|
Lyric: lrc,
|
|
}
|
|
}
|
|
}
|
|
sort.Float64s(times)
|
|
lrcs := make([]LyricLine, len(times))
|
|
for index, time := range times {
|
|
lrcs[index] = tmp[time]
|
|
}
|
|
if len(lrcs) == 0 {
|
|
lrcs = append(lrcs, LyricLine{Time: 0, Lyric: ""})
|
|
}
|
|
lrcs = append(lrcs, LyricLine{
|
|
Time: 99999999999,
|
|
Lyric: "",
|
|
})
|
|
l.Lyrics = lrcs
|
|
l.Handler.CallA(EventLyricReload, LyricReloadEvent{Lyrics: l})
|
|
return
|
|
}
|
|
|
|
func (l *Lyric) Update(time float64) {
|
|
lrc := l.Find(time)
|
|
if lrc == nil {
|
|
return
|
|
}
|
|
if l.prev == lrc.Time {
|
|
return
|
|
}
|
|
l.prev = lrc.Time
|
|
l.Handler.CallA(EventLyricUpdate, LyricUpdateEvent{
|
|
Lyrics: l,
|
|
Time: time,
|
|
Lyric: lrc,
|
|
})
|
|
return
|
|
}
|
|
|
|
func (l *Lyric) Find(time float64) *LyricLine {
|
|
for i := 0; i < len(l.Lyrics)-1; i++ {
|
|
if l.Lyrics[i].Time <= time && time < l.Lyrics[i+1].Time {
|
|
return &l.Lyrics[i]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *Lyric) FindContext(time float64, prev int, next int) []LyricLine {
|
|
for i := 0; i < len(l.Lyrics)-1; i++ {
|
|
if l.Lyrics[i].Time <= time && time < l.Lyrics[i+1].Time {
|
|
if (i + prev) < 0 {
|
|
prev = -i
|
|
}
|
|
if (i + 1 + next) > len(l.Lyrics) {
|
|
next = len(l.Lyrics) - i - 1
|
|
}
|
|
return l.Lyrics[i+prev : i+1+next]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func NewLyric(lyric string) *Lyric {
|
|
l := &Lyric{Handler: event.NewHandler(), prev: -1}
|
|
l.Reload(lyric)
|
|
return l
|
|
}
|