fix gui freeze bug (work round)

This commit is contained in:
Aynakeya
2023-02-19 04:23:03 -08:00
parent 9d99a74faf
commit 6f2349e17b
106 changed files with 2051 additions and 1580 deletions

40
core/model/liveroom.go Normal file
View File

@@ -0,0 +1,40 @@
package model
import (
"fmt"
)
type LiveRoom struct {
ClientName string
ID string
Title string
AutoConnect bool
AutoReconnect bool
}
func (r *LiveRoom) String() string {
return fmt.Sprintf("<LiveRooms %s:%s>", r.ClientName, r.ID)
}
func (r *LiveRoom) Identifier() string {
return fmt.Sprintf("%s_%s", r.ClientName, r.ID)
}
type UserMedal struct {
Name string
Level int
RoomID string
}
type DanmuUser struct {
Uid string
Username string
Medal UserMedal
Admin bool
Privilege int
}
type DanmuMessage struct {
User DanmuUser
Message string
}

117
core/model/lyric.go Normal file
View File

@@ -0,0 +1,117 @@
package model
import (
"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
Translation string
}
type LyricContext struct {
Now *LyricLine
Index int
Total int
Prev []*LyricLine
Next []*LyricLine
}
type Lyric struct {
Lyrics []*LyricLine
}
func LoadLyric(lyric string) *Lyric {
tmp := make(map[float64]*LyricLine)
times := make([]float64, 0)
for _, line := range strings.Split(lyric, "\n") {
lrc := timeTagRegex.ReplaceAllString(line, "")
if len(lrc) > 0 && lrc[len(lrc)-1] == '\r' {
lrc = lrc[:len(lrc)-1]
}
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: "",
})
return &Lyric{Lyrics: lrcs}
}
func (l *Lyric) findIndexV1(time float64) int {
for i := 0; i < len(l.Lyrics)-1; i++ {
if l.Lyrics[i].Time <= time && time < l.Lyrics[i+1].Time {
return i
}
}
return -1
}
func (l *Lyric) findIndex(time float64) int {
start := 0
end := len(l.Lyrics) - 1
mid := (start + end) / 2
for start < end {
if l.Lyrics[mid].Time <= time && time < l.Lyrics[mid+1].Time {
return mid
}
if l.Lyrics[mid].Time > time {
end = mid
} else {
start = mid
}
mid = (start + end) / 2
}
return -1
}
func (l *Lyric) Find(time float64) *LyricLine {
idx := l.findIndex(time)
if idx == -1 {
return nil
}
return l.Lyrics[idx]
}
func (l *Lyric) FindContext(time float64, prev int, next int) *LyricContext {
prev = -prev
idx := l.findIndex(time)
if idx == -1 {
return nil
}
if (idx + prev) < 0 {
prev = -idx
}
if (idx + 1 + next) > len(l.Lyrics) {
next = len(l.Lyrics) - idx - 1
}
return &LyricContext{
Now: l.Lyrics[idx],
Index: idx,
Total: len(l.Lyrics),
Prev: l.Lyrics[idx+prev : idx],
Next: l.Lyrics[idx+1 : idx+1+next],
}
}

31
core/model/lyric_test.go Normal file
View File

@@ -0,0 +1,31 @@
package model
import (
"fmt"
"github.com/magiconair/properties/assert"
"testing"
)
var testLyric = "[ti:双截棍]\n[ar:周杰伦]\n[al:范特西]\n[00:03.85]双截棍\n[00:07.14]\n[00:30.13]岩烧店的烟味弥漫隔壁是国术馆\n[00:32.57]店里面的妈妈桑茶道有三段\n[00:34.61]教拳脚武术的老板练铁沙掌耍杨家枪\n[00:37.34]硬底子功夫最擅长还会金钟罩铁步衫\n[00:39.67]他们儿子我习惯从小就耳濡目染\n[00:41.96]什么刀枪跟棍棒我都耍的有模有样\n[00:44.22]什么兵器最喜欢双截棍柔中带刚\n[00:46.73]想要去河南嵩山学少林跟武当\n[00:49.24]干什么(客)干什么(客)呼吸吐纳心自在\n[00:51.28]干什么(客)干什么(客)气沉丹田手心开\n[00:53.44]干什么(客)干什么(客)日行千里系沙袋\n[00:56.13]飞檐走壁莫奇怪去去就来\n[00:58.35]一个马步向前一记左钩拳右钩拳\n[01:01.26]一句惹毛我的人有危险一再重演\n[01:04.02]一根我不抽的菸一放好多年它一直在身边\n[01:07.28]干什么(客)干什么(客)我打开任督二脉\n[01:10.27]干什么(客)干什么(客)东亚病夫的招牌\n[01:12.75]干什么(客)干什么(客)已被我一脚踢开\n[02:32.62][01:54.69][01:15.40]快使用双截棍哼哼哈兮\n[02:34.52][01:56.63][01:18.40]快使用双截棍哼哼哈兮\n[02:36.88][01:58.98][01:20.71]习武之人切记仁者无敌\n[02:39.45][02:01.66][01:23.27]是谁在练太极风生水起\n[02:41.97][02:03.93][01:25.74]快使用双截棍哼哼哈兮\n[02:44.42][02:06.11][01:27.75]快使用双截棍哼哼哈兮\n[02:47.01][02:08.54][01:30.13]如果我有轻功飞檐走壁\n[02:49.36][02:11.03][01:32.67]为人耿直不屈一身正气\n[02:53.81]快使用双截棍哼\n[02:56.30]我用手刀防御哼\n[02:58.52]漂亮的回旋踢\n[02:59.52]"
func TestLyric(t *testing.T) {
lryic := LoadLyric(testLyric)
for _, lrc := range lryic.Lyrics {
fmt.Println(lrc)
}
}
func TestLyricFind(t *testing.T) {
lryic := LoadLyric(testLyric)
fmt.Println(lryic.Find(90.4))
for _, l := range lryic.FindContext(90.4, -2, 2).Next {
fmt.Println(l)
}
}
func TestLyricFindV2(t *testing.T) {
lryic := LoadLyric(testLyric)
for i := 0.0; i < 170; i += 0.01 {
assert.Equal(t, lryic.Find(i), lryic.Find(i))
}
}

46
core/model/media.go Normal file
View File

@@ -0,0 +1,46 @@
package model
import (
"github.com/jinzhu/copier"
)
type Picture struct {
Url string
Data []byte
}
func (p Picture) Exists() bool {
return p.Url != "" || p.Data != nil
}
type Media struct {
Title string
Artist string
Cover Picture
Album string
Lyric string
Url string
Header map[string]string
User interface{}
Meta interface{}
}
func (m *Media) ToUser() *User {
if u, ok := m.User.(*User); ok {
return u
}
return &User{Name: m.DanmuUser().Username}
}
func (m *Media) DanmuUser() *DanmuUser {
if u, ok := m.User.(*DanmuUser); ok {
return u
}
return nil
}
func (m *Media) Copy() *Media {
newMedia := &Media{}
copier.Copy(newMedia, m)
return newMedia
}

30
core/model/media_test.go Normal file
View File

@@ -0,0 +1,30 @@
package model
import (
"fmt"
"testing"
)
type A struct {
A string
}
type B struct {
B string
}
func TestStruct(t *testing.T) {
var x interface{} = &A{A: "123"}
y, ok := x.(*A)
fmt.Println(y, ok)
z, ok := x.(*B)
fmt.Println(z, ok)
}
func TestMedia_Copy(t *testing.T) {
m := &Media{Title: "asdf", User: &User{Name: "123"}}
m2 := m.Copy()
fmt.Println(m, m2)
m2.User.(*User).Name = "456"
fmt.Println(m.User.(*User).Name, m2)
}

18
core/model/player.go Normal file
View File

@@ -0,0 +1,18 @@
package model
type AudioDevice struct {
Name string
Description string
}
type PlayerPropertyValue any
type PlayerProperty string
const (
PlayerPropIdleActive PlayerProperty = "idle-active"
PlayerPropTimePos PlayerProperty = "time-pos"
PlayerPropDuration PlayerProperty = "duration"
PlayerPropPercentPos PlayerProperty = "percent-pos"
PlayerPropPause PlayerProperty = "pause"
PlayerPropVolume PlayerProperty = "volume"
)

37
core/model/playlist.go Normal file
View File

@@ -0,0 +1,37 @@
package model
import "fmt"
type PlaylistMode int
const (
PlaylistModeNormal PlaylistMode = iota
PlaylistModeRandom
PlaylistModeRepeat
)
type Playlist struct {
Title string // can be same, display name
Medias []*Media
Mode PlaylistMode
Meta Meta
}
func (p Playlist) String() string {
return fmt.Sprintf("<Playlist %s len:%d>", p.Title, len(p.Medias))
}
func (p *Playlist) Size() int {
return len(p.Medias)
}
func (p *Playlist) Copy() *Playlist {
medias := make([]*Media, len(p.Medias))
copy(medias, p.Medias)
return &Playlist{
Title: p.Title,
Medias: medias,
Mode: p.Mode,
Meta: p.Meta,
}
}

16
core/model/provider.go Normal file
View File

@@ -0,0 +1,16 @@
package model
import "fmt"
type Meta struct {
Name string
Id string
}
func (m Meta) String() string {
return fmt.Sprintf("<Meta %s:%s>", m.Name, m.Id)
}
func (m Meta) Identifier() string {
return fmt.Sprintf("%s_%s", m.Name, m.Id)
}

17
core/model/user.go Normal file
View File

@@ -0,0 +1,17 @@
package model
type User struct {
Name string
}
func ApplyUser(medias []*Media, user interface{}) {
for _, m := range medias {
m.User = user
}
}
func ToSpMedia(media *Media, user *User) *Media {
media = media.Copy()
media.User = user
return media
}