feat(audio): 添加音频播放进度监控和停滞检测
为诊断 TTS 音频播放卡死问题,在 PlayWav 函数中添加实时播放进度监控: - 每秒打印当前播放位置、进度百分比和播放时间 - 检测播放停滞(位置不变时打印警告) - 改进日志输出,显示总样本数和预计时长 - 移除 select case 中的多余花括号 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,13 +2,14 @@ package audio
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gopxl/beep/v2"
|
"github.com/gopxl/beep/v2"
|
||||||
"github.com/gopxl/beep/v2/mp3"
|
"github.com/gopxl/beep/v2/mp3"
|
||||||
"github.com/gopxl/beep/v2/speaker"
|
"github.com/gopxl/beep/v2/speaker"
|
||||||
"github.com/gopxl/beep/v2/wav"
|
"github.com/gopxl/beep/v2/wav"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"io"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var DefaultSampleRate = beep.SampleRate(44100)
|
var DefaultSampleRate = beep.SampleRate(44100)
|
||||||
@@ -30,7 +31,11 @@ func PlayWav(c context.Context, r io.Reader) {
|
|||||||
}
|
}
|
||||||
defer streamer.Close()
|
defer streamer.Close()
|
||||||
|
|
||||||
zap.S().Debugln("WAV解码成功,采样率:", format.SampleRate)
|
// 获取音频长度信息
|
||||||
|
totalSamples := streamer.Len()
|
||||||
|
zap.S().Debugf("WAV解码成功,采样率: %d, 总样本数: %d, 预计时长: %.2f秒",
|
||||||
|
format.SampleRate, totalSamples, float64(totalSamples)/float64(format.SampleRate))
|
||||||
|
|
||||||
s := beep.Resample(4, format.SampleRate, DefaultSampleRate, streamer)
|
s := beep.Resample(4, format.SampleRate, DefaultSampleRate, streamer)
|
||||||
|
|
||||||
ctrl := &beep.Ctrl{Streamer: s}
|
ctrl := &beep.Ctrl{Streamer: s}
|
||||||
@@ -41,18 +46,32 @@ func PlayWav(c context.Context, r io.Reader) {
|
|||||||
})))
|
})))
|
||||||
|
|
||||||
zap.S().Debugln("等待音频播放完成...")
|
zap.S().Debugln("等待音频播放完成...")
|
||||||
|
ticker := time.NewTicker(1 * time.Second)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
lastPos := 0
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
zap.S().Infoln("音频播放正常结束")
|
zap.S().Infoln("音频播放正常结束")
|
||||||
return
|
return
|
||||||
case <-c.Done():
|
case <-c.Done():
|
||||||
{
|
zap.S().Debugf("音频播放被 context 取消: %v", c.Err())
|
||||||
zap.S().Infoln("音频播放被 context 取消")
|
speaker.Lock()
|
||||||
speaker.Lock()
|
ctrl.Streamer = nil
|
||||||
ctrl.Streamer = nil
|
speaker.Unlock()
|
||||||
speaker.Unlock()
|
return
|
||||||
return
|
case <-ticker.C:
|
||||||
|
// 获取当前播放位置
|
||||||
|
pos := streamer.Position()
|
||||||
|
if pos != lastPos {
|
||||||
|
progress := float64(pos) / float64(totalSamples) * 100
|
||||||
|
currentTime := float64(pos) / float64(format.SampleRate)
|
||||||
|
zap.S().Debugf("播放进度: %d/%d (%.1f%%), %.2f秒", pos, totalSamples, progress, currentTime)
|
||||||
|
lastPos = pos
|
||||||
|
} else {
|
||||||
|
zap.S().Debugf("播放停滞在位置: %d/%d, Streamer状态: %v",
|
||||||
|
pos, totalSamples, ctrl.Streamer != nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,12 +98,10 @@ func PlayMP3(c context.Context, r io.ReadCloser) {
|
|||||||
case <-done:
|
case <-done:
|
||||||
return
|
return
|
||||||
case <-c.Done():
|
case <-c.Done():
|
||||||
{
|
speaker.Lock()
|
||||||
speaker.Lock()
|
ctrl.Streamer = nil
|
||||||
ctrl.Streamer = nil
|
speaker.Unlock()
|
||||||
speaker.Unlock()
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user