mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-11 20:58:13 +08:00
rewrite
This commit is contained in:
@@ -1,40 +1,26 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
import "github.com/AynaLivePlayer/liveroom-sdk"
|
||||
|
||||
type LiveRoomConfig struct {
|
||||
AutoConnect bool `json:"auto_connect"`
|
||||
}
|
||||
|
||||
type LiveRoom struct {
|
||||
ClientName string
|
||||
ID string
|
||||
Title string
|
||||
AutoConnect bool
|
||||
AutoReconnect bool
|
||||
LiveRoom liveroom.LiveRoom `json:"live_room"`
|
||||
Config LiveRoomConfig `json:"config"`
|
||||
Title string `json:"title"`
|
||||
Status bool `json:"-"`
|
||||
}
|
||||
|
||||
func (r *LiveRoom) String() string {
|
||||
return fmt.Sprintf("<LiveRooms %s:%s>", r.ClientName, r.ID)
|
||||
func (r *LiveRoom) DisplayName() string {
|
||||
if r.Title != "" {
|
||||
return r.Title
|
||||
}
|
||||
return r.LiveRoom.Identifier()
|
||||
}
|
||||
|
||||
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
|
||||
type LiveRoomProviderInfo struct {
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
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],
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
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))
|
||||
}
|
||||
}
|
||||
@@ -1,46 +1,38 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/AynaLivePlayer/liveroom-sdk"
|
||||
"github.com/AynaLivePlayer/miaosic"
|
||||
)
|
||||
|
||||
type Picture struct {
|
||||
Url string
|
||||
Data []byte
|
||||
type User struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (p Picture) Exists() bool {
|
||||
return p.Url != "" || p.Data != nil
|
||||
}
|
||||
var PlaylistUser = User{Name: "Playlists"}
|
||||
var SystemUser = User{Name: "System"}
|
||||
var HistoryUser = User{Name: "History"}
|
||||
|
||||
type Media struct {
|
||||
Title string
|
||||
Artist string
|
||||
Cover Picture
|
||||
Album string
|
||||
Lyric string
|
||||
Url string
|
||||
Header map[string]string
|
||||
User interface{}
|
||||
Meta interface{}
|
||||
Info miaosic.MediaInfo
|
||||
User interface{}
|
||||
}
|
||||
|
||||
func (m *Media) ToUser() *User {
|
||||
if u, ok := m.User.(*User); ok {
|
||||
func (m *Media) IsLiveRoomUser() bool {
|
||||
_, ok := m.User.(liveroom.User)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (m *Media) ToUser() User {
|
||||
if u, ok := m.User.(User); ok {
|
||||
return u
|
||||
}
|
||||
return &User{Name: m.DanmuUser().Username}
|
||||
return User{Name: m.DanmuUser().Username}
|
||||
}
|
||||
|
||||
func (m *Media) DanmuUser() *DanmuUser {
|
||||
if u, ok := m.User.(*DanmuUser); ok {
|
||||
func (m *Media) DanmuUser() liveroom.User {
|
||||
if u, ok := m.User.(liveroom.User); ok {
|
||||
return u
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Media) Copy() *Media {
|
||||
newMedia := &Media{}
|
||||
copier.Copy(newMedia, m)
|
||||
return newMedia
|
||||
return liveroom.User{}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
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)
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package model
|
||||
|
||||
import "fmt"
|
||||
|
||||
type PlaylistMode int
|
||||
|
||||
const (
|
||||
@@ -10,28 +8,11 @@ const (
|
||||
PlaylistModeRepeat
|
||||
)
|
||||
|
||||
type Playlist struct {
|
||||
Title string // can be same, display name
|
||||
Medias []*Media
|
||||
Mode PlaylistMode
|
||||
Meta Meta
|
||||
}
|
||||
type PlaylistID string
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
const (
|
||||
PlaylistIDPlayer PlaylistID = "player"
|
||||
PlaylistIDSystem PlaylistID = "system"
|
||||
PlaylistIDHistory PlaylistID = "history"
|
||||
PlaylistIDPlaylists PlaylistID = "playlists"
|
||||
)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
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)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user