Local-Voice/CACHE_AUDIO_FIX_SUMMARY.md
2025-09-23 13:40:57 +08:00

101 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 缓存音频播放完成检测修复总结
## 问题描述
缓存音频播放时,系统在音频还未播放完成时就错误地发送了完成信号。具体表现为:
- 缓存音频播放到6-7秒时系统错误地检测到播放完成
- 发送完成事件并重置播放状态,导致音频被中断
- 用户听到的是不完整的音频播放
## 根本原因分析
1.`_play_cached_audio()` 方法中,当播放开始时就立即设置了 `tts_generation_complete = True``llm_generation_complete = True`
2. `_check_enhanced_playback_completion()` 方法没有区分缓存音频和普通TTS音频
3. 当主控制系统发送结束信号时,播放完成检测机制错误地认为所有条件都已满足
## 修复方案
### 1. 添加缓存音频状态标识
`OutputProcess` 类的 `__init__` 方法中添加:
```python
self.is_playing_cached_audio = False # 是否正在播放缓存音频
```
### 2. 修改 `_play_cached_audio()` 方法
- 移除立即设置 `tts_generation_complete``llm_generation_complete` 的代码
- 添加缓存音频状态设置:
```python
# 设置缓存音频播放状态
self.is_playing_cached_audio = True
```
- 在发送TTS完成信号后只设置TTS完成状态
```python
# 缓存音频没有真正的TTS过程所以立即设置TTS完成状态
# 但不设置LLM完成状态让缓存音频完成检测逻辑处理
self.tts_generation_complete = True
```
### 3. 添加专门的缓存音频完成检测方法
新增 `_check_cached_audio_completion()` 方法:
```python
def _check_cached_audio_completion(self):
"""缓存音频播放完成检测 - 简化逻辑不依赖LLM和TTS完成状态"""
# 更新状态变量
self.pre_buffer_empty = (len(self.preload_buffer) == 0)
self.playback_buffer_empty = (len(self.playback_buffer) == 0)
self.no_active_playback = (not self.currently_playing)
# 计算时间差
current_time = time.time()
time_since_last_chunk = current_time - self.last_audio_chunk_time
# 缓存音频完成条件:
# 1. 缓冲区都为空
# 2. 没有活跃播放
# 3. 至少1秒没有新音频播放确保音频完全播放完成
if (self.pre_buffer_empty and
self.playback_buffer_empty and
self.no_active_playback):
if self.last_audio_chunk_time > 0 and time_since_last_chunk > 1.0:
print(f"✅ 缓存音频播放完成:缓冲区已清空,播放器空闲,{time_since_last_chunk:.2f}秒无新音频")
return True
else:
return False
else:
return False
```
### 4. 修改 `_check_enhanced_playback_completion()` 方法
在方法开头添加缓存音频检测逻辑:
```python
# 如果正在播放缓存音频,使用简化的完成检测逻辑
if self.is_playing_cached_audio:
return self._check_cached_audio_completion()
```
### 5. 确保状态正确重置
`_finish_playback()` 方法中添加:
```python
self.is_playing_cached_audio = False # 重置缓存音频播放状态
```
## 修复效果
修复后的系统具有以下特性:
1. **区分音频类型**能够区分缓存音频和普通TTS音频
2. **简化检测逻辑**缓存音频使用简化的完成检测逻辑不依赖LLM和TTS完成状态
3. **确保完整播放**只有当缓冲区为空、播放器空闲且至少1秒无新音频时才认为播放完成
4. **状态管理**:正确管理所有相关状态,确保状态一致性
## 测试验证
创建了专门的测试脚本验证修复效果:
- ✅ 新增状态变量和方法正确
- ✅ 缓存音频完成检测逻辑正确
- ✅ 缓存音频播放中检测逻辑正确
## 注意事项
1. 该修复不影响普通TTS音频的播放完成检测
2. 主控制系统的逻辑保持不变
3. 缓存音频播放仍然遵循原有的音频播放流程
4. 修复向后兼容,不会破坏现有功能
## 结论
通过区分缓存音频和TTS音频的播放完成检测逻辑成功解决了缓存音频提前结束的问题。现在缓存音频能够完整播放只有在真正播放完成后才会发送完成事件。