mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-13 21:48:30 +08:00
Initial commit
This commit is contained in:
156
player/player.go
Normal file
156
player/player.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package player
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/event"
|
||||
"AynaLivePlayer/logger"
|
||||
"AynaLivePlayer/util"
|
||||
"github.com/aynakeya/go-mpv"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const MODULE_PLAYER = "Player.Player"
|
||||
|
||||
type PropertyHandlerFunc func(property *mpv.EventProperty)
|
||||
|
||||
type Player struct {
|
||||
running bool
|
||||
libmpv *mpv.Mpv
|
||||
Playing *Media
|
||||
PropertyHandler map[string][]PropertyHandlerFunc
|
||||
EventHandler *event.Handler
|
||||
}
|
||||
|
||||
func NewPlayer() *Player {
|
||||
player := &Player{
|
||||
running: true,
|
||||
libmpv: mpv.Create(),
|
||||
PropertyHandler: make(map[string][]PropertyHandlerFunc),
|
||||
EventHandler: event.NewHandler(),
|
||||
}
|
||||
err := player.libmpv.Initialize()
|
||||
if err != nil {
|
||||
player.l().Error("initialize libmpv failed")
|
||||
return nil
|
||||
}
|
||||
player.libmpv.SetOptionString("vo", "null")
|
||||
player.l().Info("initialize libmpv success")
|
||||
return player
|
||||
}
|
||||
|
||||
func (p *Player) Start() {
|
||||
p.l().Info("starting mpv player")
|
||||
go func() {
|
||||
for p.running {
|
||||
e := p.libmpv.WaitEvent(1)
|
||||
if e == nil {
|
||||
p.l().Warn("event loop got nil event")
|
||||
}
|
||||
p.l().Trace("new event", e)
|
||||
if e.EventId == mpv.EVENT_PROPERTY_CHANGE {
|
||||
property := e.Property()
|
||||
p.l().Trace("receive property change event", property)
|
||||
for _, handler := range p.PropertyHandler[property.Name] {
|
||||
// todo: @3
|
||||
go handler(&property)
|
||||
}
|
||||
}
|
||||
if e.EventId == mpv.EVENT_SHUTDOWN {
|
||||
p.l().Info("libmpv shutdown")
|
||||
p.Stop()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (p *Player) Stop() {
|
||||
p.l().Info("stopping mpv player")
|
||||
p.running = false
|
||||
p.libmpv.TerminateDestroy()
|
||||
}
|
||||
|
||||
func (p *Player) l() *logrus.Entry {
|
||||
return logger.Logger.WithField("Module", MODULE_PLAYER)
|
||||
}
|
||||
|
||||
func (p *Player) Play(media *Media) error {
|
||||
p.l().Infof("Play media %s", media.Url)
|
||||
p.l().Trace("set user-agent for mpv player")
|
||||
if val, ok := media.Header["user-agent"]; ok {
|
||||
err := p.libmpv.SetPropertyString("user-agent", val)
|
||||
if err != nil {
|
||||
p.l().Warn("set player user-agent failed", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
p.l().Trace("set referrer for mpv player")
|
||||
if val, ok := media.Header["referrer"]; ok {
|
||||
err := p.libmpv.SetPropertyString("referrer", val)
|
||||
if err != nil {
|
||||
p.l().Warn("set player referrer failed", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
p.l().Debug("mpv command load file", media)
|
||||
if err := p.libmpv.Command([]string{"loadfile", media.Url}); err != nil {
|
||||
p.l().Warn("mpv load media failed", media)
|
||||
return err
|
||||
}
|
||||
p.Playing = media
|
||||
p.EventHandler.CallA(EventPlay, PlayEvent{Media: media})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Player) IsPaused() bool {
|
||||
property, err := p.libmpv.GetProperty("pause", mpv.FORMAT_FLAG)
|
||||
if err != nil {
|
||||
p.l().Warn("get property pause failed", err)
|
||||
return false
|
||||
}
|
||||
return property.(bool)
|
||||
}
|
||||
|
||||
func (p *Player) Pause() error {
|
||||
p.l().Tracef("pause")
|
||||
return p.libmpv.SetProperty("pause", mpv.FORMAT_FLAG, true)
|
||||
}
|
||||
|
||||
func (p *Player) Unpause() error {
|
||||
p.l().Tracef("unpause")
|
||||
return p.libmpv.SetProperty("pause", mpv.FORMAT_FLAG, false)
|
||||
}
|
||||
|
||||
// SetVolume set mpv volume, from 0.0 - 100.0
|
||||
func (p *Player) SetVolume(volume float64) error {
|
||||
p.l().Tracef("set volume to %f", volume)
|
||||
return p.libmpv.SetProperty("volume", mpv.FORMAT_DOUBLE, volume)
|
||||
}
|
||||
|
||||
func (p *Player) IsIdle() bool {
|
||||
property, err := p.libmpv.GetProperty("idle-active", mpv.FORMAT_FLAG)
|
||||
if err != nil {
|
||||
p.l().Warn("get property idle-active failed", err)
|
||||
return false
|
||||
}
|
||||
return property.(bool)
|
||||
}
|
||||
|
||||
// Seek change position for current file
|
||||
// absolute = true : position is the time in second
|
||||
// absolute = false: position is in percentage eg 0.1 0.2
|
||||
func (p *Player) Seek(position float64, absolute bool) error {
|
||||
p.l().Tracef("seek to %f (absolute=%t)", position, absolute)
|
||||
if absolute {
|
||||
return p.libmpv.SetProperty("time-pos", mpv.FORMAT_DOUBLE, position)
|
||||
} else {
|
||||
return p.libmpv.SetProperty("percent-pos", mpv.FORMAT_DOUBLE, position)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Player) ObserveProperty(property string, handler ...PropertyHandlerFunc) error {
|
||||
p.l().Trace("add property observer for mpv")
|
||||
p.PropertyHandler[property] = append(p.PropertyHandler[property], handler...)
|
||||
if len(p.PropertyHandler[property]) == 1 {
|
||||
return p.libmpv.ObserveProperty(util.Hash64(property), property, mpv.FORMAT_NODE)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user