待机功能基本实现

This commit is contained in:
2024-11-06 15:44:35 +08:00
parent 8e2bf7f59b
commit ab0678aa3b
14 changed files with 317 additions and 151 deletions

View File

@@ -1,93 +0,0 @@
package routes
import (
"game-driver/internal/common"
"game-driver/internal/middleware"
"game-driver/internal/schema"
"game-driver/leaf"
"game-driver/pkg/audio"
"github.com/gopxl/beep/v2"
"github.com/gopxl/beep/v2/mp3"
"github.com/gopxl/beep/v2/speaker"
"log"
"time"
)
func timerAction(timestamp int64) <-chan struct{} {
a := make(chan struct{})
go func() {
if timestamp == 0 {
close(a)
} else {
<-time.After(time.Until(time.Unix(timestamp, 0)))
close(a)
}
}()
return a
}
func BackgroundAction(c *leaf.Context) {
payload := leaf.Value[*schema.BackgroundModel](c, middleware.PayloadJSONKey)
if payload.Start != 0 && payload.End != 0 && time.Unix(payload.Start, 0).After(time.Unix(payload.End, 0)) {
log.Println("开始时间大于结束时间")
return
}
if payload.End != 0 {
cancel := leaf.WithDeadline(c, time.Unix(payload.End, 0))
defer cancel()
}
select {
case <-c.Done():
case <-timerAction(payload.Start):
go audioAction(c, payload.Items[0], payload.TimeModel)
}
}
func audioAction(c *leaf.Context, item schema.BackgroundItemModel, root schema.TimeModel) {
if item.Start != 0 && time.Unix(item.Start, 0).Before(time.Unix(root.Start, 0)) {
log.Println("开始时间小于根任务开始时间")
return
}
select {
case <-c.Done():
case <-timerAction(item.Start):
{
log.Println("开始执行后台任务")
data := common.LinkAudio(item.Data)
streamer, format, err := mp3.Decode(data)
if err != nil {
return
}
defer streamer.Close()
s := beep.Resample(4, format.SampleRate, audio.DefaultSampleRate, streamer)
ctrl := &beep.Ctrl{Streamer: s}
done := make(chan struct{})
speaker.Play(beep.Seq(ctrl, beep.Callback(func() {
close(done)
})))
for {
select {
case <-done:
return
case <-c.Done():
{
speaker.Lock()
ctrl.Streamer = nil
speaker.Unlock()
}
}
}
}
}
}

179
internal/routes/wait.go Normal file
View File

@@ -0,0 +1,179 @@
package routes
import (
"game-driver/internal/middleware"
"game-driver/internal/schema"
"game-driver/leaf"
"game-driver/pkg/audio"
"game-driver/pkg/relay"
"game-driver/pkg/tts"
"github.com/gopxl/beep/v2/speaker"
"log"
"sync"
"time"
)
func timerAction(timestamp int64) <-chan struct{} {
a := make(chan struct{})
go func() {
if timestamp == 0 {
close(a)
} else {
<-time.After(time.Until(time.Unix(timestamp, 0)))
close(a)
}
}()
return a
}
func WaitAction(c *leaf.Context) {
payload := leaf.Value[*schema.WaitModel](c, middleware.PayloadJSONKey)
if payload.Start != 0 && payload.End != 0 && time.Unix(payload.Start, 0).After(time.Unix(payload.End, 0)) {
log.Println("开始时间大于结束时间")
return
}
if payload.End != 0 {
cancel := leaf.WithDeadline(c, time.Unix(payload.End, 0))
defer cancel()
}
select {
case <-c.Done():
case <-timerAction(payload.Start):
// 等待组
var wait sync.WaitGroup
defer wait.Wait()
for _, item := range payload.Items {
switch item.Type {
case schema.WaitAudio:
// 执行音乐播放
go func() {
wait.Add(1)
defer wait.Done()
audioAction(c, item, payload.TimeModel)
}()
case schema.WaitTTS:
// 执行TTS播放
go func() {
wait.Add(1)
defer wait.Done()
ttsAction(c, item, payload.TimeModel)
}()
case schema.WaitRelay:
// 执行继电器供电
go func() {
wait.Add(1)
defer wait.Done()
relayAction(c, item, payload.TimeModel)
}()
case schema.WaitVideo:
case schema.WaitWeb:
default:
log.Printf("不支持的类型: %d\n", item.Type)
}
}
}
}
func audioAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeModel) {
if item.Start != 0 && time.Unix(item.Start, 0).Before(time.Unix(root.Start, 0)) {
log.Println("开始时间小于根任务开始时间")
return
}
if item.End != 0 {
cancel := leaf.WithDeadline(c, time.Unix(item.End, 0))
defer cancel()
}
select {
case <-c.Done():
case <-timerAction(item.Start):
{
log.Println("开始执行后台任务")
data := audio.LinkAudio(item.Data)
ctrl, closer := audio.PlayBgmMP3(data)
defer closer()
if ctrl == nil {
log.Println("播放背景音乐失败")
return
}
select {
case <-c.Done():
{
speaker.Lock()
ctrl.Streamer = nil
speaker.Unlock()
}
}
}
}
}
func ttsAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeModel) {
if item.Start != 0 && time.Unix(item.Start, 0).Before(time.Unix(root.Start, 0)) {
log.Println("开始时间小于根任务开始时间")
return
}
if item.End != 0 {
cancel := leaf.WithDeadline(c, time.Unix(item.End, 0))
defer cancel()
}
reader, err := tts.DefaultTTS.Get(item.Data)
if err != nil {
log.Println("语音合成异常: ", err)
return
}
select {
case <-c.Done():
case <-timerAction(item.Start):
{
for {
audio.PlayWav(c, reader)
select {
case <-c.Done():
return
case <-time.After(time.Duration(item.Interval) * time.Second):
}
}
}
}
}
func relayAction(c *leaf.Context, item schema.WaitItemModel, root schema.TimeModel) {
if item.Start != 0 && time.Unix(item.Start, 0).Before(time.Unix(root.Start, 0)) {
log.Println("开始时间小于根任务开始时间")
return
}
if item.End != 0 {
cancel := leaf.WithDeadline(c, time.Unix(item.End, 0))
defer cancel()
}
device, err := relay.New(item.Data, nil)
if err != nil {
log.Println("继电器初始化异常: ", err)
return
}
defer device.Close()
select {
case <-c.Done():
case <-timerAction(item.Start):
{
device.On(1)
<-c.Done()
device.Off(1)
}
}
}