mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-13 05:28:16 +08:00
249 lines
6.5 KiB
Go
249 lines
6.5 KiB
Go
package core
|
|
|
|
import (
|
|
"AynaLivePlayer/common/event"
|
|
"AynaLivePlayer/config"
|
|
"AynaLivePlayer/controller"
|
|
"AynaLivePlayer/model"
|
|
"AynaLivePlayer/player"
|
|
"AynaLivePlayer/repo/provider"
|
|
"errors"
|
|
)
|
|
|
|
type PlayController struct {
|
|
eventManager *event.Manager `ini:"-"`
|
|
player player.IPlayer `ini:"-"`
|
|
playlist controller.IPlaylistController `ini:"-"`
|
|
provider controller.IProviderController `ini:"-"`
|
|
lyric controller.ILyricLoader `ini:"-"`
|
|
playing *model.Media `ini:"-"`
|
|
AudioDevice string
|
|
Volume float64
|
|
SkipPlaylist bool
|
|
}
|
|
|
|
func (pc *PlayController) GetSkipPlaylist() bool {
|
|
return pc.SkipPlaylist
|
|
}
|
|
|
|
func (pc *PlayController) SetSkipPlaylist(b bool) {
|
|
pc.SkipPlaylist = b
|
|
}
|
|
|
|
func (pc *PlayController) Name() string {
|
|
return "PlayController"
|
|
}
|
|
|
|
func (pc *PlayController) OnLoad() {
|
|
return
|
|
}
|
|
|
|
func (pc *PlayController) OnSave() {
|
|
return
|
|
}
|
|
|
|
func NewPlayerController(
|
|
player player.IPlayer,
|
|
playlist controller.IPlaylistController,
|
|
lyric controller.ILyricLoader,
|
|
provider controller.IProviderController) controller.IPlayController {
|
|
pc := &PlayController{
|
|
eventManager: event.MainManager.NewChildManager(),
|
|
player: player,
|
|
playlist: playlist,
|
|
lyric: lyric,
|
|
provider: provider,
|
|
playing: &model.Media{},
|
|
AudioDevice: "auto",
|
|
Volume: 100,
|
|
SkipPlaylist: false,
|
|
}
|
|
config.LoadConfig(pc)
|
|
pc.SetVolume(pc.Volume)
|
|
pc.SetAudioDevice(pc.AudioDevice)
|
|
pc.player.ObserveProperty(model.PlayerPropIdleActive, "controller.playcontrol.idleplaynext", pc.handleMpvIdlePlayNext)
|
|
pc.playlist.GetCurrent().EventManager().RegisterA(model.EventPlaylistInsert, "controller.playcontrol.playlistadd", pc.handlePlaylistAdd)
|
|
pc.player.ObserveProperty(model.PlayerPropTimePos, "controller.playcontrol.updatelyric", pc.handleLyricUpdate)
|
|
return pc
|
|
}
|
|
|
|
func (pc *PlayController) handleMpvIdlePlayNext(event *event.Event) {
|
|
isIdle := event.Data.(model.PlayerPropertyUpdateEvent).Value.(bool)
|
|
if isIdle {
|
|
lg.Info("[Controller] mpv went idle, try play next")
|
|
pc.PlayNext()
|
|
}
|
|
}
|
|
|
|
func (pc *PlayController) handlePlaylistAdd(event *event.Event) {
|
|
if pc.player.IsIdle() {
|
|
pc.PlayNext()
|
|
return
|
|
}
|
|
lg.Debugf("[PlayController] playlist add event, SkipPlaylist=%t", pc.SkipPlaylist)
|
|
if pc.SkipPlaylist && pc.playing != nil && pc.playing.User == controller.PlaylistUser {
|
|
pc.PlayNext()
|
|
return
|
|
}
|
|
}
|
|
|
|
func (pc *PlayController) handleLyricUpdate(event *event.Event) {
|
|
data := event.Data.(model.PlayerPropertyUpdateEvent).Value
|
|
if data == nil {
|
|
return
|
|
}
|
|
pc.lyric.Update(data.(float64))
|
|
}
|
|
|
|
func (pc *PlayController) EventManager() *event.Manager {
|
|
return pc.eventManager
|
|
}
|
|
|
|
func (pc *PlayController) GetPlaying() *model.Media {
|
|
return pc.playing
|
|
}
|
|
|
|
func (pc *PlayController) GetPlayer() player.IPlayer {
|
|
return pc.player
|
|
}
|
|
|
|
func (pc *PlayController) GetLyric() controller.ILyricLoader {
|
|
return pc.lyric
|
|
}
|
|
|
|
func (pc *PlayController) PlayNext() {
|
|
lg.Infof("[PlayController] try to play next possible media")
|
|
if pc.playlist.GetCurrent().Size() == 0 && pc.playlist.GetDefault().Size() == 0 {
|
|
return
|
|
}
|
|
var media *model.Media
|
|
if pc.playlist.GetCurrent().Size() != 0 {
|
|
media = pc.playlist.GetCurrent().Pop().Copy()
|
|
} else if pc.playlist.GetDefault().Size() != 0 {
|
|
media = pc.playlist.GetDefault().Next().Copy()
|
|
media.User = controller.PlaylistUser
|
|
}
|
|
_ = pc.Play(media)
|
|
}
|
|
|
|
func (pc *PlayController) Play(media *model.Media) error {
|
|
lg.Infof("[PlayController] prepare media %s", media.Title)
|
|
err := pc.provider.PrepareMedia(media)
|
|
if err != nil {
|
|
lg.Warn("[PlayController] prepare media failed, try play next")
|
|
//pc.PlayNext()
|
|
return errors.New("prepare media failed")
|
|
}
|
|
pc.eventManager.CallA(model.EventPlay, model.PlayEvent{
|
|
Media: media,
|
|
})
|
|
pc.playing = media
|
|
pc.playlist.AddToHistory(media)
|
|
if err := pc.player.Play(media); err != nil {
|
|
lg.Warn("[PlayController] play failed", err)
|
|
return errors.New("player play failed")
|
|
}
|
|
pc.eventManager.CallA(model.EventPlayed, model.PlayEvent{
|
|
Media: media,
|
|
})
|
|
pc.lyric.Reload(media.Lyric)
|
|
// reset
|
|
media.Url = ""
|
|
return nil
|
|
}
|
|
|
|
func (pc *PlayController) Add(keyword string, user interface{}) {
|
|
media := pc.provider.MediaMatch(keyword)
|
|
if media == nil {
|
|
medias, err := pc.provider.Search(keyword)
|
|
if err != nil {
|
|
lg.Warnf("[PlayController] search for %s, got error %s", keyword, err)
|
|
return
|
|
}
|
|
if len(medias) == 0 {
|
|
lg.Info("[PlayController] search for %s, got no result", keyword)
|
|
return
|
|
}
|
|
media = medias[0]
|
|
}
|
|
media.User = user
|
|
lg.Infof("[PlayController] add media %s (%s)", media.Title, media.Artist)
|
|
pc.playlist.GetCurrent().Insert(-1, media)
|
|
}
|
|
|
|
func (pc *PlayController) AddWithProvider(keyword string, pname string, user interface{}) {
|
|
media := provider.MatchMedia(pname, keyword)
|
|
if media == nil {
|
|
medias, err := provider.Search(pname, keyword)
|
|
if err != nil {
|
|
lg.Warnf("[PlayController] search for %s, got error %s", keyword, err)
|
|
return
|
|
}
|
|
if len(medias) == 0 {
|
|
lg.Infof("[PlayController] search for %s, got no result", keyword)
|
|
return
|
|
}
|
|
|
|
media = medias[0]
|
|
}
|
|
media.User = user
|
|
lg.Infof("[PlayController] add media %s (%s)", media.Title, media.Artist)
|
|
pc.playlist.GetCurrent().Insert(-1, media)
|
|
}
|
|
|
|
func (pc *PlayController) Seek(position float64, absolute bool) {
|
|
if err := pc.player.Seek(position, absolute); err != nil {
|
|
lg.Warnf("[PlayController] seek to position %f (%t) failed, %s", position, absolute, err)
|
|
}
|
|
}
|
|
|
|
func (pc *PlayController) Toggle() (b bool) {
|
|
var err error
|
|
if pc.player.IsPaused() {
|
|
err = pc.player.Unpause()
|
|
b = false
|
|
} else {
|
|
err = pc.player.Pause()
|
|
b = true
|
|
}
|
|
if err != nil {
|
|
lg.Warn("[PlayController] toggle failed", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (pc *PlayController) SetVolume(volume float64) {
|
|
if pc.player.SetVolume(volume) != nil {
|
|
lg.Warnf("[PlayController] set mpv volume to %f failed", volume)
|
|
return
|
|
}
|
|
pc.Volume = volume
|
|
}
|
|
|
|
func (pc *PlayController) Destroy() {
|
|
pc.player.Stop()
|
|
}
|
|
|
|
func (pc *PlayController) GetCurrentAudioDevice() string {
|
|
return pc.AudioDevice
|
|
}
|
|
|
|
func (pc *PlayController) GetAudioDevices() []model.AudioDevice {
|
|
dl, err := pc.player.GetAudioDeviceList()
|
|
if err != nil {
|
|
return make([]model.AudioDevice, 0)
|
|
}
|
|
return dl
|
|
}
|
|
|
|
func (pc *PlayController) SetAudioDevice(device string) {
|
|
lg.Infof("[PlayController] set audio device to %s", device)
|
|
if err := pc.player.SetAudioDevice(device); err != nil {
|
|
lg.Warnf("[PlayController] set mpv audio device to %s failed, %s", device, err)
|
|
_ = pc.player.SetAudioDevice("auto")
|
|
pc.AudioDevice = "auto"
|
|
return
|
|
}
|
|
pc.AudioDevice = device
|
|
}
|