mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-06 18:32:50 +08:00
add text info
This commit is contained in:
219
plugin/textinfo/textinfo.go
Normal file
219
plugin/textinfo/textinfo.go
Normal file
@@ -0,0 +1,219 @@
|
||||
package textinfo
|
||||
|
||||
import (
|
||||
"AynaLivePlayer/config"
|
||||
"AynaLivePlayer/controller"
|
||||
"AynaLivePlayer/event"
|
||||
"AynaLivePlayer/gui"
|
||||
"AynaLivePlayer/i18n"
|
||||
"AynaLivePlayer/logger"
|
||||
"AynaLivePlayer/player"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/data/binding"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"github.com/aynakeya/go-mpv"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
const MODULE_PLUGIN_TEXTINFO = "plugin.textinfo"
|
||||
|
||||
func l() *logrus.Entry {
|
||||
return logger.Logger.WithField("Module", MODULE_PLUGIN_TEXTINFO)
|
||||
}
|
||||
|
||||
const Template_Path = "./template/"
|
||||
const Out_Path = "./txtinfo/"
|
||||
|
||||
type Template struct {
|
||||
Name string
|
||||
Text string
|
||||
Tmpl *template.Template
|
||||
}
|
||||
|
||||
type MediaInfo struct {
|
||||
Index int
|
||||
Title string
|
||||
Artist string
|
||||
Album string
|
||||
Username string
|
||||
}
|
||||
|
||||
type OutInfo struct {
|
||||
Current MediaInfo
|
||||
CurrentTime int
|
||||
TotalTime int
|
||||
Lyric string
|
||||
Playlist []MediaInfo
|
||||
PlaylistCount int
|
||||
}
|
||||
|
||||
type TextInfo struct {
|
||||
Rendering bool
|
||||
info OutInfo
|
||||
templates []*Template
|
||||
panel fyne.CanvasObject
|
||||
}
|
||||
|
||||
func NewTextInfo() *TextInfo {
|
||||
return &TextInfo{Rendering: true}
|
||||
}
|
||||
|
||||
func (t *TextInfo) Title() string {
|
||||
return i18n.T("plugin.textinfo.title")
|
||||
}
|
||||
|
||||
func (t *TextInfo) Description() string {
|
||||
return i18n.T("plugin.textinfo.description")
|
||||
}
|
||||
|
||||
func (t *TextInfo) CreatePanel() fyne.CanvasObject {
|
||||
if t.panel != nil {
|
||||
return t.panel
|
||||
}
|
||||
enableRendering := container.NewHBox(
|
||||
widget.NewLabel(i18n.T("plugin.textinfo.prompt")),
|
||||
widget.NewCheckWithData(i18n.T("plugin.textinfo.checkbox"), binding.BindBool(&t.Rendering)),
|
||||
)
|
||||
t.panel = container.NewVBox(enableRendering)
|
||||
return t.panel
|
||||
}
|
||||
|
||||
func (t *TextInfo) Name() string {
|
||||
return "TextInfo"
|
||||
}
|
||||
|
||||
func (t *TextInfo) Enable() (err error) {
|
||||
// ensure the output/input directory exists
|
||||
if err = os.MkdirAll(Template_Path, 0755); err != nil {
|
||||
return
|
||||
}
|
||||
if err = os.MkdirAll(Out_Path, 0755); err != nil {
|
||||
return
|
||||
}
|
||||
config.LoadConfig(t)
|
||||
t.reloadTemplates()
|
||||
t.registerHandlers()
|
||||
gui.AddConfigLayout(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TextInfo) reloadTemplates() {
|
||||
var err error
|
||||
t.templates = make([]*Template, 0)
|
||||
files, err := ioutil.ReadDir(Template_Path)
|
||||
if err != nil {
|
||||
l().Warn("read template directory failed: ", err)
|
||||
return
|
||||
}
|
||||
for _, f := range files {
|
||||
l().Info("loading template: ", f.Name())
|
||||
content, err := ioutil.ReadFile(filepath.Join(Template_Path, f.Name()))
|
||||
if err != nil {
|
||||
l().Warnf("read template file %s failed: %s", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
parse, err := template.New("info").
|
||||
Funcs(template.FuncMap{
|
||||
"GetSeconds": func(t int) int {
|
||||
return t % 60
|
||||
},
|
||||
"GetMinutes": func(t int) int {
|
||||
return t / 60
|
||||
},
|
||||
}).
|
||||
Parse(string(content))
|
||||
if err != nil {
|
||||
l().Warnf("parse template %s failed: %s", f.Name, err)
|
||||
continue
|
||||
}
|
||||
t.templates = append(t.templates, &Template{
|
||||
Name: f.Name(),
|
||||
Text: string(content),
|
||||
Tmpl: parse,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// RenderTemplates render the template to the output file
|
||||
func (t *TextInfo) RenderTemplates() {
|
||||
if !t.Rendering {
|
||||
return
|
||||
}
|
||||
for _, tmpl := range t.templates {
|
||||
l().Trace("rendering template: ", tmpl.Name)
|
||||
out, err := os.Create(filepath.Join(Out_Path, tmpl.Name))
|
||||
defer out.Close()
|
||||
if err != nil {
|
||||
l().Warnf("create output file %s failed: %s", tmpl.Name, err)
|
||||
continue
|
||||
}
|
||||
if err = tmpl.Tmpl.Execute(out, t.info); err != nil {
|
||||
l().Warnf("rendering template %s failed: %s", tmpl.Name, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TextInfo) registerHandlers() {
|
||||
controller.MainPlayer.EventHandler.RegisterA(player.EventPlay, "plugin.textinfo.current", func(event *event.Event) {
|
||||
t.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,
|
||||
Username: event.Data.(player.PlayEvent).Media.ToUser().Name,
|
||||
}
|
||||
t.RenderTemplates()
|
||||
})
|
||||
if controller.MainPlayer.ObserveProperty("time-pos", func(property *mpv.EventProperty) {
|
||||
if property.Data == nil {
|
||||
t.info.CurrentTime = 0
|
||||
return
|
||||
}
|
||||
ct := int(property.Data.(mpv.Node).Value.(float64))
|
||||
if ct == t.info.CurrentTime {
|
||||
return
|
||||
}
|
||||
t.info.CurrentTime = ct
|
||||
t.RenderTemplates()
|
||||
}) != nil {
|
||||
l().Error("register time-pos handler failed")
|
||||
}
|
||||
if controller.MainPlayer.ObserveProperty("duration", func(property *mpv.EventProperty) {
|
||||
if property.Data == nil {
|
||||
t.info.TotalTime = 0
|
||||
return
|
||||
}
|
||||
t.info.TotalTime = int(property.Data.(mpv.Node).Value.(float64))
|
||||
}) != nil {
|
||||
l().Error("fail to register handler for total time with property duration")
|
||||
}
|
||||
controller.UserPlaylist.Handler.RegisterA(player.EventPlaylistUpdate, "plugin.textinfo.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.info.Playlist = pl
|
||||
t.RenderTemplates()
|
||||
})
|
||||
controller.CurrentLyric.Handler.RegisterA(player.EventLyricUpdate, "plugin.textinfo.lyric", func(event *event.Event) {
|
||||
lrcLine := event.Data.(player.LyricUpdateEvent).Lyric
|
||||
t.info.Lyric = lrcLine.Lyric
|
||||
t.RenderTemplates()
|
||||
})
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user