diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..9fd00f1 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,104 @@ +name: Build + +on: + push: + branches: + - master + +jobs: + build-windows: + runs-on: windows-latest + timeout-minutes: 20 + + env: + GOOS: windows + GOARCH: amd64 + EXECUTABLE: AynaLivePlayer.exe + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install dependencies + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + install: >- + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-mpv + + - name: Set up MSYS2 environment for Go build + shell: msys2 {0} + run: | + mkdir -p D:/libmpv/include/mpv + cp -r /mingw64/include/mpv/* D:/libmpv/include/mpv/ + echo "CGO_CFLAGS=-ID:/libmpv/include" >> $GITHUB_ENV + echo "CGO_LDFLAGS=-LD:/a/_temp/msys64/mingw64/lib" >> $GITHUB_ENV + + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: '1.20' + + - name: Tidy go.mod + run: go mod tidy + + - name: Bundle assets + run: | + go install fyne.io/fyne/v2/cmd/fyne@latest + fyne bundle --name resImageIcon --package resource ./assets/icon.png > ./resource/bundle.go + fyne bundle --append --name resFontMSYaHei --package resource ./assets/msyh0.ttf >> ./resource/bundle.go + fyne bundle --append --name resFontMSYaHeiBold --package resource ./assets/msyhbd0.ttf >> ./resource/bundle.go + + - name: Build application + run: go build -o ./${{ env.EXECUTABLE }} -ldflags -H=windowsgui app/main.go + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: windows-build + path: ./${{ env.EXECUTABLE }} + + build-ubuntu: + runs-on: ubuntu-latest + timeout-minutes: 10 + + env: + GOOS: linux + GOARCH: amd64 + EXECUTABLE: AynaLivePlayer + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install dependencies + run: sudo apt-get install -y libmpv-dev libgl-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libgl1-mesa-dev xorg-dev + + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: '1.20' + + - name: Tidy go.mod + run: go mod tidy + + - name: Bundle assets + run: | + go install fyne.io/fyne/v2/cmd/fyne@latest + fyne bundle --name resImageIcon --package resource ./assets/icon.png > ./resource/bundle.go + fyne bundle --append --name resFontMSYaHei --package resource ./assets/msyh0.ttf >> ./resource/bundle.go + fyne bundle --append --name resFontMSYaHeiBold --package resource ./assets/msyhbd0.ttf >> ./resource/bundle.go + + - name: Build application + run: go build -o ./${{ env.EXECUTABLE }} app/main.go + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: ubuntu-build + path: ./${{ env.EXECUTABLE }} diff --git a/core/events/gui.go b/core/events/gui.go new file mode 100644 index 0000000..e4282e7 --- /dev/null +++ b/core/events/gui.go @@ -0,0 +1,7 @@ +package events + +const GUISetPlayerWindowOpenCmd = "cmd.gui.player_window.op" + +type GUISetPlayerWindowOpenCmdEvent struct { + SetOpen bool +} diff --git a/core/events/mapping.go b/core/events/mapping.go index 8585caa..9903e12 100644 --- a/core/events/mapping.go +++ b/core/events/mapping.go @@ -47,6 +47,7 @@ var EventsMapping = map[event.EventId]any{ MediaProviderUpdate: MediaProviderUpdateEvent{}, SearchCmd: SearchCmdEvent{}, SearchResultUpdate: SearchResultUpdateEvent{}, + GUISetPlayerWindowOpenCmd: GUISetPlayerWindowOpenCmdEvent{}, } func init() { diff --git a/gui/handler.go b/gui/handler.go new file mode 100644 index 0000000..5b847c0 --- /dev/null +++ b/gui/handler.go @@ -0,0 +1,18 @@ +package gui + +import ( + "AynaLivePlayer/core/events" + "AynaLivePlayer/global" + "AynaLivePlayer/pkg/event" +) + +func registerHandlers() { + global.EventManager.RegisterA(events.GUISetPlayerWindowOpenCmd, "gui.player.videoplayer.handleopen", func(event *event.Event) { + data := event.Data.(events.GUISetPlayerWindowOpenCmdEvent) + if data.SetOpen { + playerWindow.Close() + } else { + showPlayerWindow() + } + }) +} diff --git a/internal/player/mpv/mpv.go b/internal/player/mpv/mpv.go index b1eb2d0..f665bc1 100644 --- a/internal/player/mpv/mpv.go +++ b/internal/player/mpv/mpv.go @@ -18,6 +18,7 @@ import ( var running bool = false var libmpv *mpv.Mpv = nil var log logger.ILogger = nil +var mpvClientVersion uint32 = 0 func SetupPlayer() { running = true @@ -29,6 +30,8 @@ func SetupPlayer() { log.Error("initialize libmpv failed") return } + mpvClientVersion = mpv.ClientApiVersion() + log.Infof("libmpv version %d", mpv.ClientApiVersion()) _ = libmpv.SetOptionString("vo", "null") log.Info("initialize libmpv success") registerHandler() @@ -207,9 +210,21 @@ func registerCmdHandler() { Media: media, Removed: false, }) - log.Debugf("mpv command load file %s %s", mediaInfo.Title, mediaUrl.Url) - if err := libmpv.Command([]string{"loadfile", mediaUrl.Url}); err != nil { - log.Error("[MPV PlayControl] mpv load media failed", mediaInfo) + log.Debugf("mpv command loadfile %s %s", mediaInfo.Title, mediaUrl.Url) + cmd := []string{"loadfile", mediaUrl.Url} + if media.Info.Cover.Url != "" { + // add media cover to video channel. + // https://mpv.io/manual/master/#command-interface-[]]] + // api changes after client version 2.3 (0.38.0 + if mpvClientVersion >= ((2 << 16) | 3) { + cmd = append(cmd, "replace", "0", "external-files-append=\""+media.Info.Cover.Url+"\",vid=1") + } else { + cmd = append(cmd, "replace", "external-files-append=\""+media.Info.Cover.Url+"\",vid=1") + } + } + log.Debug("[MPV PlayControl] mpv command", cmd) + if err := libmpv.Command(cmd); err != nil { + log.Error("[MPV PlayControl] mpv load media failed", cmd, mediaInfo, err) global.EventManager.CallA( events.PlayerPlayErrorUpdate, events.PlayerPlayErrorUpdateEvent{ @@ -263,7 +278,7 @@ func registerCmdHandler() { } }) - global.EventManager.RegisterA(events.PlayerVideoPlayerSetWindowHandleCmd, "player.next", func(evnt *event.Event) { + global.EventManager.RegisterA(events.PlayerVideoPlayerSetWindowHandleCmd, "player.set_window_handle", func(evnt *event.Event) { handle := evnt.Data.(events.PlayerVideoPlayerSetWindowHandleCmdEvent).Handle err := SetWindowHandle(handle) if err != nil { diff --git a/pkg/config/config.go b/pkg/config/config.go index af319ce..0b7c17e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -10,7 +10,7 @@ import ( const ( ProgramName = "卡西米尔唱片机" - Version uint32 = 0x010006 + Version uint32 = 0x010007 ) const ( diff --git a/pkg/miaosic b/pkg/miaosic index 4b54a30..652e959 160000 --- a/pkg/miaosic +++ b/pkg/miaosic @@ -1 +1 @@ -Subproject commit 4b54a301c9b881489ba931e901aa7000f65f5566 +Subproject commit 652e959c5a3aff368da4bc02d461402e0e91ae6d diff --git a/plugin/qiege/qiege.go b/plugin/qiege/qiege.go index 9b26112..fc4e067 100644 --- a/plugin/qiege/qiege.go +++ b/plugin/qiege/qiege.go @@ -8,6 +8,7 @@ import ( "AynaLivePlayer/pkg/config" "AynaLivePlayer/pkg/event" "AynaLivePlayer/pkg/i18n" + "AynaLivePlayer/pkg/logger" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/data/binding" @@ -23,6 +24,7 @@ type Qiege struct { CustomCMD string currentUid string panel fyne.CanvasObject + log logger.ILogger } func NewQiege() *Qiege { @@ -31,6 +33,7 @@ func NewQiege() *Qiege { PrivilegePermission: true, AdminPermission: true, CustomCMD: "切歌", + log: global.Logger.WithPrefix("plugin.qiege"), } } @@ -71,6 +74,7 @@ func (d *Qiege) handleMessage(event *event.Event) { if len(msgs) < 1 || msgs[0] != d.CustomCMD { return } + d.log.Infof("recieve diange command") if d.UserPermission { if d.currentUid == message.User.Uid { global.EventManager.CallA( diff --git a/plugin/wshub/events.go b/plugin/wshub/events.go index 02552bc..1f3b813 100644 --- a/plugin/wshub/events.go +++ b/plugin/wshub/events.go @@ -14,3 +14,9 @@ type EventDataReceived struct { EventID event.EventId Data json.RawMessage } + +var eventCache []*EventData + +func init() { + eventCache = make([]*EventData, 0) +} diff --git a/plugin/wshub/server.go b/plugin/wshub/server.go index 2976601..3697acd 100644 --- a/plugin/wshub/server.go +++ b/plugin/wshub/server.go @@ -112,6 +112,20 @@ func (s *wsServer) handleWsInfo(w http.ResponseWriter, r *http.Request) { s.register(client) defer s.unregister(client) go client.start() + // send initial data + for _, data := range eventCache { + // ignore empty + if data.EventID == "" { + continue + } + eventCacheData, _ := json.Marshal(data) + err := client.conn.WriteMessage(websocket.TextMessage, eventCacheData) + if err != nil { + s.log.Warn("write message failed", err) + return + } + } + // start message loop for { select { case data := <-client.Data: diff --git a/plugin/wshub/wshub.go b/plugin/wshub/wshub.go index 7037b48..a0cb482 100644 --- a/plugin/wshub/wshub.go +++ b/plugin/wshub/wshub.go @@ -162,19 +162,25 @@ func (w *WsHub) CreatePanel() fyne.CanvasObject { } func (w *WsHub) registerEvents() { + i := 0 for eid, _ := range events.EventsMapping { + eventCache = append(eventCache, &EventData{}) + currentIdx := i global.EventManager.RegisterA(eid, "plugin.wshub.event."+string(eid), func(e *event.Event) { - val, err := json.Marshal(EventData{ + ed := EventData{ EventID: e.Id, Data: e.Data, - }) + } + val, err := json.Marshal(ed) if err != nil { w.log.Errorf("failed to marshal event data %v", err) return } + eventCache[currentIdx] = &ed w.server.broadcast(val) }) + i++ } } diff --git a/template/current_full.txt b/template/current_full.txt index 67ecf11..fa5bf5e 100644 --- a/template/current_full.txt +++ b/template/current_full.txt @@ -4,4 +4,4 @@ Album: {{ .Current.Album}} Username: {{ .Current.Username }} Progress(in seconds): {{.CurrentTime.TotalSeconds}} / {{.TotalTime.TotalSeconds}} Progress(in minutes:seconds): {{ .CurrentTime.Minutes}}:{{ .CurrentTime.Seconds}} / {{ .TotalTime.Minutes}}:{{ .TotalTime.Seconds}} -Lyric: {{.Lyric}} \ No newline at end of file +Lyric: {{ .Lyric}} \ No newline at end of file diff --git a/todo.txt b/todo.txt index 432e7d2..abfeefb 100644 --- a/todo.txt +++ b/todo.txt @@ -15,7 +15,11 @@ ---- Finished -- 2024.05.06@1.0.6 : 修复若干bug +- 2024.05.22@1.0.7 : 修复bug +- 2024.05.19 : 封面添加到mpv video channel +- 2024.05.17 : 更换libmpv,兼容不支持avx的cpu +- 2024.05.16 : 修复b站歌源搜索, 修复id匹配导致数字开头的的歌曲无法搜索到 +- 2024.05.06@1.0.6 : 修复若干bug, 图片加载不出导致的闪退bug - 2024.04.30 : 完成websocket hub - 2024.04.28 : 修复id点歌匹配失败的问题, 修复黑名单会被id绕过的bug - 2024.04.26@1.0.5: 修复直播间长连接重复连接导致点歌重复点的问题,修复直播间添加失败时候会触发闪退的问题,更新依赖导致的闪退问题,修复webdm断开再连接之后无法获取到弹幕的问题