add web output backend

This commit is contained in:
Aynakeya
2022-07-12 21:06:55 -07:00
parent 6e4c78daf2
commit 94615265bf
16 changed files with 554 additions and 54 deletions

View File

@@ -8,6 +8,7 @@ import (
"AynaLivePlayer/plugin/diange"
"AynaLivePlayer/plugin/qiege"
"AynaLivePlayer/plugin/textinfo"
"AynaLivePlayer/plugin/webinfo"
"fmt"
"github.com/mitchellh/panicwrap"
"os"
@@ -24,11 +25,12 @@ func init() {
}
}
var plugins = []controller.Plugin{diange.NewDiange(), qiege.NewQiege(), textinfo.NewTextInfo(), webinfo.NewWebInfo()}
func main() {
fmt.Printf("BiliAudioBot Revive %s\n", config.VERSION)
//logger.Logger.SetLevel(logrus.DebugLevel)
controller.Initialize()
controller.LoadPlugins(diange.NewDiange(), qiege.NewQiege(), textinfo.NewTextInfo())
controller.LoadPlugins(plugins...)
defer func() {
controller.Destroy()
config.SaveToConfigFile(config.CONFIG_PATH)
@@ -36,4 +38,5 @@ func main() {
}()
gui.Initialize()
gui.MainWindow.ShowAndRun()
controller.ClosePlugins(plugins...)
}

124
app/webs/main.go Normal file
View File

@@ -0,0 +1,124 @@
package main
import (
"encoding/json"
"fmt"
"github.com/gorilla/websocket"
"net/http"
"sync"
"time"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
type WebInfo struct {
A string
B string
}
type WebInfoServer struct {
ServeMux http.ServeMux
Clients map[*Client]int
lock sync.Mutex
}
type Client struct {
conn *websocket.Conn
Data chan []byte
Close chan byte
}
func NewWebInfoServer() *WebInfoServer {
server := &WebInfoServer{
Clients: map[*Client]int{},
}
server.ServeMux.Handle("/", http.FileServer(http.Dir("./assets/webinfo")))
server.ServeMux.HandleFunc("/ws/info", server.handleInfo)
return server
}
func (s *WebInfoServer) handleInfo(w http.ResponseWriter, r *http.Request) {
fmt.Println("connection start")
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println("upgrade error", err)
return
}
client := &Client{
conn: conn,
Data: make(chan []byte, 16),
Close: make(chan byte, 1),
}
s.addClient(client)
defer s.removeClient(client)
go func() {
for {
_, _, err := client.conn.ReadMessage()
if err != nil {
client.Close <- 1
}
}
}()
for {
fmt.Println("waiting for message")
select {
case data := <-client.Data:
writer, err := client.conn.NextWriter(websocket.TextMessage)
if err != nil {
fmt.Println("get writer error", err)
return
}
if _, err = writer.Write(data); err != nil {
fmt.Println("send error:", err)
return
}
if err = writer.Close(); err != nil {
fmt.Println("can't close writer")
return
}
case _ = <-client.Close:
fmt.Println("client close", client.conn.Close())
return
}
}
}
func (s *WebInfoServer) sendInfo(info *WebInfo) {
for client := range s.Clients {
d, _ := json.Marshal(info)
client.Data <- d
}
}
func (s *WebInfoServer) addClient(c *Client) {
s.lock.Lock()
s.Clients[c] = 1
s.lock.Unlock()
}
func (s *WebInfoServer) removeClient(c *Client) {
s.lock.Lock()
close(c.Data)
delete(s.Clients, c)
s.lock.Unlock()
}
var info WebInfo = WebInfo{A: "asdf", B: "ffff"}
func main() {
server := NewWebInfoServer()
go func() {
for {
time.Sleep(time.Second * 5)
server.sendInfo(&info)
}
}()
http.ListenAndServe("localhost:8080", &server.ServeMux)
}

View File

@@ -1,43 +0,0 @@
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/data/binding"
"fyne.io/fyne/v2/widget"
"strconv"
"time"
)
func main() {
var app = app.New()
var (
labelText = ""
bindedLabelText = binding.BindString(&labelText)
label = widget.NewLabelWithData(bindedLabelText)
)
var window = app.NewWindow("Canvas")
var verticalBox = container.NewVBox(label)
window.SetContent(verticalBox)
go func() {
for i := 0; ; i++ {
var newLabelText = strconv.Itoa(i)
if err := bindedLabelText.Set(newLabelText); err != nil {
panic(err)
}
time.Sleep(time.Microsecond)
// NOTE: the only thing, that helps prevent UI updates from freezes, except for the direct manipulation with window size, e.g. update window size from 499x499 -> 500x500 and vice-versa for each iteration
canvas.Refresh(label)
}
}()
window.ShowAndRun()
}

View File

@@ -92,14 +92,14 @@
"en": "ID/URL",
"zh-CN": "ID/网址"
},
"gui.playlist.add.source": {
"en": "Source",
"zh-CN": "来源"
},
"gui.playlist.add.prompt": {
"en": "Please enter the ID or URL of the song you want to add.",
"zh-CN": "输入歌单ID或者歌单网址。"
},
"gui.playlist.add.source": {
"en": "Source",
"zh-CN": "来源"
},
"gui.playlist.add.title": {
"en": "Add Playlist",
"zh-CN": "添加歌单"
@@ -220,10 +220,6 @@
"en": "Custom Command (Default one still works)",
"zh-CN": "自定义命令 (默认的依然可用)"
},
"plugin.diange.source_cmd": {
"en": "Source Command",
"zh-CN": "来源点歌命令"
},
"plugin.diange.description": {
"en": "Basic Diange Configuration",
"zh-CN": "点歌基本设置"
@@ -240,6 +236,10 @@
"en": "Max Queue",
"zh-CN": "最大点歌数"
},
"plugin.diange.source_cmd": {
"en": "Source Command",
"zh-CN": "来源点歌命令"
},
"plugin.diange.title": {
"en": "Diange",
"zh-CN": "点歌"
@@ -291,6 +291,14 @@
"plugin.textinfo.title": {
"en": "Text Output",
"zh-CN": "文本输出"
},
"plugin.webinfo.description": {
"en": "Web output configuration",
"zh-CN": "web输出设置"
},
"plugin.webinfo.title": {
"en": "Web Output",
"zh-CN": "Web输出"
}
}
}

11
assets/webinfo/index.html Normal file
View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LOL</title>
</head>
<body>
<h1>123123</h1>
<p>ABDCCC</p>
</body>
</html>

View File

@@ -0,0 +1,3 @@
function aaa() {
return 0;
}

View File

@@ -6,7 +6,7 @@ import (
"path"
)
const VERSION = "alpha 0.8.1"
const VERSION = "alpha 0.8.3"
const CONFIG_PATH = "./config.ini"
const Assests_PATH = "./assets"

View File

@@ -3,6 +3,7 @@ package controller
type Plugin interface {
Name() string
Enable() error
Disable() error
}
func LoadPlugin(plugin Plugin) {
@@ -17,3 +18,13 @@ func LoadPlugins(plugins ...Plugin) {
LoadPlugin(plugin)
}
}
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)
return
}
}
}

2
go.mod
View File

@@ -10,12 +10,14 @@ require (
github.com/aynakeya/go-mpv v0.0.4
github.com/dhowden/tag v0.0.0-20220618230019-adf36e896086
github.com/go-resty/resty/v2 v2.7.0
github.com/gorilla/websocket v1.5.0 // indirect
github.com/jinzhu/copier v0.3.5
github.com/mitchellh/panicwrap v1.0.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cast v1.3.1
github.com/tidwall/gjson v1.14.1
gopkg.in/ini.v1 v1.66.4
nhooyr.io/websocket v1.8.7
)
replace (

51
go.sum
View File

@@ -20,32 +20,70 @@ github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f h1:s0O46d8fPwk9kU4k1jj76wBquMVETx7uveQD9MCIQoU=
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8=
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lucor/goinfo v0.0.0-20210802170112-c078a2b0f08b/go.mod h1:PRq09yoB+Q2OJReAmwzKivcYyremnibWGbK7WfftHzc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mitchellh/panicwrap v1.0.0 h1:67zIyVakCIvcs69A0FGfZjBdPleaonSgGlXRSRlb6fE=
github.com/mitchellh/panicwrap v1.0.0/go.mod h1:pKvZHwWrZowLUzftuFq7coarnxbBXU4aQh3N0BJOeeA=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
@@ -67,6 +105,8 @@ github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 h1:m59mIOBO4kfcNCE
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
@@ -78,6 +118,10 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT
github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.3.8 h1:Nw158Q8QN+CPgTmVRByhVwapp8Mm1e2blinhmx4wx5E=
@@ -99,6 +143,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -107,14 +152,18 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
@@ -125,3 +174,5 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=

View File

@@ -60,6 +60,10 @@ func (d *Diange) Enable() error {
return nil
}
func (d *Diange) Disable() error {
return nil
}
func (d *Diange) initCMD() {
if len(d.SourceCMD) == len(config.Provider.Priority) {
return

View File

@@ -48,6 +48,10 @@ func (d *Qiege) Enable() error {
return nil
}
func (d *Qiege) Disable() error {
return nil
}
func (d *Qiege) Match(command string) bool {
for _, c := range []string{"切歌", d.CustomCMD} {
if command == c {

View File

@@ -106,6 +106,10 @@ func (t *TextInfo) Enable() (err error) {
return nil
}
func (d *TextInfo) Disable() error {
return nil
}
func (t *TextInfo) reloadTemplates() {
var err error
t.templates = make([]*Template, 0)
@@ -228,6 +232,7 @@ func (t *TextInfo) registerHandlers() {
return
}
t.info.TotalTime = int(property.Data.(mpv.Node).Value.(float64))
t.RenderTemplates()
}) != nil {
l().Error("fail to register handler for total time with property duration")
}

33
plugin/webinfo/info.go Normal file
View File

@@ -0,0 +1,33 @@
package webinfo
import "AynaLivePlayer/player"
type MediaInfo struct {
Index int
Title string
Artist string
Album string
Username string
Cover player.Picture
}
type OutInfo struct {
Current MediaInfo
CurrentTime int
TotalTime int
Lyric string
Playlist []MediaInfo
}
const (
OutInfoC = "Current"
OutInfoCT = "CurrentTime"
OutInfoTT = "TotalTime"
OutInfoL = "Lyric"
OutInfoPL = "Playlist"
)
type WebsocketData struct {
Update string
Data OutInfo
}

144
plugin/webinfo/server.go Normal file
View File

@@ -0,0 +1,144 @@
package webinfo
import (
"context"
"encoding/json"
"fmt"
"github.com/gorilla/websocket"
"net/http"
"sync"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
type WebInfoServer struct {
Info OutInfo
Server *http.Server
Clients map[*Client]int
lock sync.Mutex
}
type Client struct {
conn *websocket.Conn
Data chan []byte
Close chan byte
}
func NewWebInfoServer(port int) *WebInfoServer {
server := &WebInfoServer{
Clients: map[*Client]int{},
}
mux := http.NewServeMux()
mux.Handle("/", http.FileServer(http.Dir("./assets/webinfo")))
mux.HandleFunc("/ws/info", server.handleInfo)
mux.HandleFunc("/api/info", server.getInfo)
server.Server = &http.Server{
Addr: fmt.Sprintf(":%d", port),
Handler: mux,
}
return server
}
func (s *WebInfoServer) getInfo(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
d, _ := json.Marshal(s.Info)
_, err := w.Write(d)
if err != nil {
lg.Warnf("api get info error: %s", err)
return
}
}
func (s *WebInfoServer) handleInfo(w http.ResponseWriter, r *http.Request) {
lg.Debug("connection start")
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
lg.Warnf("upgrade error: %s", err)
return
}
client := &Client{
conn: conn,
Data: make(chan []byte, 16),
Close: make(chan byte, 1),
}
s.addClient(client)
defer s.removeClient(client)
go func() {
for {
_, _, err := client.conn.ReadMessage()
if err != nil {
client.Close <- 1
}
}
}()
for {
lg.Trace("waiting for message")
select {
case data := <-client.Data:
writer, err := client.conn.NextWriter(websocket.TextMessage)
if err != nil {
lg.Warn("get writer error", err)
return
}
if _, err = writer.Write(data); err != nil {
lg.Warn("send error:", err)
return
}
if err = writer.Close(); err != nil {
lg.Warnf("can't close writer: %s", err)
return
}
case _ = <-client.Close:
lg.Debug("client close")
if err := client.conn.Close(); err != nil {
lg.Warnf("close connection encouter an error: %s", err)
}
return
}
}
}
func (s *WebInfoServer) SendInfo(update string, info OutInfo) {
for client := range s.Clients {
d, _ := json.Marshal(WebsocketData{Update: update, Data: info})
client.Data <- d
}
}
func (s *WebInfoServer) addClient(c *Client) {
s.lock.Lock()
s.Clients[c] = 1
s.lock.Unlock()
}
func (s *WebInfoServer) removeClient(c *Client) {
s.lock.Lock()
close(c.Data)
delete(s.Clients, c)
s.lock.Unlock()
}
func (s *WebInfoServer) Start() {
go func() {
err := s.Server.ListenAndServe()
if err == http.ErrServerClosed {
lg.Info("server closed")
return
}
if err != nil {
lg.Warnf("Failed to start webinfo server: %s", err)
return
}
}()
}
func (s *WebInfoServer) Stop() error {
return s.Server.Shutdown(context.Background())
}

140
plugin/webinfo/webinfo.go Normal file
View File

@@ -0,0 +1,140 @@
package webinfo
import (
"AynaLivePlayer/config"
"AynaLivePlayer/controller"
"AynaLivePlayer/event"
"AynaLivePlayer/gui"
"AynaLivePlayer/i18n"
"AynaLivePlayer/logger"
"AynaLivePlayer/player"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/widget"
"github.com/aynakeya/go-mpv"
)
const MODULE_PLGUIN_WEBINFO = "plugin.webinfo"
var lg = logger.Logger.WithField("Module", MODULE_PLGUIN_WEBINFO)
type WebInfo struct {
Port int
server *WebInfoServer
}
func NewWebInfo() *WebInfo {
return &WebInfo{
Port: 4000,
}
}
func (w *WebInfo) Name() string {
return "WebInfo"
}
func (w *WebInfo) Title() string {
return i18n.T("plugin.webinfo.title")
}
func (w *WebInfo) Description() string {
return i18n.T("plugin.webinfo.description")
}
func (w *WebInfo) Enable() error {
config.LoadConfig(w)
w.server = NewWebInfoServer(w.Port)
lg.Info("starting web backend server")
w.server.Start()
w.registerHandlers()
gui.AddConfigLayout(w)
lg.Info("webinfo loaded")
return nil
}
func (w *WebInfo) Disable() error {
lg.Info("closing webinfo backend server")
if err := w.server.Stop(); err != nil {
lg.Warnf("stop webinfo server encouter an error: %s", err)
}
return nil
}
func (t *WebInfo) registerHandlers() {
controller.MainPlayer.EventHandler.RegisterA(player.EventPlay, "plugin.webinfo.current", func(event *event.Event) {
t.server.Info.Current = MediaInfo{
Index: 0,
Title: event.Data.(player.PlayEvent).Media.Title,
Artist: event.Data.(player.PlayEvent).Media.Artist,
Album: event.Data.(player.PlayEvent).Media.Album,
Cover: event.Data.(player.PlayEvent).Media.Cover,
Username: event.Data.(player.PlayEvent).Media.ToUser().Name,
}
t.server.SendInfo(
OutInfoC,
OutInfo{Current: t.server.Info.Current},
)
})
if controller.MainPlayer.ObserveProperty("time-pos", func(property *mpv.EventProperty) {
if property.Data == nil {
t.server.Info.CurrentTime = 0
return
}
ct := int(property.Data.(mpv.Node).Value.(float64))
if ct == t.server.Info.CurrentTime {
return
}
t.server.Info.CurrentTime = ct
t.server.SendInfo(
OutInfoCT,
OutInfo{CurrentTime: t.server.Info.CurrentTime},
)
}) != nil {
lg.Error("register time-pos handler failed")
}
if controller.MainPlayer.ObserveProperty("duration", func(property *mpv.EventProperty) {
if property.Data == nil {
t.server.Info.TotalTime = 0
return
}
t.server.Info.TotalTime = int(property.Data.(mpv.Node).Value.(float64))
t.server.SendInfo(
OutInfoTT,
OutInfo{TotalTime: t.server.Info.TotalTime},
)
}) != nil {
lg.Error("fail to register handler for total time with property duration")
}
controller.UserPlaylist.Handler.RegisterA(player.EventPlaylistUpdate, "plugin.webinfo.playlist", func(event *event.Event) {
pl := make([]MediaInfo, 0)
e := event.Data.(player.PlaylistUpdateEvent)
e.Playlist.Lock.RLock()
for index, m := range e.Playlist.Playlist {
pl = append(pl, MediaInfo{
Index: index,
Title: m.Title,
Artist: m.Artist,
Album: m.Album,
Username: m.ToUser().Name,
})
}
e.Playlist.Lock.RUnlock()
t.server.Info.Playlist = pl
t.server.SendInfo(
OutInfoPL,
OutInfo{Playlist: t.server.Info.Playlist},
)
})
controller.CurrentLyric.Handler.RegisterA(player.EventLyricUpdate, "plugin.webinfo.lyric", func(event *event.Event) {
lrcLine := event.Data.(player.LyricUpdateEvent).Lyric
t.server.Info.Lyric = lrcLine.Lyric
t.server.SendInfo(
OutInfoL,
OutInfo{Lyric: t.server.Info.Lyric},
)
})
}
func (w *WebInfo) CreatePanel() fyne.CanvasObject {
return widget.NewLabel("adf")
}