rewrite using IoC and DI

This commit is contained in:
Aynakeya
2022-12-23 05:06:57 -08:00
parent 0498d2dbf3
commit c47d338a9e
88 changed files with 2295 additions and 1856 deletions

52
model/event.go Normal file
View File

@@ -0,0 +1,52 @@
package model
import (
"AynaLivePlayer/common/event"
)
const (
EventPlay event.EventId = "player.play"
EventPlaylistPreInsert event.EventId = "playlist.insert.pre"
EventPlaylistInsert event.EventId = "playlist.insert.after"
EventPlaylistUpdate event.EventId = "playlist.update"
EventLyricUpdate event.EventId = "lyric.update"
EventLyricReload event.EventId = "lyric.reload"
)
func EventPlayerPropertyUpdate(property PlayerProperty) event.EventId {
return event.EventId("player.property.update." + string(property))
}
type PlaylistInsertEvent struct {
Playlist *Playlist
Index int
Media *Media
}
type PlaylistUpdateEvent struct {
Playlist *Playlist // Playlist is a copy of the playlist
}
type PlayEvent struct {
Media *Media
}
type LyricUpdateEvent struct {
Lyrics *Lyric
Time float64
Lyric *LyricLine
}
type LyricReloadEvent struct {
Lyrics *Lyric
}
type PlayerPropertyUpdateEvent struct {
Property PlayerProperty
Value PlayerPropertyValue
}
type LiveRoomStatusUpdateEvent struct {
RoomTitle string
Status bool
}

17
model/liveroom.go Normal file
View File

@@ -0,0 +1,17 @@
package model
import "fmt"
type LiveRoom struct {
ClientName string
ID string
AutoConnect bool
}
func (r *LiveRoom) String() string {
return fmt.Sprintf("<LiveRooms %s:%s>", r.ClientName, r.ID)
}
func (r *LiveRoom) Title() string {
return fmt.Sprintf("%s-%s", r.ClientName, r.ID)
}

84
model/lyric.go Normal file
View File

@@ -0,0 +1,84 @@
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 {
Current *LyricLine
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, "")
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) 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) *LyricContext {
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 &LyricContext{
Current: l.Lyrics[i],
Prev: l.Lyrics[i+prev : i],
Next: l.Lyrics[i+1 : i+1+next],
}
}
}
return nil
}

23
model/lyric_test.go Normal file
View File

@@ -0,0 +1,23 @@
package model
import (
"fmt"
"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)
}
}

54
model/media.go Normal file
View File

@@ -0,0 +1,54 @@
package model
import (
"AynaLivePlayer/liveclient"
"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) SystemUser() *User {
if u, ok := m.User.(*User); ok {
return u
}
return nil
}
func (m *Media) DanmuUser() *liveclient.DanmuUser {
if u, ok := m.User.(*liveclient.DanmuUser); ok {
return u
}
return nil
}
func (m *Media) Copy() *Media {
newMedia := &Media{}
copier.Copy(newMedia, m)
return newMedia
}

30
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
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"
)

36
model/playlist.go Normal file
View File

@@ -0,0 +1,36 @@
package model
import "fmt"
type PlaylistMode int
const (
PlaylistModeNormal PlaylistMode = iota
PlaylistModeRandom
)
type Playlist struct {
Name string
Medias []*Media
Mode PlaylistMode
Meta Meta
}
func (p Playlist) String() string {
return fmt.Sprintf("<Playlist %s>", p.Name)
}
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{
Name: p.Name,
Medias: medias,
Mode: p.Mode,
Meta: p.Meta,
}
}

6
model/provider.go Normal file
View File

@@ -0,0 +1,6 @@
package model
type Meta struct {
Name string
Id string
}

5
model/user.go Normal file
View File

@@ -0,0 +1,5 @@
package model
type User struct {
Name string
}