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

4.1 KiB
Raw Blame History

缓存音频播放完成检测修复总结

问题描述

缓存音频播放时,系统在音频还未播放完成时就错误地发送了完成信号。具体表现为:

  • 缓存音频播放到6-7秒时系统错误地检测到播放完成
  • 发送完成事件并重置播放状态,导致音频被中断
  • 用户听到的是不完整的音频播放

根本原因分析

  1. _play_cached_audio() 方法中,当播放开始时就立即设置了 tts_generation_complete = Truellm_generation_complete = True
  2. _check_enhanced_playback_completion() 方法没有区分缓存音频和普通TTS音频
  3. 当主控制系统发送结束信号时,播放完成检测机制错误地认为所有条件都已满足

修复方案

1. 添加缓存音频状态标识

OutputProcess 类的 __init__ 方法中添加:

self.is_playing_cached_audio = False  # 是否正在播放缓存音频

2. 修改 _play_cached_audio() 方法

  • 移除立即设置 tts_generation_completellm_generation_complete 的代码
  • 添加缓存音频状态设置:
    # 设置缓存音频播放状态
    self.is_playing_cached_audio = True
    
  • 在发送TTS完成信号后只设置TTS完成状态
    # 缓存音频没有真正的TTS过程所以立即设置TTS完成状态
    # 但不设置LLM完成状态让缓存音频完成检测逻辑处理
    self.tts_generation_complete = True
    

3. 添加专门的缓存音频完成检测方法

新增 _check_cached_audio_completion() 方法:

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() 方法

在方法开头添加缓存音频检测逻辑:

# 如果正在播放缓存音频,使用简化的完成检测逻辑
if self.is_playing_cached_audio:
    return self._check_cached_audio_completion()

5. 确保状态正确重置

_finish_playback() 方法中添加:

self.is_playing_cached_audio = False  # 重置缓存音频播放状态

修复效果

修复后的系统具有以下特性:

  1. 区分音频类型能够区分缓存音频和普通TTS音频
  2. 简化检测逻辑缓存音频使用简化的完成检测逻辑不依赖LLM和TTS完成状态
  3. 确保完整播放只有当缓冲区为空、播放器空闲且至少1秒无新音频时才认为播放完成
  4. 状态管理:正确管理所有相关状态,确保状态一致性

测试验证

创建了专门的测试脚本验证修复效果:

  • 新增状态变量和方法正确
  • 缓存音频完成检测逻辑正确
  • 缓存音频播放中检测逻辑正确

注意事项

  1. 该修复不影响普通TTS音频的播放完成检测
  2. 主控制系统的逻辑保持不变
  3. 缓存音频播放仍然遵循原有的音频播放流程
  4. 修复向后兼容,不会破坏现有功能

结论

通过区分缓存音频和TTS音频的播放完成检测逻辑成功解决了缓存音频提前结束的问题。现在缓存音频能够完整播放只有在真正播放完成后才会发送完成事件。