You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
synctv/internal/op/current.go

173 lines
3.5 KiB
Go

package op
import (
"sync"
"time"
"github.com/synctv-org/synctv/internal/model"
pb "github.com/synctv-org/synctv/proto"
)
type current struct {
current Current
lock sync.RWMutex
}
type Current struct {
Movie model.Movie `json:"movie"`
Status Status `json:"status"`
}
func newCurrent() *current {
return &current{
current: Current{
Status: newStatus(),
},
}
}
type Status struct {
Seek float64 `json:"seek"`
Rate float64 `json:"rate"`
Playing bool `json:"playing"`
lastUpdate time.Time
}
func newStatus() Status {
return Status{
Seek: 0,
Rate: 1.0,
lastUpdate: time.Now(),
}
}
func (c *current) Current() Current {
c.lock.RLock()
defer c.lock.RUnlock()
c.current.updateSeek()
return c.current
}
func (c *current) Movie() model.Movie {
c.lock.RLock()
defer c.lock.RUnlock()
return c.current.Movie
}
func (c *current) SetMovie(movie model.Movie) {
c.lock.Lock()
defer c.lock.Unlock()
c.current.Movie = movie
c.current.SetSeek(0, 0)
c.current.Status.Playing = true
}
func (c *current) Status() Status {
c.lock.RLock()
defer c.lock.RUnlock()
c.current.updateSeek()
return c.current.Status
}
func (c *current) SetStatus(playing bool, seek, rate, timeDiff float64) Status {
c.lock.Lock()
defer c.lock.Unlock()
return c.current.SetStatus(playing, seek, rate, timeDiff)
}
func (c *current) SetSeekRate(seek, rate, timeDiff float64) Status {
c.lock.Lock()
defer c.lock.Unlock()
return c.current.SetSeekRate(seek, rate, timeDiff)
}
func (c *Current) Proto() *pb.Current {
return &pb.Current{
Movie: &pb.MovieInfo{
Id: uint64(c.Movie.ID),
Base: &pb.BaseMovieInfo{
Url: c.Movie.BaseMovieInfo.Url,
Name: c.Movie.BaseMovieInfo.Name,
Live: c.Movie.BaseMovieInfo.Live,
Proxy: c.Movie.BaseMovieInfo.Proxy,
RtmpSource: c.Movie.BaseMovieInfo.RtmpSource,
Type: c.Movie.BaseMovieInfo.Type,
Headers: c.Movie.BaseMovieInfo.Headers,
},
PullKey: c.Movie.PullKey,
CreatedAt: c.Movie.CreatedAt.UnixMilli(),
// Creator: c.Movie.CreatorID,
},
Status: &pb.Status{
Seek: c.Status.Seek,
Rate: c.Status.Rate,
Playing: c.Status.Playing,
},
}
}
func (c *Current) updateSeek() {
if c.Movie.BaseMovieInfo.Live {
c.Status.lastUpdate = time.Now()
return
}
if c.Status.Playing {
c.Status.Seek += time.Since(c.Status.lastUpdate).Seconds() * c.Status.Rate
}
c.Status.lastUpdate = time.Now()
}
func (c *Current) setLiveStatus() Status {
c.Status.Playing = true
c.Status.Rate = 1.0
c.Status.Seek = 0
c.Status.lastUpdate = time.Now()
return c.Status
}
func (c *Current) SetStatus(playing bool, seek, rate, timeDiff float64) Status {
if c.Movie.BaseMovieInfo.Live {
return c.setLiveStatus()
}
c.Status.Playing = playing
c.Status.Rate = rate
if playing {
c.Status.Seek = seek + (timeDiff * rate)
} else {
c.Status.Seek = seek
}
c.Status.lastUpdate = time.Now()
return c.Status
}
func (c *Current) SetSeekRate(seek, rate, timeDiff float64) Status {
if c.Movie.BaseMovieInfo.Live {
return c.setLiveStatus()
}
if c.Status.Playing {
c.Status.Seek = seek + (timeDiff * rate)
} else {
c.Status.Seek = seek
}
c.Status.Rate = rate
c.Status.lastUpdate = time.Now()
return c.Status
}
func (c *Current) SetSeek(seek, timeDiff float64) Status {
if c.Movie.BaseMovieInfo.Live {
return c.setLiveStatus()
}
if c.Status.Playing {
c.Status.Seek = seek + (timeDiff * c.Status.Rate)
} else {
c.Status.Seek = seek
}
c.Status.lastUpdate = time.Now()
return c.Status
}