new room gui

This commit is contained in:
Aynakeya
2022-11-28 18:39:12 -08:00
parent eac8b7b775
commit 0498d2dbf3
38 changed files with 1368 additions and 324 deletions

View File

@@ -1,122 +1,9 @@
package controller
import (
"AynaLivePlayer/config"
"AynaLivePlayer/event"
"AynaLivePlayer/liveclient"
"AynaLivePlayer/logger"
"AynaLivePlayer/player"
"AynaLivePlayer/provider"
"AynaLivePlayer/util"
"fmt"
"github.com/sirupsen/logrus"
"strconv"
)
const MODULE_CONTROLLER = "Controller"
func l() *logrus.Entry {
return logger.Logger.WithField("Module", MODULE_CONTROLLER)
}
func SetDanmuClient(roomId string) {
ResetDanmuClient()
l().Infof("setting live client for %s", roomId)
room, err := strconv.Atoi(roomId)
if err != nil {
l().Warn("parse room id error", err)
return
}
if !util.StringSliceContains(config.LiveRoom.History, roomId) {
config.LiveRoom.History = append(config.LiveRoom.History, roomId)
}
LiveClient = liveclient.NewBilibili(room)
LiveClient.Handler().Register(&event.EventHandler{
EventId: liveclient.EventMessageReceive,
Name: "controller.commandexecutor",
Handler: danmuCommandHandler,
})
LiveClient.Handler().RegisterA(
liveclient.EventMessageReceive,
"controller.danmu.handler",
danmuHandler)
l().Infof("setting live client for %s success", roomId)
}
func StartDanmuClient() {
LiveClient.Connect()
}
func ResetDanmuClient() {
if LiveClient != nil {
l().Infof("disconnect from current live client %s", LiveClient.ClientName())
LiveClient.Disconnect()
LiveClient.Handler().UnregisterAll()
LiveClient = nil
}
}
func AddPlaylist(pname string, uri string) *player.Playlist {
l().Infof("try add playlist %s with provider %s", uri, pname)
id, err := provider.FormatPlaylistUrl(pname, uri)
if err != nil || id == "" {
l().Warnf("fail to format %s playlist id for %s", uri, pname)
return nil
}
p := player.NewPlaylist(fmt.Sprintf("%s-%s", pname, id), player.PlaylistConfig{})
p.Meta = provider.Meta{
Name: pname,
Id: id,
}
PlaylistManager = append(PlaylistManager, p)
config.Player.Playlists = append(config.Player.Playlists, id)
config.Player.PlaylistsProvider = append(config.Player.PlaylistsProvider, pname)
return p
}
func RemovePlaylist(index int) {
l().Infof("Try to remove playlist.index=%d", index)
if index < 0 || index >= len(PlaylistManager) {
l().Warnf("playlist.index=%d not found", index)
return
}
if index == config.Player.PlaylistIndex {
l().Info("Delete current system playlist, reset system playlist to index = 0")
SetSystemPlaylist(0)
}
if index < config.Player.PlaylistIndex {
l().Debugf("Delete playlist before system playlist (index=%d), reduce system playlist index by 1", config.Player.PlaylistIndex)
config.Player.PlaylistIndex = config.Player.PlaylistIndex - 1
}
PlaylistManager = append(PlaylistManager[:index], PlaylistManager[index+1:]...)
config.Player.Playlists = append(config.Player.Playlists[:index], config.Player.Playlists[index+1:]...)
config.Player.PlaylistsProvider = append(config.Player.PlaylistsProvider[:index], config.Player.PlaylistsProvider[index+1:]...)
}
func SetSystemPlaylist(index int) {
l().Infof("try set system playlist to playlist.id=%d", index)
if index < 0 || index >= len(PlaylistManager) {
l().Warn("playlist.index=%d not found", index)
return
}
err := PreparePlaylist(PlaylistManager[index])
if err != nil {
return
}
medias := PlaylistManager[index].Playlist
config.Player.PlaylistIndex = index
ApplyUser(medias, player.PlaylistUser)
SystemPlaylist.Replace(medias)
}
func PreparePlaylistByIndex(index int) {
l().Infof("try prepare playlist.id=%d", index)
if index < 0 || index >= len(PlaylistManager) {
l().Warn("playlist.id=%d not found", index)
return
}
err := PreparePlaylist(PlaylistManager[index])
if err != nil {
return
}
}
var l = logger.Logger.WithField("Module", MODULE_CONTROLLER)

View File

@@ -9,28 +9,27 @@ import (
)
var MainPlayer *player.Player
var UserPlaylist *player.Playlist
var History *player.Playlist
var HistoryUser *player.User
var SystemPlaylist *player.Playlist
var LiveClient liveclient.LiveClient
var PlaylistManager []*player.Playlist
var CurrentLyric *player.Lyric
var CurrentMedia *player.Media
func Initialize() {
MainPlayer = player.NewPlayer()
SetAudioDevice(config.Player.AudioDevice)
SetVolume(config.Player.Volume)
UserPlaylist = player.NewPlaylist("user", player.PlaylistConfig{RandomNext: false})
UserPlaylist = player.NewPlaylist("user", player.PlaylistConfig{RandomNext: config.Player.UserPlaylistRandom})
SystemPlaylist = player.NewPlaylist("system", player.PlaylistConfig{RandomNext: config.Player.PlaylistRandom})
PlaylistManager = make([]*player.Playlist, 0)
CurrentLyric = player.NewLyric("")
loadPlaylists()
History = player.NewPlaylist("history", player.PlaylistConfig{RandomNext: false})
HistoryUser = &player.User{Name: "History"}
loadPlaylists()
config.LoadConfig(LiveRoomManager)
LiveRoomManager.InitializeRooms()
CurrentLyric = player.NewLyric("")
MainPlayer.ObserveProperty("idle-active", handleMpvIdlePlayNext)
UserPlaylist.Handler.RegisterA(player.EventPlaylistInsert, "controller.playnextwhenadd", handlePlaylistAdd)
@@ -39,24 +38,31 @@ func Initialize() {
}
func CloseAndSave() {
// set value to global config
config.Player.PlaylistRandom = SystemPlaylist.Config.RandomNext
config.Player.UserPlaylistRandom = UserPlaylist.Config.RandomNext
_ = config.SaveToConfigFile(config.ConfigPath)
}
func loadPlaylists() {
l().Info("Loading playlists ", config.Player.Playlists, config.Player.PlaylistsProvider)
l.Info("Loading playlists ", config.Player.Playlists)
if len(config.Player.Playlists) != len(config.Player.Playlists) {
l().Warn("playlist id and provider does not have same length")
l.Warn("playlist id and provider does not have same length")
return
}
for i := 0; i < len(config.Player.Playlists); i++ {
pname := config.Player.PlaylistsProvider[i]
id := config.Player.Playlists[i]
p := player.NewPlaylist(fmt.Sprintf("%s-%s", pname, id), player.PlaylistConfig{})
pc := config.Player.Playlists[i]
p := player.NewPlaylist(fmt.Sprintf("%s-%s", pc.Provider, pc.ID), player.PlaylistConfig{})
p.Meta = provider.Meta{
Name: pname,
Id: id,
Name: pc.Provider,
Id: pc.ID,
}
PlaylistManager = append(PlaylistManager, p)
}
if config.Player.PlaylistIndex < 0 || config.Player.PlaylistIndex >= len(config.Player.Playlists) {
l().Warn("playlist index did not find")
config.Player.PlaylistIndex = 0
l.Warn("playlist index did not find")
return
}
go func() {

View File

@@ -10,7 +10,7 @@ import (
func handleMpvIdlePlayNext(property *mpv.EventProperty) {
isIdle := property.Data.(mpv.Node).Value.(bool)
if isIdle {
l().Info("mpv went idle, try play next")
l.Info("mpv went idle, try play next")
PlayNext()
}
}

170
controller/liveroom.go Normal file
View File

@@ -0,0 +1,170 @@
package controller
import (
"AynaLivePlayer/config"
"AynaLivePlayer/event"
"AynaLivePlayer/liveclient"
"errors"
"fmt"
)
var LiveRoomManager = &LiveRooms{
LiveRoomPath: "liverooms.json",
LiveRooms: []*LiveRoom{
{
ClientName: "bilibili",
ID: "9076804",
AutoConnect: false,
},
{
ClientName: "bilibili",
ID: "3819533",
AutoConnect: false,
},
},
}
type LiveRooms struct {
LiveRoomPath string
LiveRooms []*LiveRoom `ini:"-"`
}
func (lr *LiveRooms) Name() string {
return "LiveRoom"
}
func (lr *LiveRooms) Size() int {
return len(lr.LiveRooms)
}
func (lr *LiveRooms) OnLoad() {
_ = config.LoadJson(lr.LiveRoomPath, &lr.LiveRooms)
}
func (lr *LiveRooms) OnSave() {
_ = config.SaveJson(lr.LiveRoomPath, &lr.LiveRooms)
}
func (lr *LiveRooms) InitializeRooms() {
for i := 0; i < len(lr.LiveRooms); i++ {
if lr.LiveRooms[i].client == nil {
lr.LiveRooms[i].Init()
}
}
go func() {
for i := 0; i < len(lr.LiveRooms); i++ {
if lr.LiveRooms[i].AutoConnect {
go lr.LiveRooms[i].Connect()
}
}
}()
}
func (lr *LiveRooms) GetRoom(index int) *LiveRoom {
if index < 0 || index >= len(lr.LiveRooms) {
return nil
}
return lr.LiveRooms[index]
}
func (lr *LiveRooms) AddRoom(clientName, roomId string) (*LiveRoom, error) {
l.Infof("add live client (%s) for %s", clientName, roomId)
rm := &LiveRoom{
ClientName: clientName,
ID: roomId,
AutoConnect: false,
}
err := rm.Init()
l.Infof("live client (%s) %s init failed", clientName, roomId)
if err != nil {
return nil, err
}
lr.LiveRooms = append(lr.LiveRooms, rm)
return rm, nil
}
func (lr *LiveRooms) ConnectRoom(index int) error {
l.Infof("Try to start LiveRoom.index=%d", index)
if index < 0 || index >= len(lr.LiveRooms) {
l.Warnf("LiveRoom.index=%d not found", index)
return errors.New("index out of range")
}
lr.LiveRooms[index].client.Connect()
return nil
}
func (lr *LiveRooms) DisconnectRoom(index int) error {
l.Infof("Try to Disconnect LiveRoom.index=%d", index)
if index < 0 || index >= len(lr.LiveRooms) {
l.Warnf("LiveRoom.index=%d not found", index)
return errors.New("index out of range")
}
lr.LiveRooms[index].client.Disconnect()
return nil
}
func (lr *LiveRooms) DeleteRoom(index int) error {
l.Infof("Try to remove LiveRoom.index=%d", index)
if index < 0 || index >= len(lr.LiveRooms) {
l.Warnf("LiveRoom.index=%d not found", index)
return errors.New("index out of range")
}
if len(lr.LiveRooms) == 1 {
return errors.New("can't delete last room")
}
lr.LiveRooms[index].client.Handler().UnregisterAll()
_ = lr.LiveRooms[index].Disconnect()
lr.LiveRooms = append(lr.LiveRooms[:index], lr.LiveRooms[index+1:]...)
return nil
}
type LiveRoom struct {
ClientName string
ID string
AutoConnect bool
client liveclient.LiveClient
}
func (r *LiveRoom) Init() (err error) {
if r.client != nil {
return nil
}
r.client, err = liveclient.NewLiveClient(r.ClientName, r.ID)
if err != nil {
return
}
r.client.Handler().Register(&event.EventHandler{
EventId: liveclient.EventMessageReceive,
Name: "controller.commandexecutor",
Handler: danmuCommandHandler,
})
r.client.Handler().RegisterA(
liveclient.EventMessageReceive,
"controller.danmu.handler",
danmuHandler)
return nil
}
func (r *LiveRoom) Connect() error {
if r.client == nil {
return errors.New("client hasn't initialized yet")
}
r.client.Connect()
return nil
}
func (r *LiveRoom) Disconnect() error {
if r.client == nil {
return errors.New("client hasn't initialized yet")
}
r.client.Disconnect()
return nil
}
func (r *LiveRoom) Title() string {
return fmt.Sprintf("%s-%s", r.ClientName, r.ID)
}
func (r *LiveRoom) Client() liveclient.LiveClient {
return r.client
}

View File

@@ -7,7 +7,7 @@ import (
)
func PlayNext() {
l().Info("try to play next possible media")
l.Info("try to play next possible media")
if UserPlaylist.Size() == 0 && SystemPlaylist.Size() == 0 {
return
}
@@ -21,17 +21,17 @@ func PlayNext() {
}
func Play(media *player.Media) {
l().Infof("prepare media %s", media.Title)
l.Infof("prepare media %s", media.Title)
err := PrepareMedia(media)
if err != nil {
l().Warn("prepare media failed. try play next")
l.Warn("prepare media failed. try play next")
PlayNext()
return
}
CurrentMedia = media
AddToHistory(media)
if err := MainPlayer.Play(media); err != nil {
l().Warn("play failed", err)
l.Warn("play failed", err)
return
}
CurrentLyric.Reload(media.Lyric)
@@ -44,17 +44,17 @@ func Add(keyword string, user interface{}) {
if media == nil {
medias, err := Search(keyword)
if err != nil {
l().Warnf("search for %s, got error %s", keyword, err)
l.Warnf("search for %s, got error %s", keyword, err)
return
}
if len(medias) == 0 {
l().Info("search for %s, got no result", keyword)
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)
l.Infof("add media %s (%s)", media.Title, media.Artist)
UserPlaylist.Insert(-1, media)
}
@@ -63,23 +63,23 @@ func AddWithProvider(keyword string, pname string, user interface{}) {
if media == nil {
medias, err := provider.Search(pname, keyword)
if err != nil {
l().Warnf("search for %s, got error %s", keyword, err)
l.Warnf("search for %s, got error %s", keyword, err)
return
}
if len(medias) == 0 {
l().Infof("search for %s, got no result", keyword)
l.Infof("search for %s, got no result", keyword)
return
}
media = medias[0]
}
media.User = user
l().Infof("add media %s (%s)", media.Title, media.Artist)
l.Infof("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)
l.Warnf("seek to position %f (%t) failed, %s", position, absolute, err)
}
}
@@ -93,14 +93,14 @@ func Toggle() (b bool) {
b = true
}
if err != nil {
l().Warn("toggle failed", err)
l.Warn("toggle failed", err)
}
return
}
func SetVolume(volume float64) {
if MainPlayer.SetVolume(volume) != nil {
l().Warnf("set mpv volume to %f failed", volume)
l.Warnf("set mpv volume to %f failed", volume)
return
}
config.Player.Volume = volume
@@ -119,9 +119,9 @@ func GetAudioDevices() []player.AudioDevice {
}
func SetAudioDevice(device string) {
l().Infof("set audio device to %s", device)
l.Infof("set audio device to %s", device)
if err := MainPlayer.SetAudioDevice(device); err != nil {
l().Warnf("set mpv audio device to %s failed, %s", device, err)
l.Warnf("set mpv audio device to %s failed, %s", device, err)
MainPlayer.SetAudioDevice("auto")
config.Player.AudioDevice = "auto"
return

View File

@@ -1,9 +1,20 @@
package controller
import "AynaLivePlayer/player"
import (
"AynaLivePlayer/config"
"AynaLivePlayer/player"
"AynaLivePlayer/provider"
"fmt"
)
var UserPlaylist *player.Playlist
var History *player.Playlist
var HistoryUser *player.User
var SystemPlaylist *player.Playlist
var PlaylistManager []*player.Playlist
func AddToHistory(media *player.Media) {
l().Tracef("add media %s (%s) to history", media.Title, media.Artist)
l.Tracef("add media %s (%s) to history", media.Title, media.Artist)
media = media.Copy()
// reset url for future use
media.Url = ""
@@ -25,3 +36,69 @@ func ToSystemMedia(media *player.Media) *player.Media {
media.User = player.SystemUser
return media
}
func AddPlaylist(pname string, uri string) *player.Playlist {
l.Infof("try add playlist %s with provider %s", uri, pname)
id, err := provider.FormatPlaylistUrl(pname, uri)
if err != nil || id == "" {
l.Warnf("fail to format %s playlist id for %s", uri, pname)
return nil
}
p := player.NewPlaylist(fmt.Sprintf("%s-%s", pname, id), player.PlaylistConfig{})
p.Meta = provider.Meta{
Name: pname,
Id: id,
}
PlaylistManager = append(PlaylistManager, p)
config.Player.Playlists = append(config.Player.Playlists, &config.PlayerPlaylist{
ID: uri,
Provider: pname,
})
return p
}
func RemovePlaylist(index int) {
l.Infof("Try to remove playlist.index=%d", index)
if index < 0 || index >= len(PlaylistManager) {
l.Warnf("playlist.index=%d not found", index)
return
}
if index == config.Player.PlaylistIndex {
l.Info("Delete current system playlist, reset system playlist to index = 0")
SetSystemPlaylist(0)
}
if index < config.Player.PlaylistIndex {
l.Debugf("Delete playlist before system playlist (index=%d), reduce system playlist index by 1", config.Player.PlaylistIndex)
config.Player.PlaylistIndex = config.Player.PlaylistIndex - 1
}
PlaylistManager = append(PlaylistManager[:index], PlaylistManager[index+1:]...)
config.Player.Playlists = append(config.Player.Playlists[:index], config.Player.Playlists[index+1:]...)
}
func SetSystemPlaylist(index int) {
l.Infof("try set system playlist to playlist.id=%d", index)
if index < 0 || index >= len(PlaylistManager) {
l.Warn("playlist.index=%d not found", index)
return
}
err := PreparePlaylist(PlaylistManager[index])
if err != nil {
return
}
medias := PlaylistManager[index].Playlist
config.Player.PlaylistIndex = index
ApplyUser(medias, player.PlaylistUser)
SystemPlaylist.Replace(medias)
}
func PreparePlaylistByIndex(index int) {
l.Infof("try prepare playlist.id=%d", index)
if index < 0 || index >= len(PlaylistManager) {
l.Warn("playlist.id=%d not found", index)
return
}
err := PreparePlaylist(PlaylistManager[index])
if err != nil {
return
}
}

View File

@@ -7,9 +7,9 @@ type Plugin interface {
}
func LoadPlugin(plugin Plugin) {
l().Info("Loading plugin: " + plugin.Name())
l.Info("Loading plugin: " + plugin.Name())
if err := plugin.Enable(); err != nil {
l().Warnf("Failed to load plugin: %s, %s", plugin.Name(), err)
l.Warnf("Failed to load plugin: %s, %s", plugin.Name(), err)
}
}
@@ -23,7 +23,7 @@ func ClosePlugins(plugins ...Plugin) {
for _, plugin := range plugins {
err := plugin.Disable()
if err != nil {
l().Warnf("Failed to close plugin: %s, %s", plugin.Name(), err)
l.Warnf("Failed to close plugin: %s, %s", plugin.Name(), err)
return
}
}

View File

@@ -9,30 +9,30 @@ import (
func PrepareMedia(media *player.Media) error {
var err error
if media.Title == "" || !media.Cover.Exists() {
l().Trace("fetching media info")
l.Trace("fetching media info")
if err = provider.UpdateMedia(media); err != nil {
l().Warn("fail to prepare media when fetch info", err)
l.Warn("fail to prepare media when fetch info", err)
return err
}
}
if media.Url == "" {
l().Trace("fetching media url")
l.Trace("fetching media url")
if err = provider.UpdateMediaUrl(media); err != nil {
l().Warn("fail to prepare media when url", err)
l.Warn("fail to prepare media when url", err)
return err
}
}
if media.Lyric == "" {
l().Trace("fetching media lyric")
l.Trace("fetching media lyric")
if err = provider.UpdateMediaLyric(media); err != nil {
l().Warn("fail to prepare media when lyric", err)
l.Warn("fail to prepare media when lyric", err)
}
}
return nil
}
func MediaMatch(keyword string) *player.Media {
l().Infof("Match media for %s", keyword)
l.Infof("Match media for %s", keyword)
for _, p := range config.Provider.Priority {
if pr, ok := provider.Providers[p]; ok {
m := pr.MatchMedia(keyword)
@@ -43,36 +43,36 @@ func MediaMatch(keyword string) *player.Media {
return m
}
} else {
l().Warnf("Provider %s not exist", p)
l.Warnf("Provider %s not exist", p)
}
}
return nil
}
func Search(keyword string) ([]*player.Media, error) {
l().Infof("Search for %s", keyword)
l.Infof("Search for %s", keyword)
for _, p := range config.Provider.Priority {
if pr, ok := provider.Providers[p]; ok {
r, err := pr.Search(keyword)
if err != nil {
l().Warn("Provider %s return err", err)
l.Warn("Provider %s return err", err)
continue
}
return r, err
} else {
l().Warnf("Provider %s not exist", p)
l.Warnf("Provider %s not exist", p)
}
}
return nil, provider.ErrorNoSuchProvider
}
func SearchWithProvider(keyword string, p string) ([]*player.Media, error) {
l().Infof("Search for %s using %s", keyword, p)
l.Infof("Search for %s using %s", keyword, p)
if pr, ok := provider.Providers[p]; ok {
r, err := pr.Search(keyword)
return r, err
}
l().Warnf("Provider %s not exist", p)
l.Warnf("Provider %s not exist", p)
return nil, provider.ErrorNoSuchProvider
}
@@ -83,10 +83,10 @@ func ApplyUser(medias []*player.Media, user interface{}) {
}
func PreparePlaylist(playlist *player.Playlist) error {
l().Debug("Prepare playlist ", playlist.Meta.(provider.Meta))
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)
l.Warn("prepare playlist failed ", err)
return err
}
ApplyUser(medias, player.SystemUser)