config panel, kuwo source, playlist operation, bug fix @6, panic handling

This commit is contained in:
Aynakeya
2022-06-25 14:08:50 -07:00
parent 9f75839ebc
commit 0a53e8220e
40 changed files with 920 additions and 3992 deletions

View File

@@ -1,94 +0,0 @@
package controller
import (
"AynaLivePlayer/player"
"AynaLivePlayer/provider"
)
func PlayNext() {
l().Info("try to play next possible media")
if UserPlaylist.Size() == 0 && SystemPlaylist.Size() == 0 {
return
}
var media *player.Media
if UserPlaylist.Size() != 0 {
media = UserPlaylist.Pop()
} else if SystemPlaylist.Size() != 0 {
media = SystemPlaylist.Next()
}
Play(media)
}
func Play(media *player.Media) {
l().Info("prepare media")
err := PrepareMedia(media)
if err != nil {
l().Warn("prepare media failed. try play next")
PlayNext()
return
}
if err := MainPlayer.Play(media); err != nil {
l().Warn("play failed", err)
}
CurrentLyric.Reload(media.Lyric)
// reset
media.Url = ""
}
func Add(keyword string, user interface{}) {
medias, err := Search(keyword)
if err != nil {
l().Warnf("search for %s, got error %s", keyword, err)
return
}
if len(medias) == 0 {
l().Info("search for %s, got no result", keyword)
return
}
media := medias[0]
media.User = user
l().Infof("add media %s (%s)", media.Title, media.Artist)
UserPlaylist.Insert(-1, media)
}
func AddWithProvider(keyword string, pname string, user interface{}) {
medias, err := provider.Search(pname, keyword)
if err != nil {
l().Warnf("search for %s, got error %s", keyword, err)
return
}
if len(medias) == 0 {
l().Info("search for %s, got no result", keyword)
}
media := medias[0]
media.User = user
l().Info("add media %s (%s)", media.Title, media.Artist)
UserPlaylist.Insert(-1, media)
}
func Seek(position float64, absolute bool) {
if err := MainPlayer.Seek(position, absolute); err != nil {
l().Warnf("seek to position %f (%t) failed, %s", position, absolute, err)
}
}
func Toggle() (b bool) {
var err error
if MainPlayer.IsPaused() {
err = MainPlayer.Unpause()
b = false
} else {
err = MainPlayer.Pause()
b = true
}
if err != nil {
l().Warn("toggle failed", err)
}
return
}
func SetVolume(volume float64) {
if MainPlayer.SetVolume(volume) != nil {
l().Warnf("set mpv volume to %f failed", volume)
}
}

View File

@@ -20,6 +20,9 @@ func AddCommand(executors ...DanmuCommandExecutor) {
func danmuCommandHandler(event *event.Event) {
danmu := event.Data.(*liveclient.DanmuMessage)
args := strings.Split(danmu.Message, " ")
if len(args[0]) == 0 {
return
}
for _, cmd := range Commands {
if cmd.Match(args[0]) {
cmd.Execute(args[0], args[1:], danmu)

View File

@@ -1,25 +0,0 @@
package controller
import (
"AynaLivePlayer/liveclient"
"strings"
)
var CommandDiange = &Diange{}
type Diange struct {
}
func (d Diange) Match(command string) bool {
for _, c := range []string{"点歌"} {
if command == c {
return true
}
}
return false
}
func (d Diange) Execute(command string, args []string, danmu *liveclient.DanmuMessage) {
keyword := strings.Join(args, " ")
Add(keyword, &danmu.User)
}

View File

@@ -19,15 +19,93 @@ func l() *logrus.Entry {
return logger.Logger.WithField("Module", MODULE_CONTROLLER)
}
func Initialize() {
func PlayNext() {
l().Info("try to play next possible media")
if UserPlaylist.Size() == 0 && SystemPlaylist.Size() == 0 {
return
}
var media *player.Media
if UserPlaylist.Size() != 0 {
media = UserPlaylist.Pop()
} else if SystemPlaylist.Size() != 0 {
media = SystemPlaylist.Next()
}
Play(media)
}
AddCommand(CommandDiange)
func Play(media *player.Media) {
l().Info("prepare media")
err := PrepareMedia(media)
if err != nil {
l().Warn("prepare media failed. try play next")
PlayNext()
return
}
CurrentMedia = media
if err := MainPlayer.Play(media); err != nil {
l().Warn("play failed", err)
}
CurrentLyric.Reload(media.Lyric)
// reset
media.Url = ""
}
MainPlayer.ObserveProperty("idle-active", handleMpvIdlePlayNext)
UserPlaylist.Handler.RegisterA(player.EventPlaylistInsert, "controller.playnextwhenadd", handlePlaylistAdd)
MainPlayer.ObserveProperty("time-pos", handleLyricUpdate)
func Add(keyword string, user interface{}) {
medias, err := Search(keyword)
if err != nil {
l().Warnf("search for %s, got error %s", keyword, err)
return
}
if len(medias) == 0 {
l().Info("search for %s, got no result", keyword)
return
}
media := medias[0]
media.User = user
l().Infof("add media %s (%s)", media.Title, media.Artist)
UserPlaylist.Insert(-1, media)
}
MainPlayer.Start()
func AddWithProvider(keyword string, pname string, user interface{}) {
medias, err := provider.Search(pname, keyword)
if err != nil {
l().Warnf("search for %s, got error %s", keyword, err)
return
}
if len(medias) == 0 {
l().Info("search for %s, got no result", keyword)
}
media := medias[0]
media.User = user
l().Info("add media %s (%s)", media.Title, media.Artist)
UserPlaylist.Insert(-1, media)
}
func Seek(position float64, absolute bool) {
if err := MainPlayer.Seek(position, absolute); err != nil {
l().Warnf("seek to position %f (%t) failed, %s", position, absolute, err)
}
}
func Toggle() (b bool) {
var err error
if MainPlayer.IsPaused() {
err = MainPlayer.Unpause()
b = false
} else {
err = MainPlayer.Pause()
b = true
}
if err != nil {
l().Warn("toggle failed", err)
}
return
}
func SetVolume(volume float64) {
if MainPlayer.SetVolume(volume) != nil {
l().Warnf("set mpv volume to %f failed", volume)
}
}
func Destroy() {
@@ -51,6 +129,10 @@ func SetDanmuClient(roomId string) {
Name: "controller.commandexecutor",
Handler: danmuCommandHandler,
})
LiveClient.Handler().RegisterA(
liveclient.EventMessageReceive,
"controller.danmu.handler",
danmuHandler)
l().Infof("setting live client for %s success", roomId)
}

23
controller/danmu.go Normal file
View File

@@ -0,0 +1,23 @@
package controller
import (
"AynaLivePlayer/event"
"AynaLivePlayer/liveclient"
)
var DanmuHandlers []DanmuHandler
type DanmuHandler interface {
Execute(anmu *liveclient.DanmuMessage)
}
func AddDanmuHandler(handlers ...DanmuHandler) {
DanmuHandlers = append(DanmuHandlers, handlers...)
}
func danmuHandler(event *event.Event) {
danmu := event.Data.(*liveclient.DanmuMessage)
for _, cmd := range DanmuHandlers {
cmd.Execute(danmu)
}
}

View File

@@ -14,14 +14,21 @@ var SystemPlaylist *player.Playlist
var LiveClient liveclient.LiveClient
var PlaylistManager []*player.Playlist
var CurrentLyric *player.Lyric
var CurrentMedia *player.Media
func Initialize() {
func init() {
MainPlayer = player.NewPlayer()
UserPlaylist = player.NewPlaylist("user", player.PlaylistConfig{RandomNext: false})
SystemPlaylist = player.NewPlaylist("system", player.PlaylistConfig{RandomNext: config.Player.PlaylistRandom})
PlaylistManager = make([]*player.Playlist, 0)
CurrentLyric = player.NewLyric("")
loadPlaylists()
MainPlayer.ObserveProperty("idle-active", handleMpvIdlePlayNext)
UserPlaylist.Handler.RegisterA(player.EventPlaylistInsert, "controller.playnextwhenadd", handlePlaylistAdd)
MainPlayer.ObserveProperty("time-pos", handleLyricUpdate)
MainPlayer.Start()
}
func loadPlaylists() {

19
controller/plugin.go Normal file
View File

@@ -0,0 +1,19 @@
package controller
type Plugin interface {
Name() string
Enable() error
}
func LoadPlugin(plugin Plugin) {
l().Info("Loading plugin: " + plugin.Name())
if err := plugin.Enable(); err != nil {
l().Warnf("Failed to load plugin: %s, %s", plugin.Name(), err)
}
}
func LoadPlugins(plugins ...Plugin) {
for _, plugin := range plugins {
LoadPlugin(plugin)
}
}

View File

@@ -65,6 +65,7 @@ func ApplyUser(medias []*player.Media, user interface{}) {
}
func PreparePlaylist(playlist *player.Playlist) error {
l().Debug("Prepare playlist ", playlist.Meta.(provider.Meta))
medias, err := provider.GetPlaylist(playlist.Meta.(provider.Meta))
if err != nil {
l().Warn("prepare playlist failed ", err)