mqtt加入认证,优化视频播放与浏览器
This commit is contained in:
@@ -5,7 +5,9 @@ import (
|
||||
)
|
||||
|
||||
type MqttConfig struct {
|
||||
Url string
|
||||
Url string
|
||||
ClientID string
|
||||
Password string
|
||||
}
|
||||
|
||||
type AliyunConfig struct {
|
||||
|
||||
@@ -1,45 +1,50 @@
|
||||
package common
|
||||
|
||||
import "sync"
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type PauseSub struct {
|
||||
ctrl *CtrlWait
|
||||
// 回调函数
|
||||
ctrl *CtrlWait
|
||||
items []chan int8
|
||||
m sync.RWMutex
|
||||
}
|
||||
|
||||
// Add 添加一个暂停项
|
||||
func (p *PauseSub) Add(item chan int8) {
|
||||
func (p *PauseSub) GetNew() chan int8 {
|
||||
p.m.Lock()
|
||||
defer p.m.Unlock()
|
||||
p.items = append(p.items, item)
|
||||
sub := make(chan int8)
|
||||
p.items = append(p.items, sub)
|
||||
return sub
|
||||
}
|
||||
|
||||
// Remove 移除一个暂停项
|
||||
func (p *PauseSub) Remove(item chan int8) {
|
||||
func (p *PauseSub) Close(sub chan int8) {
|
||||
p.m.Lock()
|
||||
defer p.m.Unlock()
|
||||
close(sub)
|
||||
for i, v := range p.items {
|
||||
if v == item {
|
||||
if v == sub {
|
||||
p.items = append(p.items[:i], p.items[i+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run 开始监听
|
||||
func (p *PauseSub) Run() {
|
||||
func (p *PauseSub) Run(ctx context.Context) {
|
||||
p.ctrl.Open()
|
||||
defer p.ctrl.Close()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-p.ctrl.C:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case c := <-p.ctrl.C:
|
||||
go func() {
|
||||
p.m.RLock()
|
||||
defer p.m.RUnlock()
|
||||
for _, item := range p.items {
|
||||
item <- 1
|
||||
item <- c
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -48,6 +53,7 @@ func (p *PauseSub) Run() {
|
||||
|
||||
func NewPauseSub(c *CtrlWait) *PauseSub {
|
||||
return &PauseSub{
|
||||
ctrl: c,
|
||||
ctrl: c,
|
||||
items: make([]chan int8, 0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ func EmergencyStop(stopper common.Stopper) leaf.HandlerFunc {
|
||||
cancel := leaf.WithCancel(c)
|
||||
defer stopper.Reset()
|
||||
|
||||
zap.S().Infoln("监听停止信号")
|
||||
defer zap.S().Infoln("结束停止信号监听")
|
||||
|
||||
// 等待组
|
||||
var wait sync.WaitGroup
|
||||
defer wait.Wait()
|
||||
@@ -22,11 +25,9 @@ func EmergencyStop(stopper common.Stopper) leaf.HandlerFunc {
|
||||
// 发送结束信号
|
||||
defer close(a)
|
||||
|
||||
zap.S().Infoln("监听停止信号")
|
||||
wait.Add(1)
|
||||
go func() {
|
||||
defer wait.Done()
|
||||
defer zap.S().Infoln("结束停止信号监听")
|
||||
|
||||
select {
|
||||
case <-a:
|
||||
|
||||
@@ -16,11 +16,11 @@ func OnlyVideo(c *leaf.Context) {
|
||||
defer utils.BlankClose()
|
||||
|
||||
if url, ok := payload.Game["video"]; ok {
|
||||
local, err := utils.LinkVideo(url.(string))
|
||||
path, local, err := utils.LinkVideo(url.(string))
|
||||
if err != nil {
|
||||
zap.S().Errorln("视频文件获取异常: ", err)
|
||||
return
|
||||
}
|
||||
_ = video.Play(c, local)
|
||||
_ = video.Play(c, path, local)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
func Video(item schema.WaitItemModel) func(c context.Context) error {
|
||||
return func(c context.Context) error {
|
||||
local, err := utils.LinkVideo(item.Data)
|
||||
path, local, err := utils.LinkVideo(item.Data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("视频文件获取异常: %w", err)
|
||||
}
|
||||
@@ -24,7 +24,7 @@ func Video(item schema.WaitItemModel) func(c context.Context) error {
|
||||
defer utils.BlankClose()
|
||||
|
||||
for {
|
||||
err := video.Play(c, local)
|
||||
err := video.Play(c, path, local)
|
||||
if err != nil {
|
||||
return fmt.Errorf("视频播放异常: %w", err)
|
||||
}
|
||||
|
||||
@@ -13,14 +13,11 @@ func Pause(ps *common.PauseSub, isPause bool, play func(c context.Context) error
|
||||
run := true
|
||||
|
||||
if isPause {
|
||||
p := make(chan int8)
|
||||
defer close(p)
|
||||
zap.S().Infoln("待机暂停控制器")
|
||||
defer zap.S().Infoln("待机暂停控制器结束")
|
||||
|
||||
ps.Add(p)
|
||||
defer ps.Remove(p)
|
||||
|
||||
zap.S().Infoln("待机控制器")
|
||||
defer zap.S().Infoln("待机控制器结束")
|
||||
p := ps.GetNew()
|
||||
defer ps.Close(p)
|
||||
|
||||
// 等待组
|
||||
var wait sync.WaitGroup
|
||||
|
||||
@@ -25,6 +25,9 @@ func Time(rootRules []cronrange.Rule, cron string, play func(c context.Context)
|
||||
a := make(chan bool)
|
||||
defer close(a)
|
||||
|
||||
zap.S().Infoln("待机时间控制器")
|
||||
defer zap.S().Infoln("待机时间控制器结束")
|
||||
|
||||
// 等待组
|
||||
var waitGroup sync.WaitGroup
|
||||
defer waitGroup.Wait()
|
||||
|
||||
@@ -38,7 +38,7 @@ func WaitAction(ctrl *common.CtrlWait) leaf.HandlerFunc {
|
||||
waitGroup.Add(1)
|
||||
go func() {
|
||||
defer waitGroup.Done()
|
||||
ps.Run()
|
||||
ps.Run(c)
|
||||
}()
|
||||
|
||||
// 处理每个待机控制
|
||||
|
||||
@@ -40,6 +40,7 @@ func buildMqtt(c config.MqttConfig, r *leaf.Engine, subTopics ...string) autopah
|
||||
mqttConfig := autopaho.ClientConfig{
|
||||
ServerUrls: []*url.URL{u},
|
||||
KeepAlive: 20,
|
||||
ConnectPassword: []byte(c.Password),
|
||||
CleanStartOnInitialConnection: false,
|
||||
SessionExpiryInterval: 60,
|
||||
OnConnectionUp: func(cm *autopaho.ConnectionManager, _ *paho.Connack) {
|
||||
@@ -56,7 +57,7 @@ func buildMqtt(c config.MqttConfig, r *leaf.Engine, subTopics ...string) autopah
|
||||
zap.S().Infof("MQTT 连接异常: %s\n", err)
|
||||
},
|
||||
ClientConfig: paho.ClientConfig{
|
||||
ClientID: fmt.Sprintf("game-driver-%s-%v", config.C.Location, config.C.Point),
|
||||
ClientID: c.ClientID,
|
||||
OnPublishReceived: []func(paho.PublishReceived) (bool, error){
|
||||
func(pr paho.PublishReceived) (bool, error) {
|
||||
r.Route(pr.Packet.Packet())
|
||||
@@ -109,8 +110,8 @@ func Run() {
|
||||
|
||||
router := leaf.Default(ctx)
|
||||
|
||||
log, _ := zap.NewStdLogAt(zap.L(), zap.DebugLevel)
|
||||
router.SetDebugLogger(log)
|
||||
logAt, _ := zap.NewStdLogAt(zap.L(), zap.DebugLevel)
|
||||
router.SetDebugLogger(logAt)
|
||||
|
||||
router.DefaultHandler(func(c *leaf.Context) {
|
||||
zap.S().Infof("未处理消息,topic: %s\n payload: %s\n", c.Topic, c.Payload)
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"github.com/go-rod/rod"
|
||||
"github.com/go-rod/rod/lib/launcher"
|
||||
"github.com/go-rod/rod/lib/launcher/flags"
|
||||
"github.com/go-rod/rod/lib/proto"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// OpenApp 用APP模式打开网页
|
||||
@@ -26,18 +24,5 @@ func OpenApp(c context.Context, url string) {
|
||||
b := rod.New().ControlURL(p).MustConnect()
|
||||
defer b.MustClose()
|
||||
|
||||
s := make(chan struct{})
|
||||
|
||||
wait := b.EachEvent(func(e *proto.TargetTargetDestroyed) {
|
||||
zap.S().Infoln("浏览器关闭事件")
|
||||
s <- struct{}{}
|
||||
})
|
||||
go wait()
|
||||
|
||||
select {
|
||||
case <-c.Done():
|
||||
b.MustClose()
|
||||
<-s
|
||||
case <-s:
|
||||
}
|
||||
<-c.Done()
|
||||
}
|
||||
|
||||
@@ -2,16 +2,12 @@ package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LinkVideo 链接视频,解析链接,网络文件会下载到临时目录并返回本地路径
|
||||
func LinkVideo(link string) (local string, err error) {
|
||||
func LinkVideo(link string) (path string, local bool, err error) {
|
||||
if link == "" {
|
||||
return
|
||||
}
|
||||
@@ -20,35 +16,14 @@ func LinkVideo(link string) (local string, err error) {
|
||||
err = fmt.Errorf("URL 解析错误: %v", err)
|
||||
} else {
|
||||
if u.Scheme == "file" {
|
||||
local, _ = strings.CutPrefix(link, "file://")
|
||||
local = true
|
||||
path, _ = strings.CutPrefix(link, "file://")
|
||||
} else if u.Scheme == "http" || u.Scheme == "https" {
|
||||
p, _ := url.PathUnescape(u.EscapedPath())
|
||||
tmpLocal := path.Join(os.TempDir(), path.Base(p))
|
||||
err = Download(link, tmpLocal)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("链接文件获取失败: %v", err)
|
||||
return
|
||||
}
|
||||
local = tmpLocal
|
||||
local = false
|
||||
path = link
|
||||
} else {
|
||||
err = fmt.Errorf("不支持的链接协议: %v", u.String())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Download 下载文件
|
||||
func Download(link string, local string) (err error) {
|
||||
resp, err := http.Get(link)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
f, err := os.OpenFile(local, os.O_CREATE|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = io.Copy(f, resp.Body)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
libvlc "github.com/adrg/libvlc-go/v3"
|
||||
)
|
||||
|
||||
func Play(ctx context.Context, file string) error {
|
||||
func Play(ctx context.Context, path string, local bool) error {
|
||||
// 1. 初始化 VLC
|
||||
if err := libvlc.Init("--no-xlib"); err != nil {
|
||||
return fmt.Errorf("VLC初始化失败: %w", err)
|
||||
@@ -38,8 +38,14 @@ func Play(ctx context.Context, file string) error {
|
||||
}
|
||||
|
||||
// 4. 加载并播放文件
|
||||
if _, err := player.LoadMediaFromPath(file); err != nil {
|
||||
return fmt.Errorf("文件加载失败: %w", err)
|
||||
if local {
|
||||
if _, err := player.LoadMediaFromPath(path); err != nil {
|
||||
return fmt.Errorf("文件加载失败: %w", err)
|
||||
}
|
||||
} else {
|
||||
if _, err := player.LoadMediaFromURL(path); err != nil {
|
||||
return fmt.Errorf("文件加载失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := player.Play(); err != nil {
|
||||
@@ -57,7 +63,7 @@ func Play(ctx context.Context, file string) error {
|
||||
}
|
||||
|
||||
// 5. 等待事件
|
||||
fmt.Printf("正在播放: %s\n", file)
|
||||
fmt.Printf("正在播放: %s\n", path)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("播放被用户中断")
|
||||
|
||||
Reference in New Issue
Block a user