优化全局zap的打印,修复待机任务出现多个的情况
This commit is contained in:
@@ -3,6 +3,7 @@ package common
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"game-driver/pkg/logger"
|
||||||
"github.com/eclipse/paho.golang/autopaho"
|
"github.com/eclipse/paho.golang/autopaho"
|
||||||
"github.com/eclipse/paho.golang/paho"
|
"github.com/eclipse/paho.golang/paho"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -29,12 +30,14 @@ func (d *Device) Lock() {
|
|||||||
defer d.OnChange()
|
defer d.OnChange()
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
d.status.Store(1)
|
d.status.Store(1)
|
||||||
|
logger.Infoln("设备上锁")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) Unlock() {
|
func (d *Device) Unlock() {
|
||||||
defer d.OnChange()
|
defer d.OnChange()
|
||||||
d.status.Store(0)
|
d.status.Store(0)
|
||||||
d.mu.Unlock()
|
d.mu.Unlock()
|
||||||
|
logger.Infoln("设备解锁")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) Status() int {
|
func (d *Device) Status() int {
|
||||||
|
|||||||
@@ -10,12 +10,17 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PlayBgm 播放背景音乐
|
||||||
func PlayBgm() leaf.HandlerFunc {
|
func PlayBgm() leaf.HandlerFunc {
|
||||||
return func(c *leaf.Context) {
|
return func(c *leaf.Context) {
|
||||||
pm := leaf.Value[*schema.PlayModal](c, PayloadJSONKey)
|
pm := leaf.Value[*schema.PlayModal](c, PayloadJSONKey)
|
||||||
|
|
||||||
bgm := utils.LinkAudio(pm.BGM)
|
bgm, err := utils.LinkAudio(pm.BGM)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorln("背景音乐解析异常", err)
|
||||||
|
}
|
||||||
if bgm != nil {
|
if bgm != nil {
|
||||||
|
logger.Infoln("背景音乐解析成功")
|
||||||
// 等待组
|
// 等待组
|
||||||
var wait sync.WaitGroup
|
var wait sync.WaitGroup
|
||||||
defer wait.Wait()
|
defer wait.Wait()
|
||||||
@@ -25,15 +30,18 @@ func PlayBgm() leaf.HandlerFunc {
|
|||||||
// 发送结束信号
|
// 发送结束信号
|
||||||
defer close(a)
|
defer close(a)
|
||||||
|
|
||||||
|
wait.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
// 等待结束
|
// 等待结束
|
||||||
wait.Add(1)
|
|
||||||
defer wait.Done()
|
defer wait.Done()
|
||||||
|
|
||||||
ctrl, closer := audio.PlayBgmMP3(bgm)
|
logger.Infoln("开始播放背景音乐")
|
||||||
|
defer logger.Infoln("结束背景音乐播放")
|
||||||
|
|
||||||
|
ctrl, closer, e := audio.PlayBgmMP3(bgm)
|
||||||
defer closer()
|
defer closer()
|
||||||
if ctrl == nil {
|
if e != nil {
|
||||||
logger.Infoln("播放背景音乐失败")
|
logger.Errorln("播放背景音乐失败", e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +55,8 @@ func PlayBgm() leaf.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
} else {
|
||||||
|
logger.Errorln("背景音乐解析为空")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ func PayloadJSON[T schema.JsonModel]() leaf.HandlerFunc {
|
|||||||
pm := new(T)
|
pm := new(T)
|
||||||
err := json.Unmarshal(c.Payload, pm)
|
err := json.Unmarshal(c.Payload, pm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("报文解析错误: %v\n", err)
|
logger.Panicln("报文解析错误", err)
|
||||||
}
|
}
|
||||||
leaf.WithValue[*T](c, PayloadJSONKey, pm)
|
leaf.WithValue[*T](c, PayloadJSONKey, pm)
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
func RunLog() leaf.HandlerFunc {
|
func RunLog() leaf.HandlerFunc {
|
||||||
return func(c *leaf.Context) {
|
return func(c *leaf.Context) {
|
||||||
logger.Infof("收到消息, topic: %s, payload: %s", c.Topic, c.Payload)
|
logger.Infof("收到消息, topic: %s, payload: %s", c.Topic, c.Payload)
|
||||||
defer logger.Infof("执行结束")
|
defer logger.Infof("处理结束")
|
||||||
|
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package middleware
|
|||||||
import (
|
import (
|
||||||
"game-driver/internal/schema"
|
"game-driver/internal/schema"
|
||||||
"game-driver/leaf"
|
"game-driver/leaf"
|
||||||
|
"game-driver/pkg/logger"
|
||||||
"game-driver/pkg/relay"
|
"game-driver/pkg/relay"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,6 +14,11 @@ func RelayMaster(r *relay.Device) leaf.HandlerFunc {
|
|||||||
if r != nil && pm.Power {
|
if r != nil && pm.Power {
|
||||||
r.On(1)
|
r.On(1)
|
||||||
defer r.Off(1)
|
defer r.Off(1)
|
||||||
|
|
||||||
|
logger.Infoln("开启电源")
|
||||||
|
defer logger.Infoln("关闭电源")
|
||||||
|
} else {
|
||||||
|
logger.Infoln("继电器未开启/不需要电源控制")
|
||||||
}
|
}
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package middleware
|
|||||||
import (
|
import (
|
||||||
"game-driver/internal/common"
|
"game-driver/internal/common"
|
||||||
"game-driver/leaf"
|
"game-driver/leaf"
|
||||||
|
"game-driver/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EmergencyStop 紧急停止中间件
|
// EmergencyStop 紧急停止中间件
|
||||||
@@ -17,10 +18,13 @@ func EmergencyStop(stopper common.Stopper) leaf.HandlerFunc {
|
|||||||
defer close(a)
|
defer close(a)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
defer logger.Infoln("结束停止信号监控")
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-a:
|
case <-a:
|
||||||
case <-stopper.Done():
|
case <-stopper.Done():
|
||||||
{
|
{
|
||||||
|
logger.Infoln("紧急停止信号触发")
|
||||||
cancel()
|
cancel()
|
||||||
leaf.WithValue[leaf.EndType](c, leaf.EndKey, leaf.EndStop)
|
leaf.WithValue[leaf.EndType](c, leaf.EndKey, leaf.EndStop)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package middleware
|
|||||||
import (
|
import (
|
||||||
"game-driver/internal/schema"
|
"game-driver/internal/schema"
|
||||||
"game-driver/leaf"
|
"game-driver/leaf"
|
||||||
|
"game-driver/pkg/logger"
|
||||||
"game-driver/pkg/tts"
|
"game-driver/pkg/tts"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -31,14 +32,18 @@ func TickerAction() leaf.HandlerFunc {
|
|||||||
// 发送结束信号
|
// 发送结束信号
|
||||||
defer close(a)
|
defer close(a)
|
||||||
|
|
||||||
|
wait.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
// 等待结束
|
// 等待结束
|
||||||
wait.Add(1)
|
|
||||||
defer wait.Done()
|
defer wait.Done()
|
||||||
// 定时器
|
// 定时器
|
||||||
ticker := time.NewTicker(time.Second)
|
ticker := time.NewTicker(time.Second)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
logger.Infoln("开始 Ticker 计时")
|
||||||
|
defer logger.Infoln("结束 Ticker 计时")
|
||||||
|
|
||||||
for over := false; !over; {
|
for over := false; !over; {
|
||||||
select {
|
select {
|
||||||
case <-a:
|
case <-a:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package middleware
|
|||||||
import (
|
import (
|
||||||
"game-driver/internal/schema"
|
"game-driver/internal/schema"
|
||||||
"game-driver/leaf"
|
"game-driver/leaf"
|
||||||
|
"game-driver/pkg/logger"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -31,15 +32,20 @@ func TimeoutOver(maxTimeout int) leaf.HandlerFunc {
|
|||||||
defer close(a)
|
defer close(a)
|
||||||
|
|
||||||
cancel := leaf.WithCancel(c)
|
cancel := leaf.WithCancel(c)
|
||||||
|
wait.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
// 等待结束
|
// 等待结束
|
||||||
wait.Add(1)
|
|
||||||
defer wait.Done()
|
defer wait.Done()
|
||||||
|
|
||||||
|
logger.Infoln("超时 Timer 监控开始")
|
||||||
|
defer logger.Infoln("超时 Timer 监控结束")
|
||||||
|
|
||||||
// 结束标志
|
// 结束标志
|
||||||
select {
|
select {
|
||||||
case <-a:
|
case <-a:
|
||||||
case <-timer.C: // 定时器结束
|
case <-timer.C: // 定时器结束
|
||||||
{
|
{
|
||||||
|
logger.Infoln("超时 Timer 触发")
|
||||||
cancel()
|
cancel()
|
||||||
leaf.WithValue[leaf.EndType](c, leaf.EndKey, leaf.EndTimer)
|
leaf.WithValue[leaf.EndType](c, leaf.EndKey, leaf.EndTimer)
|
||||||
}
|
}
|
||||||
|
|||||||
28
internal/middleware/unique.go
Normal file
28
internal/middleware/unique.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"game-driver/internal/common"
|
||||||
|
"game-driver/leaf"
|
||||||
|
"game-driver/pkg/logger"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Unique 唯一任务中间件,会停止之前的任务,让新任务执行。同一时间只能有一个任务在执行
|
||||||
|
func Unique(stopper common.Stopper) leaf.HandlerFunc {
|
||||||
|
var lock sync.Mutex
|
||||||
|
return func(c *leaf.Context) {
|
||||||
|
if !lock.TryLock() {
|
||||||
|
logger.Infoln("尝试加锁失败,执行停止任务")
|
||||||
|
stopper.Stop()
|
||||||
|
lock.Lock()
|
||||||
|
}
|
||||||
|
logger.Infoln("加锁完成")
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
lock.Unlock()
|
||||||
|
logger.Infoln("解锁完成")
|
||||||
|
}()
|
||||||
|
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"game-driver/internal/middleware"
|
"game-driver/internal/middleware"
|
||||||
"game-driver/internal/schema"
|
"game-driver/internal/schema"
|
||||||
"game-driver/leaf"
|
"game-driver/leaf"
|
||||||
|
"game-driver/pkg/logger"
|
||||||
"game-driver/pkg/utils"
|
"game-driver/pkg/utils"
|
||||||
"game-driver/pkg/video"
|
"game-driver/pkg/video"
|
||||||
)
|
)
|
||||||
@@ -15,6 +16,11 @@ func OnlyVideo(c *leaf.Context) {
|
|||||||
defer utils.BlankClose()
|
defer utils.BlankClose()
|
||||||
|
|
||||||
if url, ok := payload.Game["video"]; ok {
|
if url, ok := payload.Game["video"]; ok {
|
||||||
_ = video.Play(c, utils.LinkVideo(url.(string)))
|
local, err := utils.LinkVideo(url.(string))
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorln("视频文件获取异常: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_ = video.Play(c, local)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,17 +98,23 @@ func audioAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeMod
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data, err := utils.LinkAudio(item.Data)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorln("音频文件获取异常: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-c.Done():
|
case <-c.Done():
|
||||||
case <-timerAction(item.Start):
|
case <-timerAction(item.Start):
|
||||||
{
|
{
|
||||||
logger.Infoln("开始执行后台任务")
|
logger.Infoln("播放待机音乐")
|
||||||
data := utils.LinkAudio(item.Data)
|
defer logger.Infoln("结束待机音乐")
|
||||||
|
|
||||||
ctrl, closer := audio.PlayBgmMP3(data)
|
ctrl, closer, e := audio.PlayBgmMP3(data)
|
||||||
defer closer()
|
defer closer()
|
||||||
if ctrl == nil {
|
if e != nil {
|
||||||
logger.Infoln("播放背景音乐失败")
|
logger.Errorln("播放待机音乐异常", e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +143,7 @@ func ttsAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeModel
|
|||||||
|
|
||||||
reader, err := tts.DefaultTTS.Get(item.Data)
|
reader, err := tts.DefaultTTS.Get(item.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Infoln("语音合成异常: ", err)
|
logger.Errorln("语音合成异常: ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +151,9 @@ func ttsAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeModel
|
|||||||
case <-c.Done():
|
case <-c.Done():
|
||||||
case <-timerAction(item.Start):
|
case <-timerAction(item.Start):
|
||||||
{
|
{
|
||||||
|
logger.Infoln("循环播放待机 TTS 语音")
|
||||||
|
defer logger.Infoln("结束待机 TTS 语音")
|
||||||
|
|
||||||
for {
|
for {
|
||||||
audio.PlayWav(c, reader)
|
audio.PlayWav(c, reader)
|
||||||
select {
|
select {
|
||||||
@@ -170,7 +179,7 @@ func relayAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeMod
|
|||||||
|
|
||||||
device, err := relay.New(item.Data, nil)
|
device, err := relay.New(item.Data, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Infoln("继电器初始化异常: ", err)
|
logger.Errorln("继电器初始化异常: ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer device.Close()
|
defer device.Close()
|
||||||
@@ -179,6 +188,9 @@ func relayAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeMod
|
|||||||
case <-c.Done():
|
case <-c.Done():
|
||||||
case <-timerAction(item.Start):
|
case <-timerAction(item.Start):
|
||||||
{
|
{
|
||||||
|
logger.Infoln("待机继电器供电")
|
||||||
|
defer logger.Infoln("待机继电器断电")
|
||||||
|
|
||||||
device.On(1)
|
device.On(1)
|
||||||
<-c.Done()
|
<-c.Done()
|
||||||
device.Off(1)
|
device.Off(1)
|
||||||
@@ -197,17 +209,27 @@ func videoAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeMod
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local, err := utils.LinkVideo(item.Data)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorln("视频文件获取异常: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-c.Done():
|
case <-c.Done():
|
||||||
case <-timerAction(item.Start):
|
case <-timerAction(item.Start):
|
||||||
{
|
{
|
||||||
|
logger.Infoln("循环播放待机视频")
|
||||||
|
defer logger.Infoln("结束待机视频")
|
||||||
|
|
||||||
utils.BlankOpen()
|
utils.BlankOpen()
|
||||||
defer utils.BlankClose()
|
defer utils.BlankClose()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
err := video.Play(c, utils.LinkVideo(item.Data))
|
err := video.Play(c, local)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicln("视频播放异常: ", err)
|
logger.Errorln("视频播放异常: ", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case <-c.Done():
|
case <-c.Done():
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"game-driver/internal/schema"
|
"game-driver/internal/schema"
|
||||||
"game-driver/leaf"
|
"game-driver/leaf"
|
||||||
"game-driver/pkg/logger"
|
"game-driver/pkg/logger"
|
||||||
|
"game-driver/pkg/relay"
|
||||||
"game-driver/pkg/tts"
|
"game-driver/pkg/tts"
|
||||||
"game-driver/pkg/utils"
|
"game-driver/pkg/utils"
|
||||||
"github.com/eclipse/paho.golang/autopaho"
|
"github.com/eclipse/paho.golang/autopaho"
|
||||||
@@ -44,7 +45,7 @@ func buildMqtt(c config.MqttConfig, r *leaf.Engine, subTopics ...string) autopah
|
|||||||
if _, err := cm.Subscribe(context.Background(), &paho.Subscribe{
|
if _, err := cm.Subscribe(context.Background(), &paho.Subscribe{
|
||||||
Subscriptions: subscriptions,
|
Subscriptions: subscriptions,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
logger.Infof("failed to subscribe (%s). This is likely to mean no messages will be received.", err)
|
logger.Errorf("failed to subscribe (%s). This is likely to mean no messages will be received.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Infoln("订阅完成")
|
logger.Infoln("订阅完成")
|
||||||
@@ -60,12 +61,12 @@ func buildMqtt(c config.MqttConfig, r *leaf.Engine, subTopics ...string) autopah
|
|||||||
return true, nil
|
return true, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
OnClientError: func(err error) { fmt.Printf("client error: %s\n", err) },
|
OnClientError: func(err error) { logger.Errorf("client error: %s\n", err) },
|
||||||
OnServerDisconnect: func(d *paho.Disconnect) {
|
OnServerDisconnect: func(d *paho.Disconnect) {
|
||||||
if d.Properties != nil {
|
if d.Properties != nil {
|
||||||
fmt.Printf("server requested disconnect: %s\n", d.Properties.ReasonString)
|
logger.Warnf("server requested disconnect: %s\n", d.Properties.ReasonString)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("server requested disconnect; reason code: %d\n", d.ReasonCode)
|
logger.Warnf("server requested disconnect; reason code: %d\n", d.ReasonCode)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -82,6 +83,8 @@ func Run() {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
router := leaf.Default(ctx)
|
router := leaf.Default(ctx)
|
||||||
|
// 应用推出时刷新所有缓冲日志
|
||||||
|
defer logger.DefaultLogger.Sync()
|
||||||
|
|
||||||
log, _ := zap.NewStdLogAt(logger.DefaultLogger.ZapLogger(), zap.DebugLevel)
|
log, _ := zap.NewStdLogAt(logger.DefaultLogger.ZapLogger(), zap.DebugLevel)
|
||||||
router.SetDebugLogger(log)
|
router.SetDebugLogger(log)
|
||||||
@@ -103,13 +106,13 @@ func Run() {
|
|||||||
tts.DefaultTTS = tts.New(ctx, config.C.Aliyun)
|
tts.DefaultTTS = tts.New(ctx, config.C.Aliyun)
|
||||||
|
|
||||||
// 构建继电器对象
|
// 构建继电器对象
|
||||||
//r, err := relay.New(config.C.Relay, func(msg string) {
|
r, err := relay.New(config.C.Relay, func(msg string) {
|
||||||
// logger.Infoln("串口返回: ", msg)
|
logger.Infoln("串口返回: ", msg)
|
||||||
//})
|
})
|
||||||
//if err != nil {
|
if err != nil {
|
||||||
// logger.Panicln("串口连接异常: ", err)
|
logger.Panicln("串口连接异常: ", err)
|
||||||
//}
|
}
|
||||||
//defer r.Close()
|
defer r.Close()
|
||||||
|
|
||||||
// 构建全局设备变量
|
// 构建全局设备变量
|
||||||
device := common.DefaultDevice(ctx, cm, publishTopic)
|
device := common.DefaultDevice(ctx, cm, publishTopic)
|
||||||
@@ -133,6 +136,7 @@ func Run() {
|
|||||||
router.RegisterHandler(topicPrefix+"wait",
|
router.RegisterHandler(topicPrefix+"wait",
|
||||||
middleware.RunLog(),
|
middleware.RunLog(),
|
||||||
middleware.PayloadJSON[schema.WaitModel](),
|
middleware.PayloadJSON[schema.WaitModel](),
|
||||||
|
middleware.Unique(common.GlobalBgStopper),
|
||||||
middleware.EmergencyStop(common.GlobalBgStopper),
|
middleware.EmergencyStop(common.GlobalBgStopper),
|
||||||
routes.WaitAction,
|
routes.WaitAction,
|
||||||
)
|
)
|
||||||
@@ -151,13 +155,13 @@ func Run() {
|
|||||||
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|
||||||
<-sig
|
<-sig
|
||||||
fmt.Println("接收到关闭命令 - 正在关闭程序")
|
logger.Infoln("接收到关闭命令 - 正在关闭程序")
|
||||||
|
|
||||||
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if e := cm.Disconnect(ctx); e != nil {
|
if e := cm.Disconnect(ctx); e != nil {
|
||||||
fmt.Printf("断开连接异常: %s\n", e)
|
logger.Errorln("断开连接异常", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("关闭完成")
|
logger.Infoln("关闭完成")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,16 +8,16 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PlayBgmMP3(r io.ReadCloser, opts ...beep.LoopOption) (*beep.Ctrl, func() error) {
|
func PlayBgmMP3(r io.ReadCloser, opts ...beep.LoopOption) (*beep.Ctrl, func() error, error) {
|
||||||
streamer, format, err := mp3.Decode(r)
|
streamer, format, err := mp3.Decode(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, func() error { return nil }
|
return nil, func() error { return nil }, err
|
||||||
}
|
}
|
||||||
|
|
||||||
loop2, err := beep.Loop2(streamer, opts...)
|
loop2, err := beep.Loop2(streamer, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Infoln("循环播放异常: ", err)
|
logger.Infoln("循环播放异常: ", err)
|
||||||
return nil, streamer.Close
|
return nil, streamer.Close, err
|
||||||
}
|
}
|
||||||
|
|
||||||
s := beep.Resample(4, format.SampleRate, DefaultSampleRate, loop2)
|
s := beep.Resample(4, format.SampleRate, DefaultSampleRate, loop2)
|
||||||
@@ -27,5 +27,5 @@ func PlayBgmMP3(r io.ReadCloser, opts ...beep.LoopOption) (*beep.Ctrl, func() er
|
|||||||
streamer.Close()
|
streamer.Close()
|
||||||
})))
|
})))
|
||||||
|
|
||||||
return ctrl, streamer.Close
|
return ctrl, streamer.Close, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,16 @@ func NewLogger() *Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZapLogger 返回 zap 原始的 zap.Logger
|
||||||
func (l *Logger) ZapLogger() *zap.Logger {
|
func (l *Logger) ZapLogger() *zap.Logger {
|
||||||
return l.zl
|
return l.zl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync 刷新所有缓冲的日志条目
|
||||||
|
func (l *Logger) Sync() error {
|
||||||
|
return l.zs.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
var DefaultLogger = NewLogger()
|
var DefaultLogger = NewLogger()
|
||||||
|
|
||||||
// Debug logs the provided arguments at [DebugLevel].
|
// Debug logs the provided arguments at [DebugLevel].
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func (tts *AliTTS) Sound(text string) {
|
|||||||
if err == nil && buf != nil {
|
if err == nil && buf != nil {
|
||||||
audio.PlayWav(tts.ctx, buf)
|
audio.PlayWav(tts.ctx, buf)
|
||||||
} else {
|
} else {
|
||||||
logger.Panicln("AliTTS 请求异常: ", err)
|
logger.Errorln("AliTTS 请求异常: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"game-driver/pkg/logger"
|
"game-driver/pkg/logger"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -48,21 +49,20 @@ func get(u string) io.ReadCloser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LinkAudio 链接音频,解析链接,直接提取为数据流
|
// LinkAudio 链接音频,解析链接,直接提取为数据流
|
||||||
func LinkAudio(link string) (bgm io.ReadCloser) {
|
func LinkAudio(link string) (bgm io.ReadCloser, err error) {
|
||||||
if link == "" {
|
if link == "" {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
u, err := url.Parse(link)
|
u, err := url.Parse(link)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Infoln("音频 URL 解析错误: ", err)
|
err = fmt.Errorf("URL 解析错误: %v", err)
|
||||||
} else {
|
} else {
|
||||||
if u.Scheme == "file" {
|
if u.Scheme == "file" {
|
||||||
bgm = open(link)
|
bgm = open(link)
|
||||||
} else if u.Scheme == "http" || u.Scheme == "https" {
|
} else if u.Scheme == "http" || u.Scheme == "https" {
|
||||||
bgm = get(link)
|
bgm = get(link)
|
||||||
} else {
|
} else {
|
||||||
logger.Infof("不支持的音频文件协议: %v\n", u.String())
|
err = fmt.Errorf("不支持的链接协议: %v", u.String())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
bgm = toSeeker(bgm)
|
bgm = toSeeker(bgm)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"game-driver/pkg/logger"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -11,13 +11,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// LinkVideo 链接视频,解析链接,网络文件会下载到临时目录并返回本地路径
|
// LinkVideo 链接视频,解析链接,网络文件会下载到临时目录并返回本地路径
|
||||||
func LinkVideo(link string) (local string) {
|
func LinkVideo(link string) (local string, err error) {
|
||||||
if link == "" {
|
if link == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u, err := url.Parse(link)
|
u, err := url.Parse(link)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Infoln("音频 URL 解析错误: ", err)
|
err = fmt.Errorf("URL 解析错误: %v", err)
|
||||||
} else {
|
} else {
|
||||||
if u.Scheme == "file" {
|
if u.Scheme == "file" {
|
||||||
local, _ = strings.CutPrefix(link, "file://")
|
local, _ = strings.CutPrefix(link, "file://")
|
||||||
@@ -26,13 +26,12 @@ func LinkVideo(link string) (local string) {
|
|||||||
tmpLocal := path.Join(os.TempDir(), path.Base(p))
|
tmpLocal := path.Join(os.TempDir(), path.Base(p))
|
||||||
err = Download(link, tmpLocal)
|
err = Download(link, tmpLocal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Infoln("音频文件下载失败: ", err)
|
err = fmt.Errorf("链接文件获取失败: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
local = tmpLocal
|
local = tmpLocal
|
||||||
} else {
|
} else {
|
||||||
logger.Infof("不支持的视频链接协议: %v\n", u.String())
|
err = fmt.Errorf("不支持的链接协议: %v", u.String())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ func Play(ctx context.Context, file string) error {
|
|||||||
|
|
||||||
a := make(chan struct{})
|
a := make(chan struct{})
|
||||||
defer close(a)
|
defer close(a)
|
||||||
go func() {
|
|
||||||
wait.Add(1)
|
wait.Add(1)
|
||||||
|
go func() {
|
||||||
defer wait.Done()
|
defer wait.Done()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|||||||
34
readme.md
34
readme.md
@@ -149,37 +149,3 @@ Payload:
|
|||||||
```
|
```
|
||||||
|
|
||||||
> 同一个类型的待机任务只能有一个,当有新的任务到达时会覆盖之前的任务
|
> 同一个类型的待机任务只能有一个,当有新的任务到达时会覆盖之前的任务
|
||||||
|
|
||||||
|
|
||||||
## 说明
|
|
||||||
|
|
||||||
1. linux 下播放音频
|
|
||||||
```bash
|
|
||||||
sudo apt install libasound2-dev alsa-utils
|
|
||||||
```
|
|
||||||
2. linux 下播放视频
|
|
||||||
```bash
|
|
||||||
sudo apt install ffmpeg
|
|
||||||
```
|
|
||||||
驱动安装
|
|
||||||
```bash
|
|
||||||
libdirectfb-dev
|
|
||||||
```
|
|
||||||
3. 当前用户加入播放音频与视频的组中
|
|
||||||
```bash
|
|
||||||
sudo usermod -aG audio,video $USER
|
|
||||||
```
|
|
||||||
|
|
||||||
### 关闭屏幕帧缓冲
|
|
||||||
```bash
|
|
||||||
# 关闭帧缓冲设备
|
|
||||||
echo 1 | sudo tee /sys/class/graphics/fb0/blank
|
|
||||||
|
|
||||||
# 重新打开帧缓冲设备
|
|
||||||
echo 0 | sudo tee /sys/class/graphics/fb0/blank
|
|
||||||
```
|
|
||||||
|
|
||||||
### 播放视频
|
|
||||||
```bash
|
|
||||||
ffplay -autoexit -fs -i video.mp4
|
|
||||||
```
|
|
||||||
32
todo.md
Normal file
32
todo.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
## 技术点记录
|
||||||
|
|
||||||
|
1. linux 下播放音频
|
||||||
|
```bash
|
||||||
|
sudo apt install libasound2-dev alsa-utils
|
||||||
|
```
|
||||||
|
2. linux 下播放视频
|
||||||
|
```bash
|
||||||
|
sudo apt install ffmpeg
|
||||||
|
```
|
||||||
|
驱动安装
|
||||||
|
```bash
|
||||||
|
libdirectfb-dev
|
||||||
|
```
|
||||||
|
3. 当前用户加入播放音频与视频的组中
|
||||||
|
```bash
|
||||||
|
sudo usermod -aG audio,video $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
### 关闭屏幕帧缓冲
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 关闭帧缓冲设备
|
||||||
|
echo 1 | sudo tee /sys/class/graphics/fb0/blank
|
||||||
|
# 重新打开帧缓冲设备
|
||||||
|
echo 0 | sudo tee /sys/class/graphics/fb0/blank
|
||||||
|
```
|
||||||
|
|
||||||
|
### 播放视频
|
||||||
|
```bash
|
||||||
|
ffplay -autoexit -fs -i video.mp4
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user