mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-06 10:22:50 +08:00
migrate to eventbus, add support to macos
This commit is contained in:
13
app/main.go
13
app/main.go
@@ -13,6 +13,7 @@ import (
|
||||
"flag"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -45,8 +46,18 @@ func setupGlobal() {
|
||||
global.Logger.SetLogLevel(Log.Level)
|
||||
}
|
||||
|
||||
func main() {
|
||||
func init() {
|
||||
flag.Parse()
|
||||
// if not dev, set working directory to executable directory
|
||||
if !*dev {
|
||||
exePath, _ := os.Executable()
|
||||
exePath, _ = filepath.EvalSymlinks(exePath)
|
||||
exeDir := filepath.Dir(exePath)
|
||||
_ = os.Chdir(exeDir)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
config.LoadFromFile(config.ConfigPath)
|
||||
config.LoadConfig(Log)
|
||||
i18n.LoadLanguage(config.General.Language)
|
||||
|
||||
@@ -556,37 +556,37 @@
|
||||
"en": "Obs browser output",
|
||||
"zh-CN": "OBS网页输出: "
|
||||
},
|
||||
"plugin.yinliang.title": {
|
||||
"en": "Volume Control",
|
||||
"zh-CN": "音量控制"
|
||||
"plugin.yinliang.admin_permission": {
|
||||
"en": "Admin only",
|
||||
"zh-CN": "仅房管可操作"
|
||||
},
|
||||
"plugin.yinliang.description": {
|
||||
"en": "Control volume via danmaku",
|
||||
"zh-CN": "通过弹幕控制音量"
|
||||
},
|
||||
"plugin.yinliang.admin_permission": {
|
||||
"en": "Admin only",
|
||||
"zh-CN": "仅房管可操作"
|
||||
},
|
||||
"plugin.yinliang.enabled": {
|
||||
"en": "Enabled volume control",
|
||||
"zh-CN": "启用弹幕音量控制"
|
||||
},
|
||||
"plugin.yinliang.volume_up_cmd": {
|
||||
"en": "Volume increase command",
|
||||
"zh-CN": "音量增加命令"
|
||||
"plugin.yinliang.max_volume": {
|
||||
"en": "Maximum volume (%)",
|
||||
"zh-CN": "最大音量限制 (%)"
|
||||
},
|
||||
"plugin.yinliang.title": {
|
||||
"en": "Volume Control",
|
||||
"zh-CN": "音量控制"
|
||||
},
|
||||
"plugin.yinliang.volume_down_cmd": {
|
||||
"en": "Volume decrease command",
|
||||
"en": "Volume decrease command",
|
||||
"zh-CN": "音量减少命令"
|
||||
},
|
||||
"plugin.yinliang.volume_step": {
|
||||
"en": "Adjustment step (%)",
|
||||
"zh-CN": "每次音量调整 (%)"
|
||||
},
|
||||
"plugin.yinliang.max_volume": {
|
||||
"en": "Maximum volume (%)",
|
||||
"zh-CN": "最大音量限制 (%)"
|
||||
"plugin.yinliang.volume_up_cmd": {
|
||||
"en": "Volume increase command",
|
||||
"zh-CN": "音量增加命令"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,16 +5,6 @@ import (
|
||||
liveroomsdk "github.com/AynaLivePlayer/liveroom-sdk"
|
||||
)
|
||||
|
||||
//const (
|
||||
// LiveRoomStatusChange string = "liveclient.status.change"
|
||||
// LiveRoomMessageReceive string = "liveclient.message.receive"
|
||||
//)
|
||||
//
|
||||
//type StatusChangeEvent struct {
|
||||
// Connected bool
|
||||
// Client adapter.LiveClient
|
||||
//}
|
||||
|
||||
const LiveRoomAddCmd = "cmd.liveroom.add"
|
||||
|
||||
type LiveRoomAddCmdEvent struct {
|
||||
|
||||
@@ -22,8 +22,8 @@ var EventsMapping = map[string]any{
|
||||
PlayerToggleCmd: PlayerToggleCmdEvent{},
|
||||
PlayerSetPauseCmd: PlayerSetPauseCmdEvent{},
|
||||
PlayerPlayNextCmd: PlayerPlayNextCmdEvent{},
|
||||
PlayerLyricRequestCmd: PlayerLyricRequestCmdEvent{},
|
||||
PlayerLyricReload: PlayerLyricReloadEvent{},
|
||||
CmdGetCurrentLyric: CmdGetCurrentLyricData{},
|
||||
UpdateCurrentLyric: UpdateCurrentLyricData{},
|
||||
PlayerLyricPosUpdate: PlayerLyricPosUpdateEvent{},
|
||||
PlayerPlayingUpdate: PlayerPlayingUpdateEvent{},
|
||||
PlayerPropertyPauseUpdate: PlayerPropertyPauseUpdateEvent{},
|
||||
|
||||
@@ -2,14 +2,14 @@ package events
|
||||
|
||||
import "github.com/AynaLivePlayer/miaosic"
|
||||
|
||||
const PlayerLyricRequestCmd = "cmd.player.lyric.request"
|
||||
const CmdGetCurrentLyric = "cmd.player.lyric.request"
|
||||
|
||||
type PlayerLyricRequestCmdEvent struct {
|
||||
type CmdGetCurrentLyricData struct {
|
||||
}
|
||||
|
||||
const PlayerLyricReload = "update.player.lyric.reload"
|
||||
const UpdateCurrentLyric = "update.player.lyric.reload"
|
||||
|
||||
type PlayerLyricReloadEvent struct {
|
||||
type UpdateCurrentLyricData struct {
|
||||
Lyrics miaosic.Lyrics
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package component
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
@@ -15,7 +14,6 @@ type Entry struct {
|
||||
func NewEntry() *Entry {
|
||||
e := &Entry{}
|
||||
e.ExtendBaseWidget(e)
|
||||
xfyne.EntryDisableUndoRedo(&e.Entry)
|
||||
return e
|
||||
}
|
||||
|
||||
|
||||
@@ -38,12 +38,12 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
|
||||
mode = model.PlaylistModeRandom
|
||||
}
|
||||
logger.Infof("Set player playlist mode to %d", mode)
|
||||
_ = global.EventBus.Publish(events.PlaylistModeChangeCmd(model.PlaylistIDPlayer),
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistModeChangeCmd(model.PlaylistIDPlayer),
|
||||
events.PlaylistModeChangeCmdEvent{
|
||||
Mode: mode,
|
||||
})
|
||||
})
|
||||
global.EventBus.Subscribe("", events.PlaylistModeChangeUpdate(model.PlaylistIDPlayer),
|
||||
global.EventBus.Subscribe(eventChannel, events.PlaylistModeChangeUpdate(model.PlaylistIDPlayer),
|
||||
"gui.config.basic.random_playlist.player",
|
||||
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
data := event.Data.(events.PlaylistModeChangeUpdateEvent)
|
||||
@@ -56,13 +56,13 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
|
||||
if b {
|
||||
mode = model.PlaylistModeRandom
|
||||
}
|
||||
_ = global.EventBus.Publish(events.PlaylistModeChangeCmd(model.PlaylistIDSystem),
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistModeChangeCmd(model.PlaylistIDSystem),
|
||||
events.PlaylistModeChangeCmdEvent{
|
||||
Mode: mode,
|
||||
})
|
||||
})
|
||||
|
||||
global.EventBus.Subscribe("", events.PlaylistModeChangeUpdate(model.PlaylistIDSystem),
|
||||
global.EventBus.Subscribe(eventChannel, events.PlaylistModeChangeUpdate(model.PlaylistIDSystem),
|
||||
"gui.config.basic.random_playlist.system",
|
||||
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
data := event.Data.(events.PlaylistModeChangeUpdateEvent)
|
||||
@@ -80,11 +80,11 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
_ = global.EventBus.Publish(events.PlayerSetAudioDeviceCmd, events.PlayerSetAudioDeviceCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerSetAudioDeviceCmd, events.PlayerSetAudioDeviceCmdEvent{
|
||||
Device: name,
|
||||
})
|
||||
})
|
||||
global.EventBus.Subscribe("",
|
||||
global.EventBus.Subscribe(eventChannel,
|
||||
events.PlayerAudioDeviceUpdate,
|
||||
"gui.config.basic.audio_device.update",
|
||||
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
@@ -123,7 +123,7 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
|
||||
config.General.AutoCheckUpdate),
|
||||
)
|
||||
checkUpdateBtn := widget.NewButton(i18n.T("gui.config.basic.check_update"), func() {
|
||||
_ = global.EventBus.Publish(events.CheckUpdateCmd, events.CheckUpdateCmdEvent{})
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.CheckUpdateCmd, events.CheckUpdateCmdEvent{})
|
||||
})
|
||||
useSysPlaylistBtn := container.NewHBox(
|
||||
widget.NewLabel(i18n.T("gui.config.basic.use_system_playlist")),
|
||||
|
||||
5
gui/consts.go
Normal file
5
gui/consts.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package gui
|
||||
|
||||
const (
|
||||
eventChannel = "gui"
|
||||
)
|
||||
@@ -72,7 +72,7 @@ func Initialize() {
|
||||
// setupPlayerWindow()
|
||||
|
||||
// register error
|
||||
global.EventBus.Subscribe("",
|
||||
global.EventBus.Subscribe(eventChannel,
|
||||
events.ErrorUpdate, "gui.show_error", gutil.ThreadSafeHandler(func(e *eventbus.Event) {
|
||||
err := e.Data.(events.ErrorUpdateEvent).Error
|
||||
logger.Warnf("gui received error event: %v, %v", err, err == nil)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//go:build darwin || windows || linux
|
||||
|
||||
package xfyne
|
||||
package gutil
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2"
|
||||
@@ -1,7 +1,10 @@
|
||||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
package xfyne
|
||||
package gutil
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2"
|
||||
)
|
||||
|
||||
func GetWindowHandle(window fyne.Window) uintptr {
|
||||
glfwWindow := getGlfwWindow(window)
|
||||
@@ -1,7 +1,6 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package xfyne
|
||||
package gutil
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2"
|
||||
@@ -1,7 +1,6 @@
|
||||
//go:build !darwin && !windows && !linux
|
||||
// +build !darwin,!windows,!linux
|
||||
|
||||
package xfyne
|
||||
package gutil
|
||||
|
||||
import "fyne.io/fyne/v2"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package xfyne
|
||||
package gutil
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2"
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func registerHandlers() {
|
||||
global.EventBus.Subscribe("", events.GUISetPlayerWindowOpenCmd, "gui.player.videoplayer.handleopen", func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.GUISetPlayerWindowOpenCmd, "gui.player.videoplayer.handleopen", func(event *eventbus.Event) {
|
||||
data := event.Data.(events.GUISetPlayerWindowOpenCmdEvent)
|
||||
if data.SetOpen {
|
||||
playerWindow.Close()
|
||||
|
||||
@@ -50,12 +50,12 @@ func createHistoryList() fyne.CanvasObject {
|
||||
btns := object.(*fyne.Container).Objects[2].(*fyne.Container).Objects
|
||||
m.User = model.SystemUser
|
||||
btns[0].(*widget.Button).OnTapped = func() {
|
||||
_ = global.EventBus.Publish(events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
|
||||
Media: m,
|
||||
})
|
||||
}
|
||||
btns[1].(*widget.Button).OnTapped = func() {
|
||||
_ = global.EventBus.Publish(events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
|
||||
Media: m,
|
||||
Position: -1,
|
||||
})
|
||||
@@ -75,7 +75,7 @@ func createHistoryList() fyne.CanvasObject {
|
||||
}
|
||||
|
||||
func registerHistoryHandler() {
|
||||
global.EventBus.Subscribe("",
|
||||
global.EventBus.Subscribe(eventChannel,
|
||||
events.PlaylistDetailUpdate(model.PlaylistIDHistory),
|
||||
"gui.history.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
History.mux.Lock()
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"AynaLivePlayer/core/model"
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/gui/gutil"
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
"AynaLivePlayer/pkg/eventbus"
|
||||
"AynaLivePlayer/pkg/i18n"
|
||||
"fyne.io/fyne/v2"
|
||||
@@ -59,8 +58,8 @@ func createRoomSelector() fyne.CanvasObject {
|
||||
descriptionLabel.SetText("")
|
||||
}
|
||||
})
|
||||
idEntry := xfyne.EntryDisableUndoRedo(widget.NewEntry())
|
||||
nameEntry := xfyne.EntryDisableUndoRedo(widget.NewEntry())
|
||||
idEntry := widget.NewEntry()
|
||||
nameEntry := widget.NewEntry()
|
||||
dia := dialog.NewCustomConfirm(
|
||||
i18n.T("gui.room.add.title"),
|
||||
i18n.T("gui.room.add.confirm"),
|
||||
@@ -80,7 +79,7 @@ func createRoomSelector() fyne.CanvasObject {
|
||||
func(b bool) {
|
||||
if b && len(clientNameEntry.Selected) > 0 && len(idEntry.Text) > 0 {
|
||||
logger.Infof("Add room %s %s", clientNameEntry.Selected, idEntry.Text)
|
||||
_ = global.EventBus.Publish(
|
||||
_ = global.EventBus.PublishToChannel(eventChannel,
|
||||
events.LiveRoomAddCmd,
|
||||
events.LiveRoomAddCmdEvent{
|
||||
Title: nameEntry.Text,
|
||||
@@ -98,7 +97,7 @@ func createRoomSelector() fyne.CanvasObject {
|
||||
if len(RoomTab.rooms) == 0 {
|
||||
return
|
||||
}
|
||||
_ = global.EventBus.Publish(
|
||||
_ = global.EventBus.PublishToChannel(eventChannel,
|
||||
events.LiveRoomRemoveCmd,
|
||||
events.LiveRoomRemoveCmdEvent{
|
||||
Identifier: RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(),
|
||||
@@ -133,14 +132,14 @@ func createRoomSelector() fyne.CanvasObject {
|
||||
}
|
||||
|
||||
func registerRoomHandlers() {
|
||||
global.EventBus.Subscribe("",
|
||||
global.EventBus.Subscribe(eventChannel,
|
||||
events.LiveRoomProviderUpdate,
|
||||
"gui.liveroom.provider_update",
|
||||
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
RoomTab.providers = event.Data.(events.LiveRoomProviderUpdateEvent).Providers
|
||||
RoomTab.Rooms.Refresh()
|
||||
}))
|
||||
global.EventBus.Subscribe("",
|
||||
global.EventBus.Subscribe(eventChannel,
|
||||
events.LiveRoomRoomsUpdate,
|
||||
"gui.liveroom.rooms_update",
|
||||
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
@@ -152,7 +151,7 @@ func registerRoomHandlers() {
|
||||
RoomTab.Rooms.Refresh()
|
||||
RoomTab.lock.Unlock()
|
||||
}))
|
||||
global.EventBus.Subscribe("",
|
||||
global.EventBus.Subscribe(eventChannel,
|
||||
events.LiveRoomStatusUpdate,
|
||||
"gui.liveroom.room_status_update",
|
||||
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
@@ -194,7 +193,7 @@ func createRoomController() fyne.CanvasObject {
|
||||
}
|
||||
RoomTab.ConnectBtn.Disable()
|
||||
logger.Infof("Connect to room %s", RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier())
|
||||
_ = global.EventBus.Publish(
|
||||
_ = global.EventBus.PublishToChannel(eventChannel,
|
||||
events.LiveRoomOperationCmd,
|
||||
events.LiveRoomOperationCmdEvent{
|
||||
Identifier: RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(),
|
||||
@@ -207,14 +206,14 @@ func createRoomController() fyne.CanvasObject {
|
||||
}
|
||||
RoomTab.DisConnectBtn.Disable()
|
||||
logger.Infof("Disconnect from room %s", RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier())
|
||||
_ = global.EventBus.Publish(
|
||||
_ = global.EventBus.PublishToChannel(eventChannel,
|
||||
events.LiveRoomOperationCmd,
|
||||
events.LiveRoomOperationCmdEvent{
|
||||
Identifier: RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(),
|
||||
SetConnect: false,
|
||||
})
|
||||
})
|
||||
global.EventBus.Subscribe("",
|
||||
global.EventBus.Subscribe(eventChannel,
|
||||
events.LiveRoomOperationFinish,
|
||||
"gui.liveroom.operation_finish",
|
||||
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
@@ -229,7 +228,7 @@ func createRoomController() fyne.CanvasObject {
|
||||
return
|
||||
}
|
||||
logger.Infof("Change room %s autoconnect to %v", RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(), b)
|
||||
_ = global.EventBus.Publish(
|
||||
_ = global.EventBus.PublishToChannel(eventChannel,
|
||||
events.LiveRoomConfigChangeCmd,
|
||||
events.LiveRoomConfigChangeCmdEvent{
|
||||
Identifier: RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(),
|
||||
|
||||
@@ -45,16 +45,16 @@ var PlayController = &PlayControllerContainer{}
|
||||
|
||||
func registerPlayControllerHandler() {
|
||||
PlayController.ButtonPrev.OnTapped = func() {
|
||||
_ = global.EventBus.Publish(events.PlayerSeekCmd, events.PlayerSeekCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerSeekCmd, events.PlayerSeekCmdEvent{
|
||||
Position: 0,
|
||||
Absolute: true,
|
||||
})
|
||||
}
|
||||
PlayController.ButtonSwitch.OnTapped = func() {
|
||||
_ = global.EventBus.Publish(events.PlayerToggleCmd, events.PlayerToggleCmdEvent{})
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerToggleCmd, events.PlayerToggleCmdEvent{})
|
||||
}
|
||||
PlayController.ButtonNext.OnTapped = func() {
|
||||
_ = global.EventBus.Publish(events.PlayerPlayNextCmd, events.PlayerPlayNextCmdEvent{})
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerPlayNextCmd, events.PlayerPlayNextCmdEvent{})
|
||||
}
|
||||
|
||||
PlayController.ButtonLrc.OnTapped = func() {
|
||||
@@ -68,7 +68,7 @@ func registerPlayControllerHandler() {
|
||||
showPlayerWindow()
|
||||
}
|
||||
|
||||
global.EventBus.Subscribe("", events.PlayerPropertyPauseUpdate, "gui.player.controller.paused", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyPauseUpdate, "gui.player.controller.paused", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
if event.Data.(events.PlayerPropertyPauseUpdateEvent).Paused {
|
||||
PlayController.ButtonSwitch.Icon = theme.MediaPlayIcon()
|
||||
} else {
|
||||
@@ -77,7 +77,7 @@ func registerPlayControllerHandler() {
|
||||
PlayController.ButtonSwitch.Refresh()
|
||||
}))
|
||||
|
||||
global.EventBus.Subscribe("", events.PlayerPropertyPercentPosUpdate, "gui.player.controller.percent_pos", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyPercentPosUpdate, "gui.player.controller.percent_pos", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
if PlayController.Progress.Dragging {
|
||||
return
|
||||
}
|
||||
@@ -85,7 +85,7 @@ func registerPlayControllerHandler() {
|
||||
PlayController.Progress.Refresh()
|
||||
}))
|
||||
|
||||
global.EventBus.Subscribe("", events.PlayerPropertyStateUpdate, "gui.player.controller.idle_active", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyStateUpdate, "gui.player.controller.idle_active", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
state := event.Data.(events.PlayerPropertyStateUpdateEvent).State
|
||||
if state == model.PlayerStateIdle || state == model.PlayerStateLoading {
|
||||
PlayController.Progress.Value = 0
|
||||
@@ -101,33 +101,33 @@ func registerPlayControllerHandler() {
|
||||
|
||||
PlayController.Progress.Max = 0
|
||||
PlayController.Progress.OnDragEnd = func(f float64) {
|
||||
_ = global.EventBus.Publish(events.PlayerSeekCmd, events.PlayerSeekCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerSeekCmd, events.PlayerSeekCmdEvent{
|
||||
Position: f / 10,
|
||||
Absolute: false,
|
||||
})
|
||||
}
|
||||
|
||||
global.EventBus.Subscribe("", events.PlayerPropertyTimePosUpdate, "gui.player.controller.time_pos", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyTimePosUpdate, "gui.player.controller.time_pos", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
PlayController.CurrentTime.SetText(util.FormatTime(int(event.Data.(events.PlayerPropertyTimePosUpdateEvent).TimePos)))
|
||||
}))
|
||||
|
||||
global.EventBus.Subscribe("", events.PlayerPropertyDurationUpdate, "gui.player.controller.duration", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyDurationUpdate, "gui.player.controller.duration", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
PlayController.TotalTime.SetText(util.FormatTime(int(event.Data.(events.PlayerPropertyDurationUpdateEvent).Duration)))
|
||||
}))
|
||||
|
||||
global.EventBus.Subscribe("", events.PlayerPropertyVolumeUpdate, "gui.player.controller.volume", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyVolumeUpdate, "gui.player.controller.volume", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
PlayController.Volume.Value = event.Data.(events.PlayerPropertyVolumeUpdateEvent).Volume
|
||||
PlayController.Volume.Refresh()
|
||||
}))
|
||||
|
||||
PlayController.Volume.OnChanged = func(f float64) {
|
||||
_ = global.EventBus.Publish(events.PlayerVolumeChangeCmd, events.PlayerVolumeChangeCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerVolumeChangeCmd, events.PlayerVolumeChangeCmdEvent{
|
||||
Volume: f,
|
||||
})
|
||||
}
|
||||
|
||||
// todo: double check cover loading for new thread model
|
||||
global.EventBus.Subscribe("", events.PlayerPlayingUpdate, "gui.player.updateinfo", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.PlayerPlayingUpdate, "gui.player.updateinfo", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
if event.Data.(events.PlayerPlayingUpdateEvent).Removed {
|
||||
PlayController.Progress.Value = 0
|
||||
PlayController.Progress.Max = 0
|
||||
@@ -227,7 +227,7 @@ func createPlayControllerV2() fyne.CanvasObject {
|
||||
PlayController.Progress)
|
||||
|
||||
PlayController.Title = widget.NewLabel("Title")
|
||||
PlayController.Title.Wrapping = fyne.TextTruncate
|
||||
PlayController.Title.Truncation = fyne.TextTruncateClip
|
||||
PlayController.Artist = widget.NewLabel("Artist")
|
||||
PlayController.Username = widget.NewLabel("Username")
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ func createLyricWindow() fyne.Window {
|
||||
w.CenterOnScreen()
|
||||
|
||||
// register handlers
|
||||
global.EventBus.Subscribe("",
|
||||
global.EventBus.Subscribe(eventChannel,
|
||||
events.PlayerLyricPosUpdate, "player.lyric.current_lyric", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
e := event.Data.(events.PlayerLyricPosUpdateEvent)
|
||||
logger.Debug("lyric update", e)
|
||||
@@ -69,16 +69,16 @@ func createLyricWindow() fyne.Window {
|
||||
fullLrc.Refresh()
|
||||
}))
|
||||
|
||||
global.EventBus.Subscribe("", events.PlayerLyricReload, "player.lyric.current_lyric", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
e := event.Data.(events.PlayerLyricReloadEvent)
|
||||
global.EventBus.Subscribe(eventChannel, events.UpdateCurrentLyric, "player.lyric.current_lyric", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
e := event.Data.(events.UpdateCurrentLyricData)
|
||||
fullLrc.Objects = createLyricObj(&e.Lyrics)
|
||||
lrcWindow.Refresh()
|
||||
}))
|
||||
|
||||
_ = global.EventBus.Publish(events.PlayerLyricRequestCmd, events.PlayerLyricRequestCmdEvent{})
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.CmdGetCurrentLyric, events.CmdGetCurrentLyricData{})
|
||||
|
||||
w.SetOnClosed(func() {
|
||||
global.EventBus.Unsubscribe(events.PlayerLyricReload, "player.lyric.current_lyric")
|
||||
global.EventBus.Unsubscribe(events.UpdateCurrentLyric, "player.lyric.current_lyric")
|
||||
PlayController.LrcWindowOpen = false
|
||||
})
|
||||
return w
|
||||
|
||||
@@ -28,12 +28,12 @@ func (b *playlistOperationButton) Tapped(e *fyne.PointEvent) {
|
||||
func newPlaylistOperationButton() *playlistOperationButton {
|
||||
b := &playlistOperationButton{Index: 0}
|
||||
deleteItem := fyne.NewMenuItem(i18n.T("gui.player.playlist.op.delete"), func() {
|
||||
_ = global.EventBus.Publish(events.PlaylistDeleteCmd(model.PlaylistIDPlayer), events.PlaylistDeleteCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistDeleteCmd(model.PlaylistIDPlayer), events.PlaylistDeleteCmdEvent{
|
||||
Index: b.Index,
|
||||
})
|
||||
})
|
||||
topItem := fyne.NewMenuItem(i18n.T("gui.player.playlist.op.top"), func() {
|
||||
_ = global.EventBus.Publish(events.PlaylistMoveCmd(model.PlaylistIDPlayer), events.PlaylistMoveCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistMoveCmd(model.PlaylistIDPlayer), events.PlaylistMoveCmdEvent{
|
||||
From: b.Index,
|
||||
To: 0,
|
||||
})
|
||||
@@ -75,7 +75,7 @@ func createPlaylist() fyne.CanvasObject {
|
||||
object.(*fyne.Container).Objects[1].(*widget.Label).SetText(fmt.Sprintf("%d", id))
|
||||
object.(*fyne.Container).Objects[2].(*playlistOperationButton).Index = id
|
||||
})
|
||||
global.EventBus.Subscribe("", events.PlaylistDetailUpdate(model.PlaylistIDPlayer), "gui.player.playlist.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.PlaylistDetailUpdate(model.PlaylistIDPlayer), "gui.player.playlist.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
UserPlaylist.mux.Lock()
|
||||
UserPlaylist.Medias = event.Data.(events.PlaylistDetailUpdateEvent).Medias
|
||||
UserPlaylist.List.Refresh()
|
||||
|
||||
@@ -3,7 +3,7 @@ package gui
|
||||
import (
|
||||
"AynaLivePlayer/core/events"
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
"AynaLivePlayer/gui/gutil"
|
||||
"fyne.io/fyne/v2"
|
||||
)
|
||||
|
||||
@@ -22,10 +22,10 @@ func showPlayerWindow() {
|
||||
}
|
||||
playerWindow.Show()
|
||||
if playerWindowHandle == 0 {
|
||||
playerWindowHandle = xfyne.GetWindowHandle(playerWindow)
|
||||
playerWindowHandle = gutil.GetWindowHandle(playerWindow)
|
||||
logger.Infof("video output window handle: %d", playerWindowHandle)
|
||||
if playerWindowHandle != 0 {
|
||||
_ = global.EventBus.Publish(events.PlayerVideoPlayerSetWindowHandleCmd,
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerVideoPlayerSetWindowHandleCmd,
|
||||
events.PlayerVideoPlayerSetWindowHandleCmdEvent{Handle: playerWindowHandle})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"AynaLivePlayer/core/model"
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/gui/gutil"
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
|
||||
"AynaLivePlayer/pkg/eventbus"
|
||||
"AynaLivePlayer/pkg/i18n"
|
||||
"fmt"
|
||||
@@ -46,7 +46,7 @@ func createPlaylists() fyne.CanvasObject {
|
||||
})
|
||||
PlaylistManager.AddBtn = widget.NewButton(i18n.T("gui.playlist.button.add"), func() {
|
||||
providerEntry := widget.NewSelect(PlaylistManager.providers, nil)
|
||||
idEntry := xfyne.EntryDisableUndoRedo(widget.NewEntry())
|
||||
idEntry := widget.NewEntry()
|
||||
dia := dialog.NewCustomConfirm(
|
||||
i18n.T("gui.playlist.add.title"),
|
||||
i18n.T("gui.playlist.add.confirm"),
|
||||
@@ -64,7 +64,7 @@ func createPlaylists() fyne.CanvasObject {
|
||||
func(b bool) {
|
||||
if b && len(providerEntry.Selected) > 0 && len(idEntry.Text) > 0 {
|
||||
logger.Infof("add playlists %s %s", providerEntry.Selected, idEntry.Text)
|
||||
_ = global.EventBus.Publish(
|
||||
_ = global.EventBus.PublishToChannel(eventChannel,
|
||||
events.PlaylistManagerAddPlaylistCmd,
|
||||
events.PlaylistManagerAddPlaylistCmdEvent{
|
||||
Provider: providerEntry.Selected,
|
||||
@@ -82,7 +82,7 @@ func createPlaylists() fyne.CanvasObject {
|
||||
return
|
||||
}
|
||||
logger.Infof("remove playlists %s", PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID())
|
||||
_ = global.EventBus.Publish(
|
||||
_ = global.EventBus.PublishToChannel(eventChannel,
|
||||
events.PlaylistManagerRemovePlaylistCmd,
|
||||
events.PlaylistManagerRemovePlaylistCmdEvent{
|
||||
PlaylistID: PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID(),
|
||||
@@ -93,18 +93,18 @@ func createPlaylists() fyne.CanvasObject {
|
||||
return
|
||||
}
|
||||
PlaylistManager.Index = id
|
||||
_ = global.EventBus.Publish(events.PlaylistManagerGetCurrentCmd, events.PlaylistManagerGetCurrentCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistManagerGetCurrentCmd, events.PlaylistManagerGetCurrentCmdEvent{
|
||||
PlaylistID: PlaylistManager.currentPlaylists[id].Meta.ID(),
|
||||
})
|
||||
}
|
||||
global.EventBus.Subscribe("", events.MediaProviderUpdate,
|
||||
global.EventBus.Subscribe(eventChannel, events.MediaProviderUpdate,
|
||||
"gui.playlists.provider.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
providers := event.Data.(events.MediaProviderUpdateEvent)
|
||||
s := make([]string, len(providers.Providers))
|
||||
copy(s, providers.Providers)
|
||||
PlaylistManager.providers = s
|
||||
}))
|
||||
global.EventBus.Subscribe("", events.PlaylistManagerInfoUpdate,
|
||||
global.EventBus.Subscribe(eventChannel, events.PlaylistManagerInfoUpdate,
|
||||
"gui.playlists.info.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
data := event.Data.(events.PlaylistManagerInfoUpdateEvent)
|
||||
prevLen := len(PlaylistManager.currentPlaylists)
|
||||
@@ -115,7 +115,7 @@ func createPlaylists() fyne.CanvasObject {
|
||||
PlaylistManager.Playlists.Select(0)
|
||||
}
|
||||
}))
|
||||
global.EventBus.Subscribe("", events.PlaylistManagerSystemUpdate,
|
||||
global.EventBus.Subscribe(eventChannel, events.PlaylistManagerSystemUpdate,
|
||||
"gui.playlists.system.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
data := event.Data.(events.PlaylistManagerSystemUpdateEvent)
|
||||
PlaylistManager.CurrentSystemPlaylist.SetText(i18n.T("gui.playlist.current") + data.Info.DisplayName())
|
||||
@@ -137,7 +137,7 @@ func createPlaylistMedias() fyne.CanvasObject {
|
||||
if PlaylistManager.Index >= len(PlaylistManager.currentPlaylists) {
|
||||
return
|
||||
}
|
||||
_ = global.EventBus.Publish(events.PlaylistManagerRefreshCurrentCmd, events.PlaylistManagerRefreshCurrentCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistManagerRefreshCurrentCmd, events.PlaylistManagerRefreshCurrentCmdEvent{
|
||||
PlaylistID: PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID(),
|
||||
})
|
||||
})
|
||||
@@ -148,7 +148,7 @@ func createPlaylistMedias() fyne.CanvasObject {
|
||||
return
|
||||
}
|
||||
logger.Infof("set playlist %s as system", PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID())
|
||||
_ = global.EventBus.Publish(events.PlaylistManagerSetSystemCmd, events.PlaylistManagerSetSystemCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistManagerSetSystemCmd, events.PlaylistManagerSetSystemCmdEvent{
|
||||
PlaylistID: PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID(),
|
||||
})
|
||||
})
|
||||
@@ -179,18 +179,18 @@ func createPlaylistMedias() fyne.CanvasObject {
|
||||
btns := object.(*fyne.Container).Objects[2].(*fyne.Container).Objects
|
||||
m.User = model.SystemUser
|
||||
btns[0].(*widget.Button).OnTapped = func() {
|
||||
_ = global.EventBus.Publish(events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
|
||||
Media: m,
|
||||
})
|
||||
}
|
||||
btns[1].(*widget.Button).OnTapped = func() {
|
||||
_ = global.EventBus.Publish(events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
|
||||
Media: m,
|
||||
Position: -1,
|
||||
})
|
||||
}
|
||||
})
|
||||
global.EventBus.Subscribe("", events.PlaylistManagerCurrentUpdate,
|
||||
global.EventBus.Subscribe(eventChannel, events.PlaylistManagerCurrentUpdate,
|
||||
"gui.playlists.current.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
logger.Infof("receive current playlist update, try to refresh playlist medias")
|
||||
data := event.Data.(events.PlaylistManagerCurrentUpdateEvent)
|
||||
|
||||
@@ -35,13 +35,13 @@ func createSearchBar() fyne.CanvasObject {
|
||||
SearchResult.Items = make([]model.Media, 0)
|
||||
SearchResult.List.Refresh()
|
||||
SearchResult.mux.Unlock()
|
||||
_ = global.EventBus.Publish(events.SearchCmd, events.SearchCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.SearchCmd, events.SearchCmdEvent{
|
||||
Keyword: keyword,
|
||||
Provider: pr,
|
||||
})
|
||||
})
|
||||
|
||||
global.EventBus.Subscribe("", events.MediaProviderUpdate,
|
||||
global.EventBus.Subscribe(eventChannel, events.MediaProviderUpdate,
|
||||
"gui.search.provider.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
providers := event.Data.(events.MediaProviderUpdateEvent)
|
||||
s := make([]string, len(providers.Providers))
|
||||
|
||||
@@ -51,18 +51,18 @@ func createSearchList() fyne.CanvasObject {
|
||||
object.(*fyne.Container).Objects[1].(*widget.Label).SetText(fmt.Sprintf("%d", id))
|
||||
btns := object.(*fyne.Container).Objects[2].(*fyne.Container).Objects
|
||||
btns[0].(*widget.Button).OnTapped = func() {
|
||||
_ = global.EventBus.Publish(events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
|
||||
Media: SearchResult.Items[id],
|
||||
})
|
||||
}
|
||||
btns[1].(*widget.Button).OnTapped = func() {
|
||||
_ = global.EventBus.Publish(events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
|
||||
Media: SearchResult.Items[id],
|
||||
Position: -1,
|
||||
})
|
||||
}
|
||||
})
|
||||
global.EventBus.Subscribe("", events.SearchResultUpdate, "gui.search.update_result", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
global.EventBus.Subscribe(eventChannel, events.SearchResultUpdate, "gui.search.update_result", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
items := event.Data.(events.SearchResultUpdateEvent).Medias
|
||||
SearchResult.Items = items
|
||||
SearchResult.mux.Lock()
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func checkUpdate() {
|
||||
global.EventBus.Subscribe("",
|
||||
global.EventBus.Subscribe(eventChannel,
|
||||
events.CheckUpdateResultUpdate, "gui.updater.check_update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
|
||||
data := event.Data.(events.CheckUpdateResultUpdateEvent)
|
||||
msg := data.Info.Version.String() + "\n\n\n" + data.Info.Info
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package xfyne
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
func EntryDisableUndoRedo(entry *widget.Entry) *widget.Entry {
|
||||
// do nothing because the bug has been fixed in fyne@v2.5.1
|
||||
return entry
|
||||
//val := reflect.ValueOf(entry).Elem().FieldByName("shortcut").Addr().UnsafePointer()
|
||||
//(*fyne.ShortcutHandler)(val).RemoveShortcut(&fyne.ShortcutRedo{})
|
||||
//(*fyne.ShortcutHandler)(val).RemoveShortcut(&fyne.ShortcutUndo{})
|
||||
//return entry
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package xfyne
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEntryDisableUndoRedo(t *testing.T) {
|
||||
entry := widget.NewEntry()
|
||||
EntryDisableUndoRedo(entry)
|
||||
}
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
)
|
||||
|
||||
func Initialize() {
|
||||
handleSearch()
|
||||
createLyricLoader()
|
||||
handlePlayNext()
|
||||
}
|
||||
|
||||
|
||||
5
internal/player/readme.md
Normal file
5
internal/player/readme.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# player
|
||||
|
||||
**player implementation**
|
||||
|
||||
for now, just use mpv, vlc not fully supported yet.
|
||||
46
internal/source/base.go
Normal file
46
internal/source/base.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package source
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/core/events"
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/pkg/config"
|
||||
"AynaLivePlayer/pkg/logger"
|
||||
"github.com/AynaLivePlayer/miaosic"
|
||||
)
|
||||
|
||||
type _sourceConfig struct {
|
||||
LocalSourcePath string
|
||||
QQChannel string
|
||||
}
|
||||
|
||||
func (_ _sourceConfig) Name() string {
|
||||
return "Source"
|
||||
}
|
||||
|
||||
func (_ _sourceConfig) OnLoad() {
|
||||
}
|
||||
|
||||
func (_ _sourceConfig) OnSave() {
|
||||
}
|
||||
|
||||
var sourceCfg = &_sourceConfig{
|
||||
LocalSourcePath: "./music",
|
||||
QQChannel: "qq",
|
||||
}
|
||||
|
||||
var log logger.ILogger = nil
|
||||
|
||||
func Initialize() {
|
||||
config.LoadConfig(sourceCfg)
|
||||
|
||||
log = global.Logger.WithPrefix("MediaProvider")
|
||||
|
||||
loadMediaProvider()
|
||||
handleSearch()
|
||||
createLyricLoader()
|
||||
|
||||
_ = global.EventBus.Publish(
|
||||
events.MediaProviderUpdate, events.MediaProviderUpdateEvent{
|
||||
Providers: miaosic.ListAvailableProviders(),
|
||||
})
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/AynaLivePlayer/miaosic"
|
||||
)
|
||||
|
||||
// dummySource is placeholder source for bypassing copyright requirement
|
||||
type dummySource struct{}
|
||||
|
||||
func (d *dummySource) GetName() string {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package controller
|
||||
package source
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/core/events"
|
||||
@@ -16,8 +16,8 @@ type lyricLoader struct {
|
||||
var lyricManager = &lyricLoader{}
|
||||
|
||||
func createLyricLoader() {
|
||||
log := global.Logger.WithPrefix("LyricLoader")
|
||||
global.EventBus.Subscribe("", events.PlayerPlayingUpdate, "internal.lyric.update", func(event *eventbus.Event) {
|
||||
var err error
|
||||
err = global.EventBus.Subscribe("", events.PlayerPlayingUpdate, "internal.lyric.update", func(event *eventbus.Event) {
|
||||
data := event.Data.(events.PlayerPlayingUpdateEvent)
|
||||
if data.Removed {
|
||||
log.Debugf("current media removed, clear lyric")
|
||||
@@ -32,11 +32,14 @@ func createLyricLoader() {
|
||||
lyricManager.Lyric = miaosic.ParseLyrics("", "")
|
||||
log.Errorf("failed to get lyric for %s (%s): %s", data.Media.Info.Title, data.Media.Info.Meta.ID(), err)
|
||||
}
|
||||
_ = global.EventBus.Publish(events.PlayerLyricReload, events.PlayerLyricReloadEvent{
|
||||
_ = global.EventBus.Publish(events.UpdateCurrentLyric, events.UpdateCurrentLyricData{
|
||||
Lyrics: lyricManager.Lyric,
|
||||
})
|
||||
})
|
||||
global.EventBus.Subscribe("", events.PlayerPropertyTimePosUpdate, "internal.lyric.update_current", func(event *eventbus.Event) {
|
||||
if err != nil {
|
||||
log.ErrorW("Subscribe player playing update event failed", "error", err)
|
||||
}
|
||||
err = global.EventBus.Subscribe("", events.PlayerPropertyTimePosUpdate, "internal.lyric.update_current", func(event *eventbus.Event) {
|
||||
time := event.Data.(events.PlayerPropertyTimePosUpdateEvent).TimePos
|
||||
idx := lyricManager.Lyric.FindIndex(time)
|
||||
if idx == lyricManager.prevIndex {
|
||||
@@ -53,9 +56,15 @@ func createLyricLoader() {
|
||||
})
|
||||
return
|
||||
})
|
||||
global.EventBus.Subscribe("", events.PlayerLyricRequestCmd, "internal.lyric.request", func(event *eventbus.Event) {
|
||||
_ = global.EventBus.Publish(events.PlayerLyricReload, events.PlayerLyricReloadEvent{
|
||||
if err != nil {
|
||||
log.ErrorW("Subscribe player time position update event failed", "error", err)
|
||||
}
|
||||
err = global.EventBus.Subscribe("", events.CmdGetCurrentLyric, "internal.lyric.request", func(event *eventbus.Event) {
|
||||
_ = global.EventBus.Reply(event, events.UpdateCurrentLyric, events.UpdateCurrentLyricData{
|
||||
Lyrics: lyricManager.Lyric,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
log.ErrorW("Subscribe player lyric request command event failed", "error", err)
|
||||
}
|
||||
}
|
||||
@@ -3,35 +3,9 @@
|
||||
package source
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/core/events"
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/pkg/config"
|
||||
"github.com/AynaLivePlayer/miaosic"
|
||||
)
|
||||
|
||||
type _sourceConfig struct {
|
||||
LocalSourcePath string
|
||||
}
|
||||
|
||||
func (_ _sourceConfig) Name() string {
|
||||
return "Source"
|
||||
}
|
||||
|
||||
func (_ _sourceConfig) OnLoad() {
|
||||
}
|
||||
|
||||
func (_ _sourceConfig) OnSave() {
|
||||
}
|
||||
|
||||
var sourceCfg = &_sourceConfig{
|
||||
LocalSourcePath: "./music",
|
||||
}
|
||||
|
||||
func Initialize() {
|
||||
config.LoadConfig(sourceCfg)
|
||||
func loadMediaProvider() {
|
||||
miaosic.RegisterProvider(&dummySource{})
|
||||
_ = global.EventBus.Publish(
|
||||
events.MediaProviderUpdate, events.MediaProviderUpdateEvent{
|
||||
Providers: miaosic.ListAvailableProviders(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package controller
|
||||
package source
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/core/events"
|
||||
@@ -9,9 +9,8 @@ import (
|
||||
)
|
||||
|
||||
func handleSearch() {
|
||||
log := global.Logger.WithPrefix("Search")
|
||||
global.EventBus.Subscribe("",
|
||||
events.SearchCmd, "internal.controller.search.handleSearchCmd", func(event *eventbus.Event) {
|
||||
err := global.EventBus.Subscribe("",
|
||||
events.SearchCmd, "internal.media_provider.search_handler", func(event *eventbus.Event) {
|
||||
data := event.Data.(events.SearchCmdEvent)
|
||||
log.Infof("Search %s using %s", data.Keyword, data.Provider)
|
||||
searchResult, err := miaosic.SearchByProvider(data.Provider, data.Keyword, 1, 10)
|
||||
@@ -26,9 +25,13 @@ func handleSearch() {
|
||||
User: model.SystemUser,
|
||||
}
|
||||
}
|
||||
_ = global.EventBus.Publish(
|
||||
events.SearchResultUpdate, events.SearchResultUpdateEvent{
|
||||
_ = global.EventBus.Reply(
|
||||
event, events.SearchResultUpdate,
|
||||
events.SearchResultUpdateEvent{
|
||||
Medias: medias,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
log.ErrorW("Subscribe search event failed", "error", err)
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,6 @@
|
||||
package source
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/core/events"
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/pkg/config"
|
||||
"github.com/AynaLivePlayer/miaosic"
|
||||
_ "github.com/AynaLivePlayer/miaosic/providers/bilivideo"
|
||||
"github.com/AynaLivePlayer/miaosic/providers/kugou"
|
||||
@@ -15,28 +12,7 @@ import (
|
||||
"github.com/AynaLivePlayer/miaosic/providers/qq"
|
||||
)
|
||||
|
||||
type _sourceConfig struct {
|
||||
LocalSourcePath string
|
||||
QQChannel string
|
||||
}
|
||||
|
||||
func (_ _sourceConfig) Name() string {
|
||||
return "Source"
|
||||
}
|
||||
|
||||
func (_ _sourceConfig) OnLoad() {
|
||||
}
|
||||
|
||||
func (_ _sourceConfig) OnSave() {
|
||||
}
|
||||
|
||||
var sourceCfg = &_sourceConfig{
|
||||
LocalSourcePath: "./music",
|
||||
QQChannel: "qq",
|
||||
}
|
||||
|
||||
func Initialize() {
|
||||
config.LoadConfig(sourceCfg)
|
||||
func loadMediaProvider() {
|
||||
kugou.UseInstrumental()
|
||||
miaosic.RegisterProvider(local.NewLocal(sourceCfg.LocalSourcePath))
|
||||
if sourceCfg.QQChannel == "wechat" {
|
||||
@@ -44,9 +20,4 @@ func Initialize() {
|
||||
} else {
|
||||
qq.UseQQLogin()
|
||||
}
|
||||
|
||||
_ = global.EventBus.Publish(
|
||||
events.MediaProviderUpdate, events.MediaProviderUpdateEvent{
|
||||
Providers: miaosic.ListAvailableProviders(),
|
||||
})
|
||||
}
|
||||
|
||||
9
internal/sysmediacontrol/smc_darwin.go
Normal file
9
internal/sysmediacontrol/smc_darwin.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package sysmediacontrol
|
||||
|
||||
func InitSystemMediaControl() {
|
||||
// stub
|
||||
}
|
||||
|
||||
func Destroy() {
|
||||
// stub
|
||||
}
|
||||
@@ -26,7 +26,7 @@ type Subscriber interface {
|
||||
// SubscribeAny is Subscribe with empty channel. this function will subscribe to event from any channel
|
||||
SubscribeAny(eventId string, handlerName string, fn HandlerFunc) error
|
||||
// SubscribeOnce will run handler once, and delete handler internally
|
||||
SubscribeOnce(eventId string, handlerName string, fn HandlerFunc) error
|
||||
SubscribeOnce(channel string, eventId string, handlerName string, fn HandlerFunc) error
|
||||
// Unsubscribe just remove handler for the bus
|
||||
Unsubscribe(eventId string, handlerName string) error
|
||||
}
|
||||
@@ -34,6 +34,8 @@ type Subscriber interface {
|
||||
type Publisher interface {
|
||||
// Publish basically a wrapper to PublishEvent
|
||||
Publish(eventId string, data interface{}) error
|
||||
// PublishToChannel publish event to a specific channel, basically another wrapper to PublishEvent
|
||||
PublishToChannel(channel string, eventId string, data interface{}) error
|
||||
// PublishEvent publish an event
|
||||
PublishEvent(event *Event) error
|
||||
}
|
||||
@@ -41,6 +43,7 @@ type Publisher interface {
|
||||
// Caller is special usage of a Publisher
|
||||
type Caller interface {
|
||||
Call(pubEvtId string, data interface{}, subEvtId string) (*Event, error)
|
||||
Reply(req *Event, eventId string, data interface{}) error
|
||||
}
|
||||
|
||||
type Controller interface {
|
||||
|
||||
@@ -191,7 +191,7 @@ func (b *bus) SubscribeAny(eventId, handlerName string, fn HandlerFunc) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *bus) SubscribeOnce(eventId, handlerName string, fn HandlerFunc) error {
|
||||
func (b *bus) SubscribeOnce(channel, eventId, handlerName string, fn HandlerFunc) error {
|
||||
if eventId == "" || handlerName == "" || fn == nil {
|
||||
return errors.New("invalid SubscribeOnce args")
|
||||
}
|
||||
@@ -202,7 +202,7 @@ func (b *bus) SubscribeOnce(eventId, handlerName string, fn HandlerFunc) error {
|
||||
m = make(map[string]handlerRec)
|
||||
b.handlers[eventId] = m
|
||||
}
|
||||
m[handlerName] = handlerRec{name: handlerName, fn: fn, once: true}
|
||||
m[handlerName] = handlerRec{channel: channel, name: handlerName, fn: fn, once: true}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -225,6 +225,10 @@ func (b *bus) Publish(eventId string, data interface{}) error {
|
||||
return b.PublishEvent(&Event{Id: eventId, Data: data})
|
||||
}
|
||||
|
||||
func (b *bus) PublishToChannel(channel string, eventId string, data interface{}) error {
|
||||
return b.PublishEvent(&Event{Id: eventId, Channel: channel, Data: data})
|
||||
}
|
||||
|
||||
func (b *bus) PublishEvent(ev *Event) error {
|
||||
if ev == nil || ev.Id == "" {
|
||||
return errors.New("invalid PublishEvent args")
|
||||
@@ -327,6 +331,15 @@ func (b *bus) Call(eventId string, data interface{}, subEvtId string) (*Event, e
|
||||
}
|
||||
}
|
||||
|
||||
func (b *bus) Reply(req *Event, eventId string, data interface{}) error {
|
||||
return b.PublishEvent(&Event{
|
||||
Id: eventId,
|
||||
Channel: req.Channel,
|
||||
EchoId: req.EchoId,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *bus) nextEchoId() string {
|
||||
x := b.idCtr.Add(1)
|
||||
return fmt.Sprintf("echo-%d-%d", time.Now().UnixNano(), x)
|
||||
|
||||
Submodule pkg/miaosic updated: 8f67b50eae...f0d0cdb6dd
@@ -11,7 +11,7 @@ func main() {
|
||||
a := app.New()
|
||||
w := a.NewWindow("SysTray")
|
||||
|
||||
icon, _ := fyne.LoadResourceFromPath("./assets/icon.jpg")
|
||||
icon, _ := fyne.LoadResourceFromPath("./assets/icon2.jpg")
|
||||
//icon, _ := fyne.LoadResourceFromPath("./assets/icon.png")
|
||||
|
||||
if desk, ok := a.(desktop.App); ok {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package diange
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
"AynaLivePlayer/pkg/i18n"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
@@ -31,7 +30,7 @@ func (b *blacklist) CreatePanel() fyne.CanvasObject {
|
||||
return b.panel
|
||||
}
|
||||
// UI组件
|
||||
input := xfyne.EntryDisableUndoRedo(widget.NewEntry())
|
||||
input := widget.NewEntry()
|
||||
input.SetPlaceHolder(i18n.T("plugin.diange.blacklist.input.placeholder"))
|
||||
|
||||
exactText := i18n.T("plugin.diange.blacklist.option.exact")
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/gui"
|
||||
"AynaLivePlayer/gui/component"
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
|
||||
"AynaLivePlayer/pkg/config"
|
||||
"AynaLivePlayer/pkg/eventbus"
|
||||
"AynaLivePlayer/pkg/i18n"
|
||||
@@ -382,27 +382,27 @@ func (d *Diange) CreatePanel() fyne.CanvasObject {
|
||||
container.NewGridWithColumns(2,
|
||||
container.NewBorder(nil, nil,
|
||||
widget.NewLabel(i18n.T("plugin.diange.medal.name")), nil,
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&d.MedalName)))),
|
||||
widget.NewEntryWithData(binding.BindString(&d.MedalName))),
|
||||
container.NewBorder(nil, nil,
|
||||
widget.NewLabel(i18n.T("plugin.diange.medal.level")), nil,
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MedalPermission))))),
|
||||
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MedalPermission)))),
|
||||
),
|
||||
)
|
||||
dgQueue := container.NewBorder(nil, nil,
|
||||
widget.NewLabel(i18n.T("plugin.diange.queue_max")), nil,
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.QueueMax)))),
|
||||
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.QueueMax))),
|
||||
)
|
||||
dgUserMax := container.NewBorder(nil, nil,
|
||||
widget.NewLabel(i18n.T("plugin.diange.user_max")), nil,
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserMax)))),
|
||||
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserMax))),
|
||||
)
|
||||
dgCoolDown := container.NewBorder(nil, nil,
|
||||
widget.NewLabel(i18n.T("plugin.diange.cooldown")), nil,
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserCoolDown)))),
|
||||
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserCoolDown))),
|
||||
)
|
||||
dgShortCut := container.NewBorder(nil, nil,
|
||||
widget.NewLabel(i18n.T("plugin.diange.custom_cmd")), nil,
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&d.CustomCMD))),
|
||||
widget.NewEntryWithData(binding.BindString(&d.CustomCMD)),
|
||||
)
|
||||
skipPlaylistCheck := widget.NewCheckWithData(i18n.T("plugin.diange.skip_playlist.prompt"), binding.BindBool(&d.SkipSystemPlaylist))
|
||||
skipPlaylist := container.NewHBox(
|
||||
@@ -420,9 +420,9 @@ func (d *Diange) CreatePanel() fyne.CanvasObject {
|
||||
widget.NewLabel(source),
|
||||
widget.NewCheckWithData(i18n.T("plugin.diange.source.enable"), binding.BindBool(&cfg.Enable)),
|
||||
widget.NewLabel(i18n.T("plugin.diange.source.priority")),
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&cfg.Priority)))),
|
||||
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&cfg.Priority))),
|
||||
widget.NewLabel(i18n.T("plugin.diange.source.command")),
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&cfg.Command))),
|
||||
widget.NewEntryWithData(binding.BindString(&cfg.Command)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"AynaLivePlayer/core/events"
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/gui"
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
|
||||
"AynaLivePlayer/pkg/config"
|
||||
"AynaLivePlayer/pkg/eventbus"
|
||||
"AynaLivePlayer/pkg/i18n"
|
||||
@@ -91,7 +91,7 @@ func (d *MaxDuration) CreatePanel() fyne.CanvasObject {
|
||||
if d.panel != nil {
|
||||
return d.panel
|
||||
}
|
||||
maxDurationInput := xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MaxDuration))))
|
||||
maxDurationInput := widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MaxDuration)))
|
||||
skipOnPlayCheckbox := widget.NewCheckWithData(i18n.T("plugin.maxduration.enable"), binding.BindBool(&d.SkipOnPlay))
|
||||
skipOnReachCheckbox := widget.NewCheckWithData(i18n.T("plugin.maxduration.enable"), binding.BindBool(&d.SkipOnReach))
|
||||
d.panel = container.New(
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/gui"
|
||||
"AynaLivePlayer/gui/component"
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
|
||||
"AynaLivePlayer/pkg/config"
|
||||
"AynaLivePlayer/pkg/eventbus"
|
||||
"AynaLivePlayer/pkg/i18n"
|
||||
@@ -121,7 +121,7 @@ func (d *Qiege) CreatePanel() fyne.CanvasObject {
|
||||
)
|
||||
qgShortCut := container.NewBorder(nil, nil,
|
||||
widget.NewLabel(i18n.T("plugin.qiege.custom_cmd")), nil,
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&d.CustomCMD))),
|
||||
widget.NewEntryWithData(binding.BindString(&d.CustomCMD)),
|
||||
)
|
||||
d.panel = container.NewVBox(dgPerm, qgShortCut)
|
||||
return d.panel
|
||||
|
||||
5
plugin/wshub/consts.go
Normal file
5
plugin/wshub/consts.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package wshub
|
||||
|
||||
const (
|
||||
eventChannel = "wshub"
|
||||
)
|
||||
@@ -49,7 +49,7 @@ func (c *wsClient) start() {
|
||||
return
|
||||
}
|
||||
if globalEnableWsHubControl {
|
||||
_ = global.EventBus.Publish(data.EventID, actualEventData)
|
||||
_ = global.EventBus.PublishToChannel(eventChannel, data.EventID, actualEventData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/gui"
|
||||
"AynaLivePlayer/gui/component"
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
|
||||
"AynaLivePlayer/pkg/config"
|
||||
"AynaLivePlayer/pkg/eventbus"
|
||||
"AynaLivePlayer/pkg/i18n"
|
||||
@@ -104,9 +104,9 @@ func (w *WsHub) CreatePanel() fyne.CanvasObject {
|
||||
freshStatusText()
|
||||
serverPort := container.NewBorder(nil, nil,
|
||||
widget.NewLabel(i18n.T("plugin.wshub.port")), nil,
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&w.Port)))),
|
||||
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&w.Port))),
|
||||
)
|
||||
serverUrl := xfyne.EntryDisableUndoRedo(widget.NewEntry())
|
||||
serverUrl := widget.NewEntry()
|
||||
serverUrl.SetText(w.server.getWsUrl())
|
||||
serverUrl.Disable()
|
||||
serverPreview := container.NewBorder(nil, nil,
|
||||
@@ -175,7 +175,7 @@ func (w *WsHub) registerEvents() {
|
||||
for eid, _ := range events.EventsMapping {
|
||||
eventCache = append(eventCache, &EventData{})
|
||||
currentIdx := i
|
||||
global.EventBus.Subscribe("", eid,
|
||||
global.EventBus.Subscribe(eventChannel, eid,
|
||||
"plugin.wshub.event."+string(eid),
|
||||
func(e *eventbus.Event) {
|
||||
ed := EventData{
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"AynaLivePlayer/global"
|
||||
"AynaLivePlayer/gui"
|
||||
"AynaLivePlayer/gui/component"
|
||||
"AynaLivePlayer/gui/xfyne"
|
||||
|
||||
"AynaLivePlayer/pkg/config"
|
||||
"AynaLivePlayer/pkg/eventbus"
|
||||
"AynaLivePlayer/pkg/i18n"
|
||||
@@ -147,9 +147,9 @@ func (y *Yinliang) CreatePanel() fyne.CanvasObject {
|
||||
|
||||
cmdConfig := container.NewGridWithColumns(2,
|
||||
widget.NewLabel(i18n.T("plugin.yinliang.volume_up_cmd")),
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&y.VolumeUpCMD))),
|
||||
widget.NewEntryWithData(binding.BindString(&y.VolumeUpCMD)),
|
||||
widget.NewLabel(i18n.T("plugin.yinliang.volume_down_cmd")),
|
||||
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&y.VolumeDownCMD))),
|
||||
widget.NewEntryWithData(binding.BindString(&y.VolumeDownCMD)),
|
||||
)
|
||||
|
||||
stepEntry := widget.NewEntryWithData(binding.FloatToStringWithFormat(binding.BindFloat(&y.VolumeStep), "%.1f"))
|
||||
@@ -182,9 +182,9 @@ func (y *Yinliang) CreatePanel() fyne.CanvasObject {
|
||||
|
||||
volumeControlConfig := container.NewGridWithColumns(2,
|
||||
widget.NewLabel(i18n.T("plugin.yinliang.volume_step")),
|
||||
xfyne.EntryDisableUndoRedo(stepEntry),
|
||||
stepEntry,
|
||||
widget.NewLabel(i18n.T("plugin.yinliang.max_volume")),
|
||||
xfyne.EntryDisableUndoRedo(maxVolEntry),
|
||||
maxVolEntry,
|
||||
)
|
||||
|
||||
y.panel = container.NewVBox(
|
||||
|
||||
Reference in New Issue
Block a user