interruption_flow.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 打断和恢复功能实现说明
  5. 此文件描述了完整的打断和恢复功能实现流程
  6. """
  7. """
  8. 功能概述:
  9. 实现用户在数字人介绍过程中提问的功能:
  10. 1. 数字人开始播放介绍内容
  11. 2. 用户在介绍过程中可以随时提问
  12. 3. 数字人立即暂停介绍,优先回答用户问题
  13. 4. 回答完用户问题后,继续播放之前未完成的介绍内容
  14. """
  15. """
  16. 系统组件及交互流程:
  17. 1. 前端 (dashboard.html)
  18. - 检测到用户提问时,发送带有以下参数的请求到 /human 接口:
  19. {
  20. "text": "用户问题",
  21. "type": "chat",
  22. "interrupt": true, # 表示需要打断当前播放
  23. "during_intro": true, # 表示当前在介绍过程中
  24. "sessionid": session_id,
  25. "knowledge_base": "知识库类型"
  26. }
  27. 2. 后端 (app.py)
  28. - human() 函数接收请求
  29. - 检测到 interrupt=true 且 type='chat'
  30. - 调用 flush_talk() 中断当前播放
  31. - 调用 llm_response() 处理用户问题
  32. 3. LLM处理 (llm.py)
  33. - llm_response() 函数
  34. - 根据 during_intro 参数决定处理方式
  35. - 如果 during_intro=True,调用 handle_interruption_during_intro()
  36. - 如果 during_intro=False,调用 put_user_question()
  37. 4. 播放控制 (basereal.py)
  38. - handle_interruption_during_intro() 方法:
  39. * 保存当前未完成的介绍内容到 interrupted_queue
  40. * 停止当前播放
  41. * 将用户问题的回答放入高优先级队列播放
  42. - put_user_question() 方法:
  43. * 中断当前播放
  44. * 将用户问题的回答放入高优先级队列播放
  45. 5. 播放引擎 (ttsreal.py)
  46. - 处理高优先级队列和普通队列
  47. - 优先播放高优先级队列中的内容
  48. - 发送开始和结束事件通知
  49. 6. 自动恢复机制 (basereal.py)
  50. - notify() 方法检测到用户问题回答结束
  51. - 启动定时器延时调用 _try_resume_after_qa()
  52. - _try_resume_after_qa() 检查是否有被中断的内容需要恢复
  53. - 如果有,则调用 resume_interrupted() 恢复播放
  54. 7. 恢复播放 (basereal.py)
  55. - resume_interrupted() 方法将 interrupted_queue 中的内容移回 msg_queue
  56. - 继续播放之前未完成的介绍内容
  57. """
  58. """
  59. API接口说明:
  60. 1. /human 接口 (app.py)
  61. - 用途:发送文本给数字人播放
  62. - 参数:
  63. - text: 要播放的文本
  64. - type: 'echo'(朗读) 或 'chat'(聊天)
  65. - interrupt: true/false,是否打断当前播放
  66. - during_intro: true/false,是否在介绍过程中
  67. - sessionid: 会话ID
  68. - knowledge_base: 知识库类型
  69. 2. /interrupt_talk 接口 (app.py)
  70. - 用途:专门用于打断数字人说话
  71. - 参数:
  72. - sessionid: 会话ID
  73. 3. /resume_interrupted 接口 (app.py)
  74. - 用途:恢复被中断的内容
  75. - 参数:
  76. - sessionid: 会话ID
  77. 4. /continue_after_qa 接口 (app.py)
  78. - 用途:问答后继续播放之前的内容
  79. - 参数:
  80. - sessionid: 会话ID
  81. """
  82. """
  83. 关键方法说明:
  84. 1. BaseReal.flush_talk() - 中断当前播放并保存未完成的内容
  85. 2. BaseReal.handle_interruption_during_intro() - 处理介绍过程中的用户提问
  86. 3. BaseReal.put_user_question() - 处理用户问题(高优先级)
  87. 4. BaseReal.resume_interrupted() - 恢复被中断的内容
  88. 5. BaseReal.notify() - 处理播放事件通知,实现自动恢复
  89. 6. llm_response() - 处理用户问题并获取回答
  90. """
  91. """
  92. 工作流程示例:
  93. 1. 数字人开始播放介绍:"欢迎使用本地生活App!我们提供丰富的商品和服务..."
  94. 2. 用户在播放过程中提问:"休闲娱乐有什么?"
  95. 3. 前端发送请求:{type:'chat', interrupt:true, during_intro:true, text:'休闲娱乐有什么?'}
  96. 4. 后端接收请求,调用 flush_talk() 中断当前播放
  97. 5. 系统保存未完成的介绍内容到中断队列
  98. 6. llm_response() 获取回答:"休闲娱乐包括电影院、KTV、游乐场等..."
  99. 7. 调用 handle_interruption_during_intro() 播放回答
  100. 8. 播放回答过程中,系统检测到回答结束事件
  101. 9. notify() 方法触发自动恢复机制
  102. 10. 系统从中断队列取出之前未完成的介绍内容继续播放
  103. """
  104. if __name__ == "__main__":
  105. print("打断和恢复功能实现说明")
  106. print("="*50)
  107. print("此实现确保了用户可以在数字人介绍过程中随时提问")
  108. print("系统会暂停介绍 -> 回答用户问题 -> 恢复介绍 的完整流程")