mycroft-core Audioservice可能无法恢复音量,

piah890a  于 4个月前  发布在  iOS
关注(0)|答案(4)|浏览(70)

音频在某些情况下无法恢复音量。
这可能是由wait_for_message与相同消息创建的并行等待引起的吗?
至少,当前的audioservice可能在等待消息时被重新分配给None。因此,之前的对self.current的检查不再准确。应该在内部函数中重新检查。
相关日志:

2020-09-30 03:37:48.280 | INFO     |   439 | mycroft.audio.speech:mute_and_speak:127 | Speak: Here is this hour's news on NPR News Now.
2020-09-30 03:37:52.405 | INFO     |   439 | mycroft.audio.speech:mute_and_speak:127 | Speak: Give me a moment to check for that
2020-09-30 03:37:55.083 | INFO     |   439 | audioservice_simple:add_list:75 | Track list is [['file:///tmp/mycroft/cache/NewsSkill/stream', 'audio/mpeg']]
2020-09-30 03:37:55.086 | INFO     |   439 | audioservice_simple:play:147 | Call SimpleAudioServicePlay
2020-09-30 03:37:55.176 | INFO     |   439 | audioservice_simple:_play:82 | SimpleAudioService._play
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3
	version 1.25.13; written and copyright by Michael Hipp and others
	free software (LGPL) without any warranty but with best wishes

Directory: /tmp/mycroft/cache/NewsSkill/
Playing MPEG stream 1 of 1: stream ...

MPEG 1.0 L III cbr128 44100 stereo

Title:   
2020-09-30 03:38:00.342 | INFO     |   439 | audioservice_simple:stop:152 | SimpleAudioServiceStop
2020-09-30 03:38:00.363 | INFO     |   439 | mycroft.audio.speech:mute_and_speak:127 | Speak: Here is this hour's news on NPR News Now.

mpg123: death by SIGTERM
2020-09-30 03:38:03.111 | INFO     |   439 | audioservice_simple:add_list:75 | Track list is [['file:///tmp/mycroft/cache/NewsSkill/stream', 'audio/mpeg']]
2020-09-30 03:38:03.112 | INFO     |   439 | audioservice_simple:play:147 | Call SimpleAudioServicePlay
2020-09-30 03:38:03.168 | INFO     |   439 | audioservice_simple:_play:82 | SimpleAudioService._play
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3
	version 1.25.13; written and copyright by Michael Hipp and others
	free software (LGPL) without any warranty but with best wishes

Directory: /tmp/mycroft/cache/NewsSkill/
Playing MPEG stream 1 of 1: stream ...

MPEG 1.0 L III cbr128 44100 stereo

Title:   
2020-09-30 03:38:17.459 | INFO     |   439 | audioservice_simple:stop:152 | SimpleAudioServiceStop
2020-09-30 03:38:23.158 | ERROR    |   439 | concurrent.futures | exception calling callback for <Future at 0x7f482e1fa0 state=finished raised AttributeError>
Traceback (most recent call last):
  File "/usr/lib/python3.8/concurrent/futures/_base.py", line 328, in _invoke_callbacks
    callback(self)
  File "/home/mycroft/mycroft-core/.venv/lib/python3.8/site-packages/pyee/_executor.py", line 60, in _callback
    self.emit('error', exc)
  File "/home/mycroft/mycroft-core/.venv/lib/python3.8/site-packages/pyee/_base.py", line 111, in emit
    self._emit_handle_potential_error(event, args[0] if args else None)
  File "/home/mycroft/mycroft-core/.venv/lib/python3.8/site-packages/pyee/_base.py", line 83, in _emit_handle_potential_error
    raise error
  File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/mycroft/mycroft-core/mycroft/audio/audioservice.py", line 338, in _restore_volume_after_record
    restore_volume()
  File "/home/mycroft/mycroft-core/mycroft/audio/audioservice.py", line 330, in restore_volume
    self.current.restore_volume()
AttributeError: 'NoneType' object has no attribute 'restore_volume'
ct3nt3jp

ct3nt3jp1#

我仔细研究了一下。我认为问题在于恢复音量处理程序在检查self.current的有效性与使用它之间的等待时间最多可达8秒。这本质上是一个竞争条件。
基本上我认为发生的情况是:

  • 检查self.current是否有效
  • 开始等待消息
  • 停止发生,清除self.current
  • 等待完成并启动回调
  • 回调尝试访问self.current

首先,我认为音频服务后端应该能够处理这种情况,在停止时恢复音量。
这种竞争条件可以通过两种更优雅的方式来处理

  • 使用self.service_lock进行更积极的锁定
  • 使用本地副本

例如:

def _restore_volume_after_record(self, message=None):
        """
Restores the volume when Mycroft is done recording.
If no utterance detected, restore immediately.
If no response is made in reasonable time, then also restore.
Args:
message: message bus message, not used but required
"""
        current = self.current # Create local reference to current active service

        def restore_volume():
            LOG.debug('restoring volume')
            current.restore_volume()  # restore the service that were active when this was initiated

        if current:
            self.bus.on('recognizer_loop:speech.recognition.unknown',
                        restore_volume)
            speak_msg_detected = self.bus.wait_for_message('speak',
                                                           timeout=8.0)
            if not speak_msg_detected:
                restore_volume()
            self.bus.remove('recognizer_loop:speech.recognition.unknown',
                            restore_volume)
        else:
            LOG.debug("No audio service to restore volume of")
pkwftd7m

pkwftd7m2#

当一个服务在没有恢复音量的情况下停止时,当它重新启动时,音量是否仍然静音?
这种方法似乎解决了这个问题。
另外,是否有任何危险,例如:

  1. Utt 1 - 唤醒词接收到 - 服务静音
  2. Utt 1 - 用户说话 - "停止"
  3. Utt 2 - 唤醒词接收到 - 服务静音
  4. Utt 1 - 服务停止
  5. Utt 1 - 服务音量恢复

现在播放音乐

  1. Utt 2 - 用户在音乐中说话
jm81lzqq

jm81lzqq3#

你描述的情况在当前简单的音频服务后端中应该是不可能发生的,因为停止命令会退出播放循环。但这取决于实现方式。基本上,服务在停止后如何恢复音量。
在这种情况下,使用锁可能更安全,留给实现的余地更少...

oyjwcjzk

oyjwcjzk4#

我推送了一个带有一些locks的分支,它应该会移 debugging 误信息,但我不确定它是否能解决问题(目前尚未重现)。

相关问题