Skip to content

Commit

Permalink
feat: store movie current status
Browse files Browse the repository at this point in the history
  • Loading branch information
zijiren233 committed Feb 11, 2025
1 parent e60a15d commit 14c59e9
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 124 deletions.
11 changes: 11 additions & 0 deletions internal/db/room.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,14 @@ func SetRoomStatusByCreator(userID string, status model.RoomStatus) error {
result := db.Model(&model.Room{}).Where("creator_id = ?", userID).Update("status", status)
return HandleUpdateResult(result, ErrRoomNotFound)
}

func SetRoomCurrent(roomID string, current *model.Current) error {
r := &model.Room{
Current: current,
}
result := db.Model(r).
Where("id = ?", roomID).
Select("Current").
Updates(r)
return HandleUpdateResult(result, ErrRoomNotFound)
}
5 changes: 4 additions & 1 deletion internal/db/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type dbVersion struct {
NextVersion string
}

const CurrentVersion = "0.0.12"
const CurrentVersion = "0.0.13"

var models = []any{
new(model.Setting),
Expand Down Expand Up @@ -82,6 +82,9 @@ var dbVersions = map[string]dbVersion{
NextVersion: "0.0.12",
},
"0.0.12": {
NextVersion: "0.0.13",
},
"0.0.13": {
NextVersion: "",
},
}
Expand Down
91 changes: 91 additions & 0 deletions internal/model/current.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package model

import "time"

type Current struct {
Movie CurrentMovie `json:"movie"`
Status Status `json:"status"`
}

type CurrentMovie struct {
ID string `json:"id,omitempty"`
IsLive bool `json:"isLive,omitempty"`
SubPath string `json:"subPath,omitempty"`
}

type Status struct {
LastUpdate time.Time `json:"lastUpdate,omitempty"`
CurrentTime float64 `json:"currentTime,omitempty"`
PlaybackRate float64 `json:"playbackRate,omitempty"`
IsPlaying bool `json:"isPlaying,omitempty"`
}

func NewStatus() Status {
return Status{
CurrentTime: 0,
PlaybackRate: 1.0,
LastUpdate: time.Now(),
}
}

func (c *Current) UpdateStatus() Status {
if c.Movie.IsLive {
c.Status.LastUpdate = time.Now()
return c.Status
}
if c.Status.IsPlaying {
c.Status.CurrentTime += time.Since(c.Status.LastUpdate).Seconds() * c.Status.PlaybackRate
}
c.Status.LastUpdate = time.Now()
return c.Status
}

func (c *Current) setLiveStatus() Status {
c.Status.IsPlaying = true
c.Status.PlaybackRate = 1.0
c.Status.CurrentTime = 0
c.Status.LastUpdate = time.Now()
return c.Status
}

func (c *Current) SetStatus(playing bool, seek, rate, timeDiff float64) Status {
if c.Movie.IsLive {
return c.setLiveStatus()
}
c.Status.IsPlaying = playing
c.Status.PlaybackRate = rate
if playing {
c.Status.CurrentTime = seek + (timeDiff * rate)
} else {
c.Status.CurrentTime = seek
}
c.Status.LastUpdate = time.Now()
return c.Status
}

func (c *Current) SetSeekRate(seek, rate, timeDiff float64) Status {
if c.Movie.IsLive {
return c.setLiveStatus()
}
if c.Status.IsPlaying {
c.Status.CurrentTime = seek + (timeDiff * rate)
} else {
c.Status.CurrentTime = seek
}
c.Status.PlaybackRate = rate
c.Status.LastUpdate = time.Now()
return c.Status
}

func (c *Current) SetSeek(seek, timeDiff float64) Status {
if c.Movie.IsLive {
return c.setLiveStatus()
}
if c.Status.IsPlaying {
c.Status.CurrentTime = seek + (timeDiff * c.Status.PlaybackRate)
} else {
c.Status.CurrentTime = seek
}
c.Status.LastUpdate = time.Now()
return c.Status
}
1 change: 1 addition & 0 deletions internal/model/room.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type Room struct {
RoomMembers []*RoomMember `gorm:"foreignKey:RoomID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Movies []*Movie `gorm:"foreignKey:RoomID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Status RoomStatus `gorm:"not null;default:2"`
Current *Current `gorm:"serializer:fastjson"`
}

func (r *Room) BeforeCreate(tx *gorm.DB) error {
Expand Down
128 changes: 30 additions & 98 deletions internal/op/current.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,144 +2,76 @@ package op

import (
"sync"
"time"

"github.com/synctv-org/synctv/internal/db"
"github.com/synctv-org/synctv/internal/model"
)

type current struct {
current Current
roomID string
current model.Current
lock sync.RWMutex
}

type Current struct {
Movie CurrentMovie
Status Status
}

type CurrentMovie struct {
ID string
IsLive bool
}

func newCurrent() *current {
return &current{
current: Current{
Status: newStatus(),
},
func newCurrent(roomID string, c *model.Current) *current {
if c == nil {
return &current{
roomID: roomID,
current: model.Current{
Status: model.NewStatus(),
},
}
}
}

type Status struct {
lastUpdate time.Time `json:"-"`
CurrentTime float64 `json:"currentTime"`
PlaybackRate float64 `json:"playbackRate"`
IsPlaying bool `json:"isPlaying"`
}

func newStatus() Status {
return Status{
CurrentTime: 0,
PlaybackRate: 1.0,
lastUpdate: time.Now(),
return &current{
roomID: roomID,
current: *c,
}
}

func (c *current) Current() Current {
func (c *current) Current() model.Current {
c.lock.RLock()
defer c.lock.RUnlock()
c.current.UpdateStatus()
return c.current
}

func (c *current) SetMovie(movie CurrentMovie, play bool) {
func (c *current) SubPath() string {
c.lock.RLock()
defer c.lock.RUnlock()
return c.current.Movie.SubPath
}

func (c *current) SetMovie(movie model.CurrentMovie, play bool) {
c.lock.Lock()
defer c.lock.Unlock()
defer db.SetRoomCurrent(c.roomID, &c.current)

c.current.Movie = movie
c.current.SetSeek(0, 0)
c.current.Status.IsPlaying = play
}

func (c *current) Status() Status {
func (c *current) Status() model.Status {
c.lock.RLock()
defer c.lock.RUnlock()
c.current.UpdateStatus()
return c.current.Status
}

func (c *current) SetStatus(playing bool, seek, rate, timeDiff float64) *Status {
func (c *current) SetStatus(playing bool, seek, rate, timeDiff float64) *model.Status {
c.lock.Lock()
defer c.lock.Unlock()
defer db.SetRoomCurrent(c.roomID, &c.current)

s := c.current.SetStatus(playing, seek, rate, timeDiff)
return &s
}

func (c *current) SetSeekRate(seek, rate, timeDiff float64) *Status {
func (c *current) SetSeekRate(seek, rate, timeDiff float64) *model.Status {
c.lock.Lock()
defer c.lock.Unlock()
defer db.SetRoomCurrent(c.roomID, &c.current)

s := c.current.SetSeekRate(seek, rate, timeDiff)
return &s
}

func (c *Current) UpdateStatus() Status {
if c.Movie.IsLive {
c.Status.lastUpdate = time.Now()
return c.Status
}
if c.Status.IsPlaying {
c.Status.CurrentTime += time.Since(c.Status.lastUpdate).Seconds() * c.Status.PlaybackRate
}
c.Status.lastUpdate = time.Now()
return c.Status
}

func (c *Current) setLiveStatus() Status {
c.Status.IsPlaying = true
c.Status.PlaybackRate = 1.0
c.Status.CurrentTime = 0
c.Status.lastUpdate = time.Now()
return c.Status
}

func (c *Current) SetStatus(playing bool, seek, rate, timeDiff float64) Status {
if c.Movie.IsLive {
return c.setLiveStatus()
}
c.Status.IsPlaying = playing
c.Status.PlaybackRate = rate
if playing {
c.Status.CurrentTime = seek + (timeDiff * rate)
} else {
c.Status.CurrentTime = seek
}
c.Status.lastUpdate = time.Now()
return c.Status
}

func (c *Current) SetSeekRate(seek, rate, timeDiff float64) Status {
if c.Movie.IsLive {
return c.setLiveStatus()
}
if c.Status.IsPlaying {
c.Status.CurrentTime = seek + (timeDiff * rate)
} else {
c.Status.CurrentTime = seek
}
c.Status.PlaybackRate = rate
c.Status.lastUpdate = time.Now()
return c.Status
}

func (c *Current) SetSeek(seek, timeDiff float64) Status {
if c.Movie.IsLive {
return c.setLiveStatus()
}
if c.Status.IsPlaying {
c.Status.CurrentTime = seek + (timeDiff * c.Status.PlaybackRate)
} else {
c.Status.CurrentTime = seek
}
c.Status.lastUpdate = time.Now()
return c.Status
}
8 changes: 4 additions & 4 deletions internal/op/movie.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ import (
)

type Movie struct {
room *Room
*model.Movie
channel atomic.Pointer[rtmps.Channel]
alistCache atomic.Pointer[cache.AlistMovieCache]
bilibiliCache atomic.Pointer[cache.BilibiliMovieCache]
embyCache atomic.Pointer[cache.EmbyMovieCache]
subPath string
}

func (m *Movie) SubPath() string {
return m.subPath
return m.room.CurrentSubPath()
}

func (m *Movie) ExpireID(ctx context.Context) (uint64, error) {
Expand Down Expand Up @@ -99,7 +99,7 @@ func (m *Movie) ClearCache() error {
func (m *Movie) AlistCache() *cache.AlistMovieCache {
c := m.alistCache.Load()
if c == nil {
c = cache.NewAlistMovieCache(m.Movie, m.subPath)
c = cache.NewAlistMovieCache(m.Movie, m.SubPath())
if !m.alistCache.CompareAndSwap(nil, c) {
return m.AlistCache()
}
Expand All @@ -121,7 +121,7 @@ func (m *Movie) BilibiliCache() *cache.BilibiliMovieCache {
func (m *Movie) EmbyCache() *cache.EmbyMovieCache {
c := m.embyCache.Load()
if c == nil {
c = cache.NewEmbyMovieCache(m.Movie, m.subPath)
c = cache.NewEmbyMovieCache(m.Movie, m.SubPath())
if !m.embyCache.CompareAndSwap(nil, c) {
return m.EmbyCache()
}
Expand Down
8 changes: 7 additions & 1 deletion internal/op/movies.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import (

type movies struct {
roomID string
room *Room
cache rwmap.RWMap[string, *Movie]
}

func (m *movies) AddMovie(mo *model.Movie) error {
mo.Position = uint(time.Now().UnixMilli())
movie := &Movie{
room: m.room,
Movie: mo,
}

Expand All @@ -45,6 +47,7 @@ func (m *movies) AddMovies(mos []*model.Movie) error {
for _, mo := range mos {
mo.Position = uint(time.Now().UnixMilli())
movie := &Movie{
room: m.room,
Movie: mo,
}

Expand Down Expand Up @@ -184,7 +187,10 @@ func (m *movies) GetMovieByID(id string) (*Movie, error) {
if err != nil {
return nil, err
}
mm, _ = m.cache.LoadOrStore(mv.ID, &Movie{Movie: mv})
mm, _ = m.cache.LoadOrStore(mv.ID, &Movie{
room: m.room,
Movie: mv,
})
return mm, nil
}

Expand Down
Loading

0 comments on commit 14c59e9

Please sign in to comment.