mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-16 15:08:17 +08:00
rewrite using IoC and DI
This commit is contained in:
242
controller/core/playcontrol.go
Normal file
242
controller/core/playcontrol.go
Normal file
@@ -0,0 +1,242 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/common/event"
|
||||
"AynaLivePlayer/config"
|
||||
"AynaLivePlayer/controller"
|
||||
"AynaLivePlayer/model"
|
||||
"AynaLivePlayer/player"
|
||||
"AynaLivePlayer/provider"
|
||||
)
|
||||
|
||||
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) {
|
||||
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
|
||||
}
|
||||
pc.playing = media
|
||||
pc.playlist.AddToHistory(media)
|
||||
if err := pc.player.Play(media); err != nil {
|
||||
lg.Warn("[PlayController] play failed", err)
|
||||
return
|
||||
}
|
||||
pc.eventManager.CallA(model.EventPlay, model.PlayEvent{
|
||||
Media: media,
|
||||
})
|
||||
pc.lyric.Reload(media.Lyric)
|
||||
// reset
|
||||
media.Url = ""
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user