mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2026-03-19 02:19:45 +08:00
@@ -58,9 +58,12 @@ func main() {
|
||||
global.EventManager.Start()
|
||||
}()
|
||||
gui.MainWindow.ShowAndRun()
|
||||
global.Logger.Info("closing internal server")
|
||||
internal.Stop()
|
||||
global.Logger.Infof("closing event manager")
|
||||
global.EventManager.Stop()
|
||||
if *dev {
|
||||
global.Logger.Infof("saving translation")
|
||||
i18n.SaveTranslation()
|
||||
}
|
||||
_ = config.SaveToConfigFile(config.ConfigPath)
|
||||
|
||||
BIN
assets/icon2.png
Normal file
BIN
assets/icon2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 350 KiB |
@@ -52,6 +52,14 @@
|
||||
"en": "Basic",
|
||||
"zh-CN": "基础设置"
|
||||
},
|
||||
"gui.config.basic.use_system_playlist": {
|
||||
"en": "Play system playlist when no music",
|
||||
"zh-CN": "是否播放闲置歌单(实验性)"
|
||||
},
|
||||
"gui.config.basic.use_system_playlist.prompt": {
|
||||
"en": "Yes",
|
||||
"zh-CN": "是"
|
||||
},
|
||||
"gui.history.artist": {
|
||||
"en": "Artist",
|
||||
"zh-CN": "歌手"
|
||||
@@ -543,6 +551,10 @@
|
||||
"plugin.wshub.title": {
|
||||
"en": "Websocket Hub",
|
||||
"zh-CN": "Websocket服务器"
|
||||
},
|
||||
"plugin.wshub.webinfo_text": {
|
||||
"en": "Obs browser output",
|
||||
"zh-CN": "OBS网页输出: "
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
go.mod
6
go.mod
@@ -10,7 +10,7 @@ replace (
|
||||
)
|
||||
|
||||
require (
|
||||
fyne.io/fyne/v2 v2.5.0
|
||||
fyne.io/fyne/v2 v2.5.1
|
||||
github.com/AynaLivePlayer/liveroom-sdk v0.1.0
|
||||
github.com/AynaLivePlayer/miaosic v0.1.5
|
||||
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b
|
||||
@@ -52,7 +52,7 @@ require (
|
||||
github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a // indirect
|
||||
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect
|
||||
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
|
||||
github.com/go-text/render v0.1.0 // indirect
|
||||
github.com/go-text/render v0.1.1-0.20240418202334-dd62631dae9b // indirect
|
||||
github.com/go-text/typesetting v0.1.0 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/google/uuid v1.5.0 // indirect
|
||||
@@ -63,7 +63,7 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rymdport/portal v0.2.2 // indirect
|
||||
github.com/rymdport/portal v0.2.6 // indirect
|
||||
github.com/sahilm/fuzzy v0.1.0 // indirect
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
|
||||
@@ -124,6 +124,13 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
|
||||
checkUpdateBtn := widget.NewButton(i18n.T("gui.config.basic.check_update"), func() {
|
||||
global.EventManager.CallA(events.CheckUpdateCmd, events.CheckUpdateCmdEvent{})
|
||||
})
|
||||
b.panel = container.NewVBox(randomPlaylist, skipWhenErr, outputDevice, checkUpdateBox, checkUpdateBtn)
|
||||
useSysPlaylistBtn := container.NewHBox(
|
||||
widget.NewLabel(i18n.T("gui.config.basic.use_system_playlist")),
|
||||
component.NewCheckOneWayBinding(
|
||||
i18n.T("gui.config.basic.use_system_playlist.prompt"),
|
||||
&config.General.UseSystemPlaylist,
|
||||
config.General.UseSystemPlaylist),
|
||||
)
|
||||
b.panel = container.NewVBox(randomPlaylist, useSysPlaylistBtn, skipWhenErr, outputDevice, checkUpdateBox, checkUpdateBtn)
|
||||
return b.panel
|
||||
}
|
||||
|
||||
@@ -79,15 +79,20 @@ func Initialize() {
|
||||
})
|
||||
|
||||
checkUpdate()
|
||||
MainWindow.SetFixedSize(true)
|
||||
MainWindow.SetFixedSize(config.General.FixedSize)
|
||||
if config.General.ShowSystemTray {
|
||||
setupSysTray()
|
||||
} else {
|
||||
MainWindow.SetCloseIntercept(
|
||||
func() {
|
||||
// save twice i don;t care
|
||||
// todo: save twice i don;t care
|
||||
_ = config.SaveToConfigFile(config.ConfigPath)
|
||||
MainWindow.Close()
|
||||
})
|
||||
}
|
||||
MainWindow.SetOnClosed(func() {
|
||||
if playerWindow != nil {
|
||||
playerWindow.Close()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,9 +13,6 @@ func setupPlayerWindow() {
|
||||
playerWindow.SetCloseIntercept(func() {
|
||||
playerWindow.Hide()
|
||||
})
|
||||
MainWindow.SetOnClosed(func() {
|
||||
playerWindow.Close()
|
||||
})
|
||||
playerWindow.Hide()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package xfyne
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func EntryDisableUndoRedo(entry *widget.Entry) *widget.Entry {
|
||||
val := reflect.ValueOf(entry).Elem().FieldByName("shortcut").Addr().UnsafePointer()
|
||||
(*fyne.ShortcutHandler)(val).RemoveShortcut(&fyne.ShortcutRedo{})
|
||||
(*fyne.ShortcutHandler)(val).RemoveShortcut(&fyne.ShortcutUndo{})
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -65,13 +65,17 @@ func handlePlayNext() {
|
||||
events.PlaylistNextCmdEvent{
|
||||
Remove: true,
|
||||
})
|
||||
} else {
|
||||
log.Infof("Try to play next media in system playlist")
|
||||
global.EventManager.CallA(events.PlaylistNextCmd(model.PlaylistIDSystem),
|
||||
events.PlaylistNextCmdEvent{
|
||||
Remove: false,
|
||||
})
|
||||
return
|
||||
}
|
||||
if !config.General.UseSystemPlaylist {
|
||||
// do not play system playlist
|
||||
return
|
||||
}
|
||||
log.Infof("Try to play next media in system playlist")
|
||||
global.EventManager.CallA(events.PlaylistNextCmd(model.PlaylistIDSystem),
|
||||
events.PlaylistNextCmdEvent{
|
||||
Remove: false,
|
||||
})
|
||||
})
|
||||
|
||||
global.EventManager.RegisterA(
|
||||
|
||||
@@ -37,6 +37,6 @@ func Stop() {
|
||||
//sysmediacontrol.Destroy()
|
||||
liveroom.StopAndSave()
|
||||
playlist.Close()
|
||||
player.StopMpvPlayer()
|
||||
plugins.ClosePlugins()
|
||||
player.StopMpvPlayer()
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/aynakeya/go-mpv"
|
||||
"github.com/tidwall/gjson"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
var running bool = false
|
||||
@@ -60,7 +61,8 @@ func SetupPlayer() {
|
||||
}
|
||||
if e.EventId == mpv.EVENT_SHUTDOWN {
|
||||
log.Info("[MPV Player] libmpv shutdown")
|
||||
StopPlayer()
|
||||
// should not call, otherwise StopPlayer gonna be call twice and cause panic
|
||||
// StopPlayer()
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -68,11 +70,27 @@ func SetupPlayer() {
|
||||
|
||||
func StopPlayer() {
|
||||
cfg.AudioDevice = libmpv.GetPropertyString("audio-device")
|
||||
log.Debugf("successfully get audio-device and set config %s", cfg.AudioDevice)
|
||||
log.Info("stopping mpv player")
|
||||
running = false
|
||||
// stop player async, should be closed in the end anyway
|
||||
go libmpv.TerminateDestroy()
|
||||
log.Info("mpv player stopped")
|
||||
done := make(chan struct{})
|
||||
|
||||
// Stop player async but wait for at most 1 second
|
||||
go func() {
|
||||
// todo: when call TerminateDestroy after wid has been set, a c code panic will arise.
|
||||
// maybe because the window mpv attach to has been closed. so handle was closed twice
|
||||
// for now. just don't destroy it. because it also might fix configuration
|
||||
// not properly saved issue
|
||||
libmpv.TerminateDestroy()
|
||||
close(done)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
log.Info("mpv player stopped")
|
||||
case <-time.After(2 * time.Second):
|
||||
log.Error("mpv player stop timed out (2s) ")
|
||||
}
|
||||
}
|
||||
|
||||
var prevPercentPos float64 = 0
|
||||
|
||||
@@ -151,7 +151,7 @@ func (p *playlist) Next(delete bool) {
|
||||
p.Lock.Lock()
|
||||
if p.Size() == 0 {
|
||||
// no media in the playlist
|
||||
// do not issue any event
|
||||
// do not dispatch any event
|
||||
p.Lock.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@ package config
|
||||
|
||||
type _GeneralConfig struct {
|
||||
BaseConfig
|
||||
Width float32
|
||||
Height float32
|
||||
Language string
|
||||
InfoApiServer string
|
||||
AutoCheckUpdate bool
|
||||
ShowSystemTray bool
|
||||
PlayNextOnFail bool
|
||||
Width float32
|
||||
Height float32
|
||||
Language string
|
||||
InfoApiServer string
|
||||
AutoCheckUpdate bool
|
||||
ShowSystemTray bool
|
||||
PlayNextOnFail bool
|
||||
UseSystemPlaylist bool
|
||||
FixedSize bool
|
||||
}
|
||||
|
||||
func (c *_GeneralConfig) Name() string {
|
||||
@@ -16,11 +18,13 @@ func (c *_GeneralConfig) Name() string {
|
||||
}
|
||||
|
||||
var General = &_GeneralConfig{
|
||||
Language: "zh-CN",
|
||||
ShowSystemTray: false,
|
||||
InfoApiServer: "http://localhost:9090",
|
||||
AutoCheckUpdate: true,
|
||||
Width: 960,
|
||||
Height: 480,
|
||||
PlayNextOnFail: false,
|
||||
Language: "zh-CN",
|
||||
ShowSystemTray: false,
|
||||
InfoApiServer: "http://localhost:9090",
|
||||
AutoCheckUpdate: true,
|
||||
Width: 960,
|
||||
Height: 480,
|
||||
PlayNextOnFail: false,
|
||||
UseSystemPlaylist: true,
|
||||
FixedSize: true,
|
||||
}
|
||||
|
||||
@@ -48,7 +48,9 @@ func (c *wsClient) start() {
|
||||
global.Logger.Warn("unmarshal event data failed", err)
|
||||
return
|
||||
}
|
||||
global.EventManager.CallA(data.EventID, actualEventData)
|
||||
if globalEnableWsHubControl {
|
||||
global.EventManager.CallA(data.EventID, actualEventData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,29 +16,36 @@ import (
|
||||
"fyne.io/fyne/v2/data/binding"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type WsHub struct {
|
||||
config.BaseConfig
|
||||
Enabled bool
|
||||
Port int
|
||||
LocalHostOnly bool
|
||||
panel fyne.CanvasObject
|
||||
server *wsServer
|
||||
log logger.ILogger
|
||||
Enabled bool
|
||||
Port int
|
||||
LocalHostOnly bool
|
||||
EnableWsHubControl bool
|
||||
panel fyne.CanvasObject
|
||||
server *wsServer
|
||||
log logger.ILogger
|
||||
}
|
||||
|
||||
func NewWsHub() *WsHub {
|
||||
return &WsHub{
|
||||
Enabled: false,
|
||||
Port: 29629,
|
||||
LocalHostOnly: true,
|
||||
log: global.Logger.WithPrefix("plugin.wshub"),
|
||||
Enabled: false,
|
||||
Port: 29629,
|
||||
LocalHostOnly: true,
|
||||
EnableWsHubControl: false,
|
||||
log: global.Logger.WithPrefix("plugin.wshub"),
|
||||
}
|
||||
}
|
||||
|
||||
var globalEnableWsHubControl = false
|
||||
|
||||
func (w *WsHub) Enable() error {
|
||||
config.LoadConfig(w)
|
||||
// todo: should pass EnableWsHubControl to client instead of using global variable
|
||||
globalEnableWsHubControl = w.EnableWsHubControl
|
||||
w.server = newWsServer(&w.Port, &w.LocalHostOnly)
|
||||
gui.AddConfigLayout(w)
|
||||
w.registerEvents()
|
||||
@@ -158,7 +165,9 @@ func (w *WsHub) CreatePanel() fyne.CanvasObject {
|
||||
widget.NewLabel(i18n.T("plugin.wshub.server_control")),
|
||||
startBtn, stopBtn, restartBtn,
|
||||
)
|
||||
w.panel = container.NewVBox(serverStatus, autoStart, localHostOnly, serverPreview, serverPort, ctrlBtns)
|
||||
uri, _ := url.Parse("http://obsinfo.biliaudiobot.com/")
|
||||
infos := container.NewHBox(widget.NewLabel(i18n.T("plugin.wshub.webinfo_text")), widget.NewHyperlink("http://obsinfo.biliaudiobot.com", uri))
|
||||
w.panel = container.NewVBox(serverStatus, autoStart, localHostOnly, serverPreview, serverPort, ctrlBtns, infos)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user