172 lines
3.6 KiB
Go
172 lines
3.6 KiB
Go
package metadata
|
|
|
|
import (
|
|
"github.com/oriser/regroup"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type LyricsFormat string
|
|
|
|
const (
|
|
ASS LyricsFormat = "ASS"
|
|
LRC LyricsFormat = "LRC"
|
|
WebVTT LyricsFormat = "WebVTT"
|
|
SubRip LyricsFormat = "SubRip"
|
|
Text LyricsFormat = "Text"
|
|
)
|
|
|
|
type LyricGetter func() []Lyrics
|
|
|
|
type Lyrics interface {
|
|
GetFormat() LyricsFormat
|
|
GetIdentifiers() []Name
|
|
GetLanguage() string
|
|
GetContent() string
|
|
}
|
|
|
|
type TextLyrics struct {
|
|
Language string
|
|
Identifiers []Name
|
|
Entries []string
|
|
}
|
|
|
|
func (l *TextLyrics) GetLanguage() string {
|
|
return l.Language
|
|
}
|
|
|
|
func (l *TextLyrics) GetFormat() LyricsFormat {
|
|
return Text
|
|
}
|
|
|
|
func (l *TextLyrics) GetIdentifiers() []Name {
|
|
return l.Identifiers
|
|
}
|
|
|
|
func (l *TextLyrics) GetContent() string {
|
|
return strings.Join(l.Entries, "\n")
|
|
}
|
|
|
|
type LRCLyrics struct {
|
|
Language string
|
|
Identifiers []Name
|
|
Entries []LRCLyricTextEntry
|
|
}
|
|
|
|
type LRCLyricTextEntry struct {
|
|
Start time.Duration
|
|
End time.Duration
|
|
Content string
|
|
}
|
|
|
|
func (l *LRCLyrics) GetLanguage() string {
|
|
return l.Language
|
|
}
|
|
|
|
func (l *LRCLyrics) GetFormat() LyricsFormat {
|
|
return LRC
|
|
}
|
|
|
|
func (l *LRCLyrics) GetIdentifiers() []Name {
|
|
return l.Identifiers
|
|
}
|
|
|
|
func (l *LRCLyrics) GetContent() string {
|
|
var result []string
|
|
|
|
//TODO
|
|
return strings.Join(result, "\n")
|
|
}
|
|
|
|
func NewLRCLyrics(body, language string, identifiers []Name) *LRCLyrics {
|
|
|
|
var lineRE = regroup.MustCompile(`(?m)^\[(?P<time_minutes>[0-9]+):(?P<time_seconds>[0-9]+)\.(?P<time_decimals>[0-9]+)\](?P<line>.*)$`)
|
|
var lineMetaRE = regroup.MustCompile(`(?m)^\[(?P<kind>(ti|al|ar|re)):(?P<line>.*)\]$`)
|
|
|
|
type LineMatch struct {
|
|
TimeMinutes int `regroup:"time_minutes"`
|
|
TimeSeconds int `regroup:"time_seconds"`
|
|
TimeDecimals string `regroup:"time_decimals"`
|
|
Line string `regroup:"line"`
|
|
}
|
|
type LineMetaMatch struct {
|
|
Kind string `regroup:"kind"`
|
|
Line string `regroup:"line"`
|
|
}
|
|
m := &LineMatch{}
|
|
rets, err := lineRE.MatchAllToTarget(body, -1, m)
|
|
if err == nil {
|
|
|
|
lyrics := &LRCLyrics{
|
|
Language: language,
|
|
Identifiers: identifiers,
|
|
}
|
|
|
|
m2 := &LineMetaMatch{}
|
|
rets2, _ := lineMetaRE.MatchAllToTarget(body, -1, m2)
|
|
for _, elem2 := range rets2 {
|
|
match2 := elem2.(*LineMetaMatch)
|
|
|
|
switch match2.Kind {
|
|
case "ti":
|
|
lyrics.Identifiers = append(lyrics.Identifiers, Name{
|
|
Kind: "title",
|
|
Name: strings.TrimSpace(match2.Line),
|
|
})
|
|
case "al":
|
|
lyrics.Identifiers = append(lyrics.Identifiers, Name{
|
|
Kind: "album",
|
|
Name: strings.TrimSpace(match2.Line),
|
|
})
|
|
case "ar":
|
|
lyrics.Identifiers = append(lyrics.Identifiers, Name{
|
|
Kind: "artist",
|
|
Name: strings.TrimSpace(match2.Line),
|
|
})
|
|
}
|
|
}
|
|
|
|
for _, elem := range rets {
|
|
match := elem.(*LineMatch)
|
|
|
|
var last *LRCLyricTextEntry
|
|
if len(lyrics.Entries) > 0 {
|
|
last = &lyrics.Entries[len(lyrics.Entries)-1]
|
|
}
|
|
|
|
start := time.Minute*time.Duration(match.TimeMinutes) + time.Second*time.Duration(match.TimeSeconds)
|
|
if len(match.TimeDecimals) == 1 {
|
|
d, _ := strconv.Atoi(match.TimeDecimals)
|
|
start += time.Millisecond * time.Duration(d) * 100
|
|
} else if len(match.TimeDecimals) == 2 {
|
|
d, _ := strconv.Atoi(match.TimeDecimals)
|
|
start += time.Millisecond * time.Duration(d) * 10
|
|
} else if len(match.TimeDecimals) == 3 {
|
|
d, _ := strconv.Atoi(match.TimeDecimals)
|
|
start += time.Millisecond * time.Duration(d)
|
|
} else {
|
|
//TODO
|
|
}
|
|
|
|
if last != nil {
|
|
last.End = start
|
|
}
|
|
|
|
line := strings.TrimSpace(match.Line)
|
|
|
|
if len(line) > 0 {
|
|
lyrics.Entries = append(lyrics.Entries, LRCLyricTextEntry{
|
|
Start: start,
|
|
End: -1,
|
|
Content: line,
|
|
})
|
|
}
|
|
}
|
|
|
|
return lyrics
|
|
}
|
|
|
|
return nil
|
|
}
|